/* 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)
depth--;
}
-static void chrooted_cleanuplockeddirs(const gchar *pathname)
+static void chrooted_cleanuplockeddirs(const gchar *pathname,const gchar *prefix)
{
DIR *dir;
struct dirent *dirent;
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))) {
fatal("Unsuccessful setrlimit(%s)",resource_string);
}
-static const gchar *chrooted_orbit_dir;
+static gchar *chrooted_orbit_dir;
static void chroot_setup(gboolean fragile)
{
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);
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;
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);
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) {
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()
*/
{
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;
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);
}
/* 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();
}
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);