[RFC][PATCH] Pass nameidata to security_inode_permission hook

From: Stephen Smalley
Date: Wed Sep 24 2003 - 11:14:50 EST


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 <sds@xxxxxxxxxxxxxx>
National Security Agency

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/