Fixed ORBit chroot(2)ing permissions failure
authorshort <>
Mon, 29 Sep 2003 14:15:37 +0000 (14:15 +0000)
committershort <>
Mon, 29 Sep 2003 14:15:37 +0000 (14:15 +0000)
 - Bugreport by the courtesy of Martin Drab.

NEWS
src/client/sandbox-server/Makefile.am
src/client/sandbox-server/main.c
src/libcaptive/client/vfs-parent.h
src/libcaptive/sandbox/Makefile.am
src/libcaptive/sandbox/parent-Vfs.c
src/libcaptive/sandbox/split.c

diff --git a/NEWS b/NEWS
index a8f8a22..30eb8ae 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -5,6 +5,7 @@ NEWS for captive-0.9.1
 ----------------------
 
 * Package deployment nuances fixed; 'ntfs' disks are no longer auto-mounted
+* Fixed ORBit chroot(2)ing permissions failure
 
 
 NEWS for captive-0.9 (2003-09-23)
index 0d6500a..43b7ef9 100644 (file)
@@ -20,7 +20,8 @@ include $(top_srcdir)/Makefile-head.am
 
 captive_sandbox_server_SOURCES= \
                main.c
-captive_sandbox_server_LDADD=$(captive_library) $(INTLLIBS)
+captive_sandbox_server_CFLAGS=$(ORBIT_CFLAGS) $(LINC_CFLAGS)
+captive_sandbox_server_LDADD =$(ORBIT_LIBS)   $(LINC_LIBS)   $(captive_library) $(INTLLIBS)
 sbin_PROGRAMS+=captive-sandbox-server
 sbinPROGRAMS_INSTALL=${INSTALL} -o root -g root -m 4755
 EXTRA_DIST+=.gdbinit
index ac5b22a..6846578 100644 (file)
 #include <unistd.h>
 #include <dirent.h>
 #include <errno.h>
-#include "../../libcaptive/sandbox/split.h"    /* for captive_sandbox_fd_closeup(); FIXME */
 #include <grp.h>
 #include <pwd.h>
 #include <fcntl.h>
 #include <sys/file.h>
 #include <sys/resource.h>
+#include <linc/linc-protocol.h>        /* for linc_set_tmpdir() */
+#include <orbit/orb-core/corba-defs.h>
+
+
+/* Do not: #include "../../libcaptive/sandbox/split.h" * for captive_sandbox_fd_closeup(); FIXME *
+ * as it has libcaptive-dependent includes conditioned by ORBIT2.
+ * FIXME: Unify this declaration:
+ */
+void captive_sandbox_fd_closeup(int fd_first_to_delete);
+void captive_corba_sandbox_child(const gchar *chrooted_orbit_dir);
 
 
 /* CONFIG: */
@@ -395,11 +404,7 @@ gint gi;
                umask(0000);
                if (umask(0000)!=0000)
                        fatal("Failed to set umask(0%o): %m",0000);
-               if (want_uid_name) {
-                       printf("chroot_pid_hashkey_dir=%s\n",chroot_pid_hashkey_dir);
-                       chrooted_orbit_dir=g_strdup_printf("/tmp/orbit-%s",want_uid_name);
-                       printf("chrooted_orbit_dir=%s\n",chrooted_orbit_dir);
-                       }
+               printf("chroot_pid_hashkey_dir=%s\n",chroot_pid_hashkey_dir);
                }
 
        if (fragile && !optarg_setgid)
@@ -417,9 +422,11 @@ gint gi;
                        fatal("Failed to setuid(%d)",(!want_uid ? -1 : (int)want_uid));
                }
 
-       /* Prepare /tmp for /tmp/orbit-$username directories for ORBit2
+       /* Prepare /tmp for /tmp/captive-orbit-$PID directories for ORBit2
         * and also for parent's hardlink to its /tmp/captive-orbit-$pid directory. */
        if (optarg_chroot) {
+gchar *chrooted_orbit_dir_old;
+
                if (mkdir("/tmp",S_ISVTX|0777))
                        fatal("Failed to mkdir(\"%s\"): %m","/tmp");
                if (mkdir("/etc",0700))
@@ -433,6 +440,45 @@ FILE *f;
                        if (fclose(f))
                                fatal("Failed to fclose(\"%s\"): %m","/etc/passwd");
                        }
+               chrooted_orbit_dir=g_strdup_printf("/tmp/captive-orbit-%d",getpid());
+               /* Set '0700' to prevent: Wrong permissions for ...
+                * by linc-1.0.1-1/src/linc-protocols.c/make_local_tmpdir()
+                */
+               if (mkdir(chrooted_orbit_dir,0700)) {
+                       /* Do not: g_assert(errno==EEXIST);
+                        * as if 'optarg_chroot' the whole chroot(2)ed directory should be ours.
+                        */
+                       fatal("Cannot created chrooted_orbit_dir \"%s\": %m",chrooted_orbit_dir);
+                       }
+               /* Init 'orb' to pass through its linc_set_tmpdir() to not to be overriden below. */
+               {
+CORBA_ORB orb;
+CORBA_Environment ev;
+int orb_argc=1;
+gchar *orb_argv[]={
+               (gchar *)captive_strdup_alloca("captive-sandbox-server"),
+               NULL};
+
+                       CORBA_exception_init(&ev);
+                       orb=CORBA_ORB_init(&orb_argc,orb_argv,"orbit-local-orb",&ev);
+                       if (orb==CORBA_OBJECT_NIL)
+                               fatal("Cannot initialize CORBA ORB (CORBA_OBJECT_NIL): %m");
+                       if (ev._major!=CORBA_NO_EXCEPTION)
+                               fatal("Cannot initialize CORBA ORB (exception): %m");
+                       }
+               chrooted_orbit_dir_old=linc_get_tmpdir();       /* returns g_strdup()ed string */
+               g_assert(chrooted_orbit_dir_old!=NULL);
+               linc_set_tmpdir(chrooted_orbit_dir);
+               if (rmdir(chrooted_orbit_dir_old))
+                       fatal("Cannot remove old chrooted_orbit_dir \"%s\": %m",chrooted_orbit_dir_old);
+               g_free(chrooted_orbit_dir_old);
+               /* chmod(2) it to prevent mode limitation by
+                * active ulimit(2) of being executed by mount(8).
+                */
+               /* Set '0777' as our parent does not have 'captive' user permissions. */
+               if (chmod(chrooted_orbit_dir,S_ISVTX|0777))
+                       fatal("Cannot chmod 0%o chrooted_orbit_dir \"%s\": %m",S_ISVTX|0777,chrooted_orbit_dir);
+               printf("chrooted_orbit_dir=%s\n",chrooted_orbit_dir);
                }
 
        if (fragile || !optarg_no_rlimit) {
index 2adf94a..92c2405 100644 (file)
@@ -58,6 +58,8 @@ struct _CaptiveVfsParentObject {
        GIOChannel *corba_parent_giochanel_blind;
        GIOChannel *corba_parent_giochanel_blind_source;
        int corba_parentheart_fds_1;
+       gchar *corba_chrooted_orbit_dir;
+       gchar *corba_socketname;
        pid_t corba_child_pid;
        xmlDoc *corba_bug_doc;
        xmlNode *corba_bug;
index c2bb7d8..5aa94e0 100644 (file)
@@ -53,10 +53,7 @@ libsandbox_la_SOURCES= \
 
 libsandbox_la_CFLAGS=$(ORBIT_CFLAGS) $(LINC_CFLAGS) $(GNOME_VFS_MODULE_CFLAGS) $(LIBXML_CFLAGS)
 
-# $(LINC_LIBS) should be included by $(ORBIT_LIBS)
-# As we have no direct dependency on 'linc' it would be fatal if unexpectedly
-# ORBit-2 would not use 'linc'.
-libsandbox_la_LIBADD=$(ORBIT_LIBS) $(GNOME_VFS_MODULE_LIBS)
+libsandbox_la_LIBADD=$(ORBIT_LIBS)   $(LINC_LIBS)   $(GNOME_VFS_MODULE_LIBS)
 
 CLEANFILES+= \
                $(sandbox_SOURCES)
index 61175f7..0a8c290 100644 (file)
@@ -153,6 +153,22 @@ GIOStatus erriostatus;
                g_return_val_if_fail(errint==0,FALSE);
                }
 
+       /* Cleanup linked child socket to our parent '/tmp'. */
+       if (captive_vfs_parent_object->corba_chrooted_orbit_dir) {
+               if (captive_vfs_parent_object->corba_socketname) {
+const gchar *socketpathname;
+
+                       socketpathname=captive_printf_alloca("%s/%s",
+                                       captive_vfs_parent_object->corba_chrooted_orbit_dir,captive_vfs_parent_object->corba_socketname);
+                       unlink(socketpathname); /* errors ignored */
+                       g_free(captive_vfs_parent_object->corba_socketname);
+                       captive_vfs_parent_object->corba_socketname=NULL;
+                       }
+               rmdir(captive_vfs_parent_object->corba_chrooted_orbit_dir);     /* errors ignored */
+               g_free(captive_vfs_parent_object->corba_chrooted_orbit_dir);
+               captive_vfs_parent_object->corba_chrooted_orbit_dir=NULL;
+               }
+
        /* Cleanup the child process. */
        if (captive_vfs_parent_object->corba_child_pid!=(pid_t)-1) {
                kill(captive_vfs_parent_object->corba_child_pid,SIGKILL);       /* errors ignored */
index c2fdd07..90fb01b 100644 (file)
@@ -76,7 +76,7 @@ gchar *orb_argv[]={
        g_return_val_if_fail(poap!=NULL,FALSE);
 
        if (done)
-               return TRUE;
+               return TRUE;    /* FIXME: '*poap' is left invalid! */
 
        /* Init 'ev' */
        CORBA_exception_init(evp);
@@ -430,7 +430,8 @@ struct sandbox_parent_own_orbit_dir_cleanup_signal *sigstructp;
                }
 }
 
-gchar *sandbox_parent_read_ior(int Vfs_IOR_fd_read,gchar **child_chroot_pid_hashkey_dirp)
+static gchar *sandbox_parent_read_ior
+               (int Vfs_IOR_fd_read,gchar **child_chroot_pid_hashkey_dirp,CaptiveVfsParentObject *captive_vfs_parent_object)
 {
 gchar *data;
 gsize data_size;
@@ -485,15 +486,20 @@ const gchar *chrooted_orbit_dir;
                /* IOR contains the full pathname with the setuid username encoded. */
                chrooted_orbit_dir=g_hash_table_lookup(hash,"chrooted_orbit_dir");
                g_assert(chrooted_orbit_dir!=NULL);
-               if (mkdir(chrooted_orbit_dir,S_ISVTX|0777)) {
+               captive_vfs_parent_object->corba_chrooted_orbit_dir=g_strdup(chrooted_orbit_dir);
+               /* 0700 as this directory will not be reused
+                * to commuicate with any other sandbox child.
+                */
+               if (mkdir(chrooted_orbit_dir,0700)) {
                        g_assert(errno==EEXIST);
                        }
 
                socketname=g_hash_table_lookup(hash,"socketname");
                g_assert(socketname!=NULL);
+               captive_vfs_parent_object->corba_socketname=g_strdup(socketname);
 
                socketpathname_src=captive_printf_alloca("%s/%s/%s",child_chroot_pid_hashkey_dir,chrooted_orbit_dir,socketname);
-               socketpathname_dest=captive_printf_alloca("%s/%s",chrooted_orbit_dir,socketname);
+               socketpathname_dest=g_strdup_printf("%s/%s",chrooted_orbit_dir,socketname);
                errint=link(socketpathname_src,socketpathname_dest);
                g_assert(errint==0);
                }
@@ -837,7 +843,8 @@ gchar *child_chroot_pid_hashkey_dir;
 
                        Vfs_IOR=sandbox_parent_read_ior(
                                        Vfs_IOR_fds[0], /* Vfs_IOR_fd_read */
-                                       &child_chroot_pid_hashkey_dir);
+                                       &child_chroot_pid_hashkey_dir,
+                                       captive_vfs_parent_object);
 
                        sandbox_parent(
                                        Vfs_IOR,        /* Vfs_IOR */