Exemplo n.º 1
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;
}
Exemplo n.º 2
0
asmlinkage long sys_chroot(const char * filename)
{
	int error;
	struct nameidata nd;

	error = __user_walk(filename, LOOKUP_POSITIVE | LOOKUP_FOLLOW |
		      LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd);
	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;
}
Exemplo n.º 3
0
Arquivo: open.c Projeto: 274914765/C
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 = vfs_permission(&nd, 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.path);
    set_fs_altroot();
    error = 0;
dput_and_out:
    path_put(&nd.path);
out:
    return error;
}
Exemplo n.º 4
0
/*
 * Note that a shared library must be both readable and executable due to
 * security reasons.
 *
 * Also note that we take the address to load from from the file itself.
 */
asmlinkage long sys_uselib(const char __user * library)
{
	struct file * file;
	struct nameidata nd;
	int error;

	nd.intent.open.flags = FMODE_READ;
	error = __user_walk(library, LOOKUP_FOLLOW|LOOKUP_OPEN, &nd);
	if (error)
		goto out;

	error = -EINVAL;
	if (!S_ISREG(nd.dentry->d_inode->i_mode))
		goto exit;

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

	file = dentry_open(nd.dentry, nd.mnt, O_RDONLY);
	error = PTR_ERR(file);
	if (IS_ERR(file))
		goto out;

	error = -ENOEXEC;
	if(file->f_op) {
		struct linux_binfmt * fmt;

		read_lock(&binfmt_lock);
		for (fmt = formats ; fmt ; fmt = fmt->next) {
			if (!fmt->load_shlib)
				continue;
			if (!try_module_get(fmt->module))
				continue;
			read_unlock(&binfmt_lock);
			error = fmt->load_shlib(file);
			read_lock(&binfmt_lock);
			put_binfmt(fmt);
			if (error != -ENOEXEC)
				break;
		}
		read_unlock(&binfmt_lock);
	}
	fput(file);
out:
  	return error;
exit:
	path_release(&nd);
	goto out;
}
Exemplo n.º 5
0
/*
 * access() needs to use the real uid/gid, not the effective uid/gid.
 * We do this by temporarily clearing all FS-related capabilities and
 * switching the fsuid/fsgid around to the real ones.
 */
asmlinkage long sys_access(const char __user * filename, int mode)
{
	struct nameidata nd;
	int old_fsuid, old_fsgid;
	kernel_cap_t old_cap;
	int res;

	if (mode & ~S_IRWXO)	/* where's F_OK, X_OK, W_OK, R_OK? */
		return -EINVAL;

	old_fsuid = current->fsuid;
	old_fsgid = current->fsgid;
	old_cap = current->cap_effective;

	current->fsuid = current->uid;
	current->fsgid = current->gid;

	/*
	 * Clear the capabilities if we switch to a non-root user
	 *
	 * FIXME: There is a race here against sys_capset.  The
	 * capabilities can change yet we will restore the old
	 * value below.  We should hold task_capabilities_lock,
	 * but we cannot because user_path_walk can sleep.
	 */
	if (current->uid)
		cap_clear(current->cap_effective);
	else
		current->cap_effective = current->cap_permitted;

	res = __user_walk(filename, LOOKUP_FOLLOW|LOOKUP_ACCESS, &nd);
	if (!res) {
		res = permission(nd.dentry->d_inode, mode, &nd);
		/* SuS v2 requires we report a read only fs too */
		if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode)
		   && !special_file(nd.dentry->d_inode->i_mode))
			res = -EROFS;
		path_release(&nd);
	}

	current->fsuid = old_fsuid;
	current->fsgid = old_fsgid;
	current->cap_effective = old_cap;

	return res;
}
Exemplo n.º 6
0
asmlinkage long sys_chdir(const char * filename)
{
	int error;
	struct nameidata nd;

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

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

	set_fs_pwd(current->fs, nd.mnt, nd.dentry);

dput_and_out:
	path_release(&nd);
out:
	return error;
}
Exemplo n.º 7
0
asmlinkage long sys_chdir(const char __user * filename)
{
	struct nameidata nd;
	int error;

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

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

	set_fs_pwd(current->fs, nd.mnt, nd.dentry);

dput_and_out:
	path_release(&nd);
out:
	return error;
}
Exemplo n.º 8
0
asmlinkage long sys_chdir(const char __user * filename)
{
	struct nameidata nd;
	int error;
	struct fs_struct *fs;

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

	error = vfs_permission(d_get_inode_ro(nd.dentry), &nd, MAY_EXEC);
	if (error)
		goto dput_and_out;
	
	fs = tx_cache_get_fs(current);
	
	set_fs_pwd(fs, nd.mnt, parent(nd.dentry));

dput_and_out:
	path_release(&nd);
out:
	return error;
}