Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

[PATCH] SELinux: default labeling of MLS field

Implement kernel labeling of the MLS (multilevel security) field of
security contexts for files which have no existing MLS field. This is to
enable upgrades of a system from non-MLS to MLS without performing a full
filesystem relabel including all of the mountpoints, which would be quite
painful for users.

With this patch, with MLS enabled, if a file has no MLS field, the kernel
internally adds an MLS field to the in-core inode (but not to the on-disk
file). This MLS field added is the default for the superblock, allowing
per-mountpoint control over the values via fixed policy or mount options.

This patch has been tested by enabling MLS without relabeling its
filesystem, and seems to be working correctly.

Signed-off-by: James Morris <jmorris@redhat.com>
Signed-off-by: Stephen Smalley <sds@epoch.ncsc.mil>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

authored by

James Morris and committed by
Linus Torvalds
f5c1d5b2 e1699f50

+97 -38
+2 -1
security/selinux/hooks.c
··· 826 826 sid = sbsec->def_sid; 827 827 rc = 0; 828 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 831 if (rc) { 831 832 printk(KERN_WARNING "%s: context_to_sid(%s) " 832 833 "returned %d for dev=%s ino=%ld\n",
+2
security/selinux/include/security.h
··· 65 65 int security_context_to_sid(char *scontext, u32 scontext_len, 66 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 70 int security_get_user_sids(u32 callsid, char *username, 69 71 u32 **sids, u32 *nel); 70 72
+48 -23
security/selinux/ss/mls.c
··· 15 15 #include <linux/slab.h> 16 16 #include <linux/string.h> 17 17 #include <linux/errno.h> 18 + #include "sidtab.h" 18 19 #include "mls.h" 19 20 #include "policydb.h" 20 21 #include "services.h" ··· 209 208 } 210 209 211 210 /* 211 + * Copies the MLS range from `src' into `dst'. 212 + */ 213 + static inline int mls_copy_context(struct context *dst, 214 + struct context *src) 215 + { 216 + int l, rc = 0; 217 + 218 + /* Copy the MLS range from the source context */ 219 + for (l = 0; l < 2; l++) { 220 + dst->range.level[l].sens = src->range.level[l].sens; 221 + rc = ebitmap_cpy(&dst->range.level[l].cat, 222 + &src->range.level[l].cat); 223 + if (rc) 224 + break; 225 + } 226 + 227 + return rc; 228 + } 229 + 230 + /* 212 231 * Set the MLS fields in the security context structure 213 232 * `context' based on the string representation in 214 233 * the string `*scontext'. Update `*scontext' to ··· 237 216 * 238 217 * This function modifies the string in place, inserting 239 218 * NULL characters to terminate the MLS fields. 219 + * 220 + * If a def_sid is provided and no MLS field is present, 221 + * copy the MLS field of the associated default context. 222 + * Used for upgraded to MLS systems where objects may lack 223 + * MLS fields. 224 + * 225 + * Policy read-lock must be held for sidtab lookup. 226 + * 240 227 */ 241 228 int mls_context_to_sid(char oldc, 242 229 char **scontext, 243 - struct context *context) 230 + struct context *context, 231 + struct sidtab *s, 232 + u32 def_sid) 244 233 { 245 234 246 235 char delim; ··· 262 231 if (!selinux_mls_enabled) 263 232 return 0; 264 233 265 - /* No MLS component to the security context. */ 266 - if (!oldc) 234 + /* 235 + * No MLS component to the security context, try and map to 236 + * default if provided. 237 + */ 238 + if (!oldc) { 239 + struct context *defcon; 240 + 241 + if (def_sid == SECSID_NULL) 242 + goto out; 243 + 244 + defcon = sidtab_search(s, def_sid); 245 + if (!defcon) 246 + goto out; 247 + 248 + rc = mls_copy_context(context, defcon); 267 249 goto out; 250 + } 268 251 269 252 /* Extract low sensitivity. */ 270 253 scontextp = p = *scontext; ··· 375 330 *scontext = ++p; 376 331 rc = 0; 377 332 out: 378 - return rc; 379 - } 380 - 381 - /* 382 - * Copies the MLS range from `src' into `dst'. 383 - */ 384 - static inline int mls_copy_context(struct context *dst, 385 - struct context *src) 386 - { 387 - int l, rc = 0; 388 - 389 - /* Copy the MLS range from the source context */ 390 - for (l = 0; l < 2; l++) { 391 - dst->range.level[l].sens = src->range.level[l].sens; 392 - rc = ebitmap_cpy(&dst->range.level[l].cat, 393 - &src->range.level[l].cat); 394 - if (rc) 395 - break; 396 - } 397 - 398 333 return rc; 399 334 } 400 335
+3 -1
security/selinux/ss/mls.h
··· 23 23 24 24 int mls_context_to_sid(char oldc, 25 25 char **scontext, 26 - struct context *context); 26 + struct context *context, 27 + struct sidtab *s, 28 + u32 def_sid); 27 29 28 30 int mls_convert_context(struct policydb *oldp, 29 31 struct policydb *newp,
+42 -13
security/selinux/ss/services.c
··· 601 601 602 602 } 603 603 604 - /** 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) 604 + static int security_context_to_sid_core(char *scontext, u32 scontext_len, u32 *sid, u32 def_sid) 616 605 { 617 606 char *scontext2; 618 607 struct context context; ··· 692 703 693 704 context.type = typdatum->value; 694 705 695 - rc = mls_context_to_sid(oldc, &p, &context); 706 + rc = mls_context_to_sid(oldc, &p, &context, &sidtab, def_sid); 696 707 if (rc) 697 708 goto out_unlock; 698 709 ··· 714 725 kfree(scontext2); 715 726 out: 716 727 return rc; 728 + } 729 + 730 + /** 731 + * security_context_to_sid - Obtain a SID for a given security context. 732 + * @scontext: security context 733 + * @scontext_len: length in bytes 734 + * @sid: security identifier, SID 735 + * 736 + * Obtains a SID associated with the security context that 737 + * has the string representation specified by @scontext. 738 + * Returns -%EINVAL if the context is invalid, -%ENOMEM if insufficient 739 + * memory is available, or 0 on success. 740 + */ 741 + int security_context_to_sid(char *scontext, u32 scontext_len, u32 *sid) 742 + { 743 + return security_context_to_sid_core(scontext, scontext_len, 744 + sid, SECSID_NULL); 745 + } 746 + 747 + /** 748 + * security_context_to_sid_default - Obtain a SID for a given security context, 749 + * falling back to specified default if needed. 750 + * 751 + * @scontext: security context 752 + * @scontext_len: length in bytes 753 + * @sid: security identifier, SID 754 + * @def_sid: default SID to assign on errror 755 + * 756 + * Obtains a SID associated with the security context that 757 + * has the string representation specified by @scontext. 758 + * The default SID is passed to the MLS layer to be used to allow 759 + * kernel labeling of the MLS field if the MLS field is not present 760 + * (for upgrading to MLS without full relabel). 761 + * Returns -%EINVAL if the context is invalid, -%ENOMEM if insufficient 762 + * memory is available, or 0 on success. 763 + */ 764 + int security_context_to_sid_default(char *scontext, u32 scontext_len, u32 *sid, u32 def_sid) 765 + { 766 + return security_context_to_sid_core(scontext, scontext_len, 767 + sid, def_sid); 717 768 } 718 769 719 770 static int compute_sid_handle_invalid_context(