summaryrefslogtreecommitdiffstats
path: root/fs/open.c
diff options
context:
space:
mode:
authorTetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>2009-10-04 21:49:47 +0900
committerJames Morris <jmorris@namei.org>2009-10-12 10:56:00 +1100
commit89eda06837094ce9f34fae269b8773fcfd70f046 (patch)
treedc11701c68ebcc8346d7567cfb53b9c7327ef445 /fs/open.c
parent941fc5b2bf8f7dd1d0a9c502e152fa719ff6578e (diff)
downloadlinux-89eda06837094ce9f34fae269b8773fcfd70f046.tar.gz
linux-89eda06837094ce9f34fae269b8773fcfd70f046.tar.bz2
linux-89eda06837094ce9f34fae269b8773fcfd70f046.zip
LSM: Add security_path_chmod() and security_path_chown().
This patch allows pathname based LSM modules to check chmod()/chown() operations. Since notify_change() does not receive "struct vfsmount *", we add security_path_chmod() and security_path_chown() to the caller of notify_change(). These hooks are used by TOMOYO. Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> Signed-off-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'fs/open.c')
-rw-r--r--fs/open.c24
1 files changed, 20 insertions, 4 deletions
diff --git a/fs/open.c b/fs/open.c
index 4f01e06227c6..b5c294d35bd1 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -616,6 +616,9 @@ SYSCALL_DEFINE2(fchmod, unsigned int, fd, mode_t, mode)
err = mnt_want_write_file(file);
if (err)
goto out_putf;
+ err = security_path_chmod(dentry, file->f_vfsmnt, mode);
+ if (err)
+ goto out_drop_write;
mutex_lock(&inode->i_mutex);
if (mode == (mode_t) -1)
mode = inode->i_mode;
@@ -623,6 +626,7 @@ SYSCALL_DEFINE2(fchmod, unsigned int, fd, mode_t, mode)
newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
err = notify_change(dentry, &newattrs);
mutex_unlock(&inode->i_mutex);
+out_drop_write:
mnt_drop_write(file->f_path.mnt);
out_putf:
fput(file);
@@ -645,6 +649,9 @@ SYSCALL_DEFINE3(fchmodat, int, dfd, const char __user *, filename, mode_t, mode)
error = mnt_want_write(path.mnt);
if (error)
goto dput_and_out;
+ error = security_path_chmod(path.dentry, path.mnt, mode);
+ if (error)
+ goto out_drop_write;
mutex_lock(&inode->i_mutex);
if (mode == (mode_t) -1)
mode = inode->i_mode;
@@ -652,6 +659,7 @@ SYSCALL_DEFINE3(fchmodat, int, dfd, const char __user *, filename, mode_t, mode)
newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
error = notify_change(path.dentry, &newattrs);
mutex_unlock(&inode->i_mutex);
+out_drop_write:
mnt_drop_write(path.mnt);
dput_and_out:
path_put(&path);
@@ -700,7 +708,9 @@ 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 = security_path_chown(&path, user, group);
+ if (!error)
+ error = chown_common(path.dentry, user, group);
mnt_drop_write(path.mnt);
out_release:
path_put(&path);
@@ -725,7 +735,9 @@ 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 = security_path_chown(&path, user, group);
+ if (!error)
+ error = chown_common(path.dentry, user, group);
mnt_drop_write(path.mnt);
out_release:
path_put(&path);
@@ -744,7 +756,9 @@ 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 = security_path_chown(&path, user, group);
+ if (!error)
+ error = chown_common(path.dentry, user, group);
mnt_drop_write(path.mnt);
out_release:
path_put(&path);
@@ -767,7 +781,9 @@ 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 = security_path_chown(&file->f_path, user, group);
+ if (!error)
+ error = chown_common(dentry, user, group);
mnt_drop_write(file->f_path.mnt);
out_fput:
fput(file);