diff options
Diffstat (limited to 'fs/open.c')
| -rw-r--r-- | fs/open.c | 27 | 
1 files changed, 20 insertions, 7 deletions
diff --git a/fs/open.c b/fs/open.c index 4f01e06227c..b4b31d277f3 100644 --- a/fs/open.c +++ b/fs/open.c @@ -587,6 +587,9 @@ SYSCALL_DEFINE1(chroot, const char __user *, filename)  	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; @@ -617,11 +620,15 @@ SYSCALL_DEFINE2(fchmod, unsigned int, fd, mode_t, mode)  	if (err)  		goto out_putf;  	mutex_lock(&inode->i_mutex); +	err = security_path_chmod(dentry, file->f_vfsmnt, mode); +	if (err) +		goto out_unlock;  	if (mode == (mode_t) -1)  		mode = inode->i_mode;  	newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);  	newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;  	err = notify_change(dentry, &newattrs); +out_unlock:  	mutex_unlock(&inode->i_mutex);  	mnt_drop_write(file->f_path.mnt);  out_putf: @@ -646,11 +653,15 @@ SYSCALL_DEFINE3(fchmodat, int, dfd, const char __user *, filename, mode_t, mode)  	if (error)  		goto dput_and_out;  	mutex_lock(&inode->i_mutex); +	error = security_path_chmod(path.dentry, path.mnt, mode); +	if (error) +		goto out_unlock;  	if (mode == (mode_t) -1)  		mode = inode->i_mode;  	newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);  	newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;  	error = notify_change(path.dentry, &newattrs); +out_unlock:  	mutex_unlock(&inode->i_mutex);  	mnt_drop_write(path.mnt);  dput_and_out: @@ -664,9 +675,9 @@ SYSCALL_DEFINE2(chmod, const char __user *, filename, mode_t, mode)  	return sys_fchmodat(AT_FDCWD, filename, mode);  } -static int chown_common(struct dentry * dentry, uid_t user, gid_t group) +static int chown_common(struct path *path, uid_t user, gid_t group)  { -	struct inode *inode = dentry->d_inode; +	struct inode *inode = path->dentry->d_inode;  	int error;  	struct iattr newattrs; @@ -683,7 +694,9 @@ static int chown_common(struct dentry * dentry, uid_t user, gid_t group)  		newattrs.ia_valid |=  			ATTR_KILL_SUID | ATTR_KILL_SGID | ATTR_KILL_PRIV;  	mutex_lock(&inode->i_mutex); -	error = notify_change(dentry, &newattrs); +	error = security_path_chown(path, user, group); +	if (!error) +		error = notify_change(path->dentry, &newattrs);  	mutex_unlock(&inode->i_mutex);  	return error; @@ -700,7 +713,7 @@ SYSCALL_DEFINE3(chown, const char __user *, filename, uid_t, user, gid_t, group)  	error = mnt_want_write(path.mnt);  	if (error)  		goto out_release; -	error = chown_common(path.dentry, user, group); +	error = chown_common(&path, user, group);  	mnt_drop_write(path.mnt);  out_release:  	path_put(&path); @@ -725,7 +738,7 @@ SYSCALL_DEFINE5(fchownat, int, dfd, const char __user *, filename, uid_t, user,  	error = mnt_want_write(path.mnt);  	if (error)  		goto out_release; -	error = chown_common(path.dentry, user, group); +	error = chown_common(&path, user, group);  	mnt_drop_write(path.mnt);  out_release:  	path_put(&path); @@ -744,7 +757,7 @@ SYSCALL_DEFINE3(lchown, const char __user *, filename, uid_t, user, gid_t, group  	error = mnt_want_write(path.mnt);  	if (error)  		goto out_release; -	error = chown_common(path.dentry, user, group); +	error = chown_common(&path, user, group);  	mnt_drop_write(path.mnt);  out_release:  	path_put(&path); @@ -767,7 +780,7 @@ SYSCALL_DEFINE3(fchown, unsigned int, fd, uid_t, user, gid_t, group)  		goto out_fput;  	dentry = file->f_path.dentry;  	audit_inode(NULL, dentry); -	error = chown_common(dentry, user, group); +	error = chown_common(&file->f_path, user, group);  	mnt_drop_write(file->f_path.mnt);  out_fput:  	fput(file);  |