#include "../client/giochannel-blind.h" /* for captive_giochannel_blind_new() */
#include <signal.h>
#include "../storage/relastblock.h" /* for captive_storage_relastblock() */
+#include <sys/file.h> /* flock() */
#ifdef HAVE_ORBIT_LINK
void link_set_tmpdir(const char *dir);
}
}
+static void createlockdir(const gchar *dir)
+{
+gint retries;
+
+ for (retries=0;retries<10;retries++) {
+struct stat statbuf;
+int dirfd;
+
+ if (mkdir(dir,0700)) {
+ if (errno!=EEXIST)
+ g_error(_("Failed to create chroot directory \"%s\": %m"),dir);
+ unlink_nonrecursive(dir);
+ if (mkdir(dir,0700))
+ g_error(_("Failed to create chroot directory \"%s\" after attempted unlink: %m"),dir);
+ }
+ dirfd=open(dir,O_RDONLY);
+ if (dirfd==-1) {
+ if (errno!=ENOENT)
+ g_error(_("Failed to open created chroot directory \"%s\" to lock it: %m"),dir);
+ continue;
+ }
+ /* Do not use 'LOCK_NB' here as the garbage collector should release it soon. */
+ if (flock(dirfd,LOCK_EX))
+ g_error(_("Failed to lock created chroot directory \"%s\": %m"),dir);
+ if (lstat(dir,&statbuf)) {
+ if (errno!=ENOENT)
+ g_error(_("Failed to lstat(2) created chroot directory \"%s\": %m"),dir);
+ if (close(dirfd))
+ g_error(_("Failed to close created and locked chroot directory \"%s\": %m"),dir);
+ continue;
+ }
+ /* Leave 'dirfd' open to leave it LOCK_EX-ed. */
+ break;
+ }
+}
+
static gchar *sandbox_parent_read_ior
(int Vfs_IOR_fd_read,gchar **child_chroot_pid_hashkey_dirp,CaptiveVfsParentObject *captive_vfs_parent_object)
{
/* FIXME: Security: Duplicate giop_tmpdir_init() here. */
if (!sandbox_parent_own_orbit_dir) {
/* 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();
- unlink_nonrecursive(sandbox_parent_own_orbit_dir);
- if (mkdir(sandbox_parent_own_orbit_dir,0700))
- g_assert_not_reached();
- }
+ /* Use also geteuid() marker here as could not remove the directory
+ * of some other user otherwise.
+ */
+ sandbox_parent_own_orbit_dir=g_strdup_printf("%s/tmp/captive-orbit-%d-%d",CAPTIVE_SANDBOX_CHROOT,getpid(),geteuid());
sandbox_parent_own_orbit_dir_cleanup_init();
+ createlockdir(sandbox_parent_own_orbit_dir);
#ifdef HAVE_ORBIT_LINK
link_set_tmpdir(sandbox_parent_own_orbit_dir);
#else