From: David Howells <dhowells@redhat.com>
To: jmorris@namei.org, akpm@linux-foundation.org, morgan@kernel.org
Cc: sfr@canb.auug.org.au, dhowells@redhat.com, viro@ftp.linux.org.uk,
casey@schaufler-ca.com, linux-security-module@vger.kernel.org,
linux-kernel@vger.kernel.org
Subject: [PATCH 15/24] CRED: Make inode_has_perm() and file_has_perm() take a cred pointer [ver #7]
Date: Wed, 06 Aug 2008 16:38:31 +0100 [thread overview]
Message-ID: <20080806153831.14351.2400.stgit@warthog.procyon.org.uk> (raw)
In-Reply-To: <20080806153713.14351.91448.stgit@warthog.procyon.org.uk>
Make inode_has_perm() and file_has_perm() take a cred pointer rather than a
task pointer.
Signed-off-by: David Howells <dhowells@redhat.com>
Acked-by: James Morris <jmorris@namei.org>
Acked-by: Serge Hallyn <serue@us.ibm.com>
---
security/selinux/hooks.c | 140 ++++++++++++++++++++++++++++++----------------
1 files changed, 92 insertions(+), 48 deletions(-)
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 27d1779..fb76940 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -172,16 +172,25 @@ static int cred_alloc_security(struct cred *cred)
}
/*
+ * get the security ID of a set of credentials
+ */
+static inline u32 cred_sid(const struct cred *cred)
+{
+ const struct task_security_struct *tsec;
+
+ tsec = cred->security;
+ return tsec->sid;
+}
+
+/*
* get the security ID of a task
*/
static inline u32 task_sid(const struct task_struct *task)
{
- const struct task_security_struct *tsec;
u32 sid;
rcu_read_lock();
- tsec = __task_cred(task)->security;
- sid = tsec->sid;
+ sid = cred_sid(__task_cred(task));
rcu_read_unlock();
return sid;
}
@@ -196,6 +205,8 @@ static inline u32 current_sid(void)
return tsec->sid;
}
+/* Allocate and free functions for each kind of security blob. */
+
static int inode_alloc_security(struct inode *inode)
{
struct inode_security_struct *isec;
@@ -1366,7 +1377,7 @@ static inline u32 signal_to_av(int sig)
}
/*
- * Check permission betweeen a pair of tasks, e.g. signal checks,
+ * Check permission between a pair of tasks, e.g. signal checks,
* fork check, ptrace check, etc.
* tsk1 is the actor and tsk2 is the target
*/
@@ -1429,7 +1440,7 @@ static int task_has_system(struct task_struct *tsk,
/* Check whether a task has a particular permission to an inode.
The 'adp' parameter is optional and allows other audit
data to be passed (e.g. the dentry). */
-static int inode_has_perm(struct task_struct *tsk,
+static int inode_has_perm(const struct cred *cred,
struct inode *inode,
u32 perms,
struct avc_audit_data *adp)
@@ -1441,7 +1452,7 @@ static int inode_has_perm(struct task_struct *tsk,
if (unlikely(IS_PRIVATE(inode)))
return 0;
- sid = task_sid(tsk);
+ sid = cred_sid(cred);
isec = inode->i_security;
if (!adp) {
@@ -1456,17 +1467,18 @@ static int inode_has_perm(struct task_struct *tsk,
/* Same as inode_has_perm, but pass explicit audit data containing
the dentry to help the auditing code to more easily generate the
pathname if needed. */
-static inline int dentry_has_perm(struct task_struct *tsk,
+static inline int dentry_has_perm(const struct cred *cred,
struct vfsmount *mnt,
struct dentry *dentry,
u32 av)
{
struct inode *inode = dentry->d_inode;
struct avc_audit_data ad;
+
AVC_AUDIT_DATA_INIT(&ad, FS);
ad.u.fs.path.mnt = mnt;
ad.u.fs.path.dentry = dentry;
- return inode_has_perm(tsk, inode, av, &ad);
+ return inode_has_perm(cred, inode, av, &ad);
}
/* Check whether a task can use an open file descriptor to
@@ -1477,14 +1489,14 @@ static inline int dentry_has_perm(struct task_struct *tsk,
has the same SID as the process. If av is zero, then
access to the file is not checked, e.g. for cases
where only the descriptor is affected like seek. */
-static int file_has_perm(struct task_struct *tsk,
- struct file *file,
- u32 av)
+static int file_has_perm(const struct cred *cred,
+ struct file *file,
+ u32 av)
{
struct file_security_struct *fsec = file->f_security;
struct inode *inode = file->f_path.dentry->d_inode;
struct avc_audit_data ad;
- u32 sid = task_sid(tsk);
+ u32 sid = cred_sid(cred);
int rc;
AVC_AUDIT_DATA_INIT(&ad, FS);
@@ -1496,14 +1508,16 @@ static int file_has_perm(struct task_struct *tsk,
FD__USE,
&ad);
if (rc)
- return rc;
+ goto out;
}
/* av is zero if only checking access to the descriptor. */
+ rc = 0;
if (av)
- return inode_has_perm(tsk, inode, av, &ad);
+ rc = inode_has_perm(cred, inode, av, &ad);
- return 0;
+out:
+ return rc;
}
/* Check whether a task can create a file. */
@@ -1662,13 +1676,13 @@ static inline int may_rename(struct inode *old_dir,
}
/* Check whether a task can perform a filesystem operation. */
-static int superblock_has_perm(struct task_struct *tsk,
+static int superblock_has_perm(const struct cred *cred,
struct super_block *sb,
u32 perms,
struct avc_audit_data *ad)
{
struct superblock_security_struct *sbsec;
- u32 sid = task_sid(tsk);
+ u32 sid = cred_sid(cred);
sbsec = sb->s_security;
return avc_has_perm(sid, sbsec->sid, SECCLASS_FILESYSTEM, perms, ad);
@@ -1910,6 +1924,7 @@ static int selinux_sysctl(ctl_table *table, int op)
static int selinux_quotactl(int cmds, int type, int id, struct super_block *sb)
{
+ const struct cred *cred = current_cred();
int rc = 0;
if (!sb)
@@ -1921,14 +1936,12 @@ static int selinux_quotactl(int cmds, int type, int id, struct super_block *sb)
case Q_QUOTAOFF:
case Q_SETINFO:
case Q_SETQUOTA:
- rc = superblock_has_perm(current, sb, FILESYSTEM__QUOTAMOD,
- NULL);
+ rc = superblock_has_perm(cred, sb, FILESYSTEM__QUOTAMOD, NULL);
break;
case Q_GETFMT:
case Q_GETINFO:
case Q_GETQUOTA:
- rc = superblock_has_perm(current, sb, FILESYSTEM__QUOTAGET,
- NULL);
+ rc = superblock_has_perm(cred, sb, FILESYSTEM__QUOTAGET, NULL);
break;
default:
rc = 0; /* let the kernel handle invalid cmds */
@@ -1939,7 +1952,9 @@ static int selinux_quotactl(int cmds, int type, int id, struct super_block *sb)
static int selinux_quota_on(struct dentry *dentry)
{
- return dentry_has_perm(current, NULL, dentry, FILE__QUOTAON);
+ const struct cred *cred = current_cred();
+
+ return dentry_has_perm(cred, NULL, dentry, FILE__QUOTAON);
}
static int selinux_syslog(int type)
@@ -2136,6 +2151,7 @@ extern struct dentry *selinux_null;
/* Derived from fs/exec.c:flush_old_files. */
static inline void flush_unauthorized_files(struct files_struct *files)
{
+ const struct cred *cred = current_cred();
struct avc_audit_data ad;
struct file *file, *devnull = NULL;
struct tty_struct *tty;
@@ -2155,7 +2171,7 @@ static inline void flush_unauthorized_files(struct files_struct *files)
file may belong to another process and we are only
interested in the inode-based check here. */
struct inode *inode = file->f_path.dentry->d_inode;
- if (inode_has_perm(current, inode,
+ if (inode_has_perm(cred, inode,
FILE__READ | FILE__WRITE, NULL)) {
drop_tty = 1;
}
@@ -2190,7 +2206,7 @@ static inline void flush_unauthorized_files(struct files_struct *files)
file = fget(i);
if (!file)
continue;
- if (file_has_perm(current,
+ if (file_has_perm(cred,
file,
file_to_av(file))) {
sys_close(i);
@@ -2462,6 +2478,7 @@ out:
static int selinux_sb_kern_mount(struct super_block *sb, void *data)
{
+ const struct cred *cred = current_cred();
struct avc_audit_data ad;
int rc;
@@ -2471,16 +2488,17 @@ static int selinux_sb_kern_mount(struct super_block *sb, void *data)
AVC_AUDIT_DATA_INIT(&ad, FS);
ad.u.fs.path.dentry = sb->s_root;
- return superblock_has_perm(current, sb, FILESYSTEM__MOUNT, &ad);
+ return superblock_has_perm(cred, sb, FILESYSTEM__MOUNT, &ad);
}
static int selinux_sb_statfs(struct dentry *dentry)
{
+ const struct cred *cred = current_cred();
struct avc_audit_data ad;
AVC_AUDIT_DATA_INIT(&ad, FS);
ad.u.fs.path.dentry = dentry->d_sb->s_root;
- return superblock_has_perm(current, dentry->d_sb, FILESYSTEM__GETATTR, &ad);
+ return superblock_has_perm(cred, dentry->d_sb, FILESYSTEM__GETATTR, &ad);
}
static int selinux_mount(char *dev_name,
@@ -2489,6 +2507,7 @@ static int selinux_mount(char *dev_name,
unsigned long flags,
void *data)
{
+ const struct cred *cred = current_cred();
int rc;
rc = secondary_ops->sb_mount(dev_name, path, type, flags, data);
@@ -2496,22 +2515,23 @@ static int selinux_mount(char *dev_name,
return rc;
if (flags & MS_REMOUNT)
- return superblock_has_perm(current, path->mnt->mnt_sb,
+ return superblock_has_perm(cred, path->mnt->mnt_sb,
FILESYSTEM__REMOUNT, NULL);
else
- return dentry_has_perm(current, path->mnt, path->dentry,
+ return dentry_has_perm(cred, path->mnt, path->dentry,
FILE__MOUNTON);
}
static int selinux_umount(struct vfsmount *mnt, int flags)
{
+ const struct cred *cred = current_cred();
int rc;
rc = secondary_ops->sb_umount(mnt, flags);
if (rc)
return rc;
- return superblock_has_perm(current, mnt->mnt_sb,
+ return superblock_has_perm(cred, mnt->mnt_sb,
FILESYSTEM__UNMOUNT, NULL);
}
@@ -2649,21 +2669,25 @@ static int selinux_inode_rename(struct inode *old_inode, struct dentry *old_dent
static int selinux_inode_readlink(struct dentry *dentry)
{
- return dentry_has_perm(current, NULL, dentry, FILE__READ);
+ const struct cred *cred = current_cred();
+
+ return dentry_has_perm(cred, NULL, dentry, FILE__READ);
}
static int selinux_inode_follow_link(struct dentry *dentry, struct nameidata *nameidata)
{
+ const struct cred *cred = current_cred();
int rc;
rc = secondary_ops->inode_follow_link(dentry, nameidata);
if (rc)
return rc;
- return dentry_has_perm(current, NULL, dentry, FILE__READ);
+ return dentry_has_perm(cred, NULL, dentry, FILE__READ);
}
static int selinux_inode_permission(struct inode *inode, int mask)
{
+ const struct cred *cred = current_cred();
int rc;
rc = secondary_ops->inode_permission(inode, mask);
@@ -2675,12 +2699,13 @@ static int selinux_inode_permission(struct inode *inode, int mask)
return 0;
}
- return inode_has_perm(current, inode,
+ return inode_has_perm(cred, inode,
open_file_mask_to_av(inode->i_mode, mask), NULL);
}
static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr)
{
+ const struct cred *cred = current_cred();
int rc;
rc = secondary_ops->inode_setattr(dentry, iattr);
@@ -2692,18 +2717,22 @@ static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr)
if (iattr->ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID |
ATTR_ATIME_SET | ATTR_MTIME_SET))
- return dentry_has_perm(current, NULL, dentry, FILE__SETATTR);
+ return dentry_has_perm(cred, NULL, dentry, FILE__SETATTR);
- return dentry_has_perm(current, NULL, dentry, FILE__WRITE);
+ return dentry_has_perm(cred, NULL, dentry, FILE__WRITE);
}
static int selinux_inode_getattr(struct vfsmount *mnt, struct dentry *dentry)
{
- return dentry_has_perm(current, mnt, dentry, FILE__GETATTR);
+ const struct cred *cred = current_cred();
+
+ return dentry_has_perm(cred, mnt, dentry, FILE__GETATTR);
}
static int selinux_inode_setotherxattr(struct dentry *dentry, const char *name)
{
+ const struct cred *cred = current_cred();
+
if (!strncmp(name, XATTR_SECURITY_PREFIX,
sizeof XATTR_SECURITY_PREFIX - 1)) {
if (!strcmp(name, XATTR_NAME_CAPS)) {
@@ -2718,7 +2747,7 @@ static int selinux_inode_setotherxattr(struct dentry *dentry, const char *name)
/* Not an attribute we recognize, so just check the
ordinary setattr permission. */
- return dentry_has_perm(current, NULL, dentry, FILE__SETATTR);
+ return dentry_has_perm(cred, NULL, dentry, FILE__SETATTR);
}
static int selinux_inode_setxattr(struct dentry *dentry, const char *name,
@@ -2803,12 +2832,16 @@ static void selinux_inode_post_setxattr(struct dentry *dentry, const char *name,
static int selinux_inode_getxattr(struct dentry *dentry, const char *name)
{
- return dentry_has_perm(current, NULL, dentry, FILE__GETATTR);
+ const struct cred *cred = current_cred();
+
+ return dentry_has_perm(cred, NULL, dentry, FILE__GETATTR);
}
static int selinux_inode_listxattr(struct dentry *dentry)
{
- return dentry_has_perm(current, NULL, dentry, FILE__GETATTR);
+ const struct cred *cred = current_cred();
+
+ return dentry_has_perm(cred, NULL, dentry, FILE__GETATTR);
}
static int selinux_inode_removexattr(struct dentry *dentry, const char *name)
@@ -2919,6 +2952,7 @@ static void selinux_inode_getsecid(const struct inode *inode, u32 *secid)
static int selinux_revalidate_file_permission(struct file *file, int mask)
{
+ const struct cred *cred = current_cred();
int rc;
struct inode *inode = file->f_path.dentry->d_inode;
@@ -2931,7 +2965,7 @@ static int selinux_revalidate_file_permission(struct file *file, int mask)
if ((file->f_flags & O_APPEND) && (mask & MAY_WRITE))
mask |= MAY_APPEND;
- rc = file_has_perm(current, file,
+ rc = file_has_perm(cred, file,
file_mask_to_av(inode->i_mode, mask));
if (rc)
return rc;
@@ -2971,6 +3005,7 @@ static void selinux_file_free_security(struct file *file)
static int selinux_file_ioctl(struct file *file, unsigned int cmd,
unsigned long arg)
{
+ const struct cred *cred = current_cred();
u32 av = 0;
if (_IOC_DIR(cmd) & _IOC_WRITE)
@@ -2980,11 +3015,13 @@ static int selinux_file_ioctl(struct file *file, unsigned int cmd,
if (!av)
av = FILE__IOCTL;
- return file_has_perm(current, file, av);
+ return file_has_perm(cred, file, av);
}
static int file_map_prot_check(struct file *file, unsigned long prot, int shared)
{
+ const struct cred *cred = current_cred();
+
#ifndef CONFIG_PPC32
if ((prot & PROT_EXEC) && (!file || (!shared && (prot & PROT_WRITE)))) {
/*
@@ -3009,7 +3046,7 @@ static int file_map_prot_check(struct file *file, unsigned long prot, int shared
if (prot & PROT_EXEC)
av |= FILE__EXECUTE;
- return file_has_perm(current, file, av);
+ return file_has_perm(cred, file, av);
}
return 0;
}
@@ -3038,6 +3075,7 @@ static int selinux_file_mprotect(struct vm_area_struct *vma,
unsigned long reqprot,
unsigned long prot)
{
+ const struct cred *cred = current_cred();
int rc;
rc = secondary_ops->file_mprotect(vma, reqprot, prot);
@@ -3066,7 +3104,7 @@ static int selinux_file_mprotect(struct vm_area_struct *vma,
* modified content. This typically should only
* occur for text relocations.
*/
- rc = file_has_perm(current, vma->vm_file,
+ rc = file_has_perm(cred, vma->vm_file,
FILE__EXECMOD);
}
if (rc)
@@ -3079,12 +3117,15 @@ static int selinux_file_mprotect(struct vm_area_struct *vma,
static int selinux_file_lock(struct file *file, unsigned int cmd)
{
- return file_has_perm(current, file, FILE__LOCK);
+ const struct cred *cred = current_cred();
+
+ return file_has_perm(cred, file, FILE__LOCK);
}
static int selinux_file_fcntl(struct file *file, unsigned int cmd,
unsigned long arg)
{
+ const struct cred *cred = current_cred();
int err = 0;
switch (cmd) {
@@ -3095,7 +3136,7 @@ static int selinux_file_fcntl(struct file *file, unsigned int cmd,
}
if ((file->f_flags & O_APPEND) && !(arg & O_APPEND)) {
- err = file_has_perm(current, file, FILE__WRITE);
+ err = file_has_perm(cred, file, FILE__WRITE);
break;
}
/* fall through */
@@ -3105,7 +3146,7 @@ static int selinux_file_fcntl(struct file *file, unsigned int cmd,
case F_GETOWN:
case F_GETSIG:
/* Just check FD__USE permission */
- err = file_has_perm(current, file, 0);
+ err = file_has_perm(cred, file, 0);
break;
case F_GETLK:
case F_SETLK:
@@ -3119,7 +3160,7 @@ static int selinux_file_fcntl(struct file *file, unsigned int cmd,
err = -EINVAL;
break;
}
- err = file_has_perm(current, file, FILE__LOCK);
+ err = file_has_perm(cred, file, FILE__LOCK);
break;
}
@@ -3160,11 +3201,14 @@ static int selinux_file_send_sigiotask(struct task_struct *tsk,
static int selinux_file_receive(struct file *file)
{
- return file_has_perm(current, file, file_to_av(file));
+ const struct cred *cred = current_cred();
+
+ return file_has_perm(cred, file, file_to_av(file));
}
static int selinux_dentry_open(struct file *file)
{
+ const struct cred *cred = current_cred();
struct file_security_struct *fsec;
struct inode *inode;
struct inode_security_struct *isec;
@@ -3188,7 +3232,7 @@ static int selinux_dentry_open(struct file *file)
* new inode label or new policy.
* This check is not redundant - do not remove.
*/
- return inode_has_perm(current, inode, file_to_av(file), NULL);
+ return inode_has_perm(cred, inode, file_to_av(file), NULL);
}
/* task security operations */
next prev parent reply other threads:[~2008-08-06 15:41 UTC|newest]
Thread overview: 30+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-08-06 15:37 [PATCH 00/24] Introduce credentials " David Howells
2008-08-06 15:37 ` [PATCH 01/24] Fix setting of PF_SUPERPRIV by __capable() " David Howells
2008-08-06 15:37 ` [PATCH 02/24] KEYS: Disperse linux/key_ui.h " David Howells
2008-08-06 15:37 ` [PATCH 03/24] KEYS: Alter use of key instantiation link-to-keyring argument " David Howells
2008-08-06 15:37 ` [PATCH 04/24] CRED: Neuter sys_capset() " David Howells
2008-08-06 15:37 ` [PATCH 05/24] CRED: Constify the kernel_cap_t arguments to the capset LSM hooks " David Howells
2008-08-06 15:37 ` [PATCH 06/24] CRED: Change current->fs[ug]id to current_fs[ug]id() " David Howells
2008-08-06 15:37 ` [PATCH 07/24] CRED: Wrap most current->e?[ug]id and some task->e?[ug]id " David Howells
2008-08-06 15:37 ` [PATCH 08/24] CRED: Separate task security context from task_struct " David Howells
2008-08-06 15:38 ` [PATCH 09/24] CRED: Detach the credentials " David Howells
2008-08-06 15:38 ` [PATCH 10/24] CRED: Wrap current->cred and a few other accessors " David Howells
2008-08-06 15:38 ` [PATCH 11/24] CRED: Use RCU to access another task's creds and to release a task's own creds " David Howells
2008-08-06 15:38 ` [PATCH 12/24] CRED: Wrap access to SELinux's task SID " David Howells
2008-08-06 15:38 ` [PATCH 13/24] CRED: Separate per-task-group keyrings from signal_struct " David Howells
2008-08-06 15:38 ` [PATCH 14/24] CRED: Rename is_single_threaded() to is_wq_single_threaded() " David Howells
2008-08-06 15:38 ` David Howells [this message]
2008-08-06 15:38 ` [PATCH 16/24] CRED: Pass credentials through dentry_open() " David Howells
2008-08-06 15:38 ` [PATCH 17/24] CRED: Inaugurate COW credentials " David Howells
2008-08-06 15:38 ` [PATCH 18/24] CRED: Make execve() take advantage of copy-on-write " David Howells
2008-08-06 15:38 ` [PATCH 19/24] CRED: Prettify commoncap.c " David Howells
2008-08-06 15:38 ` [PATCH 20/24] CRED: Use creds in file structs " David Howells
2008-08-06 15:39 ` [PATCH 21/24] CRED: Documentation " David Howells
2008-08-06 15:39 ` [PATCH 22/24] CRED: Differentiate objective and effective subjective credentials on a task " David Howells
2008-08-06 15:39 ` [PATCH 23/24] CRED: Add a kernel_service object class to SELinux " David Howells
2008-08-06 15:39 ` [PATCH 24/24] CRED: Allow kernel services to override LSM settings for task actions " David Howells
2008-08-07 8:50 ` [PATCH 00/24] Introduce credentials " James Morris
2008-08-07 9:32 ` David Howells
2008-08-07 9:56 ` James Morris
2008-08-07 12:03 ` James Morris
2008-08-08 0:23 ` Stephen Rothwell
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20080806153831.14351.2400.stgit@warthog.procyon.org.uk \
--to=dhowells@redhat.com \
--cc=akpm@linux-foundation.org \
--cc=casey@schaufler-ca.com \
--cc=jmorris@namei.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-security-module@vger.kernel.org \
--cc=morgan@kernel.org \
--cc=sfr@canb.auug.org.au \
--cc=viro@ftp.linux.org.uk \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®