2003-09-24 16:13:58

by Stephen Smalley

[permalink] [raw]
Subject: [RFC][PATCH] Pass nameidata to security_inode_permission hook

This patch against 2.6.0-test5 changes the security_inode_permission
hook to also take a nameidata parameter in addition to the existing
inode and mask parameters. A nameidata is already passed (although
sometimes NULL) to fs/namei.c:permission(), and the patch changes
exec_permission_lite() to also take a nameidata parameter so that it can
pass it along to the security hook. The patch includes corresponding
changes to the SELinux module to use the nameidata information when it
is available; this allows SELinux to include pathname information in
audit messages when a nameidata structure was supplied. If anyone has
any objections to this change, please let me know.

fs/namei.c | 9 +++++----
include/linux/security.h | 11 +++++++----
security/dummy.c | 2 +-
security/selinux/hooks.c | 7 ++++++-
4 files changed, 19 insertions(+), 10 deletions(-)

Index: linux-2.6/fs/namei.c
===================================================================
RCS file: /nfshome/pal/CVS/linux-2.6/fs/namei.c,v
retrieving revision 1.13
diff -u -r1.13 namei.c
--- linux-2.6/fs/namei.c 25 Aug 2003 15:29:19 -0000 1.13
+++ linux-2.6/fs/namei.c 24 Sep 2003 14:54:40 -0000
@@ -218,7 +218,7 @@
if (retval)
return retval;

- return security_inode_permission(inode, mask);
+ return security_inode_permission(inode, mask, nd);
}

/*
@@ -302,7 +302,8 @@
* short-cut DAC fails, then call permission() to do more
* complete permission check.
*/
-static inline int exec_permission_lite(struct inode *inode)
+static inline int exec_permission_lite(struct inode *inode,
+ struct nameidata *nd)
{
umode_t mode = inode->i_mode;

@@ -325,7 +326,7 @@

return -EACCES;
ok:
- return security_inode_permission(inode, MAY_EXEC);
+ return security_inode_permission(inode, MAY_EXEC, nd);
}

/*
@@ -584,7 +585,7 @@
struct qstr this;
unsigned int c;

- err = exec_permission_lite(inode);
+ err = exec_permission_lite(inode, nd);
if (err == -EAGAIN) {
err = permission(inode, MAY_EXEC, nd);
}
Index: linux-2.6/include/linux/security.h
===================================================================
RCS file: /nfshome/pal/CVS/linux-2.6/include/linux/security.h,v
retrieving revision 1.25
diff -u -r1.25 security.h
--- linux-2.6/include/linux/security.h 24 Jun 2003 14:55:43 -0000 1.25
+++ linux-2.6/include/linux/security.h 24 Sep 2003 14:55:17 -0000
@@ -334,6 +334,7 @@
* called when the actual read/write operations are performed.
* @inode contains the inode structure to check.
* @mask contains the permission mask.
+ * @nd contains the nameidata (may be NULL).
* Return 0 if permission is granted.
* @inode_setattr:
* Check permission before setting file attributes. Note that the kernel
@@ -1055,7 +1056,7 @@
struct dentry *new_dentry);
int (*inode_readlink) (struct dentry *dentry);
int (*inode_follow_link) (struct dentry *dentry, struct nameidata *nd);
- int (*inode_permission) (struct inode *inode, int mask);
+ int (*inode_permission) (struct inode *inode, int mask, struct nameidata *nd);
int (*inode_setattr) (struct dentry *dentry, struct iattr *attr);
int (*inode_getattr) (struct vfsmount *mnt, struct dentry *dentry);
void (*inode_delete) (struct inode *inode);
@@ -1474,9 +1475,10 @@
return security_ops->inode_follow_link (dentry, nd);
}

-static inline int security_inode_permission (struct inode *inode, int mask)
+static inline int security_inode_permission (struct inode *inode, int mask,
+ struct nameidata *nd)
{
- return security_ops->inode_permission (inode, mask);
+ return security_ops->inode_permission (inode, mask, nd);
}

static inline int security_inode_setattr (struct dentry *dentry,
@@ -2110,7 +2112,8 @@
return 0;
}

-static inline int security_inode_permission (struct inode *inode, int mask)
+static inline int security_inode_permission (struct inode *inode, int mask,
+ struct nameidata *nd)
{
return 0;
}
Index: linux-2.6/security/dummy.c
===================================================================
RCS file: /nfshome/pal/CVS/linux-2.6/security/dummy.c,v
retrieving revision 1.22
diff -u -r1.22 dummy.c
--- linux-2.6/security/dummy.c 3 Jul 2003 14:31:12 -0000 1.22
+++ linux-2.6/security/dummy.c 24 Sep 2003 14:54:40 -0000
@@ -364,7 +364,7 @@
return 0;
}

-static int dummy_inode_permission (struct inode *inode, int mask)
+static int dummy_inode_permission (struct inode *inode, int mask, struct nameidata *nd)
{
return 0;
}
Index: linux-2.6/security/selinux/hooks.c
===================================================================
RCS file: /nfshome/pal/CVS/linux-2.6/security/selinux/hooks.c,v
retrieving revision 1.73
diff -u -r1.73 hooks.c
--- linux-2.6/security/selinux/hooks.c 4 Sep 2003 18:23:49 -0000 1.73
+++ linux-2.6/security/selinux/hooks.c 24 Sep 2003 14:54:40 -0000
@@ -1730,12 +1730,17 @@
return dentry_has_perm(current, NULL, dentry, FILE__READ);
}

-static int selinux_inode_permission(struct inode *inode, int mask)
+static int selinux_inode_permission(struct inode *inode, int mask,
+ struct nameidata *nd)
{
if (!mask) {
/* No permission to check. Existence test. */
return 0;
}
+
+ if (nd && nd->dentry)
+ return dentry_has_perm(current, nd->mnt, nd->dentry,
+ file_mask_to_av(inode->i_mode, mask));

return inode_has_perm(current, inode,
file_mask_to_av(inode->i_mode, mask), NULL, NULL);



--
Stephen Smalley <[email protected]>
National Security Agency


2003-09-30 06:17:03

by Chris Wright

[permalink] [raw]
Subject: Re: [RFC][PATCH] Pass nameidata to security_inode_permission hook

* Stephen Smalley ([email protected]) wrote:
> This patch against 2.6.0-test5 changes the security_inode_permission
> hook to also take a nameidata parameter in addition to the existing
> inode and mask parameters. A nameidata is already passed (although
> sometimes NULL) to fs/namei.c:permission(), and the patch changes
> exec_permission_lite() to also take a nameidata parameter so that it can
> pass it along to the security hook. The patch includes corresponding
> changes to the SELinux module to use the nameidata information when it
> is available; this allows SELinux to include pathname information in
> audit messages when a nameidata structure was supplied. If anyone has
> any objections to this change, please let me know.

Looks like Andrew already picked this up. I'll put it in the LSM tree
as well. It'd be nice if nameidata were never NULL and we could drop
the inode argument altogether. But we can make that change when the VFS
supports it.

thanks,
-chris
--
Linux Security Modules http://lsm.immunix.org http://lsm.bkbits.net