aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux
diff options
context:
space:
mode:
Diffstat (limited to 'security/selinux')
-rw-r--r--security/selinux/hooks.c34
-rw-r--r--security/selinux/include/av_perm_to_string.h2
-rw-r--r--security/selinux/include/av_permissions.h2
-rw-r--r--security/selinux/include/security.h2
-rw-r--r--security/selinux/selinuxfs.c9
-rw-r--r--security/selinux/ss/conditional.c9
-rw-r--r--security/selinux/ss/mls.c71
-rw-r--r--security/selinux/ss/mls.h4
-rw-r--r--security/selinux/ss/policydb.c15
-rw-r--r--security/selinux/ss/services.c61
10 files changed, 140 insertions, 69 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 87302a49067b..2253f388234f 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -68,6 +68,7 @@
68#include <linux/personality.h> 68#include <linux/personality.h>
69#include <linux/sysctl.h> 69#include <linux/sysctl.h>
70#include <linux/audit.h> 70#include <linux/audit.h>
71#include <linux/string.h>
71 72
72#include "avc.h" 73#include "avc.h"
73#include "objsec.h" 74#include "objsec.h"
@@ -825,7 +826,8 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent
825 sid = sbsec->def_sid; 826 sid = sbsec->def_sid;
826 rc = 0; 827 rc = 0;
827 } else { 828 } else {
828 rc = security_context_to_sid(context, rc, &sid); 829 rc = security_context_to_sid_default(context, rc, &sid,
830 sbsec->def_sid);
829 if (rc) { 831 if (rc) {
830 printk(KERN_WARNING "%s: context_to_sid(%s) " 832 printk(KERN_WARNING "%s: context_to_sid(%s) "
831 "returned %d for dev=%s ino=%ld\n", 833 "returned %d for dev=%s ino=%ld\n",
@@ -1658,9 +1660,8 @@ static int selinux_bprm_secureexec (struct linux_binprm *bprm)
1658 1660
1659static void selinux_bprm_free_security(struct linux_binprm *bprm) 1661static void selinux_bprm_free_security(struct linux_binprm *bprm)
1660{ 1662{
1661 struct bprm_security_struct *bsec = bprm->security; 1663 kfree(bprm->security);
1662 bprm->security = NULL; 1664 bprm->security = NULL;
1663 kfree(bsec);
1664} 1665}
1665 1666
1666extern struct vfsmount *selinuxfs_mount; 1667extern struct vfsmount *selinuxfs_mount;
@@ -1944,7 +1945,7 @@ static int selinux_sb_copy_data(struct file_system_type *type, void *orig, void
1944 } 1945 }
1945 } while (*in_end++); 1946 } while (*in_end++);
1946 1947
1947 copy_page(in_save, nosec_save); 1948 strcpy(in_save, nosec_save);
1948 free_page((unsigned long)nosec_save); 1949 free_page((unsigned long)nosec_save);
1949out: 1950out:
1950 return rc; 1951 return rc;
@@ -2477,6 +2478,17 @@ static int selinux_file_mprotect(struct vm_area_struct *vma,
2477 prot = reqprot; 2478 prot = reqprot;
2478 2479
2479#ifndef CONFIG_PPC32 2480#ifndef CONFIG_PPC32
2481 if ((prot & PROT_EXEC) && !(vma->vm_flags & VM_EXECUTABLE) &&
2482 (vma->vm_start >= vma->vm_mm->start_brk &&
2483 vma->vm_end <= vma->vm_mm->brk)) {
2484 /*
2485 * We are making an executable mapping in the brk region.
2486 * This has an additional execheap check.
2487 */
2488 rc = task_has_perm(current, current, PROCESS__EXECHEAP);
2489 if (rc)
2490 return rc;
2491 }
2480 if (vma->vm_file != NULL && vma->anon_vma != NULL && (prot & PROT_EXEC)) { 2492 if (vma->vm_file != NULL && vma->anon_vma != NULL && (prot & PROT_EXEC)) {
2481 /* 2493 /*
2482 * We are making executable a file mapping that has 2494 * We are making executable a file mapping that has
@@ -2488,6 +2500,16 @@ static int selinux_file_mprotect(struct vm_area_struct *vma,
2488 if (rc) 2500 if (rc)
2489 return rc; 2501 return rc;
2490 } 2502 }
2503 if (!vma->vm_file && (prot & PROT_EXEC) &&
2504 vma->vm_start <= vma->vm_mm->start_stack &&
2505 vma->vm_end >= vma->vm_mm->start_stack) {
2506 /* Attempt to make the process stack executable.
2507 * This has an additional execstack check.
2508 */
2509 rc = task_has_perm(current, current, PROCESS__EXECSTACK);
2510 if (rc)
2511 return rc;
2512 }
2491#endif 2513#endif
2492 2514
2493 return file_map_prot_check(vma->vm_file, prot, vma->vm_flags&VM_SHARED); 2515 return file_map_prot_check(vma->vm_file, prot, vma->vm_flags&VM_SHARED);
@@ -3104,12 +3126,12 @@ static int selinux_socket_connect(struct socket *sock, struct sockaddr *address,
3104 3126
3105 if (sk->sk_family == PF_INET) { 3127 if (sk->sk_family == PF_INET) {
3106 addr4 = (struct sockaddr_in *)address; 3128 addr4 = (struct sockaddr_in *)address;
3107 if (addrlen != sizeof(struct sockaddr_in)) 3129 if (addrlen < sizeof(struct sockaddr_in))
3108 return -EINVAL; 3130 return -EINVAL;
3109 snum = ntohs(addr4->sin_port); 3131 snum = ntohs(addr4->sin_port);
3110 } else { 3132 } else {
3111 addr6 = (struct sockaddr_in6 *)address; 3133 addr6 = (struct sockaddr_in6 *)address;
3112 if (addrlen != sizeof(struct sockaddr_in6)) 3134 if (addrlen < SIN6_LEN_RFC2133)
3113 return -EINVAL; 3135 return -EINVAL;
3114 snum = ntohs(addr6->sin6_port); 3136 snum = ntohs(addr6->sin6_port);
3115 } 3137 }
diff --git a/security/selinux/include/av_perm_to_string.h b/security/selinux/include/av_perm_to_string.h
index 8928bb4d3c53..1deb59e1b762 100644
--- a/security/selinux/include/av_perm_to_string.h
+++ b/security/selinux/include/av_perm_to_string.h
@@ -70,6 +70,8 @@
70 S_(SECCLASS_PROCESS, PROCESS__DYNTRANSITION, "dyntransition") 70 S_(SECCLASS_PROCESS, PROCESS__DYNTRANSITION, "dyntransition")
71 S_(SECCLASS_PROCESS, PROCESS__SETCURRENT, "setcurrent") 71 S_(SECCLASS_PROCESS, PROCESS__SETCURRENT, "setcurrent")
72 S_(SECCLASS_PROCESS, PROCESS__EXECMEM, "execmem") 72 S_(SECCLASS_PROCESS, PROCESS__EXECMEM, "execmem")
73 S_(SECCLASS_PROCESS, PROCESS__EXECSTACK, "execstack")
74 S_(SECCLASS_PROCESS, PROCESS__EXECHEAP, "execheap")
73 S_(SECCLASS_MSGQ, MSGQ__ENQUEUE, "enqueue") 75 S_(SECCLASS_MSGQ, MSGQ__ENQUEUE, "enqueue")
74 S_(SECCLASS_MSG, MSG__SEND, "send") 76 S_(SECCLASS_MSG, MSG__SEND, "send")
75 S_(SECCLASS_MSG, MSG__RECEIVE, "receive") 77 S_(SECCLASS_MSG, MSG__RECEIVE, "receive")
diff --git a/security/selinux/include/av_permissions.h b/security/selinux/include/av_permissions.h
index bdfce4ca8f8e..a78b5d59c9fc 100644
--- a/security/selinux/include/av_permissions.h
+++ b/security/selinux/include/av_permissions.h
@@ -465,6 +465,8 @@
465#define PROCESS__DYNTRANSITION 0x00800000UL 465#define PROCESS__DYNTRANSITION 0x00800000UL
466#define PROCESS__SETCURRENT 0x01000000UL 466#define PROCESS__SETCURRENT 0x01000000UL
467#define PROCESS__EXECMEM 0x02000000UL 467#define PROCESS__EXECMEM 0x02000000UL
468#define PROCESS__EXECSTACK 0x04000000UL
469#define PROCESS__EXECHEAP 0x08000000UL
468 470
469#define IPC__CREATE 0x00000001UL 471#define IPC__CREATE 0x00000001UL
470#define IPC__DESTROY 0x00000002UL 472#define IPC__DESTROY 0x00000002UL
diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h
index fa187c9a351d..71c0a19c9753 100644
--- a/security/selinux/include/security.h
+++ b/security/selinux/include/security.h
@@ -65,6 +65,8 @@ int security_sid_to_context(u32 sid, char **scontext,
65int security_context_to_sid(char *scontext, u32 scontext_len, 65int security_context_to_sid(char *scontext, u32 scontext_len,
66 u32 *out_sid); 66 u32 *out_sid);
67 67
68int security_context_to_sid_default(char *scontext, u32 scontext_len, u32 *out_sid, u32 def_sid);
69
68int security_get_user_sids(u32 callsid, char *username, 70int security_get_user_sids(u32 callsid, char *username,
69 u32 **sids, u32 *nel); 71 u32 **sids, u32 *nel);
70 72
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
index 07221568b505..8eb140dd2e4b 100644
--- a/security/selinux/selinuxfs.c
+++ b/security/selinux/selinuxfs.c
@@ -951,8 +951,7 @@ static int sel_make_bools(void)
951 u32 sid; 951 u32 sid;
952 952
953 /* remove any existing files */ 953 /* remove any existing files */
954 if (bool_pending_values) 954 kfree(bool_pending_values);
955 kfree(bool_pending_values);
956 955
957 sel_remove_bools(dir); 956 sel_remove_bools(dir);
958 957
@@ -997,10 +996,8 @@ static int sel_make_bools(void)
997out: 996out:
998 free_page((unsigned long)page); 997 free_page((unsigned long)page);
999 if (names) { 998 if (names) {
1000 for (i = 0; i < num; i++) { 999 for (i = 0; i < num; i++)
1001 if (names[i]) 1000 kfree(names[i]);
1002 kfree(names[i]);
1003 }
1004 kfree(names); 1001 kfree(names);
1005 } 1002 }
1006 return ret; 1003 return ret;
diff --git a/security/selinux/ss/conditional.c b/security/selinux/ss/conditional.c
index b53441184aca..e2057f5a411a 100644
--- a/security/selinux/ss/conditional.c
+++ b/security/selinux/ss/conditional.c
@@ -166,16 +166,14 @@ static void cond_list_destroy(struct cond_node *list)
166 166
167void cond_policydb_destroy(struct policydb *p) 167void cond_policydb_destroy(struct policydb *p)
168{ 168{
169 if (p->bool_val_to_struct != NULL) 169 kfree(p->bool_val_to_struct);
170 kfree(p->bool_val_to_struct);
171 avtab_destroy(&p->te_cond_avtab); 170 avtab_destroy(&p->te_cond_avtab);
172 cond_list_destroy(p->cond_list); 171 cond_list_destroy(p->cond_list);
173} 172}
174 173
175int cond_init_bool_indexes(struct policydb *p) 174int cond_init_bool_indexes(struct policydb *p)
176{ 175{
177 if (p->bool_val_to_struct) 176 kfree(p->bool_val_to_struct);
178 kfree(p->bool_val_to_struct);
179 p->bool_val_to_struct = (struct cond_bool_datum**) 177 p->bool_val_to_struct = (struct cond_bool_datum**)
180 kmalloc(p->p_bools.nprim * sizeof(struct cond_bool_datum*), GFP_KERNEL); 178 kmalloc(p->p_bools.nprim * sizeof(struct cond_bool_datum*), GFP_KERNEL);
181 if (!p->bool_val_to_struct) 179 if (!p->bool_val_to_struct)
@@ -185,8 +183,7 @@ int cond_init_bool_indexes(struct policydb *p)
185 183
186int cond_destroy_bool(void *key, void *datum, void *p) 184int cond_destroy_bool(void *key, void *datum, void *p)
187{ 185{
188 if (key) 186 kfree(key);
189 kfree(key);
190 kfree(datum); 187 kfree(datum);
191 return 0; 188 return 0;
192} 189}
diff --git a/security/selinux/ss/mls.c b/security/selinux/ss/mls.c
index 756036bcc243..d4c32c39ccc9 100644
--- a/security/selinux/ss/mls.c
+++ b/security/selinux/ss/mls.c
@@ -15,6 +15,7 @@
15#include <linux/slab.h> 15#include <linux/slab.h>
16#include <linux/string.h> 16#include <linux/string.h>
17#include <linux/errno.h> 17#include <linux/errno.h>
18#include "sidtab.h"
18#include "mls.h" 19#include "mls.h"
19#include "policydb.h" 20#include "policydb.h"
20#include "services.h" 21#include "services.h"
@@ -208,6 +209,26 @@ int mls_context_isvalid(struct policydb *p, struct context *c)
208} 209}
209 210
210/* 211/*
212 * Copies the MLS range from `src' into `dst'.
213 */
214static inline int mls_copy_context(struct context *dst,
215 struct context *src)
216{
217 int l, rc = 0;
218
219 /* Copy the MLS range from the source context */
220 for (l = 0; l < 2; l++) {
221 dst->range.level[l].sens = src->range.level[l].sens;
222 rc = ebitmap_cpy(&dst->range.level[l].cat,
223 &src->range.level[l].cat);
224 if (rc)
225 break;
226 }
227
228 return rc;
229}
230
231/*
211 * Set the MLS fields in the security context structure 232 * Set the MLS fields in the security context structure
212 * `context' based on the string representation in 233 * `context' based on the string representation in
213 * the string `*scontext'. Update `*scontext' to 234 * the string `*scontext'. Update `*scontext' to
@@ -216,10 +237,20 @@ int mls_context_isvalid(struct policydb *p, struct context *c)
216 * 237 *
217 * This function modifies the string in place, inserting 238 * This function modifies the string in place, inserting
218 * NULL characters to terminate the MLS fields. 239 * NULL characters to terminate the MLS fields.
240 *
241 * If a def_sid is provided and no MLS field is present,
242 * copy the MLS field of the associated default context.
243 * Used for upgraded to MLS systems where objects may lack
244 * MLS fields.
245 *
246 * Policy read-lock must be held for sidtab lookup.
247 *
219 */ 248 */
220int mls_context_to_sid(char oldc, 249int mls_context_to_sid(char oldc,
221 char **scontext, 250 char **scontext,
222 struct context *context) 251 struct context *context,
252 struct sidtab *s,
253 u32 def_sid)
223{ 254{
224 255
225 char delim; 256 char delim;
@@ -231,9 +262,23 @@ int mls_context_to_sid(char oldc,
231 if (!selinux_mls_enabled) 262 if (!selinux_mls_enabled)
232 return 0; 263 return 0;
233 264
234 /* No MLS component to the security context. */ 265 /*
235 if (!oldc) 266 * No MLS component to the security context, try and map to
267 * default if provided.
268 */
269 if (!oldc) {
270 struct context *defcon;
271
272 if (def_sid == SECSID_NULL)
273 goto out;
274
275 defcon = sidtab_search(s, def_sid);
276 if (!defcon)
277 goto out;
278
279 rc = mls_copy_context(context, defcon);
236 goto out; 280 goto out;
281 }
237 282
238 /* Extract low sensitivity. */ 283 /* Extract low sensitivity. */
239 scontextp = p = *scontext; 284 scontextp = p = *scontext;
@@ -334,26 +379,6 @@ out:
334} 379}
335 380
336/* 381/*
337 * Copies the MLS range from `src' into `dst'.
338 */
339static inline int mls_copy_context(struct context *dst,
340 struct context *src)
341{
342 int l, rc = 0;
343
344 /* Copy the MLS range from the source context */
345 for (l = 0; l < 2; l++) {
346 dst->range.level[l].sens = src->range.level[l].sens;
347 rc = ebitmap_cpy(&dst->range.level[l].cat,
348 &src->range.level[l].cat);
349 if (rc)
350 break;
351 }
352
353 return rc;
354}
355
356/*
357 * Copies the effective MLS range from `src' into `dst'. 382 * Copies the effective MLS range from `src' into `dst'.
358 */ 383 */
359static inline int mls_scopy_context(struct context *dst, 384static inline int mls_scopy_context(struct context *dst,
diff --git a/security/selinux/ss/mls.h b/security/selinux/ss/mls.h
index 0d37beaa85e2..03de697c8058 100644
--- a/security/selinux/ss/mls.h
+++ b/security/selinux/ss/mls.h
@@ -23,7 +23,9 @@ int mls_context_isvalid(struct policydb *p, struct context *c);
23 23
24int mls_context_to_sid(char oldc, 24int mls_context_to_sid(char oldc,
25 char **scontext, 25 char **scontext,
26 struct context *context); 26 struct context *context,
27 struct sidtab *s,
28 u32 def_sid);
27 29
28int mls_convert_context(struct policydb *oldp, 30int mls_convert_context(struct policydb *oldp,
29 struct policydb *newp, 31 struct policydb *newp,
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c
index 14190efbf333..785c33cf4864 100644
--- a/security/selinux/ss/policydb.c
+++ b/security/selinux/ss/policydb.c
@@ -590,17 +590,12 @@ void policydb_destroy(struct policydb *p)
590 hashtab_destroy(p->symtab[i].table); 590 hashtab_destroy(p->symtab[i].table);
591 } 591 }
592 592
593 for (i = 0; i < SYM_NUM; i++) { 593 for (i = 0; i < SYM_NUM; i++)
594 if (p->sym_val_to_name[i]) 594 kfree(p->sym_val_to_name[i]);
595 kfree(p->sym_val_to_name[i]);
596 }
597 595
598 if (p->class_val_to_struct) 596 kfree(p->class_val_to_struct);
599 kfree(p->class_val_to_struct); 597 kfree(p->role_val_to_struct);
600 if (p->role_val_to_struct) 598 kfree(p->user_val_to_struct);
601 kfree(p->role_val_to_struct);
602 if (p->user_val_to_struct)
603 kfree(p->user_val_to_struct);
604 599
605 avtab_destroy(&p->te_avtab); 600 avtab_destroy(&p->te_avtab);
606 601
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index b6149147d5cb..014120474e69 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -601,18 +601,7 @@ out:
601 601
602} 602}
603 603
604/** 604static int security_context_to_sid_core(char *scontext, u32 scontext_len, u32 *sid, u32 def_sid)
605 * security_context_to_sid - Obtain a SID for a given security context.
606 * @scontext: security context
607 * @scontext_len: length in bytes
608 * @sid: security identifier, SID
609 *
610 * Obtains a SID associated with the security context that
611 * has the string representation specified by @scontext.
612 * Returns -%EINVAL if the context is invalid, -%ENOMEM if insufficient
613 * memory is available, or 0 on success.
614 */
615int security_context_to_sid(char *scontext, u32 scontext_len, u32 *sid)
616{ 605{
617 char *scontext2; 606 char *scontext2;
618 struct context context; 607 struct context context;
@@ -703,7 +692,7 @@ int security_context_to_sid(char *scontext, u32 scontext_len, u32 *sid)
703 692
704 context.type = typdatum->value; 693 context.type = typdatum->value;
705 694
706 rc = mls_context_to_sid(oldc, &p, &context); 695 rc = mls_context_to_sid(oldc, &p, &context, &sidtab, def_sid);
707 if (rc) 696 if (rc)
708 goto out_unlock; 697 goto out_unlock;
709 698
@@ -727,6 +716,46 @@ out:
727 return rc; 716 return rc;
728} 717}
729 718
719/**
720 * security_context_to_sid - Obtain a SID for a given security context.
721 * @scontext: security context
722 * @scontext_len: length in bytes
723 * @sid: security identifier, SID
724 *
725 * Obtains a SID associated with the security context that
726 * has the string representation specified by @scontext.
727 * Returns -%EINVAL if the context is invalid, -%ENOMEM if insufficient
728 * memory is available, or 0 on success.
729 */
730int security_context_to_sid(char *scontext, u32 scontext_len, u32 *sid)
731{
732 return security_context_to_sid_core(scontext, scontext_len,
733 sid, SECSID_NULL);
734}
735
736/**
737 * security_context_to_sid_default - Obtain a SID for a given security context,
738 * falling back to specified default if needed.
739 *
740 * @scontext: security context
741 * @scontext_len: length in bytes
742 * @sid: security identifier, SID
743 * @def_sid: default SID to assign on errror
744 *
745 * Obtains a SID associated with the security context that
746 * has the string representation specified by @scontext.
747 * The default SID is passed to the MLS layer to be used to allow
748 * kernel labeling of the MLS field if the MLS field is not present
749 * (for upgrading to MLS without full relabel).
750 * Returns -%EINVAL if the context is invalid, -%ENOMEM if insufficient
751 * memory is available, or 0 on success.
752 */
753int security_context_to_sid_default(char *scontext, u32 scontext_len, u32 *sid, u32 def_sid)
754{
755 return security_context_to_sid_core(scontext, scontext_len,
756 sid, def_sid);
757}
758
730static int compute_sid_handle_invalid_context( 759static int compute_sid_handle_invalid_context(
731 struct context *scontext, 760 struct context *scontext,
732 struct context *tcontext, 761 struct context *tcontext,
@@ -1705,11 +1734,9 @@ out:
1705err: 1734err:
1706 if (*names) { 1735 if (*names) {
1707 for (i = 0; i < *len; i++) 1736 for (i = 0; i < *len; i++)
1708 if ((*names)[i]) 1737 kfree((*names)[i]);
1709 kfree((*names)[i]);
1710 } 1738 }
1711 if (*values) 1739 kfree(*values);
1712 kfree(*values);
1713 goto out; 1740 goto out;
1714} 1741}
1715 1742