diff options
Diffstat (limited to 'security/selinux/hooks.c')
-rw-r--r-- | security/selinux/hooks.c | 48 |
1 files changed, 29 insertions, 19 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 6237933f7d8..3c3fff33d1c 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -47,7 +47,7 @@ #include <linux/netfilter_ipv6.h> #include <linux/tty.h> #include <net/icmp.h> -#include <net/ip.h> /* for sysctl_local_port_range[] */ +#include <net/ip.h> /* for local_port_range[] */ #include <net/tcp.h> /* struct or_callable used in sock_rcv_skb */ #include <asm/uaccess.h> #include <asm/ioctls.h> @@ -316,6 +316,7 @@ static inline int inode_doinit(struct inode *inode) } enum { + Opt_error = -1, Opt_context = 1, Opt_fscontext = 2, Opt_defcontext = 4, @@ -327,6 +328,7 @@ static match_table_t tokens = { {Opt_fscontext, "fscontext=%s"}, {Opt_defcontext, "defcontext=%s"}, {Opt_rootcontext, "rootcontext=%s"}, + {Opt_error, NULL}, }; #define SEL_MOUNT_FAIL_MSG "SELinux: duplicate or incompatible mount options\n" @@ -1584,7 +1586,7 @@ static int selinux_syslog(int type) * Do not audit the selinux permission check, as this is applied to all * processes that allocate mappings. */ -static int selinux_vm_enough_memory(long pages) +static int selinux_vm_enough_memory(struct mm_struct *mm, long pages) { int rc, cap_sys_admin = 0; struct task_security_struct *tsec = current->security; @@ -1600,7 +1602,7 @@ static int selinux_vm_enough_memory(long pages) if (rc == 0) cap_sys_admin = 1; - return __vm_enough_memory(pages, cap_sys_admin); + return __vm_enough_memory(mm, pages, cap_sys_admin); } /* binprm security operations */ @@ -1907,6 +1909,9 @@ static void selinux_bprm_post_apply_creds(struct linux_binprm *bprm) spin_unlock_irq(¤t->sighand->siglock); } + /* Always clear parent death signal on SID transitions. */ + current->pdeath_signal = 0; + /* Check whether the new SID can inherit resource limits from the old SID. If not, reset all soft limits to the lower of the current task's hard limit and the init @@ -3227,8 +3232,6 @@ static int selinux_socket_post_create(struct socket *sock, int family, /* Range of port numbers used to automatically bind. Need to determine whether we should perform a name_bind permission check between the socket and the port number. */ -#define ip_local_port_range_0 sysctl_local_port_range[0] -#define ip_local_port_range_1 sysctl_local_port_range[1] static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, int addrlen) { @@ -3271,20 +3274,27 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in addrp = (char *)&addr6->sin6_addr.s6_addr; } - if (snum&&(snum < max(PROT_SOCK,ip_local_port_range_0) || - snum > ip_local_port_range_1)) { - err = security_port_sid(sk->sk_family, sk->sk_type, - sk->sk_protocol, snum, &sid); - if (err) - goto out; - AVC_AUDIT_DATA_INIT(&ad,NET); - ad.u.net.sport = htons(snum); - ad.u.net.family = family; - err = avc_has_perm(isec->sid, sid, - isec->sclass, - SOCKET__NAME_BIND, &ad); - if (err) - goto out; + if (snum) { + int low, high; + + inet_get_local_port_range(&low, &high); + + if (snum < max(PROT_SOCK, low) || snum > high) { + err = security_port_sid(sk->sk_family, + sk->sk_type, + sk->sk_protocol, snum, + &sid); + if (err) + goto out; + AVC_AUDIT_DATA_INIT(&ad,NET); + ad.u.net.sport = htons(snum); + ad.u.net.family = family; + err = avc_has_perm(isec->sid, sid, + isec->sclass, + SOCKET__NAME_BIND, &ad); + if (err) + goto out; + } } switch(isec->sclass) { |