Example #1
0
int sc_lock(const char *scope)
{
	// Create (if required) and open the lock directory.
	debug("creating lock directory %s (if missing)", sc_lock_dir);
	if (sc_nonfatal_mkpath(sc_lock_dir, 0755) < 0) {
		die("cannot create lock directory %s", sc_lock_dir);
	}
	debug("opening lock directory %s", sc_lock_dir);
	int dir_fd SC_CLEANUP(sc_cleanup_close) = -1;
	dir_fd =
	    open(sc_lock_dir, O_DIRECTORY | O_PATH | O_CLOEXEC | O_NOFOLLOW);
	if (dir_fd < 0) {
		die("cannot open lock directory");
	}
	// Construct the name of the lock file.
	char lock_fname[PATH_MAX];
	sc_must_snprintf(lock_fname, sizeof lock_fname, "%s/%s.lock",
			 sc_lock_dir, scope ? : "");

	// Open the lock file and acquire an exclusive lock.
	debug("opening lock file: %s", lock_fname);
	int lock_fd = openat(dir_fd, lock_fname,
			     O_CREAT | O_RDWR | O_CLOEXEC | O_NOFOLLOW, 0600);
	if (lock_fd < 0) {
		die("cannot open lock file: %s", lock_fname);
	}

	sc_enable_sanity_timeout();
	debug("acquiring exclusive lock (scope %s)", scope ? : "(global)");
	if (flock(lock_fd, LOCK_EX) < 0) {
		sc_disable_sanity_timeout();
		close(lock_fd);
		die("cannot acquire exclusive lock (scope %s)",
		    scope ? : "(global)");
	} else {
Example #2
0
/**
 * Create an empty directory and bind mount something there.
 *
 * The empty directory is created at destdir. The bind mount is
 * done from srcdir to destdir. The bind mount is performed with
 * caller-defined flags.
 **/
static void sc_quirk_mkdir_bind(const char *src_dir, const char *dest_dir,
				unsigned flags)
{
	flags |= MS_BIND;
	debug("creating empty directory at %s", dest_dir);
	if (sc_nonfatal_mkpath(dest_dir, 0755) < 0) {
		die("cannot create empty directory at %s", dest_dir);
	}
	const char *flags_str = sc_mount_opt2str(flags);
	debug("performing operation: mount %s %s -o %s", src_dir, dest_dir,
	      flags_str);
	if (mount(src_dir, dest_dir, NULL, flags, NULL) != 0) {
		die("cannot perform operation: mount %s %s -o %s", src_dir,
		    dest_dir, flags_str);
	}
}
Example #3
0
void sc_initialize_ns_groups()
{
	debug("creating namespace group directory %s", sc_ns_dir);
	if (sc_nonfatal_mkpath(sc_ns_dir, 0755) < 0) {
		die("cannot create namespace group directory %s", sc_ns_dir);
	}
	debug("opening namespace group directory %s", sc_ns_dir);
	int dir_fd __attribute__ ((cleanup(sc_cleanup_close))) = -1;
	dir_fd = open(sc_ns_dir, O_DIRECTORY | O_PATH | O_CLOEXEC | O_NOFOLLOW);
	if (dir_fd < 0) {
		die("cannot open namespace group directory");
	}
	debug("opening lock file for group directory");
	int lock_fd __attribute__ ((cleanup(sc_cleanup_close))) = -1;
	lock_fd = openat(dir_fd,
			 SC_NS_LOCK_FILE,
			 O_CREAT | O_RDWR | O_CLOEXEC | O_NOFOLLOW, 0600);
	if (lock_fd < 0) {
		die("cannot open lock file for namespace group directory");
	}
	debug("locking the namespace group directory");
	sc_enable_sanity_timeout();
	if (flock(lock_fd, LOCK_EX) < 0) {
		die("cannot acquire exclusive lock for namespace group directory");
	}
	sc_disable_sanity_timeout();
	if (!sc_is_ns_group_dir_private()) {
		debug
		    ("bind mounting the namespace group directory over itself");
		if (mount(sc_ns_dir, sc_ns_dir, NULL, MS_BIND | MS_REC, NULL) <
		    0) {
			die("cannot bind mount namespace group directory over itself");
		}
		debug
		    ("making the namespace group directory mount point private");
		if (mount(NULL, sc_ns_dir, NULL, MS_PRIVATE, NULL) < 0) {
			die("cannot make the namespace group directory mount point private");
		}
	} else {
		debug
		    ("namespace group directory does not require intialization");
	}
	debug("unlocking the namespace group directory");
	if (flock(lock_fd, LOCK_UN) < 0) {
		die("cannot release lock for namespace control directory");
	}
}
void setup_user_data(void)
{
	const char *user_data = getenv("SNAP_USER_DATA");

	if (user_data == NULL)
		return;

	// Only support absolute paths.
	if (user_data[0] != '/') {
		die("user data directory must be an absolute path");
	}

	debug("creating user data directory: %s", user_data);
	if (sc_nonfatal_mkpath(user_data, 0755) < 0) {
		die("cannot create user data directory: %s", user_data);
	};
}
void setup_user_xdg_runtime_dir(void)
{
	const char *xdg_runtime_dir = getenv("XDG_RUNTIME_DIR");

	if (xdg_runtime_dir == NULL)
		return;
	// Only support absolute paths.
	if (xdg_runtime_dir[0] != '/') {
		die("XDG_RUNTIME_DIR must be an absolute path");
	}

	errno = 0;
	debug("creating user XDG_RUNTIME_DIR directory: %s", xdg_runtime_dir);
	if (sc_nonfatal_mkpath(xdg_runtime_dir, 0755) < 0) {
		die("cannot create user XDG_RUNTIME_DIR directory: %s",
		    xdg_runtime_dir);
	}
	// if successfully created the directory (ie, not EEXIST), then chmod it.
	if (errno == 0 && chmod(xdg_runtime_dir, 0700) != 0) {
		die("cannot change permissions of user XDG_RUNTIME_DIR directory to 0700");
	}
}
Example #6
0
void sc_initialize_ns_groups(void)
{
	debug("creating namespace group directory %s", sc_ns_dir);
	if (sc_nonfatal_mkpath(sc_ns_dir, 0755) < 0) {
		die("cannot create namespace group directory %s", sc_ns_dir);
	}
	if (!sc_is_ns_group_dir_private()) {
		debug
		    ("bind mounting the namespace group directory over itself");
		if (mount(sc_ns_dir, sc_ns_dir, NULL, MS_BIND | MS_REC, NULL) <
		    0) {
			die("cannot bind mount namespace group directory over itself");
		}
		debug
		    ("making the namespace group directory mount point private");
		if (mount(NULL, sc_ns_dir, NULL, MS_PRIVATE, NULL) < 0) {
			die("cannot make the namespace group directory mount point private");
		}
	} else {
		debug
		    ("namespace group directory does not require intialization");
	}
}