aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Morris <jmorris@redhat.com>2005-07-28 04:07:37 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2005-07-28 11:39:02 -0400
commitf5c1d5b2aaf9a98f15a6dcdfbba1f494d0aaae52 (patch)
treee896d0b6b9f561c9d124fa81efd261518ccbddf4
parente1699f508ab5098de4b258268fa8913db38d9d35 (diff)
[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>
-rw-r--r--security/selinux/hooks.c3
-rw-r--r--security/selinux/include/security.h2
-rw-r--r--security/selinux/ss/mls.c71
-rw-r--r--security/selinux/ss/mls.h4
-rw-r--r--security/selinux/ss/services.c55
5 files changed, 97 insertions, 38 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 6be273851144..10fd51c9056d 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",
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/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/services.c b/security/selinux/ss/services.c
index 922bb45054aa..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,