diff --git a/fs/proc/base.c b/fs/proc/base.c index 43871c85729d8255ea25966e0611c84f35f4d66a..6ba7785319de46dd2020c6b1132c2bf9e4462fe9 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -132,6 +132,7 @@ enum pid_directory_inos { PROC_TGID_ATTR_EXEC, PROC_TGID_ATTR_FSCREATE, PROC_TGID_ATTR_KEYCREATE, + PROC_TGID_ATTR_SOCKCREATE, #endif #ifdef CONFIG_AUDITSYSCALL PROC_TGID_LOGINUID, @@ -174,6 +175,7 @@ enum pid_directory_inos { PROC_TID_ATTR_EXEC, PROC_TID_ATTR_FSCREATE, PROC_TID_ATTR_KEYCREATE, + PROC_TID_ATTR_SOCKCREATE, #endif #ifdef CONFIG_AUDITSYSCALL PROC_TID_LOGINUID, @@ -291,6 +293,7 @@ static struct pid_entry tgid_attr_stuff[] = { E(PROC_TGID_ATTR_EXEC, "exec", S_IFREG|S_IRUGO|S_IWUGO), E(PROC_TGID_ATTR_FSCREATE, "fscreate", S_IFREG|S_IRUGO|S_IWUGO), E(PROC_TGID_ATTR_KEYCREATE, "keycreate", S_IFREG|S_IRUGO|S_IWUGO), + E(PROC_TGID_ATTR_SOCKCREATE, "sockcreate", S_IFREG|S_IRUGO|S_IWUGO), {0,0,NULL,0} }; static struct pid_entry tid_attr_stuff[] = { @@ -299,6 +302,7 @@ static struct pid_entry tid_attr_stuff[] = { E(PROC_TID_ATTR_EXEC, "exec", S_IFREG|S_IRUGO|S_IWUGO), E(PROC_TID_ATTR_FSCREATE, "fscreate", S_IFREG|S_IRUGO|S_IWUGO), E(PROC_TID_ATTR_KEYCREATE, "keycreate", S_IFREG|S_IRUGO|S_IWUGO), + E(PROC_TID_ATTR_SOCKCREATE, "sockcreate", S_IFREG|S_IRUGO|S_IWUGO), {0,0,NULL,0} }; #endif @@ -1764,6 +1768,8 @@ static struct dentry *proc_pident_lookup(struct inode *dir, case PROC_TGID_ATTR_FSCREATE: case PROC_TID_ATTR_KEYCREATE: case PROC_TGID_ATTR_KEYCREATE: + case PROC_TID_ATTR_SOCKCREATE: + case PROC_TGID_ATTR_SOCKCREATE: inode->i_fop = &proc_pid_attr_operations; break; #endif diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 0d8b27513bdc7e27a28c1319d93792169b7b84a6..ac7f2b2e39240024a70cfe06b464e93050447410 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -1532,8 +1532,9 @@ static int selinux_bprm_set_security(struct linux_binprm *bprm) /* Default to the current task SID. */ bsec->sid = tsec->sid; - /* Reset create SID on execve. */ + /* Reset create and sockcreate SID on execve. */ tsec->create_sid = 0; + tsec->sockcreate_sid = 0; if (tsec->exec_sid) { newsid = tsec->exec_sid; @@ -2585,9 +2586,10 @@ static int selinux_task_alloc_security(struct task_struct *tsk) tsec2->osid = tsec1->osid; tsec2->sid = tsec1->sid; - /* Retain the exec and create SIDs across fork */ + /* Retain the exec, create, and sock SIDs across fork */ tsec2->exec_sid = tsec1->exec_sid; tsec2->create_sid = tsec1->create_sid; + tsec2->sockcreate_sid = tsec1->sockcreate_sid; /* Retain ptracer SID across fork, if any. This will be reset by the ptrace hook upon any @@ -2937,12 +2939,14 @@ static int selinux_socket_create(int family, int type, { int err = 0; struct task_security_struct *tsec; + u32 newsid; if (kern) goto out; tsec = current->security; - err = avc_has_perm(tsec->sid, tsec->sid, + newsid = tsec->sockcreate_sid ? : tsec->sid; + err = avc_has_perm(tsec->sid, newsid, socket_type_to_security_class(family, type, protocol), SOCKET__CREATE, NULL); @@ -2955,12 +2959,14 @@ static void selinux_socket_post_create(struct socket *sock, int family, { struct inode_security_struct *isec; struct task_security_struct *tsec; + u32 newsid; isec = SOCK_INODE(sock)->i_security; tsec = current->security; + newsid = tsec->sockcreate_sid ? : tsec->sid; isec->sclass = socket_type_to_security_class(family, type, protocol); - isec->sid = kern ? SECINITSID_KERNEL : tsec->sid; + isec->sid = kern ? SECINITSID_KERNEL : newsid; isec->initialized = 1; return; @@ -4163,6 +4169,8 @@ static int selinux_getprocattr(struct task_struct *p, sid = tsec->create_sid; else if (!strcmp(name, "keycreate")) sid = tsec->keycreate_sid; + else if (!strcmp(name, "sockcreate")) + sid = tsec->sockcreate_sid; else return -EINVAL; @@ -4197,6 +4205,8 @@ static int selinux_setprocattr(struct task_struct *p, error = task_has_perm(current, p, PROCESS__SETFSCREATE); else if (!strcmp(name, "keycreate")) error = task_has_perm(current, p, PROCESS__SETKEYCREATE); + else if (!strcmp(name, "sockcreate")) + error = task_has_perm(current, p, PROCESS__SETSOCKCREATE); else if (!strcmp(name, "current")) error = task_has_perm(current, p, PROCESS__SETCURRENT); else @@ -4231,7 +4241,9 @@ static int selinux_setprocattr(struct task_struct *p, if (error) return error; tsec->keycreate_sid = sid; - } else if (!strcmp(name, "current")) { + } else if (!strcmp(name, "sockcreate")) + tsec->sockcreate_sid = sid; + else if (!strcmp(name, "current")) { struct av_decision avd; if (sid == 0) diff --git a/security/selinux/include/av_perm_to_string.h b/security/selinux/include/av_perm_to_string.h index e777578ccd9d373551e745f72ca4582d4d291d10..7c9b583808337960eab8cbfccdad94d2cf315a66 100644 --- a/security/selinux/include/av_perm_to_string.h +++ b/security/selinux/include/av_perm_to_string.h @@ -73,6 +73,7 @@ S_(SECCLASS_PROCESS, PROCESS__EXECSTACK, "execstack") S_(SECCLASS_PROCESS, PROCESS__EXECHEAP, "execheap") S_(SECCLASS_PROCESS, PROCESS__SETKEYCREATE, "setkeycreate") + S_(SECCLASS_PROCESS, PROCESS__SETSOCKCREATE, "setsockcreate") S_(SECCLASS_MSGQ, MSGQ__ENQUEUE, "enqueue") S_(SECCLASS_MSG, MSG__SEND, "send") S_(SECCLASS_MSG, MSG__RECEIVE, "receive") diff --git a/security/selinux/include/av_permissions.h b/security/selinux/include/av_permissions.h index 1e1678023b68bb98a8621e49a379cdb94fbf942f..69fd4b48202ce6784c81a147d4d8bd18dfdaed2b 100644 --- a/security/selinux/include/av_permissions.h +++ b/security/selinux/include/av_permissions.h @@ -468,6 +468,7 @@ #define PROCESS__EXECSTACK 0x04000000UL #define PROCESS__EXECHEAP 0x08000000UL #define PROCESS__SETKEYCREATE 0x10000000UL +#define PROCESS__SETSOCKCREATE 0x20000000UL #define IPC__CREATE 0x00000001UL #define IPC__DESTROY 0x00000002UL diff --git a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h index 191b3e4484cecaba16ca34d1e455e23b77a69cbb..cf54a304169a0fc4ce2224e26d99221aff5821e3 100644 --- a/security/selinux/include/objsec.h +++ b/security/selinux/include/objsec.h @@ -33,6 +33,7 @@ struct task_security_struct { u32 exec_sid; /* exec SID */ u32 create_sid; /* fscreate SID */ u32 keycreate_sid; /* keycreate SID */ + u32 sockcreate_sid; /* fscreate SID */ u32 ptrace_sid; /* SID of ptrace parent */ };