Eric's patch was rejected because it broke selinux labeling: http://thread.gmane.org/gmane.linux.kernel.lsm/9807/focus=9841 This seems to break labeling. Prior to this patch, I see: # ls -lZ /proc/1/net/rpc/nfsd.fh -rw-------. root root system_u:object_r:sysctl_rpc_t:s0 channel with the patch: # ls -lZ /proc/1/net/rpc/nfsd.fh -rw-------. root root system_u:object_r:proc_t:s0 channel My patch seems to have fixed this problem (it correctly reports sysctl_rpc_t in this case), but my selinux experience is Î > 0 and I have no ideea what else it may have broken. I ran 'find /proc | xargs ls -Z > f' on a kernel with an without these patches: * http://swarm.cs.pub.ro/~lucian/store/ls-Z-with-patch * http://swarm.cs.pub.ro/~lucian/store/ls-Z-without-patch My setup is a custom busybox live CD with selinux enabled, with /etc/selinux and /usr/share/selinux/default copied from Ubuntu 10.10's selinux-policy-default package. I'm sure there are lots of reasons why this is not correcly configured, etc., but I have no experience regarding selinux. I can make all the scripts/sources/configs/etc available to anyone interested. NOTE: this patch will be merged with: security/selinux: Simplify proc inode to security label mapping I'm only prividing this patch separately to point out the differences to Eric W. Biederman's patch. Both of these patches apply cleanly agains Linux 2.6.37. Signed-off-by: Lucian Adrian Grijincu <lucian.grijincu@xxxxxxxxx> --- fs/proc/proc_sysctl.c | 1 - security/selinux/hooks.c | 20 ++++++++++++++++---- 2 files changed, 16 insertions(+), 5 deletions(-)
diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c index b652cb0..b17619d 100644 --- a/fs/proc/proc_sysctl.c +++ b/fs/proc/proc_sysctl.c @@ -31,7 +31,6 @@ static struct inode *proc_sys_make_inode(struct super_block *sb, ei->sysctl_entry = table; inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; - inode->i_flags |= S_PRIVATE; /* tell selinux to ignore this inode */ inode->i_mode = table->mode; if (!table->child) { inode->i_mode |= S_IFREG; diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 51615f6..5f58019 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -1132,8 +1132,23 @@ static int selinux_proc_get_sid(struct dentry *dentry, path = dentry_path(dentry, buffer, PAGE_SIZE); if (IS_ERR(path)) rc = PTR_ERR(path); - else + else { + /* because dentry is not hashed, dentry_path() will + * append "//deleted" to the end of the string. We'll + * remove this as no /proc/ file is named so. */ + int pathlen = strlen(path); + int dellen = strlen("//deleted"); + if ((pathlen > dellen) && strcmp(path + pathlen - dellen, "//deleted") == 0) + path[pathlen-dellen] = '\0'; + + /* each process gets a /proc/PID/ entry. Strip off the + * PID part to get a valid selinux labeling. */ + while (path[1] >= '0' && path[1] <= '9') { + path[1] = '/'; + path++; + } rc = security_genfs_sid("proc", path, tclass, sid); + } free_page((unsigned long)buffer); return rc; } @@ -1464,9 +1479,6 @@ static int inode_has_perm(const struct cred *cred, validate_creds(cred); - if (unlikely(IS_PRIVATE(inode))) - return 0; - sid = cred_sid(cred); isec = inode->i_security;