initial checkin
[util-vserver.git] / util-vserver / src / secure-mount.c
1 // $Id$    --*- c++ -*--
2
3 // Copyright (C) 2003 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
4 //  
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; version 2 of the License.
8 //  
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 // GNU General Public License for more details.
13 //  
14 // You should have received a copy of the GNU General Public License
15 // along with this program; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18
19   // secure-mount <chroot-base> <src> <dst>
20   //
21   // mounts <src> into the chroot <chroot-base> at destination <dst> in a way
22   // that prevents symlink attacks
23
24   // algorithm:
25   //   enter chroot
26   //     mount tmpfs-directory
27   //   leave chroot
28   //   mount --bind <src> tmpfs
29   //   enter chroot
30   //     mount --move tmpfs <dst>
31
32 #ifdef HAVE_CONFIG_H
33 #  include <config.h>
34 #endif
35
36 #define VERSION_COPYRIGHT_YEAR          "2003"
37 #define VERSION_COPYRIGHT_AUTHOR        "Enrico Scholz"
38 #include "util.h"
39
40 #include <unistd.h>
41 #include <sys/mount.h>
42 #include <linux/fs.h>
43 #include <sys/types.h>
44 #include <sys/stat.h>
45 #include <fcntl.h>
46 #include <string.h>
47 #include <stdio.h>
48 #include <stdlib.h>
49
50
51 #define MNTPOINT        "/etc"
52
53 static void
54 showHelp(int fd, char const *cmd, int res)
55 {
56   WRITE_MSG(fd, "Usage:  ");
57   WRITE_STR(fd, cmd);
58   WRITE_MSG(fd,
59             " <chroot-base> <src> <dst>\n\n"
60             "Please report bugs to " PACKAGE_BUGREPORT "\n");
61
62   exit(res);
63 }
64
65 static void
66 showVersion()
67 {
68   WRITE_MSG(1,
69             "secure-mount 0.23.5\n"
70             "Copyright (C) 2003 Enrico Scholz\n"
71             VERSION_COPYRIGHT_DISCLAIMER);
72   exit(0);
73 }
74
75 int main(int argc, char *argv[])
76 {
77   int   fd = open("/", O_RDONLY);
78     // HACK: sanity checks should be done before declaration, but this does
79     // not work with C89 compilers
80   char  path[strlen(argc==1 ? "" : argv[1]) + sizeof(MNTPOINT) + 3];
81
82   if (argc>=2) {
83     if (!strcmp(argv[1], "--help"))    showHelp(1, argv[0], 0);
84     if (!strcmp(argv[1], "--version")) showVersion();
85   }
86   if (argc!=4) {
87     WRITE_MSG(2, "Bad parameter count; use --help for further information.\n");
88     exit(255);
89   }
90
91   if (chroot(argv[1]) == -1 ||
92       chdir("/")      == -1) {
93     perror("chroot()/chdir()");
94     exit(1);
95   }
96   
97   if (mount("none", MNTPOINT, "tmpfs", 0, "size=4k")==-1) {
98     perror("mount()");
99     exit(1);
100   }
101
102   if (mkdir(MNTPOINT "/x",0600) == -1) {
103     perror("mkdir()/fchdir()");
104     goto err1;
105   }
106   
107   if (fchdir(fd)      == -1 ||
108       chroot(".")     == -1) {
109     perror("chroot()");
110     goto err2;
111   }
112
113   strcpy(path, argv[1]);
114   strcat(path, MNTPOINT "/x");
115   
116   if (mount(argv[2], path, "", MS_BIND, 0)==-1) {
117     perror("mount()");
118     goto err3;
119   }
120
121   if (chroot(argv[1]) == -1) {
122     perror("chroot()");
123     goto err4;
124   }
125
126   if (chdir("/")      == -1 ||
127       mount(MNTPOINT "/x", argv[3], "", MS_MOVE, 0) == -1) {
128     perror("chdir()/mount()");
129     goto err5;
130   }
131
132   if (umount(MNTPOINT) == -1) {
133     perror("umount()");
134   }
135
136   return 0;
137
138   err5:
139   err4:
140   if (umount(path)==-1)   perror("umount(path)");
141   
142   err3:
143   if (chdir(argv[1])==-1) {
144     perror("chdir()");
145     return 1;
146   }
147
148   err2:
149   err1:
150   if (umount("mnt")==-1)  perror("umount(\"mnt\")");
151
152   return 1;
153 }