Пример #1
0
SYSCALL_DEFINE1(chroot, const char __user *, filename)
{
	struct path path;
	int error;

	error = user_path_dir(filename, &path);
	if (error)
		goto out;

	error = inode_permission(path.dentry->d_inode, MAY_EXEC | MAY_CHDIR);
	if (error)
		goto dput_and_out;

	error = -EPERM;
	if (!capable(CAP_SYS_CHROOT))
		goto dput_and_out;
	error = security_path_chroot(&path);
	if (error)
		goto dput_and_out;

	set_fs_root(current->fs, &path);
	error = 0;
dput_and_out:
	path_put(&path);
out:
	return error;
}
Пример #2
0
asmlinkage long sys_chroot(const char __user * filename)
{
	struct nameidata nd;
	struct fs_struct *fs;
	int error;

	error = __user_walk(filename, LOOKUP_FOLLOW | LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd);
	if (error)
		goto out;

	error = vfs_permission(d_get_inode_ro(nd.dentry), &nd, MAY_EXEC);
	if (error)
		goto dput_and_out;

	error = -EPERM;
	if (!capable(CAP_SYS_CHROOT))
		goto dput_and_out;

	fs = tx_cache_get_fs(current);

	set_fs_root(fs, nd.mnt, parent(nd.dentry));
	set_fs_altroot();
	error = 0;
dput_and_out:
	path_release(&nd);
out:
	return error;
}
Пример #3
0
SYSCALL_DEFINE1(chroot, const char __user *, filename)
{
	struct path path;
	int error;

	error = user_path_dir(filename, &path);
	if (error)
		goto out;

	error = inode_permission(path.dentry->d_inode, MAY_EXEC | MAY_ACCESS);
	if (error)
		goto dput_and_out;

	error = -EPERM;
	if (!capable(CAP_SYS_CHROOT))
		goto dput_and_out;

	if (gr_handle_chroot_chroot(path.dentry, path.mnt))
		goto dput_and_out;

	if (gr_handle_chroot_caps(&path)) {
		error = -ENOMEM;
		goto dput_and_out;
	}

	set_fs_root(current->fs, &path);

	gr_handle_chroot_chdir(&path);

	error = 0;
dput_and_out:
	path_put(&path);
out:
	return error;
}
Пример #4
0
asmlinkage long sys_chroot(const char * filename)
{
	int error;
	struct nameidata nd;
	char *name;

	name = getname(filename);
	error = PTR_ERR(name);
	if (IS_ERR(name))
		goto out;

	path_init(name, LOOKUP_POSITIVE | LOOKUP_FOLLOW |
		      LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd);
	error = path_walk(name, &nd);	
	putname(name);
	if (error)
		goto out;

	error = permission(nd.dentry->d_inode,MAY_EXEC);
	if (error)
		goto dput_and_out;

	error = -EPERM;
	if (!capable(CAP_SYS_CHROOT))
		goto dput_and_out;

	set_fs_root(current->fs, nd.mnt, nd.dentry);
	set_fs_altroot();
	error = 0;
dput_and_out:
	path_release(&nd);
out:
	return error;
}
Пример #5
0
SYSCALL_DEFINE1(chroot, const char __user *, filename)
{
	struct path path;
	int error;
	unsigned int lookup_flags = LOOKUP_FOLLOW | LOOKUP_DIRECTORY;
retry:
	error = user_path_at(AT_FDCWD, filename, lookup_flags, &path);
	if (error)
		goto out;

	error = inode_permission(path.dentry->d_inode, MAY_EXEC | MAY_CHDIR);
	if (error)
		goto dput_and_out;

	error = -EPERM;
	if (!nsown_capable(CAP_SYS_CHROOT))
		goto dput_and_out;
	error = security_path_chroot(&path);
	if (error)
		goto dput_and_out;

	set_fs_root(current->fs, &path);
	error = 0;
dput_and_out:
	path_put(&path);
	if (retry_estale(error, lookup_flags)) {
		lookup_flags |= LOOKUP_REVAL;
		goto retry;
	}
out:
	return error;
}
Пример #6
0
asmlinkage long sys_chroot(const char __user * filename)
{
	struct nameidata nd;
	int error;

	error = __user_walk(filename, LOOKUP_FOLLOW | LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd);
	if (error)
		goto out;

	error = permission(nd.dentry->d_inode,MAY_EXEC,&nd);
	if (error)
		goto dput_and_out;

	error = -EPERM;
	if (!capable(CAP_SYS_CHROOT))
		goto dput_and_out;

	set_fs_root(current->fs, nd.mnt, nd.dentry);
	set_fs_altroot();
	error = 0;
dput_and_out:
	path_release(&nd);
out:
	return error;
}
Пример #7
0
/**
 * Change current's root to configfs scheduler subsystem'root, and save
 * previous root in parameters.
 *
 * @param prev_root    valid pointer to a struct path
 *
 * @return	       prev_rootmnt and prev_root are filled with the previous
 *		       root. They must be restored with chroot_restore, or
 *		       mntput/dput when not needed anymore.
 */
static void chroot_to_scheduler_subsystem(struct path *prev_root)
{
	struct path new_root;

	/*
	 * These two values won't change unless a pivot_root is running ...
	 * but we assume that this can not happen.
	 * Locking is more used for memory barriers than for anything else.
	 */
	read_lock(&current->fs->lock);
	*prev_root = current->fs->root;
	path_get(prev_root);
	read_unlock(&current->fs->lock);

	new_root.mnt = scheduler_fs_mount;
	new_root.dentry = krg_scheduler_subsys.su_group.cg_item.ci_dentry;
	set_fs_root(current->fs, &new_root);
}
Пример #8
0
asmlinkage long sys_chroot(const char __user * filename)
{
	struct path path;
	int error;

	error = user_path_dir(filename, &path);
	if (error)
		goto out;

	error = inode_permission(path.dentry->d_inode, MAY_EXEC | MAY_ACCESS);
	if (error)
		goto dput_and_out;

	error = -EPERM;
	if (!capable(CAP_SYS_CHROOT))
		goto dput_and_out;

	set_fs_root(current->fs, &path);
	error = 0;
dput_and_out:
	path_put(&path);
out:
	return error;
}
Пример #9
0
/*
 * Allocates utab entry (upd->fs) for mount/remount. This function should be
 * called *before* mount(2) syscall. The @fs is used as a read-only template.
 *
 * Returns: 0 on success, negative number on error, 1 if utabs update is
 *          unnecessary.
 */
static int utab_new_entry(struct libmnt_update *upd, struct libmnt_fs *fs,
			  unsigned long mountflags)
{
	int rc = 0;
	const char *o = NULL, *a = NULL;
	char *u = NULL;

	assert(fs);
	assert(upd);
	assert(upd->fs == NULL);
	assert(!(mountflags & MS_MOVE));

	DBG(UPDATE, mnt_debug("prepare utab entry"));

	o = mnt_fs_get_user_options(fs);
	a = mnt_fs_get_attributes(fs);
	upd->fs = NULL;

	if (o) {
		/* remove non-mtab options */
		rc = mnt_optstr_get_options(o, &u,
				mnt_get_builtin_optmap(MNT_USERSPACE_MAP),
				MNT_NOMTAB);
		if (rc)
			goto err;
	}

	if (!u && !a) {
		DBG(UPDATE, mnt_debug("utab entry unnecessary (no options)"));
		return 1;
	}

	/* allocate the entry */
	upd->fs = mnt_copy_fs(NULL, fs);
	if (!upd->fs) {
		rc = -ENOMEM;
		goto err;
	}

	rc = mnt_fs_set_options(upd->fs, u);
	if (rc)
		goto err;
	rc = mnt_fs_set_attributes(upd->fs, a);
	if (rc)
		goto err;

	if (!(mountflags & MS_REMOUNT)) {
		rc = set_fs_root(upd, fs, mountflags);
		if (rc)
			goto err;
	}

	free(u);
	DBG(UPDATE, mnt_debug("utab entry OK"));
	return 0;
err:
	free(u);
	mnt_free_fs(upd->fs);
	upd->fs = NULL;
	return rc;
}
Пример #10
0
static void chroot_restore(struct path *prev_root)
{
	set_fs_root(current->fs, prev_root);
	path_put(prev_root);
}