diff options
Diffstat (limited to 'security')
-rw-r--r-- | security/keys/keyctl.c | 11 | ||||
-rw-r--r-- | security/keys/keyring.c | 6 | ||||
-rw-r--r-- | security/keys/process_keys.c | 2 | ||||
-rw-r--r-- | security/keys/request_key.c | 2 | ||||
-rw-r--r-- | security/selinux/hooks.c | 7 | ||||
-rw-r--r-- | security/selinux/include/security.h | 2 | ||||
-rw-r--r-- | security/selinux/ss/mls.c | 71 | ||||
-rw-r--r-- | security/selinux/ss/mls.h | 4 | ||||
-rw-r--r-- | security/selinux/ss/services.c | 55 |
9 files changed, 113 insertions, 47 deletions
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c index fea262860ea0..a6516a64b297 100644 --- a/security/keys/keyctl.c +++ b/security/keys/keyctl.c | |||
@@ -49,9 +49,6 @@ asmlinkage long sys_add_key(const char __user *_type, | |||
49 | goto error; | 49 | goto error; |
50 | type[31] = '\0'; | 50 | type[31] = '\0'; |
51 | 51 | ||
52 | if (!type[0]) | ||
53 | goto error; | ||
54 | |||
55 | ret = -EPERM; | 52 | ret = -EPERM; |
56 | if (type[0] == '.') | 53 | if (type[0] == '.') |
57 | goto error; | 54 | goto error; |
@@ -144,6 +141,10 @@ asmlinkage long sys_request_key(const char __user *_type, | |||
144 | goto error; | 141 | goto error; |
145 | type[31] = '\0'; | 142 | type[31] = '\0'; |
146 | 143 | ||
144 | ret = -EPERM; | ||
145 | if (type[0] == '.') | ||
146 | goto error; | ||
147 | |||
147 | /* pull the description into kernel space */ | 148 | /* pull the description into kernel space */ |
148 | ret = -EFAULT; | 149 | ret = -EFAULT; |
149 | dlen = strnlen_user(_description, PAGE_SIZE - 1); | 150 | dlen = strnlen_user(_description, PAGE_SIZE - 1); |
@@ -362,7 +363,7 @@ long keyctl_revoke_key(key_serial_t id) | |||
362 | 363 | ||
363 | key_put(key); | 364 | key_put(key); |
364 | error: | 365 | error: |
365 | return 0; | 366 | return ret; |
366 | 367 | ||
367 | } /* end keyctl_revoke_key() */ | 368 | } /* end keyctl_revoke_key() */ |
368 | 369 | ||
@@ -685,6 +686,8 @@ long keyctl_read_key(key_serial_t keyid, char __user *buffer, size_t buflen) | |||
685 | goto can_read_key2; | 686 | goto can_read_key2; |
686 | 687 | ||
687 | ret = PTR_ERR(skey); | 688 | ret = PTR_ERR(skey); |
689 | if (ret == -EAGAIN) | ||
690 | ret = -EACCES; | ||
688 | goto error2; | 691 | goto error2; |
689 | } | 692 | } |
690 | 693 | ||
diff --git a/security/keys/keyring.c b/security/keys/keyring.c index a1f6bac647a1..9c208c756df8 100644 --- a/security/keys/keyring.c +++ b/security/keys/keyring.c | |||
@@ -201,7 +201,11 @@ static void keyring_destroy(struct key *keyring) | |||
201 | 201 | ||
202 | if (keyring->description) { | 202 | if (keyring->description) { |
203 | write_lock(&keyring_name_lock); | 203 | write_lock(&keyring_name_lock); |
204 | list_del(&keyring->type_data.link); | 204 | |
205 | if (keyring->type_data.link.next != NULL && | ||
206 | !list_empty(&keyring->type_data.link)) | ||
207 | list_del(&keyring->type_data.link); | ||
208 | |||
205 | write_unlock(&keyring_name_lock); | 209 | write_unlock(&keyring_name_lock); |
206 | } | 210 | } |
207 | 211 | ||
diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c index 9b0369c5a223..c089f78fb94e 100644 --- a/security/keys/process_keys.c +++ b/security/keys/process_keys.c | |||
@@ -678,7 +678,7 @@ long join_session_keyring(const char *name) | |||
678 | keyring = keyring_alloc(name, tsk->uid, tsk->gid, 0, NULL); | 678 | keyring = keyring_alloc(name, tsk->uid, tsk->gid, 0, NULL); |
679 | if (IS_ERR(keyring)) { | 679 | if (IS_ERR(keyring)) { |
680 | ret = PTR_ERR(keyring); | 680 | ret = PTR_ERR(keyring); |
681 | goto error; | 681 | goto error2; |
682 | } | 682 | } |
683 | } | 683 | } |
684 | else if (IS_ERR(keyring)) { | 684 | else if (IS_ERR(keyring)) { |
diff --git a/security/keys/request_key.c b/security/keys/request_key.c index dfcd983af1fd..90c1506d007c 100644 --- a/security/keys/request_key.c +++ b/security/keys/request_key.c | |||
@@ -405,7 +405,7 @@ struct key *request_key_and_link(struct key_type *type, | |||
405 | key_user_put(user); | 405 | key_user_put(user); |
406 | 406 | ||
407 | /* link the new key into the appropriate keyring */ | 407 | /* link the new key into the appropriate keyring */ |
408 | if (!PTR_ERR(key)) | 408 | if (!IS_ERR(key)) |
409 | request_key_link(key, dest_keyring); | 409 | request_key_link(key, dest_keyring); |
410 | } | 410 | } |
411 | 411 | ||
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 5e755a3f4cae..9f9463000683 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
@@ -826,7 +826,8 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent | |||
826 | sid = sbsec->def_sid; | 826 | sid = sbsec->def_sid; |
827 | rc = 0; | 827 | rc = 0; |
828 | } else { | 828 | } else { |
829 | rc = security_context_to_sid(context, rc, &sid); | 829 | rc = security_context_to_sid_default(context, rc, &sid, |
830 | sbsec->def_sid); | ||
830 | if (rc) { | 831 | if (rc) { |
831 | printk(KERN_WARNING "%s: context_to_sid(%s) " | 832 | printk(KERN_WARNING "%s: context_to_sid(%s) " |
832 | "returned %d for dev=%s ino=%ld\n", | 833 | "returned %d for dev=%s ino=%ld\n", |
@@ -3125,12 +3126,12 @@ static int selinux_socket_connect(struct socket *sock, struct sockaddr *address, | |||
3125 | 3126 | ||
3126 | if (sk->sk_family == PF_INET) { | 3127 | if (sk->sk_family == PF_INET) { |
3127 | addr4 = (struct sockaddr_in *)address; | 3128 | addr4 = (struct sockaddr_in *)address; |
3128 | if (addrlen != sizeof(struct sockaddr_in)) | 3129 | if (addrlen < sizeof(struct sockaddr_in)) |
3129 | return -EINVAL; | 3130 | return -EINVAL; |
3130 | snum = ntohs(addr4->sin_port); | 3131 | snum = ntohs(addr4->sin_port); |
3131 | } else { | 3132 | } else { |
3132 | addr6 = (struct sockaddr_in6 *)address; | 3133 | addr6 = (struct sockaddr_in6 *)address; |
3133 | if (addrlen != sizeof(struct sockaddr_in6)) | 3134 | if (addrlen < SIN6_LEN_RFC2133) |
3134 | return -EINVAL; | 3135 | return -EINVAL; |
3135 | snum = ntohs(addr6->sin6_port); | 3136 | snum = ntohs(addr6->sin6_port); |
3136 | } | 3137 | } |
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/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/services.c b/security/selinux/ss/services.c index bfa5a7dd6cf5..45d317044cb2 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, |