Avoid /tmp to solve crossdeviced /tmp and /var/lib/captive
authorshort <>
Sat, 11 Oct 2003 15:47:33 +0000 (15:47 +0000)
committershort <>
Sat, 11 Oct 2003 15:47:33 +0000 (15:47 +0000)
 - Bugreported by Martin Drab.

captive.spec.in
debian/rules
src/client/sandbox-server/Makefile.am
src/client/sandbox-server/main.c
src/libcaptive/sandbox/split.c

index 42fe66d..acd19f2 100644 (file)
@@ -159,6 +159,7 @@ rm -rf %{_var}/lib/@PACKAGE@/sandbox-server-*
 %config %{_sysconfdir}/gnome-vfs-2.0/modules/@PACKAGE@.conf
 %{_datadir}/locale/*/LC_MESSAGES/@PACKAGE@.mo
 %attr(755,root,root) %{_var}/lib/@PACKAGE@
+%attr(1777,root,root) %{_var}/lib/@PACKAGE@/tmp
 %attr(644,root,root) %{_var}/lib/@PACKAGE@/*.sys
 
 %files lufs
index fc5c7a7..7b1ed2a 100755 (executable)
@@ -85,7 +85,10 @@ install: build
        dh_movefiles
        #FIXME: dh_movefiles(1) ignores any directories
        #       and dh_installdirs(1) creates them in debian/tmp/
-       mkdir -p $(CURDIR)/debian/captive/var/lib/captive
+       mkdir -p   $(CURDIR)/debian/captive/var/lib/captive
+       chmod  755 $(CURDIR)/debian/captive/var/lib/captive
+       mkdir -p   $(CURDIR)/debian/captive/var/lib/captive/tmp
+       chmod 1777 $(CURDIR)/debian/captive/var/lib/captive/tmp
 
 # Build architecture-dependent files here.
 binary-arch: build install
index 43b7ef9..0a41b75 100644 (file)
@@ -28,6 +28,8 @@ EXTRA_DIST+=.gdbinit
 
 install-data-hook:
        $(mkinstalldirs) $(DESTDIR)$(CAPTIVE_SANDBOX_CHROOT)
+       $(mkinstalldirs) $(DESTDIR)$(CAPTIVE_SANDBOX_CHROOT)/tmp
+       chmod 1777 $(DESTDIR)$(CAPTIVE_SANDBOX_CHROOT)/tmp
 
 EXTRA_DIST+=captive-sandbox-server.pod.pl.in
 CLEANFILES+=captive-sandbox-server.pod captive-sandbox-server.1
index 6846578..3f470bc 100644 (file)
@@ -54,7 +54,11 @@ void captive_corba_sandbox_child(const gchar *chrooted_orbit_dir);
 
 /* CONFIG: */
 
-#define CHROOT_PATH_HASHKEY_LENGTH (64)
+/* FIXME: We hit linc-1.0.1/src/linc-protocols.c/linc_protocol_get_sockaddr_unix()
+ * limit of socket pathname 64 characters.
+ * With CHROOT_PATH_HASHKEY_LENGTH 12 "linc-%x-%x-%x%x" still does not fit completely.
+ */
+#define CHROOT_PATH_HASHKEY_LENGTH (12)
 
 
 GQuark sandbox_server_main_error_quark(void)
@@ -202,7 +206,7 @@ done:
        depth--;
 }
 
-static void chrooted_cleanuplockeddirs(const gchar *pathname)
+static void chrooted_cleanuplockeddirs(const gchar *pathname,const gchar *prefix)
 {
 DIR *dir;
 struct dirent *dirent;
@@ -221,7 +225,7 @@ int direntfd;
 
                if (!strcmp(dirent->d_name,".") || !strcmp(dirent->d_name,".."))
                        continue;
-               if (strncmp(dirent->d_name,"sandbox-server-",strlen("sandbox-server-")))
+               if (strncmp(dirent->d_name,prefix,strlen(prefix)))
                        continue;
                dirent_path=g_strdup_printf("%s/%s",pathname,dirent->d_name);
                if (-1==(direntfd=open(dirent_path,O_RDONLY))) {
@@ -302,7 +306,7 @@ struct rlimit rlim;
                fatal("Unsuccessful setrlimit(%s)",resource_string);
 }
 
-static const gchar *chrooted_orbit_dir;
+static gchar *chrooted_orbit_dir;
 
 static void chroot_setup(gboolean fragile)
 {
@@ -310,6 +314,7 @@ uid_t want_uid=0;
 const gchar *want_uid_name=NULL;
 gid_t want_gid=0;
 char *endptr;
+const gchar *chroot_pid_hashkey_dir=NULL;
 
        if (fragile) {
                captive_sandbox_fd_closeup(2 /* STDERR */ +1);
@@ -366,7 +371,7 @@ struct passwd *want_uid_passwd;
        if (fragile && !optarg_chroot)
                fatal("Fragile setuid/root environment but no --chroot set");
        if (optarg_chroot) {
-const gchar *chroot_pid_dir,*chroot_pid_hashkey_dir;
+const gchar *chroot_pid_dir;
 GRand *grand;
 gchar chroot_hashkey[CHROOT_PATH_HASHKEY_LENGTH+1],*s;
 gint gi;
@@ -387,8 +392,8 @@ gint gi;
                g_rand_free(grand);
                *s=0;
                if (geteuid()==0)       /* Not 'fragile' as we can be native 'root'. */
-                       chrooted_cleanuplockeddirs(optarg_chroot);
-               chroot_pid_dir=captive_printf_alloca("%s/sandbox-server-%d",optarg_chroot,(int)getpid());
+                       chrooted_cleanuplockeddirs(optarg_chroot,"s-");
+               chroot_pid_dir=captive_printf_alloca("%s/s-%d",optarg_chroot,(int)getpid());
                chrooted_createdir(chroot_pid_dir,(!optarg_setuid ? (uid_t)-1 : want_uid),(!optarg_setgid ? (gid_t)-1 : want_gid),
                                TRUE);  /* lock */
                chroot_pid_hashkey_dir=captive_printf_alloca("%s/%s",chroot_pid_dir,chroot_hashkey);
@@ -422,13 +427,15 @@ gint gi;
                        fatal("Failed to setuid(%d)",(!want_uid ? -1 : (int)want_uid));
                }
 
-       /* Prepare /tmp for /tmp/captive-orbit-$PID directories for ORBit2
-        * and also for parent's hardlink to its /tmp/captive-orbit-$pid directory. */
+       /* Prepare /t for /t/o-$PID directories for ORBit2
+        * and also for parent's hardlink to its /t/o-$pid directory. */
        if (optarg_chroot) {
-gchar *chrooted_orbit_dir_old;
+gchar *chrooted_orbit_dir_old,*gs,*gs2;
 
-               if (mkdir("/tmp",S_ISVTX|0777))
-                       fatal("Failed to mkdir(\"%s\"): %m","/tmp");
+               if (mkdir("/t",S_ISVTX|0777)) {
+                       if (errno!=EEXIST)
+                               fatal("Failed to mkdir(\"%s\"): %m","/t");
+                       }
                if (mkdir("/etc",0700))
                        fatal("Failed to mkdir(\"%s\"): %m","/etc");
                if (want_uid_name && want_uid && want_gid) {
@@ -440,7 +447,22 @@ FILE *f;
                        if (fclose(f))
                                fatal("Failed to fclose(\"%s\"): %m","/etc/passwd");
                        }
-               chrooted_orbit_dir=g_strdup_printf("/tmp/captive-orbit-%d",getpid());
+               g_assert(chroot_pid_hashkey_dir!=NULL);
+               chrooted_orbit_dir=g_strdup_printf("%s/t/o-%d",chroot_pid_hashkey_dir,getpid());
+               /* Missing mkdir(2) of the last component path is intentional: */
+               for (gs=chrooted_orbit_dir;(gs2=strchr(gs,'/'));gs=gs2) {
+                       *gs2='\0';
+                       if (*chrooted_orbit_dir && mkdir(chrooted_orbit_dir,S_ISVTX|0777)) {
+                               if (errno!=EEXIST)
+                                       fatal("Failed to mkdir(\"%s\"): %m",chrooted_orbit_dir);
+                               }
+                       *gs2++='/';
+                       }
+               /* Prepare '/tmp' for the initial CORBA_ORB_init() default path: */
+               if (mkdir("/tmp",S_ISVTX|0777)) {
+                       if (errno!=EEXIST)
+                               fatal("Failed to mkdir(\"%s\"): %m","/tmp");
+                       }
                /* Set '0700' to prevent: Wrong permissions for ...
                 * by linc-1.0.1-1/src/linc-protocols.c/make_local_tmpdir()
                 */
index 686622b..f6e1dc5 100644 (file)
@@ -372,7 +372,9 @@ static void sandbox_parent_own_orbit_dir_cleanup_atexit(void)
 {
 static gboolean done=FALSE;
 
-       g_log(G_LOG_DOMAIN,G_LOG_LEVEL_DEBUG,"%s; done=%d",G_STRLOC,(int)done);
+       /* Do not: g_log(G_LOG_DOMAIN,G_LOG_LEVEL_DEBUG,"%s; done=%d",G_STRLOC,(int)done);
+        * as any memory allocation is not permitted for atexit functions.
+        */
        if (done)
                return;
        done=TRUE;
@@ -408,11 +410,15 @@ struct sandbox_parent_own_orbit_dir_cleanup_signal *sigstructp;
        signal(signum,sigstructp->sighandler_orig);
 
        /* Prevent recursive fatal logging before signal restore: */
-       g_log(G_LOG_DOMAIN,G_LOG_LEVEL_DEBUG,"%s: signum=%d,sighandler_orig=%p",G_STRLOC,signum,sigstructp->sighandler_orig);
+       /* Do not: g_log(G_LOG_DOMAIN,G_LOG_LEVEL_DEBUG,"%s: signum=%d,sighandler_orig=%p",G_STRLOC,signum,sigstructp->sighandler_orig);
+        * as it is dangerous to g_log() from sighandler.
+        */
 
        sandbox_parent_own_orbit_dir_cleanup_atexit();
 
-       g_log(G_LOG_DOMAIN,G_LOG_LEVEL_DEBUG,"%s: re-raising...",G_STRLOC);
+       /* Do not: g_log(G_LOG_DOMAIN,G_LOG_LEVEL_DEBUG,"%s: re-raising...",G_STRLOC);
+        * as it is dangerous to g_log() from sighandler.
+        */
        raise(signum);
 }
 
@@ -447,7 +453,8 @@ gboolean errbool;
 
        /* FIXME: Security: Duplicate giop_tmpdir_init() here. */
        if (!sandbox_parent_own_orbit_dir) {
-               sandbox_parent_own_orbit_dir=g_strdup_printf("/tmp/captive-orbit-%d",getpid());
+               /* FIXME: Make 'CAPTIVE_SANDBOX_CHROOT' configurable. */
+               sandbox_parent_own_orbit_dir=g_strdup_printf("%s/tmp/captive-orbit-%d",CAPTIVE_SANDBOX_CHROOT,getpid());
                if (mkdir(sandbox_parent_own_orbit_dir,0700)) {
                        g_assert(errno==EEXIST);
                        sandbox_parent_own_orbit_dir_cleanup_init();
@@ -661,14 +668,29 @@ struct dirent *dirent;
                }
 
        if (child_chroot_pid_hashkey_dir) {
+gchar *s;
+
                child_chroot_parent_own_orbit_dir=captive_printf_alloca("%s/%s",child_chroot_pid_hashkey_dir,sandbox_parent_own_orbit_dir);
-               errint=mkdir(child_chroot_parent_own_orbit_dir,0777);
-               g_assert(errint==0);
-               /* chmod(2) it to prevent mode limitation by
-                * active ulimit(2) of being executed by mount(8).
-                */
-               errint=chmod(child_chroot_parent_own_orbit_dir,0777);
-               g_assert(errint==0);
+               s=(/* de-const */ gchar *)child_chroot_parent_own_orbit_dir;
+               do {
+                       s=strchr(s,'/');
+                       if (s)
+                               *s=0;
+                       if (*child_chroot_parent_own_orbit_dir) {
+                               errint=mkdir(child_chroot_parent_own_orbit_dir,0777);
+                               if (errint)
+                                       g_assert(errno==EEXIST);
+                               else {
+                                       /* chmod(2) it to prevent mode limitation by
+                                        * active ulimit(2) of being executed by mount(8).
+                                        */
+                                       errint=chmod(child_chroot_parent_own_orbit_dir,0777);
+                                       g_assert(errint==0);
+                                       }
+                               }
+                       if (s)
+                               *s++='/';
+                       } while (s);
                child_chroot_parent_own_orbit_socket=captive_printf_alloca("%s/%s",
                                child_chroot_pid_hashkey_dir,sandbox_parent_own_orbit_socket);
                errint=link(sandbox_parent_own_orbit_socket,child_chroot_parent_own_orbit_socket);