diff options
author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2007-10-12 21:27:47 -0400 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2007-10-12 21:27:47 -0400 |
commit | b981d8b3f5e008ff10d993be633ad00564fc22cd (patch) | |
tree | e292dc07b22308912cf6a58354a608b9e5e8e1fd /security/selinux/hooks.c | |
parent | b11d2127c4893a7315d1e16273bc8560049fa3ca (diff) | |
parent | 2b9e0aae1d50e880c58d46788e5e3ebd89d75d62 (diff) |
Merge master.kernel.org:/pub/scm/linux/kernel/git/torvalds/linux-2.6
Conflicts:
drivers/macintosh/adbhid.c
Diffstat (limited to 'security/selinux/hooks.c')
-rw-r--r-- | security/selinux/hooks.c | 74 |
1 files changed, 42 insertions, 32 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 520b9998123e..3c3fff33d1ce 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
@@ -47,7 +47,7 @@ | |||
47 | #include <linux/netfilter_ipv6.h> | 47 | #include <linux/netfilter_ipv6.h> |
48 | #include <linux/tty.h> | 48 | #include <linux/tty.h> |
49 | #include <net/icmp.h> | 49 | #include <net/icmp.h> |
50 | #include <net/ip.h> /* for sysctl_local_port_range[] */ | 50 | #include <net/ip.h> /* for local_port_range[] */ |
51 | #include <net/tcp.h> /* struct or_callable used in sock_rcv_skb */ | 51 | #include <net/tcp.h> /* struct or_callable used in sock_rcv_skb */ |
52 | #include <asm/uaccess.h> | 52 | #include <asm/uaccess.h> |
53 | #include <asm/ioctls.h> | 53 | #include <asm/ioctls.h> |
@@ -316,6 +316,7 @@ static inline int inode_doinit(struct inode *inode) | |||
316 | } | 316 | } |
317 | 317 | ||
318 | enum { | 318 | enum { |
319 | Opt_error = -1, | ||
319 | Opt_context = 1, | 320 | Opt_context = 1, |
320 | Opt_fscontext = 2, | 321 | Opt_fscontext = 2, |
321 | Opt_defcontext = 4, | 322 | Opt_defcontext = 4, |
@@ -327,6 +328,7 @@ static match_table_t tokens = { | |||
327 | {Opt_fscontext, "fscontext=%s"}, | 328 | {Opt_fscontext, "fscontext=%s"}, |
328 | {Opt_defcontext, "defcontext=%s"}, | 329 | {Opt_defcontext, "defcontext=%s"}, |
329 | {Opt_rootcontext, "rootcontext=%s"}, | 330 | {Opt_rootcontext, "rootcontext=%s"}, |
331 | {Opt_error, NULL}, | ||
330 | }; | 332 | }; |
331 | 333 | ||
332 | #define SEL_MOUNT_FAIL_MSG "SELinux: duplicate or incompatible mount options\n" | 334 | #define SEL_MOUNT_FAIL_MSG "SELinux: duplicate or incompatible mount options\n" |
@@ -1584,7 +1586,7 @@ static int selinux_syslog(int type) | |||
1584 | * Do not audit the selinux permission check, as this is applied to all | 1586 | * Do not audit the selinux permission check, as this is applied to all |
1585 | * processes that allocate mappings. | 1587 | * processes that allocate mappings. |
1586 | */ | 1588 | */ |
1587 | static int selinux_vm_enough_memory(long pages) | 1589 | static int selinux_vm_enough_memory(struct mm_struct *mm, long pages) |
1588 | { | 1590 | { |
1589 | int rc, cap_sys_admin = 0; | 1591 | int rc, cap_sys_admin = 0; |
1590 | struct task_security_struct *tsec = current->security; | 1592 | struct task_security_struct *tsec = current->security; |
@@ -1600,7 +1602,7 @@ static int selinux_vm_enough_memory(long pages) | |||
1600 | if (rc == 0) | 1602 | if (rc == 0) |
1601 | cap_sys_admin = 1; | 1603 | cap_sys_admin = 1; |
1602 | 1604 | ||
1603 | return __vm_enough_memory(pages, cap_sys_admin); | 1605 | return __vm_enough_memory(mm, pages, cap_sys_admin); |
1604 | } | 1606 | } |
1605 | 1607 | ||
1606 | /* binprm security operations */ | 1608 | /* binprm security operations */ |
@@ -1907,6 +1909,9 @@ static void selinux_bprm_post_apply_creds(struct linux_binprm *bprm) | |||
1907 | spin_unlock_irq(¤t->sighand->siglock); | 1909 | spin_unlock_irq(¤t->sighand->siglock); |
1908 | } | 1910 | } |
1909 | 1911 | ||
1912 | /* Always clear parent death signal on SID transitions. */ | ||
1913 | current->pdeath_signal = 0; | ||
1914 | |||
1910 | /* Check whether the new SID can inherit resource limits | 1915 | /* Check whether the new SID can inherit resource limits |
1911 | from the old SID. If not, reset all soft limits to | 1916 | from the old SID. If not, reset all soft limits to |
1912 | the lower of the current task's hard limit and the init | 1917 | the lower of the current task's hard limit and the init |
@@ -3129,17 +3134,19 @@ static int selinux_parse_skb(struct sk_buff *skb, struct avc_audit_data *ad, | |||
3129 | /** | 3134 | /** |
3130 | * selinux_skb_extlbl_sid - Determine the external label of a packet | 3135 | * selinux_skb_extlbl_sid - Determine the external label of a packet |
3131 | * @skb: the packet | 3136 | * @skb: the packet |
3132 | * @base_sid: the SELinux SID to use as a context for MLS only external labels | ||
3133 | * @sid: the packet's SID | 3137 | * @sid: the packet's SID |
3134 | * | 3138 | * |
3135 | * Description: | 3139 | * Description: |
3136 | * Check the various different forms of external packet labeling and determine | 3140 | * Check the various different forms of external packet labeling and determine |
3137 | * the external SID for the packet. | 3141 | * the external SID for the packet. If only one form of external labeling is |
3142 | * present then it is used, if both labeled IPsec and NetLabel labels are | ||
3143 | * present then the SELinux type information is taken from the labeled IPsec | ||
3144 | * SA and the MLS sensitivity label information is taken from the NetLabel | ||
3145 | * security attributes. This bit of "magic" is done in the call to | ||
3146 | * selinux_netlbl_skbuff_getsid(). | ||
3138 | * | 3147 | * |
3139 | */ | 3148 | */ |
3140 | static void selinux_skb_extlbl_sid(struct sk_buff *skb, | 3149 | static void selinux_skb_extlbl_sid(struct sk_buff *skb, u32 *sid) |
3141 | u32 base_sid, | ||
3142 | u32 *sid) | ||
3143 | { | 3150 | { |
3144 | u32 xfrm_sid; | 3151 | u32 xfrm_sid; |
3145 | u32 nlbl_sid; | 3152 | u32 nlbl_sid; |
@@ -3147,10 +3154,9 @@ static void selinux_skb_extlbl_sid(struct sk_buff *skb, | |||
3147 | selinux_skb_xfrm_sid(skb, &xfrm_sid); | 3154 | selinux_skb_xfrm_sid(skb, &xfrm_sid); |
3148 | if (selinux_netlbl_skbuff_getsid(skb, | 3155 | if (selinux_netlbl_skbuff_getsid(skb, |
3149 | (xfrm_sid == SECSID_NULL ? | 3156 | (xfrm_sid == SECSID_NULL ? |
3150 | base_sid : xfrm_sid), | 3157 | SECINITSID_NETMSG : xfrm_sid), |
3151 | &nlbl_sid) != 0) | 3158 | &nlbl_sid) != 0) |
3152 | nlbl_sid = SECSID_NULL; | 3159 | nlbl_sid = SECSID_NULL; |
3153 | |||
3154 | *sid = (nlbl_sid == SECSID_NULL ? xfrm_sid : nlbl_sid); | 3160 | *sid = (nlbl_sid == SECSID_NULL ? xfrm_sid : nlbl_sid); |
3155 | } | 3161 | } |
3156 | 3162 | ||
@@ -3226,8 +3232,6 @@ static int selinux_socket_post_create(struct socket *sock, int family, | |||
3226 | /* Range of port numbers used to automatically bind. | 3232 | /* Range of port numbers used to automatically bind. |
3227 | Need to determine whether we should perform a name_bind | 3233 | Need to determine whether we should perform a name_bind |
3228 | permission check between the socket and the port number. */ | 3234 | permission check between the socket and the port number. */ |
3229 | #define ip_local_port_range_0 sysctl_local_port_range[0] | ||
3230 | #define ip_local_port_range_1 sysctl_local_port_range[1] | ||
3231 | 3235 | ||
3232 | static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, int addrlen) | 3236 | static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, int addrlen) |
3233 | { | 3237 | { |
@@ -3270,20 +3274,27 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in | |||
3270 | addrp = (char *)&addr6->sin6_addr.s6_addr; | 3274 | addrp = (char *)&addr6->sin6_addr.s6_addr; |
3271 | } | 3275 | } |
3272 | 3276 | ||
3273 | if (snum&&(snum < max(PROT_SOCK,ip_local_port_range_0) || | 3277 | if (snum) { |
3274 | snum > ip_local_port_range_1)) { | 3278 | int low, high; |
3275 | err = security_port_sid(sk->sk_family, sk->sk_type, | 3279 | |
3276 | sk->sk_protocol, snum, &sid); | 3280 | inet_get_local_port_range(&low, &high); |
3277 | if (err) | 3281 | |
3278 | goto out; | 3282 | if (snum < max(PROT_SOCK, low) || snum > high) { |
3279 | AVC_AUDIT_DATA_INIT(&ad,NET); | 3283 | err = security_port_sid(sk->sk_family, |
3280 | ad.u.net.sport = htons(snum); | 3284 | sk->sk_type, |
3281 | ad.u.net.family = family; | 3285 | sk->sk_protocol, snum, |
3282 | err = avc_has_perm(isec->sid, sid, | 3286 | &sid); |
3283 | isec->sclass, | 3287 | if (err) |
3284 | SOCKET__NAME_BIND, &ad); | 3288 | goto out; |
3285 | if (err) | 3289 | AVC_AUDIT_DATA_INIT(&ad,NET); |
3286 | goto out; | 3290 | ad.u.net.sport = htons(snum); |
3291 | ad.u.net.family = family; | ||
3292 | err = avc_has_perm(isec->sid, sid, | ||
3293 | isec->sclass, | ||
3294 | SOCKET__NAME_BIND, &ad); | ||
3295 | if (err) | ||
3296 | goto out; | ||
3297 | } | ||
3287 | } | 3298 | } |
3288 | 3299 | ||
3289 | switch(isec->sclass) { | 3300 | switch(isec->sclass) { |
@@ -3695,7 +3706,7 @@ static int selinux_socket_getpeersec_dgram(struct socket *sock, struct sk_buff * | |||
3695 | if (sock && sock->sk->sk_family == PF_UNIX) | 3706 | if (sock && sock->sk->sk_family == PF_UNIX) |
3696 | selinux_get_inode_sid(SOCK_INODE(sock), &peer_secid); | 3707 | selinux_get_inode_sid(SOCK_INODE(sock), &peer_secid); |
3697 | else if (skb) | 3708 | else if (skb) |
3698 | selinux_skb_extlbl_sid(skb, SECINITSID_UNLABELED, &peer_secid); | 3709 | selinux_skb_extlbl_sid(skb, &peer_secid); |
3699 | 3710 | ||
3700 | if (peer_secid == SECSID_NULL) | 3711 | if (peer_secid == SECSID_NULL) |
3701 | err = -EINVAL; | 3712 | err = -EINVAL; |
@@ -3756,7 +3767,7 @@ static int selinux_inet_conn_request(struct sock *sk, struct sk_buff *skb, | |||
3756 | u32 newsid; | 3767 | u32 newsid; |
3757 | u32 peersid; | 3768 | u32 peersid; |
3758 | 3769 | ||
3759 | selinux_skb_extlbl_sid(skb, SECINITSID_UNLABELED, &peersid); | 3770 | selinux_skb_extlbl_sid(skb, &peersid); |
3760 | if (peersid == SECSID_NULL) { | 3771 | if (peersid == SECSID_NULL) { |
3761 | req->secid = sksec->sid; | 3772 | req->secid = sksec->sid; |
3762 | req->peer_secid = SECSID_NULL; | 3773 | req->peer_secid = SECSID_NULL; |
@@ -3794,7 +3805,7 @@ static void selinux_inet_conn_established(struct sock *sk, | |||
3794 | { | 3805 | { |
3795 | struct sk_security_struct *sksec = sk->sk_security; | 3806 | struct sk_security_struct *sksec = sk->sk_security; |
3796 | 3807 | ||
3797 | selinux_skb_extlbl_sid(skb, SECINITSID_UNLABELED, &sksec->peer_sid); | 3808 | selinux_skb_extlbl_sid(skb, &sksec->peer_sid); |
3798 | } | 3809 | } |
3799 | 3810 | ||
3800 | static void selinux_req_classify_flow(const struct request_sock *req, | 3811 | static void selinux_req_classify_flow(const struct request_sock *req, |
@@ -4657,8 +4668,7 @@ static int selinux_secid_to_secctx(u32 secid, char **secdata, u32 *seclen) | |||
4657 | 4668 | ||
4658 | static void selinux_release_secctx(char *secdata, u32 seclen) | 4669 | static void selinux_release_secctx(char *secdata, u32 seclen) |
4659 | { | 4670 | { |
4660 | if (secdata) | 4671 | kfree(secdata); |
4661 | kfree(secdata); | ||
4662 | } | 4672 | } |
4663 | 4673 | ||
4664 | #ifdef CONFIG_KEYS | 4674 | #ifdef CONFIG_KEYS |
@@ -4912,7 +4922,7 @@ static __init int selinux_init(void) | |||
4912 | 4922 | ||
4913 | sel_inode_cache = kmem_cache_create("selinux_inode_security", | 4923 | sel_inode_cache = kmem_cache_create("selinux_inode_security", |
4914 | sizeof(struct inode_security_struct), | 4924 | sizeof(struct inode_security_struct), |
4915 | 0, SLAB_PANIC, NULL, NULL); | 4925 | 0, SLAB_PANIC, NULL); |
4916 | avc_init(); | 4926 | avc_init(); |
4917 | 4927 | ||
4918 | original_ops = secondary_ops = security_ops; | 4928 | original_ops = secondary_ops = security_ops; |