diff options
Diffstat (limited to 'security/selinux')
| -rw-r--r-- | security/selinux/hooks.c | 34 | ||||
| -rw-r--r-- | security/selinux/include/av_perm_to_string.h | 2 | ||||
| -rw-r--r-- | security/selinux/include/av_permissions.h | 2 | ||||
| -rw-r--r-- | security/selinux/include/security.h | 2 | ||||
| -rw-r--r-- | security/selinux/selinuxfs.c | 9 | ||||
| -rw-r--r-- | security/selinux/ss/conditional.c | 9 | ||||
| -rw-r--r-- | security/selinux/ss/mls.c | 71 | ||||
| -rw-r--r-- | security/selinux/ss/mls.h | 4 | ||||
| -rw-r--r-- | security/selinux/ss/policydb.c | 15 | ||||
| -rw-r--r-- | security/selinux/ss/services.c | 61 |
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 | ||
| 1659 | static void selinux_bprm_free_security(struct linux_binprm *bprm) | 1661 | static 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 | ||
| 1666 | extern struct vfsmount *selinuxfs_mount; | 1667 | extern 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); |
| 1949 | out: | 1950 | out: |
| 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, | |||
| 65 | int security_context_to_sid(char *scontext, u32 scontext_len, | 65 | int security_context_to_sid(char *scontext, u32 scontext_len, |
| 66 | u32 *out_sid); | 66 | u32 *out_sid); |
| 67 | 67 | ||
| 68 | int security_context_to_sid_default(char *scontext, u32 scontext_len, u32 *out_sid, u32 def_sid); | ||
| 69 | |||
| 68 | int security_get_user_sids(u32 callsid, char *username, | 70 | int 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) | |||
| 997 | out: | 996 | out: |
| 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 | ||
| 167 | void cond_policydb_destroy(struct policydb *p) | 167 | void 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 | ||
| 175 | int cond_init_bool_indexes(struct policydb *p) | 174 | int 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 | ||
| 186 | int cond_destroy_bool(void *key, void *datum, void *p) | 184 | int 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 | */ | ||
| 214 | static 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 | */ |
| 220 | int mls_context_to_sid(char oldc, | 249 | int 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 | */ | ||
| 339 | static 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 | */ |
| 359 | static inline int mls_scopy_context(struct context *dst, | 384 | static 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 | ||
| 24 | int mls_context_to_sid(char oldc, | 24 | int 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 | ||
| 28 | int mls_convert_context(struct policydb *oldp, | 30 | int 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 | /** | 604 | static 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 | */ | ||
| 615 | int 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 | */ | ||
| 730 | int 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 | */ | ||
| 753 | int 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 | |||
| 730 | static int compute_sid_handle_invalid_context( | 759 | static 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: | |||
| 1705 | err: | 1734 | err: |
| 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 | ||
