X-Git-Url: http://git.jankratochvil.net/?a=blobdiff_plain;f=src%2Flibcaptive%2Fsandbox%2Fsplit.c;h=72107a1ef7470ee9da3d71373f891afd6a6f66c3;hb=d9ed28783f1fead15ddacd50782e3c7fdc004b7d;hp=2aa1b214e26ec2ed703a8394a679f1bb63e30a6e;hpb=112b5b46562f01d5a34d6d0859f5a3776fdccc72;p=captive.git diff --git a/src/libcaptive/sandbox/split.c b/src/libcaptive/sandbox/split.c index 2aa1b21..72107a1 100644 --- a/src/libcaptive/sandbox/split.c +++ b/src/libcaptive/sandbox/split.c @@ -32,11 +32,12 @@ #include "server-Directory.h" #include "server-Vfs.h" #include "../client/vfs.h" -#include "captive/parent-Vfs.h" +#include "parent-Vfs.h" #include #include "server-CaptiveIOChannel.h" #include #include "../client/giochannel-blind.h" /* for captive_giochannel_blind_new() */ +#include /* CONFIG: */ @@ -50,8 +51,9 @@ gboolean validate_CORBA_Environment(CORBA_Environment *evp) if (evp->_major==CORBA_NO_EXCEPTION) return TRUE; - g_message(_("CORBA Exception occured: id=\"%s\", value=%p"), + g_error(_("CORBA Exception occured: id=\"%s\", value=%p"), CORBA_exception_id(evp),CORBA_exception_value(evp)); + CORBA_exception_free(evp); return FALSE; } @@ -74,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); @@ -126,7 +128,11 @@ CORBA_ORB orb; *orbp=CORBA_OBJECT_NIL; heartbeat_source_callback_orb=CORBA_OBJECT_NIL; CORBA_ORB_destroy(orb,evp); - g_return_val_if_fail(validate_CORBA_Environment(evp),FALSE); + /* Do not: g_return_val_if_fail(validate_CORBA_Environment(evp),FALSE); + * here as CORBA_ORB_destroy() sometimes reports: + * WARNING **: ORB: a total of X refs to X ORB objects were leaked + */ + CORBA_exception_free(evp); /* Shutdown 'ev' */ CORBA_exception_free(evp); @@ -134,17 +140,23 @@ CORBA_ORB orb; return TRUE; } +static void sandbox_parent_own_orbit_dir_cleanup_atexit(void); + static void corba_shutdown_atexit(void) { gboolean errbool; errbool=corba_shutdown(&captive_corba_ev,&captive_corba_orb,&captive_corba_poa); g_assert(errbool==TRUE); + + /* Delete the CORBA ORB socket directory only after full CORBA ORB shutdown. */ + sandbox_parent_own_orbit_dir_cleanup_atexit(); } static GSource *captive_corba_sandbox_child_heartbeat_gsource; +#if 0 /* Currently unused - see server-Vfs.c:impl_Captive_Vfs_shutdown() */ void sandbox_child_prepare_shutdown(void) { /* Prevent during shutdown: Captive-WARNING **: CORBA Exception occured: id="IDL:omg.org/CORBA/COMM_FAILURE:1.0" */ @@ -154,6 +166,7 @@ void sandbox_child_prepare_shutdown(void) captive_corba_sandbox_child_heartbeat_gsource=NULL; } } +#endif void sandbox_child_shutdown(void) @@ -208,23 +221,22 @@ Captive_Vfs Vfs_object; impl_POA_Captive_Vfs *Vfs_servant; gboolean errbool; guint errguint; -GSource *gsource; int errint; /* attach heartbeat_source_callback() to watch for any abnormalities * on our open pipe 'parentheart_fds' and terminate the child if parent dies. */ - gsource=g_source_new(&heartbeat_source_watch_funcs,sizeof(GSource)); - g_return_if_fail(gsource!=NULL); + captive_corba_sandbox_child_heartbeat_gsource=g_source_new(&heartbeat_source_watch_funcs,sizeof(GSource)); + g_return_if_fail(captive_corba_sandbox_child_heartbeat_gsource!=NULL); g_source_set_callback( - gsource, /* source */ + captive_corba_sandbox_child_heartbeat_gsource, /* source */ heartbeat_source_callback, /* func */ NULL, /* data */ NULL); /* notify */ heartbeat_source_check_gpollfd.fd=0 /* STDIN */; /* parentheart_fd_read */ heartbeat_source_check_gpollfd.events=HEARTBEAT_SOURCE_CHECK_EVENTS; heartbeat_source_check_gpollfd.revents=0; - g_source_add_poll(gsource,&heartbeat_source_check_gpollfd); + g_source_add_poll(captive_corba_sandbox_child_heartbeat_gsource,&heartbeat_source_check_gpollfd); errbool=corba_init("captive-sandbox-child",&captive_corba_ev,&captive_corba_orb,&captive_corba_poa); g_return_if_fail(errbool==TRUE); @@ -233,7 +245,7 @@ int errint; /* linc_main_get_loop() makes sense only after corba_init() -> CORBA_ORB_init() */ errguint=g_source_attach( - gsource, /* source */ + captive_corba_sandbox_child_heartbeat_gsource, /* source */ g_main_loop_get_context(linc_main_get_loop())); /* context; NULL means 'default context' */ g_assert(errguint!=0); @@ -319,19 +331,113 @@ static void options_module_captive_to_options_module_corba g_return_if_fail(src_options_module_captive->type==CAPTIVE_OPTIONS_MODULE_TYPE_PE32); - dest_options_module_corba->pathname_utf8=g_strdup(src_options_module_captive->pathname_utf8); - dest_options_module_corba->data._buffer=g_memdup(src_options_module_captive->u.pe32.base, - src_options_module_captive->u.pe32.length); + dest_options_module_corba->pathname_utf8=CORBA_string_dup(src_options_module_captive->pathname_utf8); dest_options_module_corba->data._maximum=src_options_module_captive->u.pe32.length; dest_options_module_corba->data._length =src_options_module_captive->u.pe32.length; + dest_options_module_corba->data._buffer=Captive_Bytes_allocbuf(dest_options_module_corba->data._maximum); + memcpy(dest_options_module_corba->data._buffer,src_options_module_captive->u.pe32.base, + src_options_module_captive->u.pe32.length); dest_options_module_corba->data._release=TRUE; } +static void unlink_nonrecursive(const gchar *dirname) +{ +DIR *dir; +struct dirent *dirent; +int errint; + + dir=opendir(dirname); + g_assert(dir!=NULL); + + while (errno=0,(dirent=readdir(dir))) { +gchar *pathname; + + if (!strcmp(dirent->d_name,".") || !strcmp(dirent->d_name,"..")) + continue; + pathname=g_strdup_printf("%s/%s",dirname,dirent->d_name); + errint=unlink(pathname); + g_assert(errint==0); + g_free(pathname); + } + g_assert(errno==0); + errint=closedir(dir); + g_assert(errint==0); + errint=rmdir(dirname); + g_assert(errint==0); +} static const gchar *sandbox_parent_own_orbit_dir; static const gchar *sandbox_parent_own_orbit_socket; -gchar *sandbox_parent_read_ior(int Vfs_IOR_fd_read,gchar **child_chroot_pid_hashkey_dirp) +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); + + if (done) + return; + done=TRUE; + + if (sandbox_parent_own_orbit_dir) + unlink_nonrecursive(sandbox_parent_own_orbit_dir); +} + +static struct sandbox_parent_own_orbit_dir_cleanup_signal { + int signum; + /* FIXME: Why we cannot use 'sighandler_t'? */ void (*sighandler_orig)(int signum); + } sandbox_parent_own_orbit_dir_cleanup_signals[]={ + { SIGINT }, + { SIGQUIT }, + { SIGTERM }, + { SIGHUP }, + { SIGABRT }, + { SIGFPE }, + }; + +static void sandbox_parent_own_orbit_dir_cleanup_sighandler(int signum) +{ +struct sandbox_parent_own_orbit_dir_cleanup_signal *sigstructp; + + for ( + sigstructp=sandbox_parent_own_orbit_dir_cleanup_signals; + sigstructpsignum==signum) + break; + } + g_assert(sigstructpsighandler_orig); + + /* Prevent recursive fatal logging before signal restore: */ + /* 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(); + + /* 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); +} + +static void sandbox_parent_own_orbit_dir_cleanup_init(void) +{ +struct sandbox_parent_own_orbit_dir_cleanup_signal *sigstructp; + + for ( + sigstructp=sandbox_parent_own_orbit_dir_cleanup_signals; + sigstructpsighandler_orig=signal(sigstructp->signum,sandbox_parent_own_orbit_dir_cleanup_sighandler); + if (sigstructp->sighandler_orig==SIG_IGN) + sigstructp->sighandler_orig=SIG_DFL; + } +} + +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; @@ -347,28 +453,16 @@ 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)) { -DIR *dir; -struct dirent *dirent; g_assert(errno==EEXIST); - - dir=opendir(sandbox_parent_own_orbit_dir); - g_assert(dir!=NULL); - - while (errno=0,(dirent=readdir(dir))) { -gchar *pathname; - if (!strcmp(dirent->d_name,".") || !strcmp(dirent->d_name,"..")) - continue; - pathname=g_strdup_printf("%s/%s",sandbox_parent_own_orbit_dir,dirent->d_name); - errint=unlink(pathname); - g_assert(errint==0); - g_free(pathname); - } - g_assert(errno==0); - errint=closedir(dir); - g_assert(errint==0); + sandbox_parent_own_orbit_dir_cleanup_init(); + unlink_nonrecursive(sandbox_parent_own_orbit_dir); + if (mkdir(sandbox_parent_own_orbit_dir,0700)) + g_assert_not_reached(); } + sandbox_parent_own_orbit_dir_cleanup_init(); linc_set_tmpdir(sandbox_parent_own_orbit_dir); } @@ -399,17 +493,23 @@ 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); + if (errint) + g_error("link(\"%s\",\"%s\")=%d:%m",socketpathname_src,socketpathname_dest,errint); } if (child_chroot_pid_hashkey_dirp) *child_chroot_pid_hashkey_dirp=g_strdup(child_chroot_pid_hashkey_dir); @@ -425,10 +525,74 @@ const gchar *chrooted_orbit_dir; } -static void sandbox_parent(const gchar *Vfs_IOR,const gchar *child_chroot_pid_hashkey_dir, - struct captive_options *options_captive,Captive_Vfs *corba_Vfs_object_return, - Captive_GLogFunc *corba_GLogFunc_object_return,Captive_CaptiveIOChannel *corba_CaptiveIOChannel_object_return, - GIOChannel **corba_parent_giochanel_blind_ptr) +static xmlNode *options_module_captive_to_xml + (xmlNode *dest_xml_parent,const struct captive_options_module *src_options_module_captive) +{ + g_return_val_if_fail(dest_xml_parent!=NULL,NULL); + g_return_val_if_fail(src_options_module_captive!=NULL,NULL); + + { xmlNode *module=xmlNewTextChild(dest_xml_parent,NULL,"module",NULL); + const gchar *type_string="???"; /* Prevent: ... might be used uninitialized in this function */ + const gchar *basename,*cgs; + + basename=src_options_module_captive->pathname_utf8; + if ((cgs=strrchr(basename,'/'))) + basename=cgs+1; + xmlNewProp(module,"basename",basename); + switch (src_options_module_captive->type) { + case CAPTIVE_OPTIONS_MODULE_TYPE_PE32: + type_string="PE32"; + xmlNewProp(module,"length",captive_printf_alloca("%lu",(unsigned long)src_options_module_captive->u.pe32.length)); + xmlNewProp(module,"md5" ,src_options_module_captive->u.pe32.md5); + break; + case CAPTIVE_OPTIONS_MODULE_TYPE_GMODULE: + type_string="gmodule"; + break; + default: g_assert_not_reached(); + } + xmlNewProp(module,"type",type_string); /* AFTER the 'switch' to set 'type_string'! */ + return module; + } +} + + +static void sandbox_parent_bug_doc_make(CaptiveVfsParentObject *captive_vfs_parent_object) +{ + { xmlDoc *doc=xmlNewDoc("1.0"); + captive_vfs_parent_object->corba_bug_doc=doc; + { xmlNode *bug=xmlNewDocNode(captive_vfs_parent_object->corba_bug_doc,NULL,"bug",NULL); + xmlDocSetRootElement(captive_vfs_parent_object->corba_bug_doc,bug); + captive_vfs_parent_object->corba_bug=bug; + { xmlNode *bug_captive=xmlNewTextChild(bug,NULL,"captive",NULL); + xmlNewProp(bug_captive,"version",VERSION); + } + { xmlNode *bug_filesystem=xmlNewTextChild(bug,NULL,"filesystem",NULL); + options_module_captive_to_xml(bug_filesystem,&CAPTIVE_VFS_OBJECT(captive_vfs_parent_object)->options.filesystem); + } + { xmlNode *bug_load_module=xmlNewTextChild(bug,NULL,"load_module",NULL); + guint load_moduleui; + struct captive_options_module *options_module; + GList *load_module_node; + + for (load_moduleui=0,load_module_node=CAPTIVE_VFS_OBJECT(captive_vfs_parent_object)->options.load_module; + load_module_node; + load_moduleui++,load_module_node=load_module_node->next) { + options_module=load_module_node->data; + options_module_captive_to_xml(bug_load_module,options_module); + } + } + { xmlNode *bug_action=xmlNewTextChild(bug,NULL,"action",NULL); + captive_vfs_parent_object->corba_bug_action=bug_action; + } + { xmlNode *bug_log=xmlNewTextChild(bug,NULL,"log",NULL); + captive_vfs_parent_object->corba_bug_log=bug_log; + } + } + } +} + + +static void sandbox_parent(const gchar *Vfs_IOR,const gchar *child_chroot_pid_hashkey_dir,CaptiveVfsParentObject *captive_vfs_parent_object) { Captive_Vfs Vfs_object; Captive_GLogFunc GLogFunc_object; @@ -441,22 +605,36 @@ const gchar *child_chroot_parent_own_orbit_socket,*child_chroot_parent_own_orbit int errint; g_return_if_fail(Vfs_IOR!=NULL); - g_return_if_fail(corba_Vfs_object_return!=NULL); - g_return_if_fail(corba_GLogFunc_object_return!=NULL); - g_return_if_fail(corba_CaptiveIOChannel_object_return!=NULL); + /* 'child_chroot_pid_hashkey_dir' may be NULL */ + g_return_if_fail(CAPTIVE_VFS_PARENT_IS_OBJECT(captive_vfs_parent_object)); Vfs_object=CORBA_ORB_string_to_object(captive_corba_orb,Vfs_IOR,&captive_corba_ev); g_assert(validate_CORBA_Environment(&captive_corba_ev)); /* Init 'GLogFunc_object' */ - GLogFunc_object=impl_Captive_GLogFunc__create(captive_corba_poa,&captive_corba_ev); + GLogFunc_object=impl_Captive_GLogFunc__create(captive_corba_poa,captive_vfs_parent_object,&captive_corba_ev); g_assert(validate_CORBA_Environment(&captive_corba_ev)); /* Init 'CaptiveIOChannel_object' */ - if (!*corba_parent_giochanel_blind_ptr) - *corba_parent_giochanel_blind_ptr=(GIOChannel *)captive_giochannel_blind_new(options_captive->image_iochannel); + if (!captive_vfs_parent_object->corba_parent_giochanel_blind_source) + switch (CAPTIVE_VFS_OBJECT(captive_vfs_parent_object)->options.rwmode) { + case CAPTIVE_OPTION_RWMODE_RO: + case CAPTIVE_OPTION_RWMODE_RW: + captive_vfs_parent_object->corba_parent_giochanel_blind_source=CAPTIVE_VFS_OBJECT(captive_vfs_parent_object)->options.image_iochannel; + break; + case CAPTIVE_OPTION_RWMODE_BLIND: + captive_vfs_parent_object->corba_parent_giochanel_blind_source=(GIOChannel *)captive_giochannel_blind_new( + CAPTIVE_VFS_OBJECT(captive_vfs_parent_object)->options.image_iochannel, /* giochannel_orig */ + TRUE); /* writeable */ + break; + default: g_assert_not_reached(); + } + if (!captive_vfs_parent_object->corba_parent_giochanel_blind) + captive_vfs_parent_object->corba_parent_giochanel_blind=(GIOChannel *)captive_giochannel_blind_new( + captive_vfs_parent_object->corba_parent_giochanel_blind_source, /* giochannel_orig */ + (CAPTIVE_VFS_OBJECT(captive_vfs_parent_object)->options.rwmode!=CAPTIVE_OPTION_RWMODE_RO)); /* writeable */ CaptiveIOChannel_object=impl_Captive_CaptiveIOChannel__create(captive_corba_poa, - *corba_parent_giochanel_blind_ptr,&captive_corba_ev); + captive_vfs_parent_object->corba_parent_giochanel_blind,&captive_corba_ev); g_assert(validate_CORBA_Environment(&captive_corba_ev)); /* Create the socket needed for 'sandbox_parent_own_orbit_socket' below @@ -490,9 +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); + 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); @@ -502,23 +700,27 @@ struct dirent *dirent; g_assert(errint==0); } - options_corba.g_log_func=GLogFunc_object; - options_module_captive_to_options_module_corba(&options_corba.filesystem,&options_captive->filesystem); + options_corba.g_log_func=CORBA_Object_duplicate(GLogFunc_object,&captive_corba_ev); + g_assert(validate_CORBA_Environment(&captive_corba_ev)); + + options_module_captive_to_options_module_corba(&options_corba.filesystem,&CAPTIVE_VFS_OBJECT(captive_vfs_parent_object)->options.filesystem); /* Prevent secondary captive_giochannel_blind inside of our sandbox child * as we already have one captive_giochannel_blind in the parent. */ - options_corba.rwmode =(options_captive->rwmode == CAPTIVE_OPTION_RWMODE_BLIND ? CAPTIVE_OPTION_RWMODE_RW - : options_captive->rwmode); - options_corba.media =options_captive->media; - options_corba.debug_messages=options_captive->debug_messages; - options_corba.image_iochannel=CaptiveIOChannel_object; - - load_module_length=g_list_length(options_captive->load_module); - captive_newn(options_corba.load_module._buffer,load_module_length); + options_corba.rwmode =(CAPTIVE_VFS_OBJECT(captive_vfs_parent_object)->options.rwmode == CAPTIVE_OPTION_RWMODE_BLIND ? CAPTIVE_OPTION_RWMODE_RW + : CAPTIVE_VFS_OBJECT(captive_vfs_parent_object)->options.rwmode); + options_corba.media =CAPTIVE_VFS_OBJECT(captive_vfs_parent_object)->options.media; + options_corba.debug_messages=CAPTIVE_VFS_OBJECT(captive_vfs_parent_object)->options.debug_messages; + + options_corba.image_iochannel=CORBA_Object_duplicate(CaptiveIOChannel_object,&captive_corba_ev); + g_assert(validate_CORBA_Environment(&captive_corba_ev)); + + load_module_length=g_list_length(CAPTIVE_VFS_OBJECT(captive_vfs_parent_object)->options.load_module); options_corba.load_module._maximum=load_module_length; options_corba.load_module._length=load_module_length; + options_corba.load_module._buffer=Captive_CaptiveOptionsModuleList_allocbuf(options_corba.load_module._maximum); options_corba.load_module._release=TRUE; - for (load_moduleui=0,load_module_node=options_captive->load_module; + for (load_moduleui=0,load_module_node=CAPTIVE_VFS_OBJECT(captive_vfs_parent_object)->options.load_module; load_module_node; load_moduleui++,load_module_node=load_module_node->next) { options_module=load_module_node->data; @@ -528,11 +730,15 @@ struct dirent *dirent; Captive_Vfs_init(Vfs_object,&options_corba,&captive_corba_ev); g_assert(validate_CORBA_Environment(&captive_corba_ev)); - /* FIXME: Free 'options_corba' - LEAK */ + Captive_CaptiveOptions__freekids(&options_corba, + NULL); /* d; unused */ + + captive_vfs_parent_object->corba_Vfs_object=Vfs_object; + captive_vfs_parent_object->corba_GLogFunc_object=GLogFunc_object; + captive_vfs_parent_object->corba_CaptiveIOChannel_object=CaptiveIOChannel_object; - *corba_Vfs_object_return=Vfs_object; - *corba_GLogFunc_object_return=GLogFunc_object; - *corba_CaptiveIOChannel_object_return=CaptiveIOChannel_object; + if (CAPTIVE_VFS_OBJECT(captive_vfs_parent_object)->options.bug_pathname) + sandbox_parent_bug_doc_make(captive_vfs_parent_object); } static void fd_shiftup(int *fdp) @@ -584,10 +790,7 @@ char *endptr; close(dir_fd); g_assert(errno==EBADF); /* just a bit of paranoia; it should be already closed by closedir() */ } -gboolean captive_sandbox_spawn(CaptiveVfsObject *child_captive_vfs_object, - Captive_Vfs *corba_Vfs_object_return,Captive_GLogFunc *corba_GLogFunc_object_return, - Captive_CaptiveIOChannel *corba_CaptiveIOChannel_object_return,GIOChannel **corba_parent_giochanel_blind_ptr, - int *parentheart_fds_1_return,pid_t *child_pid_return) +gboolean captive_sandbox_spawn(CaptiveVfsParentObject *captive_vfs_parent_object) { /* Vfs_IOR_fds[0] for reading by sandbox_parent() - client, * Vfs_IOR_fds[1] for writing by sandbox_child() - server @@ -596,11 +799,7 @@ int Vfs_IOR_fds[2],parentheart_fds[2]; int errint; gboolean errbool; - g_return_val_if_fail(child_captive_vfs_object!=NULL,FALSE); - g_return_val_if_fail(corba_Vfs_object_return!=NULL,FALSE); - g_return_val_if_fail(corba_GLogFunc_object_return!=NULL,FALSE); - g_return_val_if_fail(parentheart_fds_1_return!=NULL,FALSE); - g_return_val_if_fail(child_pid_return!=NULL,FALSE); + g_return_val_if_fail(CAPTIVE_VFS_PARENT_IS_OBJECT(captive_vfs_parent_object),FALSE); errint=pipe(Vfs_IOR_fds); g_return_val_if_fail(errint==0,FALSE); @@ -612,27 +811,23 @@ gboolean errbool; * g_assert(errbool==TRUE); */ - if (child_captive_vfs_object->options.sandbox_server_ior) { - g_assert(child_captive_vfs_object->options.sandbox_server_argv==NULL); + if (CAPTIVE_VFS_OBJECT(captive_vfs_parent_object)->options.sandbox_server_ior) { + g_assert(CAPTIVE_VFS_OBJECT(captive_vfs_parent_object)->options.sandbox_server_argv==NULL); errbool=corba_init("captive-sandbox-parent",&captive_corba_ev,&captive_corba_orb,&captive_corba_poa); g_assert(errbool==TRUE); - *parentheart_fds_1_return=-1; - *child_pid_return=-1; + captive_vfs_parent_object->corba_parentheart_fds_1=-1; + captive_vfs_parent_object->corba_child_pid=-1; sandbox_parent( - child_captive_vfs_object->options.sandbox_server_ior, /* Vfs_IOR */ + CAPTIVE_VFS_OBJECT(captive_vfs_parent_object)->options.sandbox_server_ior, /* Vfs_IOR */ NULL, /* child_chroot_pid_hashkey_dir */ - &child_captive_vfs_object->options, /* options_captive */ - corba_Vfs_object_return, /* corba_Vfs_object_return */ - corba_GLogFunc_object_return, /* corba_GLogFunc_object_return */ - corba_CaptiveIOChannel_object_return, /* corba_CaptiveIOChannel_object_return */ - corba_parent_giochanel_blind_ptr); /* corba_parent_giochanel_blind_ptr */ + captive_vfs_parent_object); /* captive_vfs_parent_object */ return TRUE; } - g_assert(child_captive_vfs_object->options.sandbox_server_argv!=NULL); - switch ((*child_pid_return=fork())) { + g_assert(CAPTIVE_VFS_OBJECT(captive_vfs_parent_object)->options.sandbox_server_argv!=NULL); + switch ((captive_vfs_parent_object->corba_child_pid=fork())) { case -1: /* error */ g_return_val_if_reached(FALSE); @@ -652,8 +847,8 @@ gboolean errbool; captive_sandbox_fd_closeup(2 /* STDERR */ +1); - execv(child_captive_vfs_object->options.sandbox_server_argv[0], - /* re-const */ (char * const *)child_captive_vfs_object->options.sandbox_server_argv); + execv(CAPTIVE_VFS_OBJECT(captive_vfs_parent_object)->options.sandbox_server_argv[0], + /* re-const */ (char * const *)CAPTIVE_VFS_OBJECT(captive_vfs_parent_object)->options.sandbox_server_argv); g_return_val_if_reached(FALSE); } /* NOTREACHED */ @@ -672,20 +867,17 @@ gchar *child_chroot_pid_hashkey_dir; * Currently I am not aware such case would occur. */ g_return_val_if_fail(errint==0,FALSE); - *parentheart_fds_1_return=parentheart_fds[1]; + captive_vfs_parent_object->corba_parentheart_fds_1=parentheart_fds[1]; 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 */ child_chroot_pid_hashkey_dir, /* child_chroot_pid_hashkey_dir */ - &child_captive_vfs_object->options, /* options_captive */ - corba_Vfs_object_return, /* corba_Vfs_object_return */ - corba_GLogFunc_object_return, /* corba_GLogFunc_object_return */ - corba_CaptiveIOChannel_object_return, /* corba_CaptiveIOChannel_object_return */ - corba_parent_giochanel_blind_ptr); /* corba_parent_giochanel_blind_ptr */ + captive_vfs_parent_object); /* captive_vfs_parent_object */ g_free(Vfs_IOR); g_free(child_chroot_pid_hashkey_dir); @@ -699,15 +891,27 @@ gchar *child_chroot_pid_hashkey_dir; } -GnomeVFSResult captive_sandbox_parent_return_from_CORBA_Environment(CORBA_Environment *evp) +GnomeVFSResult captive_sandbox_parent_return_from_CORBA_Environment + (CORBA_Environment *evp,CaptiveVfsParentObject *captive_vfs_parent_object) { GnomeVFSResult r; if (evp->_major==CORBA_NO_EXCEPTION) return GNOME_VFS_OK; - if (evp->_major==CORBA_USER_EXCEPTION && !strcmp(ex_Captive_GnomeVFSResultException,CORBA_exception_id(evp))) + /* If !CAPTIVE_VFS_OBJECT(captive_vfs_parent_object)->options.sandbox_server_argv it is CAPTIVE_VFS_OBJECT(captive_vfs_parent_object)->options.sandbox_server_ior + * where we cannot do any restart anyway. + */ + if (captive_vfs_parent_object && CAPTIVE_VFS_OBJECT(captive_vfs_parent_object)->options.sandbox_server_argv + && (evp->_major==CORBA_SYSTEM_EXCEPTION && !strcmp(ex_CORBA_COMM_FAILURE,CORBA_exception_id(evp)))) { + r=GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE; + if (captive_vfs_parent_object->corba_Vfs_object!=CORBA_OBJECT_NIL) + captive_vfs_parent_object_aborted(captive_vfs_parent_object); /* errors ignored */ + } + else if (evp->_major==CORBA_USER_EXCEPTION && !strcmp(ex_Captive_GnomeVFSResultException,CORBA_exception_id(evp))) { r=((Captive_GnomeVFSResultException *)CORBA_exception_value(evp))->gnome_vfs_result; + g_assert(r!=GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE); /* code reserved for sandbox restarts */ + } else { r=GNOME_VFS_ERROR_GENERIC; g_warning(_("CORBA Exception occured: id=\"%s\", value=%p"), @@ -719,28 +923,6 @@ GnomeVFSResult r; } -gboolean captive_sandbox_parent_query_vfs_retry(CORBA_Environment *evp,CaptiveVfsObject *captive_vfs_object) -{ -GnomeVFSResult errvfsresult; - - g_return_val_if_fail(evp!=NULL,FALSE); - g_return_val_if_fail(captive_vfs_object!=NULL,FALSE); - - /* If !child_captive_vfs_object->options.sandbox_server_argv it is child_captive_vfs_object->options.sandbox_server_ior - * where we cannot do any restart anyway. - */ - if (!captive_vfs_object->options.sandbox_server_argv - || !(evp->_major==CORBA_SYSTEM_EXCEPTION && !strcmp(ex_CORBA_COMM_FAILURE,CORBA_exception_id(evp)))) - return FALSE; /* no retry */ - CORBA_exception_free(evp); - - captive_sandbox_parent_vfs_close(captive_vfs_object); /* errors ignored */ - errvfsresult=captive_sandbox_parent_vfs_new(captive_vfs_object); - - return errvfsresult==GNOME_VFS_OK; /* retry if restart succeeded */ -} - - void captive_sandbox_child_GnomeVFSResultException_throw(CORBA_Environment *evp,GnomeVFSResult errvfsresult) { Captive_GnomeVFSResultException *gnome_vfs_result_exception;