* [RFC][PATCH v2] selinux: support deferred mapping of contexts
@ 2008-04-30 20:56 Stephen Smalley
2008-04-30 21:51 ` Casey Schaufler
2008-04-30 23:06 ` James Morris
0 siblings, 2 replies; 16+ messages in thread
From: Stephen Smalley @ 2008-04-30 20:56 UTC (permalink / raw)
To: selinux; +Cc: James Morris, Eric Paris
As discussed in:
http://marc.info/?t=120837952900003&r=1&w=2
the ability to permit package managers and similar programs to set down
unknown file contexts is still desired/required, not only for putting
policy modules in packages but also for enabling build systems to create
images of different distro releases with different policies w/o
requiring all of the types to be defined in the build host policy.
This is an updated form of the patch originally posted in:
http://marc.info/?l=selinux&m=114771094617968&w=2
The only significant change to the patch aside from re-basing is that
rather than introducing a labelpriv permission in the security class to
control the new operation, I chose to use a class/permission that is not
already allowed for unconfined domains so that unconfined user shells
won't get this permission by default. I was going to add a new class
and permission but then realized that the mac_override capability check
seemed to fit well conceptually and since it falls in the new
capability2 class, it is not allowed to any existing domains in policy.
Further, by making this a capable() check rather than only a SELinux
permission check, the ability to set unknown file contexts is still
limited to superuser (or at least CAP_MAC_OVERRIDE) processes even if
SELinux is in permissive mode, which I think is desirable. These
safeguards should help against accidental setting of invalid contexts.
With this patch applied, the following sequence is possible, subject to
policy, which must allow <domain> self:capability2 mac_override; and
allow unlabeled_t fs_t:filesystem associate; in order for this to work
in enforcing mode or you can try it in permissive mode.
# touch bar
# chcon -t foo_exec_t bar # foo_exec_t is not yet defined
# ls -Z bar
-rw-r--r-- root root system_u:object_r:unlabeled_t bar
# cat foo.te
policy_module(foo, 1.0)
type foo_exec_t;
files_type(foo_exec_t)
# make -f /usr/share/selinux/devel/Makefile foo.pp
# semodule -i foo.pp # defines foo_exec_t
# ls -Z bar
-rw-r--r-- root root user_u:object_r:foo_exec_t bar
# semodule -r foo
# ls -Z bar
-rw-r--r-- root root system_u:object_r:unlabeled_t bar
# semodule -i foo.pp
# ls -Z bar
-rw-r--r-- root root user_u:object_r:foo_exec_t bar
---<snip>---
Introduce support for deferred mapping of security contexts in the
SID table upon policy reload, and use this support for inode security
contexts when the context is not yet valid under the current policy.
Only processes with CAP_MAC_OVERRIDE + mac_override permission can
set such invalid security contexts on inodes. Inodes with such
invalid contexts are treated as having the unlabeled SID until the context
becomes valid under a policy. This support is for use by privileged processes
like rpm that need to set down files in the proper security contexts prior to
loading the policy module that defines the context and its associated rules.
---
security/selinux/hooks.c | 18 ++-
security/selinux/include/security.h | 2
security/selinux/ss/context.h | 27 ++++
security/selinux/ss/mls.c | 11 +-
security/selinux/ss/mls.h | 3
security/selinux/ss/services.c | 198 +++++++++++++++++++++++++-----------
security/selinux/ss/sidtab.c | 6 -
7 files changed, 194 insertions(+), 71 deletions(-)
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 308e2cf..250344c 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -2667,6 +2667,11 @@ static int selinux_inode_setxattr(struct dentry *dentry, char *name, void *value
return rc;
rc = security_context_to_sid(value, size, &newsid);
+ if (rc == -EINVAL) {
+ if (!capable(CAP_MAC_OVERRIDE))
+ return rc;
+ rc = security_context_to_sid_force(value, size, &newsid);
+ }
if (rc)
return rc;
@@ -2700,10 +2705,11 @@ static void selinux_inode_post_setxattr(struct dentry *dentry, char *name,
return;
}
- rc = security_context_to_sid(value, size, &newsid);
+ rc = security_context_to_sid_force(value, size, &newsid);
if (rc) {
- printk(KERN_WARNING "%s: unable to obtain SID for context "
- "%s, rc=%d\n", __func__, (char *)value, -rc);
+ printk(KERN_ERR "SELinux: unable to map context to SID"
+ "for (%s, %lu), rc=%d\n",
+ inode->i_sb->s_id, inode->i_ino, -rc);
return;
}
@@ -5152,6 +5158,12 @@ static int selinux_setprocattr(struct task_struct *p,
size--;
}
error = security_context_to_sid(value, size, &sid);
+ if (error == -EINVAL && !strcmp(name, "fscreate")) {
+ if (!capable(CAP_MAC_OVERRIDE))
+ return error;
+ error = security_context_to_sid_force(value, size,
+ &sid);
+ }
if (error)
return error;
}
diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h
index 1904c46..112d4b1 100644
--- a/security/selinux/include/security.h
+++ b/security/selinux/include/security.h
@@ -99,6 +99,8 @@ int security_context_to_sid(char *scontext, u32 scontext_len,
int security_context_to_sid_default(char *scontext, u32 scontext_len,
u32 *out_sid, u32 def_sid, gfp_t gfp_flags);
+int security_context_to_sid_force(char *scontext, u32 scontext_len, u32 *sid);
+
int security_get_user_sids(u32 callsid, char *username,
u32 **sids, u32 *nel);
diff --git a/security/selinux/ss/context.h b/security/selinux/ss/context.h
index 2eee0da..776d90f 100644
--- a/security/selinux/ss/context.h
+++ b/security/selinux/ss/context.h
@@ -28,6 +28,8 @@ struct context {
u32 role;
u32 type;
struct mls_range range;
+ char *str; /* string representation if context cannot be mapped. */
+ u32 len; /* length of string in bytes */
};
static inline void mls_context_init(struct context *c)
@@ -106,20 +108,43 @@ static inline void context_init(struct context *c)
static inline int context_cpy(struct context *dst, struct context *src)
{
+ int rc;
+
dst->user = src->user;
dst->role = src->role;
dst->type = src->type;
- return mls_context_cpy(dst, src);
+ if (src->str) {
+ dst->str = kstrdup(src->str, GFP_ATOMIC);
+ if (!dst->str)
+ return -ENOMEM;
+ dst->len = src->len;
+ } else {
+ dst->str = NULL;
+ dst->len = 0;
+ }
+ rc = mls_context_cpy(dst, src);
+ if (rc) {
+ kfree(dst->str);
+ return rc;
+ }
+ return 0;
}
static inline void context_destroy(struct context *c)
{
c->user = c->role = c->type = 0;
+ kfree(c->str);
+ c->str = NULL;
+ c->len = 0;
mls_context_destroy(c);
}
static inline int context_cmp(struct context *c1, struct context *c2)
{
+ if (c1->len && c2->len)
+ return (c1->len == c2->len && !strcmp(c1->str, c2->str));
+ if (c1->len || c2->len)
+ return 0;
return ((c1->user == c2->user) &&
(c1->role == c2->role) &&
(c1->type == c2->type) &&
diff --git a/security/selinux/ss/mls.c b/security/selinux/ss/mls.c
index 8b1706b..a6ca058 100644
--- a/security/selinux/ss/mls.c
+++ b/security/selinux/ss/mls.c
@@ -239,7 +239,8 @@ int mls_context_isvalid(struct policydb *p, struct context *c)
* Policy read-lock must be held for sidtab lookup.
*
*/
-int mls_context_to_sid(char oldc,
+int mls_context_to_sid(struct policydb *pol,
+ char oldc,
char **scontext,
struct context *context,
struct sidtab *s,
@@ -286,7 +287,7 @@ int mls_context_to_sid(char oldc,
*p++ = 0;
for (l = 0; l < 2; l++) {
- levdatum = hashtab_search(policydb.p_levels.table, scontextp);
+ levdatum = hashtab_search(pol->p_levels.table, scontextp);
if (!levdatum) {
rc = -EINVAL;
goto out;
@@ -311,7 +312,7 @@ int mls_context_to_sid(char oldc,
*rngptr++ = 0;
}
- catdatum = hashtab_search(policydb.p_cats.table,
+ catdatum = hashtab_search(pol->p_cats.table,
scontextp);
if (!catdatum) {
rc = -EINVAL;
@@ -327,7 +328,7 @@ int mls_context_to_sid(char oldc,
if (rngptr) {
int i;
- rngdatum = hashtab_search(policydb.p_cats.table, rngptr);
+ rngdatum = hashtab_search(pol->p_cats.table, rngptr);
if (!rngdatum) {
rc = -EINVAL;
goto out;
@@ -395,7 +396,7 @@ int mls_from_string(char *str, struct context *context, gfp_t gfp_mask)
if (!tmpstr) {
rc = -ENOMEM;
} else {
- rc = mls_context_to_sid(':', &tmpstr, context,
+ rc = mls_context_to_sid(&policydb, ':', &tmpstr, context,
NULL, SECSID_NULL);
kfree(freestr);
}
diff --git a/security/selinux/ss/mls.h b/security/selinux/ss/mls.h
index ab53663..900fb0e 100644
--- a/security/selinux/ss/mls.h
+++ b/security/selinux/ss/mls.h
@@ -30,7 +30,8 @@ int mls_context_isvalid(struct policydb *p, struct context *c);
int mls_range_isvalid(struct policydb *p, struct mls_range *r);
int mls_level_isvalid(struct policydb *p, struct mls_level *l);
-int mls_context_to_sid(char oldc,
+int mls_context_to_sid(struct policydb *p,
+ char oldc,
char **scontext,
struct context *context,
struct sidtab *s,
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index 2daaddb..6724b4f 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -708,36 +708,24 @@ out:
}
-static int security_context_to_sid_core(char *scontext, u32 scontext_len,
- u32 *sid, u32 def_sid, gfp_t gfp_flags)
+static int string_to_context_struct(struct policydb *pol,
+ struct sidtab *sidtabp,
+ char *scontext,
+ u32 scontext_len,
+ struct context *ctx,
+ u32 def_sid,
+ gfp_t gfp_flags)
{
- char *scontext2;
- struct context context;
+ char *scontext2 = NULL;
struct role_datum *role;
struct type_datum *typdatum;
struct user_datum *usrdatum;
char *scontextp, *p, oldc;
int rc = 0;
- if (!ss_initialized) {
- int i;
+ context_init(ctx);
- for (i = 1; i < SECINITSID_NUM; i++) {
- if (!strcmp(initial_sid_to_string[i], scontext)) {
- *sid = i;
- goto out;
- }
- }
- *sid = SECINITSID_KERNEL;
- goto out;
- }
- *sid = SECSID_NULL;
-
- /* Copy the string so that we can modify the copy as we parse it.
- The string should already by null terminated, but we append a
- null suffix to the copy to avoid problems with the existing
- attr package, which doesn't view the null terminator as part
- of the attribute value. */
+ /* Copy the string so that we can modify the copy as we parse it. */
scontext2 = kmalloc(scontext_len+1, gfp_flags);
if (!scontext2) {
rc = -ENOMEM;
@@ -746,11 +734,6 @@ static int security_context_to_sid_core(char *scontext, u32 scontext_len,
memcpy(scontext2, scontext, scontext_len);
scontext2[scontext_len] = 0;
- context_init(&context);
- *sid = SECSID_NULL;
-
- POLICY_RDLOCK;
-
/* Parse the security context. */
rc = -EINVAL;
@@ -762,15 +745,15 @@ static int security_context_to_sid_core(char *scontext, u32 scontext_len,
p++;
if (*p == 0)
- goto out_unlock;
+ goto out;
*p++ = 0;
- usrdatum = hashtab_search(policydb.p_users.table, scontextp);
+ usrdatum = hashtab_search(pol->p_users.table, scontextp);
if (!usrdatum)
- goto out_unlock;
+ goto out;
- context.user = usrdatum->value;
+ ctx->user = usrdatum->value;
/* Extract role. */
scontextp = p;
@@ -778,14 +761,14 @@ static int security_context_to_sid_core(char *scontext, u32 scontext_len,
p++;
if (*p == 0)
- goto out_unlock;
+ goto out;
*p++ = 0;
- role = hashtab_search(policydb.p_roles.table, scontextp);
+ role = hashtab_search(pol->p_roles.table, scontextp);
if (!role)
- goto out_unlock;
- context.role = role->value;
+ goto out;
+ ctx->role = role->value;
/* Extract type. */
scontextp = p;
@@ -794,33 +777,74 @@ static int security_context_to_sid_core(char *scontext, u32 scontext_len,
oldc = *p;
*p++ = 0;
- typdatum = hashtab_search(policydb.p_types.table, scontextp);
+ typdatum = hashtab_search(pol->p_types.table, scontextp);
if (!typdatum)
- goto out_unlock;
+ goto out;
- context.type = typdatum->value;
+ ctx->type = typdatum->value;
- rc = mls_context_to_sid(oldc, &p, &context, &sidtab, def_sid);
+ rc = mls_context_to_sid(pol, oldc, &p, ctx, sidtabp, def_sid);
if (rc)
- goto out_unlock;
+ goto out;
if ((p - scontext2) < scontext_len) {
rc = -EINVAL;
- goto out_unlock;
+ goto out;
}
/* Check the validity of the new context. */
- if (!policydb_context_isvalid(&policydb, &context)) {
+ if (!policydb_context_isvalid(pol, ctx)) {
rc = -EINVAL;
- goto out_unlock;
+ context_destroy(ctx);
+ goto out;
}
- /* Obtain the new sid. */
- rc = sidtab_context_to_sid(&sidtab, &context, sid);
-out_unlock:
- POLICY_RDUNLOCK;
- context_destroy(&context);
+ rc = 0;
+out:
kfree(scontext2);
+ return rc;
+}
+
+static int security_context_to_sid_core(char *scontext, u32 scontext_len,
+ u32 *sid, u32 def_sid, gfp_t gfp_flags,
+ int force)
+{
+ struct context context;
+ int rc = 0;
+
+ if (!ss_initialized) {
+ int i;
+
+ for (i = 1; i < SECINITSID_NUM; i++) {
+ if (!strcmp(initial_sid_to_string[i], scontext)) {
+ *sid = i;
+ goto out;
+ }
+ }
+ *sid = SECINITSID_KERNEL;
+ goto out;
+ }
+ *sid = SECSID_NULL;
+
+ POLICY_RDLOCK;
+ rc = string_to_context_struct(&policydb, &sidtab,
+ scontext, scontext_len,
+ &context, def_sid, gfp_flags);
+ if (rc == -EINVAL && force) {
+ context.str = kmalloc(scontext_len+1, gfp_flags);
+ if (!context.str) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ memcpy(context.str, scontext, scontext_len);
+ context.str[scontext_len] = 0;
+ context.len = scontext_len;
+ } else if (rc)
+ goto out;
+ rc = sidtab_context_to_sid(&sidtab, &context, sid);
+ if (rc)
+ context_destroy(&context);
out:
+ POLICY_RDUNLOCK;
return rc;
}
@@ -838,7 +862,7 @@ out:
int security_context_to_sid(char *scontext, u32 scontext_len, u32 *sid)
{
return security_context_to_sid_core(scontext, scontext_len,
- sid, SECSID_NULL, GFP_KERNEL);
+ sid, SECSID_NULL, GFP_KERNEL, 0);
}
/**
@@ -855,6 +879,7 @@ int security_context_to_sid(char *scontext, u32 scontext_len, u32 *sid)
* The default SID is passed to the MLS layer to be used to allow
* kernel labeling of the MLS field if the MLS field is not present
* (for upgrading to MLS without full relabel).
+ * Implicitly forces adding of the context even if it cannot be mapped yet.
* Returns -%EINVAL if the context is invalid, -%ENOMEM if insufficient
* memory is available, or 0 on success.
*/
@@ -862,7 +887,13 @@ int security_context_to_sid_default(char *scontext, u32 scontext_len, u32 *sid,
u32 def_sid, gfp_t gfp_flags)
{
return security_context_to_sid_core(scontext, scontext_len,
- sid, def_sid, gfp_flags);
+ sid, def_sid, gfp_flags, 1);
+}
+
+int security_context_to_sid_force(char *scontext, u32 scontext_len, u32 *sid)
+{
+ return security_context_to_sid_core(scontext, scontext_len,
+ sid, SECSID_NULL, GFP_KERNEL, 1);
}
static int compute_sid_handle_invalid_context(
@@ -1246,9 +1277,12 @@ static inline int convert_context_handle_invalid_context(struct context *context
char *s;
u32 len;
- context_struct_to_string(context, &s, &len);
- printk(KERN_ERR "SELinux: context %s is invalid\n", s);
- kfree(s);
+ if (!context_struct_to_string(context, &s, &len)) {
+ printk(KERN_WARNING
+ "SELinux: Context %s would be invalid if enforcing\n",
+ s);
+ kfree(s);
+ }
}
return rc;
}
@@ -1280,6 +1314,32 @@ static int convert_context(u32 key,
args = p;
+ if (c->str) {
+ struct context ctx;
+ rc = string_to_context_struct(args->newp, NULL, c->str,
+ c->len, &ctx, SECSID_NULL,
+ GFP_KERNEL);
+ if (!rc) {
+ printk(KERN_INFO
+ "SELinux: Context %s became valid (mapped).\n",
+ c->str);
+ /* Replace string with mapped representation. */
+ kfree(c->str);
+ memcpy(c, &ctx, sizeof(*c));
+ goto out;
+ } else if (rc == -EINVAL) {
+ /* Retain string representation for later mapping. */
+ rc = 0;
+ goto out;
+ } else {
+ /* Other error condition, e.g. ENOMEM. */
+ printk(KERN_ERR
+ "SELinux: Unable to map context %s, rc = %d.\n",
+ c->str, -rc);
+ goto out;
+ }
+ }
+
rc = context_cpy(&oldc, c);
if (rc)
goto out;
@@ -1319,13 +1379,21 @@ static int convert_context(u32 key,
}
context_destroy(&oldc);
+ rc = 0;
out:
return rc;
bad:
- context_struct_to_string(&oldc, &s, &len);
+ /* Map old representation to string and save it. */
+ if (context_struct_to_string(&oldc, &s, &len))
+ return -ENOMEM;
context_destroy(&oldc);
- printk(KERN_ERR "SELinux: invalidating context %s\n", s);
- kfree(s);
+ context_destroy(c);
+ c->str = s;
+ c->len = len;
+ printk(KERN_INFO
+ "SELinux: Context %s became invalid (unmapped).\n",
+ c->str);
+ rc = 0;
goto out;
}
@@ -1406,7 +1474,11 @@ int security_load_policy(void *data, size_t len)
return -EINVAL;
}
- sidtab_init(&newsidtab);
+ if (sidtab_init(&newsidtab)) {
+ LOAD_UNLOCK;
+ policydb_destroy(&newpolicydb);
+ return -ENOMEM;
+ }
/* Verify that the kernel defined classes are correct. */
if (validate_classes(&newpolicydb)) {
@@ -1429,11 +1501,15 @@ int security_load_policy(void *data, size_t len)
goto err;
}
- /* Convert the internal representations of contexts
- in the new SID table and remove invalid SIDs. */
+ /*
+ * Convert the internal representations of contexts
+ * in the new SID table.
+ */
args.oldp = &policydb;
args.newp = &newpolicydb;
- sidtab_map_remove_on_error(&newsidtab, convert_context, &args);
+ rc = sidtab_map(&newsidtab, convert_context, &args);
+ if (rc)
+ goto err;
/* Save the old policydb and SID table to free later. */
memcpy(&oldpolicydb, &policydb, sizeof policydb);
@@ -1673,6 +1749,8 @@ int security_get_user_sids(u32 fromsid,
POLICY_RDLOCK;
+ context_init(&usercon);
+
fromcon = sidtab_search(&sidtab, fromsid);
if (!fromcon) {
rc = -EINVAL;
diff --git a/security/selinux/ss/sidtab.c b/security/selinux/ss/sidtab.c
index 4a516ff..7f4c0d0 100644
--- a/security/selinux/ss/sidtab.c
+++ b/security/selinux/ss/sidtab.c
@@ -99,7 +99,7 @@ struct context *sidtab_search(struct sidtab *s, u32 sid)
while (cur != NULL && sid > cur->sid)
cur = cur->next;
- if (cur == NULL || sid != cur->sid) {
+ if (cur == NULL || sid != cur->sid || cur->context.len) {
/* Remap invalid SIDs to the unlabeled SID. */
sid = SECINITSID_UNLABELED;
hvalue = SIDTAB_HASH(sid);
@@ -215,6 +215,10 @@ int sidtab_context_to_sid(struct sidtab *s,
goto unlock_out;
}
sid = s->next_sid++;
+ if (context->len)
+ printk(KERN_INFO
+ "SELinux: Context %s is not valid (left unmapped).\n",
+ context->str);
ret = sidtab_insert(s, sid, context);
if (ret)
s->next_sid--;
--
Stephen Smalley
National Security Agency
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [RFC][PATCH v2] selinux: support deferred mapping of contexts
2008-04-30 20:56 [RFC][PATCH v2] selinux: support deferred mapping of contexts Stephen Smalley
@ 2008-04-30 21:51 ` Casey Schaufler
2008-05-01 10:37 ` Stephen Smalley
2008-04-30 23:06 ` James Morris
1 sibling, 1 reply; 16+ messages in thread
From: Casey Schaufler @ 2008-04-30 21:51 UTC (permalink / raw)
To: Stephen Smalley, selinux; +Cc: James Morris, Eric Paris
--- Stephen Smalley <sds@tycho.nsa.gov> wrote:
> As discussed in:
> http://marc.info/?t=120837952900003&r=1&w=2
> the ability to permit package managers and similar programs to set down
> unknown file contexts is still desired/required, not only for putting
> policy modules in packages but also for enabling build systems to create
> images of different distro releases with different policies w/o
> requiring all of the types to be defined in the build host policy.
>
> This is an updated form of the patch originally posted in:
> http://marc.info/?l=selinux&m=114771094617968&w=2
>
> The only significant change to the patch aside from re-basing is that
> rather than introducing a labelpriv permission in the security class to
> control the new operation, I chose to use a class/permission that is not
> already allowed for unconfined domains so that unconfined user shells
> won't get this permission by default. I was going to add a new class
> and permission but then realized that the mac_override capability check
> seemed to fit well conceptually and since it falls in the new
> capability2 class, it is not allowed to any existing domains in policy.
> Further, by making this a capable() check rather than only a SELinux
> permission check, the ability to set unknown file contexts is still
> limited to superuser (or at least CAP_MAC_OVERRIDE)
I think you should be using CAP_MAC_ADMIN as you are explictly
setting the attribute. CAP_MAC_OVERRIDE is for violations of
normal policy, whereas this appears more like an administrative
action.
Unless I'm reading the code wrong, which does happen on occasion.
> processes even if
> SELinux is in permissive mode, which I think is desirable. These
> safeguards should help against accidental setting of invalid contexts.
>
> With this patch applied, the following sequence is possible, subject to
> policy, which must allow <domain> self:capability2 mac_override; and
> allow unlabeled_t fs_t:filesystem associate; in order for this to work
> in enforcing mode or you can try it in permissive mode.
>
> # touch bar
> # chcon -t foo_exec_t bar # foo_exec_t is not yet defined
> # ls -Z bar
> -rw-r--r-- root root system_u:object_r:unlabeled_t bar
> # cat foo.te
> policy_module(foo, 1.0)
> type foo_exec_t;
> files_type(foo_exec_t)
> # make -f /usr/share/selinux/devel/Makefile foo.pp
> # semodule -i foo.pp # defines foo_exec_t
> # ls -Z bar
> -rw-r--r-- root root user_u:object_r:foo_exec_t bar
> # semodule -r foo
> # ls -Z bar
> -rw-r--r-- root root system_u:object_r:unlabeled_t bar
> # semodule -i foo.pp
> # ls -Z bar
> -rw-r--r-- root root user_u:object_r:foo_exec_t bar
>
> ---<snip>---
>
> Introduce support for deferred mapping of security contexts in the
> SID table upon policy reload, and use this support for inode security
> contexts when the context is not yet valid under the current policy.
> Only processes with CAP_MAC_OVERRIDE + mac_override permission can
> set such invalid security contexts on inodes. Inodes with such
> invalid contexts are treated as having the unlabeled SID until the context
> becomes valid under a policy. This support is for use by privileged
> processes
> like rpm that need to set down files in the proper security contexts prior to
>
> loading the policy module that defines the context and its associated rules.
>
> ---
>
> security/selinux/hooks.c | 18 ++-
> security/selinux/include/security.h | 2
> security/selinux/ss/context.h | 27 ++++
> security/selinux/ss/mls.c | 11 +-
> security/selinux/ss/mls.h | 3
> security/selinux/ss/services.c | 198
> +++++++++++++++++++++++++-----------
> security/selinux/ss/sidtab.c | 6 -
> 7 files changed, 194 insertions(+), 71 deletions(-)
>
> diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
> index 308e2cf..250344c 100644
> --- a/security/selinux/hooks.c
> +++ b/security/selinux/hooks.c
> @@ -2667,6 +2667,11 @@ static int selinux_inode_setxattr(struct dentry
> *dentry, char *name, void *value
> return rc;
>
> rc = security_context_to_sid(value, size, &newsid);
> + if (rc == -EINVAL) {
> + if (!capable(CAP_MAC_OVERRIDE))
> + return rc;
> + rc = security_context_to_sid_force(value, size, &newsid);
> + }
> if (rc)
> return rc;
>
> @@ -2700,10 +2705,11 @@ static void selinux_inode_post_setxattr(struct dentry
> *dentry, char *name,
> return;
> }
>
> - rc = security_context_to_sid(value, size, &newsid);
> + rc = security_context_to_sid_force(value, size, &newsid);
> if (rc) {
> - printk(KERN_WARNING "%s: unable to obtain SID for context "
> - "%s, rc=%d\n", __func__, (char *)value, -rc);
> + printk(KERN_ERR "SELinux: unable to map context to SID"
> + "for (%s, %lu), rc=%d\n",
> + inode->i_sb->s_id, inode->i_ino, -rc);
> return;
> }
>
> @@ -5152,6 +5158,12 @@ static int selinux_setprocattr(struct task_struct *p,
> size--;
> }
> error = security_context_to_sid(value, size, &sid);
> + if (error == -EINVAL && !strcmp(name, "fscreate")) {
> + if (!capable(CAP_MAC_OVERRIDE))
> + return error;
> + error = security_context_to_sid_force(value, size,
> + &sid);
> + }
> if (error)
> return error;
> }
> diff --git a/security/selinux/include/security.h
> b/security/selinux/include/security.h
> index 1904c46..112d4b1 100644
> --- a/security/selinux/include/security.h
> +++ b/security/selinux/include/security.h
> @@ -99,6 +99,8 @@ int security_context_to_sid(char *scontext, u32
> scontext_len,
> int security_context_to_sid_default(char *scontext, u32 scontext_len,
> u32 *out_sid, u32 def_sid, gfp_t gfp_flags);
>
> +int security_context_to_sid_force(char *scontext, u32 scontext_len, u32
> *sid);
> +
> int security_get_user_sids(u32 callsid, char *username,
> u32 **sids, u32 *nel);
>
> diff --git a/security/selinux/ss/context.h b/security/selinux/ss/context.h
> index 2eee0da..776d90f 100644
> --- a/security/selinux/ss/context.h
> +++ b/security/selinux/ss/context.h
> @@ -28,6 +28,8 @@ struct context {
> u32 role;
> u32 type;
> struct mls_range range;
> + char *str; /* string representation if context cannot be mapped. */
> + u32 len; /* length of string in bytes */
> };
>
> static inline void mls_context_init(struct context *c)
> @@ -106,20 +108,43 @@ static inline void context_init(struct context *c)
>
> static inline int context_cpy(struct context *dst, struct context *src)
> {
> + int rc;
> +
> dst->user = src->user;
> dst->role = src->role;
> dst->type = src->type;
> - return mls_context_cpy(dst, src);
> + if (src->str) {
> + dst->str = kstrdup(src->str, GFP_ATOMIC);
> + if (!dst->str)
> + return -ENOMEM;
> + dst->len = src->len;
> + } else {
> + dst->str = NULL;
> + dst->len = 0;
> + }
> + rc = mls_context_cpy(dst, src);
> + if (rc) {
> + kfree(dst->str);
> + return rc;
> + }
> + return 0;
> }
>
> static inline void context_destroy(struct context *c)
> {
> c->user = c->role = c->type = 0;
> + kfree(c->str);
> + c->str = NULL;
> + c->len = 0;
> mls_context_destroy(c);
> }
>
> static inline int context_cmp(struct context *c1, struct context *c2)
> {
> + if (c1->len && c2->len)
> + return (c1->len == c2->len && !strcmp(c1->str, c2->str));
> + if (c1->len || c2->len)
> + return 0;
> return ((c1->user == c2->user) &&
> (c1->role == c2->role) &&
> (c1->type == c2->type) &&
> diff --git a/security/selinux/ss/mls.c b/security/selinux/ss/mls.c
> index 8b1706b..a6ca058 100644
> --- a/security/selinux/ss/mls.c
> +++ b/security/selinux/ss/mls.c
> @@ -239,7 +239,8 @@ int mls_context_isvalid(struct policydb *p, struct
> context *c)
> * Policy read-lock must be held for sidtab lookup.
> *
> */
> -int mls_context_to_sid(char oldc,
> +int mls_context_to_sid(struct policydb *pol,
> + char oldc,
> char **scontext,
> struct context *context,
> struct sidtab *s,
> @@ -286,7 +287,7 @@ int mls_context_to_sid(char oldc,
> *p++ = 0;
>
> for (l = 0; l < 2; l++) {
> - levdatum = hashtab_search(policydb.p_levels.table, scontextp);
> + levdatum = hashtab_search(pol->p_levels.table, scontextp);
> if (!levdatum) {
> rc = -EINVAL;
> goto out;
> @@ -311,7 +312,7 @@ int mls_context_to_sid(char oldc,
> *rngptr++ = 0;
> }
>
> - catdatum = hashtab_search(policydb.p_cats.table,
> + catdatum = hashtab_search(pol->p_cats.table,
> scontextp);
> if (!catdatum) {
> rc = -EINVAL;
> @@ -327,7 +328,7 @@ int mls_context_to_sid(char oldc,
> if (rngptr) {
> int i;
>
> - rngdatum = hashtab_search(policydb.p_cats.table, rngptr);
> + rngdatum = hashtab_search(pol->p_cats.table, rngptr);
> if (!rngdatum) {
> rc = -EINVAL;
> goto out;
> @@ -395,7 +396,7 @@ int mls_from_string(char *str, struct context *context,
> gfp_t gfp_mask)
> if (!tmpstr) {
> rc = -ENOMEM;
> } else {
> - rc = mls_context_to_sid(':', &tmpstr, context,
> + rc = mls_context_to_sid(&policydb, ':', &tmpstr, context,
> NULL, SECSID_NULL);
> kfree(freestr);
> }
> diff --git a/security/selinux/ss/mls.h b/security/selinux/ss/mls.h
> index ab53663..900fb0e 100644
> --- a/security/selinux/ss/mls.h
> +++ b/security/selinux/ss/mls.h
> @@ -30,7 +30,8 @@ int mls_context_isvalid(struct policydb *p, struct context
> *c);
> int mls_range_isvalid(struct policydb *p, struct mls_range *r);
> int mls_level_isvalid(struct policydb *p, struct mls_level *l);
>
> -int mls_context_to_sid(char oldc,
> +int mls_context_to_sid(struct policydb *p,
> + char oldc,
> char **scontext,
> struct context *context,
> struct sidtab *s,
> diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
> index 2daaddb..6724b4f 100644
> --- a/security/selinux/ss/services.c
> +++ b/security/selinux/ss/services.c
> @@ -708,36 +708,24 @@ out:
>
> }
>
> -static int security_context_to_sid_core(char *scontext, u32 scontext_len,
> - u32 *sid, u32 def_sid, gfp_t gfp_flags)
> +static int string_to_context_struct(struct policydb *pol,
> + struct sidtab *sidtabp,
> + char *scontext,
> + u32 scontext_len,
> + struct context *ctx,
> + u32 def_sid,
> + gfp_t gfp_flags)
> {
> - char *scontext2;
> - struct context context;
> + char *scontext2 = NULL;
> struct role_datum *role;
> struct type_datum *typdatum;
> struct user_datum *usrdatum;
> char *scontextp, *p, oldc;
> int rc = 0;
>
> - if (!ss_initialized) {
> - int i;
> + context_init(ctx);
>
> - for (i = 1; i < SECINITSID_NUM; i++) {
> - if (!strcmp(initial_sid_to_string[i], scontext)) {
> - *sid = i;
> - goto out;
> - }
> - }
> - *sid = SECINITSID_KERNEL;
> - goto out;
> - }
> - *sid = SECSID_NULL;
> -
> - /* Copy the string so that we can modify the copy as we parse it.
> - The string should already by null terminated, but we append a
> - null suffix to the copy to avoid problems with the existing
> - attr package, which doesn't view the null terminator as part
> - of the attribute value. */
> + /* Copy the string so that we can modify the copy as we parse it. */
> scontext2 = kmalloc(scontext_len+1, gfp_flags);
> if (!scontext2) {
> rc = -ENOMEM;
> @@ -746,11 +734,6 @@ static int security_context_to_sid_core(char *scontext,
> u32 scontext_len,
> memcpy(scontext2, scontext, scontext_len);
> scontext2[scontext_len] = 0;
>
> - context_init(&context);
> - *sid = SECSID_NULL;
> -
> - POLICY_RDLOCK;
> -
> /* Parse the security context. */
>
> rc = -EINVAL;
> @@ -762,15 +745,15 @@ static int security_context_to_sid_core(char *scontext,
> u32 scontext_len,
> p++;
>
> if (*p == 0)
> - goto out_unlock;
> + goto out;
>
> *p++ = 0;
>
> - usrdatum = hashtab_search(policydb.p_users.table, scontextp);
> + usrdatum = hashtab_search(pol->p_users.table, scontextp);
> if (!usrdatum)
> - goto out_unlock;
> + goto out;
>
> - context.user = usrdatum->value;
> + ctx->user = usrdatum->value;
>
> /* Extract role. */
> scontextp = p;
> @@ -778,14 +761,14 @@ static int security_context_to_sid_core(char *scontext,
> u32 scontext_len,
> p++;
>
> if (*p == 0)
> - goto out_unlock;
> + goto out;
>
> *p++ = 0;
>
> - role = hashtab_search(policydb.p_roles.table, scontextp);
> + role = hashtab_search(pol->p_roles.table, scontextp);
> if (!role)
> - goto out_unlock;
> - context.role = role->value;
> + goto out;
> + ctx->role = role->value;
>
> /* Extract type. */
> scontextp = p;
> @@ -794,33 +777,74 @@ static int security_context_to_sid_core(char *scontext,
> u32 scontext_len,
> oldc = *p;
> *p++ = 0;
>
> - typdatum = hashtab_search(policydb.p_types.table, scontextp);
> + typdatum = hashtab_search(pol->p_types.table, scontextp);
> if (!typdatum)
> - goto out_unlock;
> + goto out;
>
> - context.type = typdatum->value;
> + ctx->type = typdatum->value;
>
> - rc = mls_context_to_sid(oldc, &p, &context, &sidtab, def_sid);
> + rc = mls_context_to_sid(pol, oldc, &p, ctx, sidtabp, def_sid);
> if (rc)
> - goto out_unlock;
> + goto out;
>
> if ((p - scontext2) < scontext_len) {
> rc = -EINVAL;
> - goto out_unlock;
> + goto out;
> }
>
> /* Check the validity of the new context. */
> - if (!policydb_context_isvalid(&policydb, &context)) {
> + if (!policydb_context_isvalid(pol, ctx)) {
> rc = -EINVAL;
> - goto out_unlock;
> + context_destroy(ctx);
> + goto out;
> }
> - /* Obtain the new sid. */
> - rc = sidtab_context_to_sid(&sidtab, &context, sid);
> -out_unlock:
> - POLICY_RDUNLOCK;
> - context_destroy(&context);
> + rc = 0;
> +out:
> kfree(scontext2);
> + return rc;
> +}
> +
> +static int security_context_to_sid_core(char *scontext, u32 scontext_len,
> + u32 *sid, u32 def_sid, gfp_t gfp_flags,
> + int force)
> +{
> + struct context context;
> + int rc = 0;
> +
> + if (!ss_initialized) {
> + int i;
> +
> + for (i = 1; i < SECINITSID_NUM; i++) {
> + if (!strcmp(initial_sid_to_string[i], scontext)) {
> + *sid = i;
> + goto out;
> + }
> + }
> + *sid = SECINITSID_KERNEL;
> + goto out;
> + }
> + *sid = SECSID_NULL;
> +
> + POLICY_RDLOCK;
> + rc = string_to_context_struct(&policydb, &sidtab,
> + scontext, scontext_len,
> + &context, def_sid, gfp_flags);
> + if (rc == -EINVAL && force) {
> + context.str = kmalloc(scontext_len+1, gfp_flags);
> + if (!context.str) {
> + rc = -ENOMEM;
> + goto out;
> + }
> + memcpy(context.str, scontext, scontext_len);
> + context.str[scontext_len] = 0;
> + context.len = scontext_len;
> + } else if (rc)
> + goto out;
> + rc = sidtab_context_to_sid(&sidtab, &context, sid);
> + if (rc)
> + context_destroy(&context);
> out:
> + POLICY_RDUNLOCK;
> return rc;
> }
>
> @@ -838,7 +862,7 @@ out:
> int security_context_to_sid(char *scontext, u32 scontext_len, u32 *sid)
> {
> return security_context_to_sid_core(scontext, scontext_len,
> - sid, SECSID_NULL, GFP_KERNEL);
> + sid, SECSID_NULL, GFP_KERNEL, 0);
> }
>
> /**
> @@ -855,6 +879,7 @@ int security_context_to_sid(char *scontext, u32
> scontext_len, u32 *sid)
> * The default SID is passed to the MLS layer to be used to allow
> * kernel labeling of the MLS field if the MLS field is not present
> * (for upgrading to MLS without full relabel).
> + * Implicitly forces adding of the context even if it cannot be mapped yet.
> * Returns -%EINVAL if the context is invalid, -%ENOMEM if insufficient
> * memory is available, or 0 on success.
> */
> @@ -862,7 +887,13 @@ int security_context_to_sid_default(char *scontext, u32
> scontext_len, u32 *sid,
> u32 def_sid, gfp_t gfp_flags)
> {
> return security_context_to_sid_core(scontext, scontext_len,
> - sid, def_sid, gfp_flags);
> + sid, def_sid, gfp_flags, 1);
> +}
> +
> +int security_context_to_sid_force(char *scontext, u32 scontext_len, u32
> *sid)
> +{
> + return security_context_to_sid_core(scontext, scontext_len,
> + sid, SECSID_NULL, GFP_KERNEL, 1);
> }
>
> static int compute_sid_handle_invalid_context(
> @@ -1246,9 +1277,12 @@ static inline int
> convert_context_handle_invalid_context(struct context *context
> char *s;
> u32 len;
>
> - context_struct_to_string(context, &s, &len);
> - printk(KERN_ERR "SELinux: context %s is invalid\n", s);
> - kfree(s);
> + if (!context_struct_to_string(context, &s, &len)) {
> + printk(KERN_WARNING
> + "SELinux: Context %s would be invalid if enforcing\n",
> + s);
> + kfree(s);
> + }
> }
> return rc;
> }
> @@ -1280,6 +1314,32 @@ static int convert_context(u32 key,
>
> args = p;
>
> + if (c->str) {
> + struct context ctx;
> + rc = string_to_context_struct(args->newp, NULL, c->str,
> + c->len, &ctx, SECSID_NULL,
> + GFP_KERNEL);
> + if (!rc) {
> + printk(KERN_INFO
> + "SELinux: Context %s became valid (mapped).\n",
> + c->str);
> + /* Replace string with mapped representation. */
> + kfree(c->str);
> + memcpy(c, &ctx, sizeof(*c));
> + goto out;
> + } else if (rc == -EINVAL) {
> + /* Retain string representation for later mapping. */
> + rc = 0;
> + goto out;
> + } else {
> + /* Other error condition, e.g. ENOMEM. */
> + printk(KERN_ERR
> + "SELinux: Unable to map context %s, rc = %d.\n",
> + c->str, -rc);
> + goto out;
> + }
> + }
> +
> rc = context_cpy(&oldc, c);
> if (rc)
> goto out;
> @@ -1319,13 +1379,21 @@ static int convert_context(u32 key,
> }
>
> context_destroy(&oldc);
> + rc = 0;
> out:
> return rc;
> bad:
> - context_struct_to_string(&oldc, &s, &len);
> + /* Map old representation to string and save it. */
> + if (context_struct_to_string(&oldc, &s, &len))
> + return -ENOMEM;
> context_destroy(&oldc);
> - printk(KERN_ERR "SELinux: invalidating context %s\n", s);
> - kfree(s);
> + context_destroy(c);
> + c->str = s;
> + c->len = len;
> + printk(KERN_INFO
> + "SELinux: Context %s became invalid (unmapped).\n",
> + c->str);
> + rc = 0;
> goto out;
> }
>
> @@ -1406,7 +1474,11 @@ int security_load_policy(void *data, size_t len)
> return -EINVAL;
> }
>
> - sidtab_init(&newsidtab);
> + if (sidtab_init(&newsidtab)) {
> + LOAD_UNLOCK;
> + policydb_destroy(&newpolicydb);
> + return -ENOMEM;
> + }
>
> /* Verify that the kernel defined classes are correct. */
> if (validate_classes(&newpolicydb)) {
> @@ -1429,11 +1501,15 @@ int security_load_policy(void *data, size_t len)
> goto err;
> }
>
> - /* Convert the internal representations of contexts
> - in the new SID table and remove invalid SIDs. */
> + /*
> + * Convert the internal representations of contexts
> + * in the new SID table.
> + */
> args.oldp = &policydb;
> args.newp = &newpolicydb;
> - sidtab_map_remove_on_error(&newsidtab, convert_context, &args);
> + rc = sidtab_map(&newsidtab, convert_context, &args);
> + if (rc)
> + goto err;
>
> /* Save the old policydb and SID table to free later. */
> memcpy(&oldpolicydb, &policydb, sizeof policydb);
> @@ -1673,6 +1749,8 @@ int security_get_user_sids(u32 fromsid,
>
> POLICY_RDLOCK;
>
> + context_init(&usercon);
> +
> fromcon = sidtab_search(&sidtab, fromsid);
> if (!fromcon) {
> rc = -EINVAL;
> diff --git a/security/selinux/ss/sidtab.c b/security/selinux/ss/sidtab.c
> index 4a516ff..7f4c0d0 100644
> --- a/security/selinux/ss/sidtab.c
> +++ b/security/selinux/ss/sidtab.c
> @@ -99,7 +99,7 @@ struct context *sidtab_search(struct sidtab *s, u32 sid)
> while (cur != NULL && sid > cur->sid)
> cur = cur->next;
>
> - if (cur == NULL || sid != cur->sid) {
> + if (cur == NULL || sid != cur->sid || cur->context.len) {
> /* Remap invalid SIDs to the unlabeled SID. */
> sid = SECINITSID_UNLABELED;
> hvalue = SIDTAB_HASH(sid);
> @@ -215,6 +215,10 @@ int sidtab_context_to_sid(struct sidtab *s,
> goto unlock_out;
> }
> sid = s->next_sid++;
> + if (context->len)
> + printk(KERN_INFO
> + "SELinux: Context %s is not valid (left unmapped).\n",
> + context->str);
> ret = sidtab_insert(s, sid, context);
> if (ret)
> s->next_sid--;
>
>
>
>
> --
> Stephen Smalley
> National Security Agency
>
>
> --
> This message was distributed to subscribers of the selinux mailing list.
> If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
> the words "unsubscribe selinux" without quotes as the message.
>
>
>
Casey Schaufler
casey@schaufler-ca.com
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [RFC][PATCH v2] selinux: support deferred mapping of contexts
2008-04-30 20:56 [RFC][PATCH v2] selinux: support deferred mapping of contexts Stephen Smalley
2008-04-30 21:51 ` Casey Schaufler
@ 2008-04-30 23:06 ` James Morris
2008-05-01 11:04 ` Stephen Smalley
1 sibling, 1 reply; 16+ messages in thread
From: James Morris @ 2008-04-30 23:06 UTC (permalink / raw)
To: Stephen Smalley; +Cc: selinux, Eric Paris
On Wed, 30 Apr 2008, Stephen Smalley wrote:
> As discussed in:
> http://marc.info/?t=120837952900003&r=1&w=2
> the ability to permit package managers and similar programs to set down
> unknown file contexts is still desired/required, not only for putting
> policy modules in packages but also for enabling build systems to create
> images of different distro releases with different policies w/o
> requiring all of the types to be defined in the build host policy.
>
Does this solve all known issues for this case? e.g. what if a script
needs to be run by RPM on a file it just created ? Does that ever happen?
- James
--
James Morris
<jmorris@namei.org>
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [RFC][PATCH v2] selinux: support deferred mapping of contexts
2008-04-30 21:51 ` Casey Schaufler
@ 2008-05-01 10:37 ` Stephen Smalley
0 siblings, 0 replies; 16+ messages in thread
From: Stephen Smalley @ 2008-05-01 10:37 UTC (permalink / raw)
To: casey; +Cc: selinux, James Morris, Eric Paris
On Wed, 2008-04-30 at 14:51 -0700, Casey Schaufler wrote:
> --- Stephen Smalley <sds@tycho.nsa.gov> wrote:
>
> > As discussed in:
> > http://marc.info/?t=120837952900003&r=1&w=2
> > the ability to permit package managers and similar programs to set down
> > unknown file contexts is still desired/required, not only for putting
> > policy modules in packages but also for enabling build systems to create
> > images of different distro releases with different policies w/o
> > requiring all of the types to be defined in the build host policy.
> >
> > This is an updated form of the patch originally posted in:
> > http://marc.info/?l=selinux&m=114771094617968&w=2
> >
> > The only significant change to the patch aside from re-basing is that
> > rather than introducing a labelpriv permission in the security class to
> > control the new operation, I chose to use a class/permission that is not
> > already allowed for unconfined domains so that unconfined user shells
> > won't get this permission by default. I was going to add a new class
> > and permission but then realized that the mac_override capability check
> > seemed to fit well conceptually and since it falls in the new
> > capability2 class, it is not allowed to any existing domains in policy.
> > Further, by making this a capable() check rather than only a SELinux
> > permission check, the ability to set unknown file contexts is still
> > limited to superuser (or at least CAP_MAC_OVERRIDE)
>
> I think you should be using CAP_MAC_ADMIN as you are explictly
> setting the attribute. CAP_MAC_OVERRIDE is for violations of
> normal policy, whereas this appears more like an administrative
> action.
Ok, I'll include that change in the next version of the patch (if there
is one). Thanks.
--
Stephen Smalley
National Security Agency
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [RFC][PATCH v2] selinux: support deferred mapping of contexts
2008-04-30 23:06 ` James Morris
@ 2008-05-01 11:04 ` Stephen Smalley
2008-05-01 11:41 ` Stephen Smalley
2008-05-01 12:11 ` James Morris
0 siblings, 2 replies; 16+ messages in thread
From: Stephen Smalley @ 2008-05-01 11:04 UTC (permalink / raw)
To: James Morris; +Cc: selinux, Eric Paris, Daniel J Walsh
On Thu, 2008-05-01 at 09:06 +1000, James Morris wrote:
> On Wed, 30 Apr 2008, Stephen Smalley wrote:
>
> > As discussed in:
> > http://marc.info/?t=120837952900003&r=1&w=2
> > the ability to permit package managers and similar programs to set down
> > unknown file contexts is still desired/required, not only for putting
> > policy modules in packages but also for enabling build systems to create
> > images of different distro releases with different policies w/o
> > requiring all of the types to be defined in the build host policy.
> >
>
> Does this solve all known issues for this case? e.g. what if a script
> needs to be run by RPM on a file it just created ? Does that ever happen?
If required, I believe that can be addressed by allowing rpm_script_t
the ability to execute (along with create, read, and write) an
unlabeled_t file. And note that this only happens when the file's type
is only defined by the policy module within the package itself (for
policy-modules-in-packages) or when the file's type is not defined by
the build host's policy (for buildsys), whereas the most common
executable types are all defined in the base policy and will typically
be present in the build host policy as well.
It isn't a perfectly general solution, of course.
An alternative approach would be for rpm to load policy at least
defining the types first before setting down the files, which was our
original preference, but that wasn't viewed as workable by the distro
folks. It might be easier if we had a specific SELinux kernel interface
(i.e. another selinuxfs node) that permitted adding types w/o performing
a complete policy reload.
Also, as with the prior version of this patch, we could split this patch
into two logical changes, the first of which would only introduce the
support for deferred mapping of contexts but not allow userspace to set
invalid contexts, and the second of which would allow userspace to set
invalid contexts. The first change would fix an existing problem we
have, where removing a policy module that defines a type previously set
in the filesystem (when it was defined by policy) and later re-inserting
it still leaves the inode with an invalidated SID at present (but not
after the patch). The second change is the controversial part -
allowing userspace to explicitly set down invalid contexts in the first
place.
--
Stephen Smalley
National Security Agency
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [RFC][PATCH v2] selinux: support deferred mapping of contexts
2008-05-01 11:04 ` Stephen Smalley
@ 2008-05-01 11:41 ` Stephen Smalley
2008-05-01 14:46 ` Eric Paris
2008-05-01 12:11 ` James Morris
1 sibling, 1 reply; 16+ messages in thread
From: Stephen Smalley @ 2008-05-01 11:41 UTC (permalink / raw)
To: James Morris; +Cc: selinux, Eric Paris, Daniel J Walsh
On Thu, 2008-05-01 at 07:04 -0400, Stephen Smalley wrote:
> On Thu, 2008-05-01 at 09:06 +1000, James Morris wrote:
> > On Wed, 30 Apr 2008, Stephen Smalley wrote:
> >
> > > As discussed in:
> > > http://marc.info/?t=120837952900003&r=1&w=2
> > > the ability to permit package managers and similar programs to set down
> > > unknown file contexts is still desired/required, not only for putting
> > > policy modules in packages but also for enabling build systems to create
> > > images of different distro releases with different policies w/o
> > > requiring all of the types to be defined in the build host policy.
> > >
> >
> > Does this solve all known issues for this case? e.g. what if a script
> > needs to be run by RPM on a file it just created ? Does that ever happen?
>
> If required, I believe that can be addressed by allowing rpm_script_t
> the ability to execute (along with create, read, and write) an
> unlabeled_t file. And note that this only happens when the file's type
> is only defined by the policy module within the package itself (for
> policy-modules-in-packages) or when the file's type is not defined by
> the build host's policy (for buildsys), whereas the most common
> executable types are all defined in the base policy and will typically
> be present in the build host policy as well.
>
> It isn't a perfectly general solution, of course.
>
> An alternative approach would be for rpm to load policy at least
> defining the types first before setting down the files, which was our
> original preference, but that wasn't viewed as workable by the distro
> folks. It might be easier if we had a specific SELinux kernel interface
> (i.e. another selinuxfs node) that permitted adding types w/o performing
> a complete policy reload.
...except that adding new types affects attributes, and attribute
expansion still happens in part in userspace (e.g. for file_type
-shadow_t expressions), and attributes aren't preserved in the kernel's
types symtab. So it isn't straightforward to support such direct
additions at the kernel interface presently.
> Also, as with the prior version of this patch, we could split this patch
> into two logical changes, the first of which would only introduce the
> support for deferred mapping of contexts but not allow userspace to set
> invalid contexts, and the second of which would allow userspace to set
> invalid contexts. The first change would fix an existing problem we
> have, where removing a policy module that defines a type previously set
> in the filesystem (when it was defined by policy) and later re-inserting
> it still leaves the inode with an invalidated SID at present (but not
> after the patch). The second change is the controversial part -
> allowing userspace to explicitly set down invalid contexts in the first
> place.
>
--
Stephen Smalley
National Security Agency
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [RFC][PATCH v2] selinux: support deferred mapping of contexts
2008-05-01 11:04 ` Stephen Smalley
2008-05-01 11:41 ` Stephen Smalley
@ 2008-05-01 12:11 ` James Morris
2008-05-01 12:31 ` Stephen Smalley
1 sibling, 1 reply; 16+ messages in thread
From: James Morris @ 2008-05-01 12:11 UTC (permalink / raw)
To: Stephen Smalley; +Cc: selinux, Eric Paris, Daniel J Walsh
On Thu, 1 May 2008, Stephen Smalley wrote:
> It isn't a perfectly general solution, of course.
>
> An alternative approach would be for rpm to load policy at least
> defining the types first before setting down the files, which was our
> original preference, but that wasn't viewed as workable by the distro
> folks. It might be easier if we had a specific SELinux kernel interface
> (i.e. another selinuxfs node) that permitted adding types w/o performing
> a complete policy reload.
I gather the problem is build hosts where you don't want to give that much
privilege to users.
- James
--
James Morris
<jmorris@namei.org>
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [RFC][PATCH v2] selinux: support deferred mapping of contexts
2008-05-01 12:11 ` James Morris
@ 2008-05-01 12:31 ` Stephen Smalley
2008-05-01 13:22 ` James Morris
0 siblings, 1 reply; 16+ messages in thread
From: Stephen Smalley @ 2008-05-01 12:31 UTC (permalink / raw)
To: James Morris; +Cc: selinux, Eric Paris, Daniel J Walsh
On Thu, 2008-05-01 at 22:11 +1000, James Morris wrote:
> On Thu, 1 May 2008, Stephen Smalley wrote:
>
> > It isn't a perfectly general solution, of course.
> >
> > An alternative approach would be for rpm to load policy at least
> > defining the types first before setting down the files, which was our
> > original preference, but that wasn't viewed as workable by the distro
> > folks. It might be easier if we had a specific SELinux kernel interface
> > (i.e. another selinuxfs node) that permitted adding types w/o performing
> > a complete policy reload.
>
> I gather the problem is build hosts where you don't want to give that much
> privilege to users.
No, it isn't about privilege. It is about:
1) Being able to handle new labels not known to the build host policy
w/o otherwise changing the build host policy (i.e. we do not want to
wholesale replace the build host policy with the policy for the
distribution image we are building, and they may be quite different in
nature - in terms of applications covered, strict vs. targeted, mcs vs.
mls, etc), and
2) Avoiding the performance overhead of a complete policy reload on each
package install.
So our options are either to provide a way to set unknown labels on disk
(the current patch) or to provide a lightweight mechanism for adding new
labels to an existing policy (difficult for the reasons already
described, plus it is even more of an issue for e.g. building a mcs or
mls enabled distro on a non-mcs/mls build host, e.g. building RHEL5 on
RHEL4, as then you have another label component completely foreign to
the build host with no way to define it). Or a mechanism for a
hierarchy of policies (complex, and not clear how to handle objects as
they may be visible to processes operating under more than one policy,
e.g. both inside and outside of the chroot).
--
Stephen Smalley
National Security Agency
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [RFC][PATCH v2] selinux: support deferred mapping of contexts
2008-05-01 12:31 ` Stephen Smalley
@ 2008-05-01 13:22 ` James Morris
2008-05-01 13:49 ` Stephen Smalley
0 siblings, 1 reply; 16+ messages in thread
From: James Morris @ 2008-05-01 13:22 UTC (permalink / raw)
To: Stephen Smalley; +Cc: selinux, Eric Paris, Daniel J Walsh
On Thu, 1 May 2008, Stephen Smalley wrote:
> the build host with no way to define it). Or a mechanism for a
> hierarchy of policies (complex, and not clear how to handle objects as
> they may be visible to processes operating under more than one policy,
> e.g. both inside and outside of the chroot).
Indeed, this might be helped by encoding DOIs into labels but would likely
add lots of complexity and performance overhead. AFAICT, entities in
different policy namespaces would need to be totally separated (unless
purely hierarchical).
- James
--
James Morris
<jmorris@namei.org>
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [RFC][PATCH v2] selinux: support deferred mapping of contexts
2008-05-01 13:22 ` James Morris
@ 2008-05-01 13:49 ` Stephen Smalley
2008-05-02 15:47 ` Daniel J Walsh
0 siblings, 1 reply; 16+ messages in thread
From: Stephen Smalley @ 2008-05-01 13:49 UTC (permalink / raw)
To: James Morris; +Cc: selinux, Eric Paris, Daniel J Walsh
On Thu, 2008-05-01 at 23:22 +1000, James Morris wrote:
> On Thu, 1 May 2008, Stephen Smalley wrote:
>
> > the build host with no way to define it). Or a mechanism for a
> > hierarchy of policies (complex, and not clear how to handle objects as
> > they may be visible to processes operating under more than one policy,
> > e.g. both inside and outside of the chroot).
>
> Indeed, this might be helped by encoding DOIs into labels but would likely
> add lots of complexity and performance overhead. AFAICT, entities in
> different policy namespaces would need to be totally separated (unless
> purely hierarchical).
Pure isolation would be cleaner, but won't work in the buildsys example,
as there we have rpm (running outside the chroot) installing files into
the chroot tree and then launching scriptlets within the chroot, so we
have processes both outside and within the chroot acting on the files.
In any event, of the available alternatives, I think the
set-unknown-label option may be the only practical one. So if you have
any comments on the code in the patch or if you want it split into two
stages, let me know. Otherwise, I'll re-spin it with Casey's suggested
change.
--
Stephen Smalley
National Security Agency
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [RFC][PATCH v2] selinux: support deferred mapping of contexts
2008-05-01 11:41 ` Stephen Smalley
@ 2008-05-01 14:46 ` Eric Paris
2008-05-01 15:01 ` Stephen Smalley
0 siblings, 1 reply; 16+ messages in thread
From: Eric Paris @ 2008-05-01 14:46 UTC (permalink / raw)
To: Stephen Smalley; +Cc: James Morris, selinux, Daniel J Walsh
On Thu, May 1, 2008 at 7:41 AM, Stephen Smalley <sds@tycho.nsa.gov> wrote:
>
>
> On Thu, 2008-05-01 at 07:04 -0400, Stephen Smalley wrote:
> > On Thu, 2008-05-01 at 09:06 +1000, James Morris wrote:
> > > On Wed, 30 Apr 2008, Stephen Smalley wrote:
> > >
> > > > As discussed in:
> > > > http://marc.info/?t=120837952900003&r=1&w=2
> > > > the ability to permit package managers and similar programs to set down
> > > > unknown file contexts is still desired/required, not only for putting
> > > > policy modules in packages but also for enabling build systems to create
> > > > images of different distro releases with different policies w/o
> > > > requiring all of the types to be defined in the build host policy.
> > > >
> > >
> > > Does this solve all known issues for this case? e.g. what if a script
> > > needs to be run by RPM on a file it just created ? Does that ever happen?
> >
> > If required, I believe that can be addressed by allowing rpm_script_t
> > the ability to execute (along with create, read, and write) an
> > unlabeled_t file. And note that this only happens when the file's type
> > is only defined by the policy module within the package itself (for
> > policy-modules-in-packages) or when the file's type is not defined by
> > the build host's policy (for buildsys), whereas the most common
> > executable types are all defined in the base policy and will typically
> > be present in the build host policy as well.
> >
> > It isn't a perfectly general solution, of course.
> >
> > An alternative approach would be for rpm to load policy at least
> > defining the types first before setting down the files, which was our
> > original preference, but that wasn't viewed as workable by the distro
> > folks. It might be easier if we had a specific SELinux kernel interface
> > (i.e. another selinuxfs node) that permitted adding types w/o performing
> > a complete policy reload.
>
> ...except that adding new types affects attributes, and attribute
> expansion still happens in part in userspace (e.g. for file_type
> -shadow_t expressions), and attributes aren't preserved in the kernel's
> types symtab. So it isn't straightforward to support such direct
> additions at the kernel interface presently.
In the case of adding types merely for the purposes of having them
defined but not including any allow rules around them I don't see this
an issue. Is there a problem with 'lightweight' types which you can
push in via some new mechanism but which are basically useless for
anything other than validation of existence? If you want a real type
with allow rules you have to load it in a real policy load?
Just not sure attribute expansion has to stop this line of thought.
Although the original patch does seem to solve all the problems in a
manor that requires a lot less changes everywhere else.
-Eric
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [RFC][PATCH v2] selinux: support deferred mapping of contexts
2008-05-01 14:46 ` Eric Paris
@ 2008-05-01 15:01 ` Stephen Smalley
0 siblings, 0 replies; 16+ messages in thread
From: Stephen Smalley @ 2008-05-01 15:01 UTC (permalink / raw)
To: Eric Paris; +Cc: James Morris, selinux, Daniel J Walsh
On Thu, 2008-05-01 at 10:46 -0400, Eric Paris wrote:
> On Thu, May 1, 2008 at 7:41 AM, Stephen Smalley <sds@tycho.nsa.gov> wrote:
> >
> >
> > On Thu, 2008-05-01 at 07:04 -0400, Stephen Smalley wrote:
> > > On Thu, 2008-05-01 at 09:06 +1000, James Morris wrote:
> > > > On Wed, 30 Apr 2008, Stephen Smalley wrote:
> > > >
> > > > > As discussed in:
> > > > > http://marc.info/?t=120837952900003&r=1&w=2
> > > > > the ability to permit package managers and similar programs to set down
> > > > > unknown file contexts is still desired/required, not only for putting
> > > > > policy modules in packages but also for enabling build systems to create
> > > > > images of different distro releases with different policies w/o
> > > > > requiring all of the types to be defined in the build host policy.
> > > > >
> > > >
> > > > Does this solve all known issues for this case? e.g. what if a script
> > > > needs to be run by RPM on a file it just created ? Does that ever happen?
> > >
> > > If required, I believe that can be addressed by allowing rpm_script_t
> > > the ability to execute (along with create, read, and write) an
> > > unlabeled_t file. And note that this only happens when the file's type
> > > is only defined by the policy module within the package itself (for
> > > policy-modules-in-packages) or when the file's type is not defined by
> > > the build host's policy (for buildsys), whereas the most common
> > > executable types are all defined in the base policy and will typically
> > > be present in the build host policy as well.
> > >
> > > It isn't a perfectly general solution, of course.
> > >
> > > An alternative approach would be for rpm to load policy at least
> > > defining the types first before setting down the files, which was our
> > > original preference, but that wasn't viewed as workable by the distro
> > > folks. It might be easier if we had a specific SELinux kernel interface
> > > (i.e. another selinuxfs node) that permitted adding types w/o performing
> > > a complete policy reload.
> >
> > ...except that adding new types affects attributes, and attribute
> > expansion still happens in part in userspace (e.g. for file_type
> > -shadow_t expressions), and attributes aren't preserved in the kernel's
> > types symtab. So it isn't straightforward to support such direct
> > additions at the kernel interface presently.
>
> In the case of adding types merely for the purposes of having them
> defined but not including any allow rules around them I don't see this
> an issue. Is there a problem with 'lightweight' types which you can
> push in via some new mechanism but which are basically useless for
> anything other than validation of existence? If you want a real type
> with allow rules you have to load it in a real policy load?
>
> Just not sure attribute expansion has to stop this line of thought.
> Although the original patch does seem to solve all the problems in a
> manor that requires a lot less changes everywhere else.
We need more than validation of existence in order for them to be useful
- we need to allow them to be associated with the filesystem type in
which they will be created, we need to allow rpm's domain to be able to
create and access them, etc. Which would fall out naturally if we can
push them along with attribute declarations (e.g. file_type) that would
automatically expand in existing allow rules to permit association and
access to occur. We are perhaps halfway there already since we do
preserve allow rules in attribute form in the kernel in policy.20 and
later, but only in the simplest case (e.g. allow rpm_t file_type:file
all_file_perms; gets pushed down directly without requiring userland
expansion, but allow rpm_t { file_type -specialprotectedtype }:file
all_file_perms; is still preexpanded by the policy toolchain). But we
don't (yet) preserve the attribute names in the kernel symtabs. I would
like to introduce that support as well, but it doesn't solve the entire
problem, see below.
Independent of the type definition issue, there is the mcs vs. mls or
non-mls/mcs vs mls/mcs cases to consider for buildsys, which is even
more complex than being able to define a type - now we have to deal with
additional or missing context fields altogether.
So I think the ability to set down a completely uninterpreted label is
likely needed here, which is what the current patch supports.
--
Stephen Smalley
National Security Agency
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [RFC][PATCH v2] selinux: support deferred mapping of contexts
2008-05-01 13:49 ` Stephen Smalley
@ 2008-05-02 15:47 ` Daniel J Walsh
2008-05-02 16:14 ` Stephen Smalley
0 siblings, 1 reply; 16+ messages in thread
From: Daniel J Walsh @ 2008-05-02 15:47 UTC (permalink / raw)
To: Stephen Smalley; +Cc: James Morris, selinux, Eric Paris
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Stephen Smalley wrote:
> On Thu, 2008-05-01 at 23:22 +1000, James Morris wrote:
>> On Thu, 1 May 2008, Stephen Smalley wrote:
>>
>>> the build host with no way to define it). Or a mechanism for a
>>> hierarchy of policies (complex, and not clear how to handle objects as
>>> they may be visible to processes operating under more than one policy,
>>> e.g. both inside and outside of the chroot).
>> Indeed, this might be helped by encoding DOIs into labels but would likely
>> add lots of complexity and performance overhead. AFAICT, entities in
>> different policy namespaces would need to be totally separated (unless
>> purely hierarchical).
>
> Pure isolation would be cleaner, but won't work in the buildsys example,
> as there we have rpm (running outside the chroot) installing files into
> the chroot tree and then launching scriptlets within the chroot, so we
> have processes both outside and within the chroot acting on the files.
>
> In any event, of the available alternatives, I think the
> set-unknown-label option may be the only practical one. So if you have
> any comments on the code in the patch or if you want it split into two
> stages, let me know. Otherwise, I'll re-spin it with Casey's suggested
> change.
>
This is half the solution. Don't we need a new /selinux for inside the
chroot, so that when selinux-policy rpm installs the policy, it lies and
says the policy was loaded. Then at the end of the install , restorecon
is running on the entire image to make sure the labels match the
file_context in the chroot.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)
Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org
iEYEARECAAYFAkgbN68ACgkQrlYvE4MpobNNHwCg2nEftevFAgohBB7sWYe1olzk
WjQAn2BKSqmNkEaiZZrhAJZBTp32PvdC
=+3Br
-----END PGP SIGNATURE-----
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [RFC][PATCH v2] selinux: support deferred mapping of contexts
2008-05-02 15:47 ` Daniel J Walsh
@ 2008-05-02 16:14 ` Stephen Smalley
2008-05-02 16:22 ` Stephen Smalley
0 siblings, 1 reply; 16+ messages in thread
From: Stephen Smalley @ 2008-05-02 16:14 UTC (permalink / raw)
To: Daniel J Walsh; +Cc: James Morris, selinux, Eric Paris
On Fri, 2008-05-02 at 11:47 -0400, Daniel J Walsh wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> Stephen Smalley wrote:
> > On Thu, 2008-05-01 at 23:22 +1000, James Morris wrote:
> >> On Thu, 1 May 2008, Stephen Smalley wrote:
> >>
> >>> the build host with no way to define it). Or a mechanism for a
> >>> hierarchy of policies (complex, and not clear how to handle objects as
> >>> they may be visible to processes operating under more than one policy,
> >>> e.g. both inside and outside of the chroot).
> >> Indeed, this might be helped by encoding DOIs into labels but would likely
> >> add lots of complexity and performance overhead. AFAICT, entities in
> >> different policy namespaces would need to be totally separated (unless
> >> purely hierarchical).
> >
> > Pure isolation would be cleaner, but won't work in the buildsys example,
> > as there we have rpm (running outside the chroot) installing files into
> > the chroot tree and then launching scriptlets within the chroot, so we
> > have processes both outside and within the chroot acting on the files.
> >
> > In any event, of the available alternatives, I think the
> > set-unknown-label option may be the only practical one. So if you have
> > any comments on the code in the patch or if you want it split into two
> > stages, let me know. Otherwise, I'll re-spin it with Casey's suggested
> > change.
> >
> This is half the solution. Don't we need a new /selinux for inside the
> chroot, so that when selinux-policy rpm installs the policy, it lies and
> says the policy was loaded. Then at the end of the install , restorecon
> is running on the entire image to make sure the labels match the
> file_context in the chroot.
I don't know offhand, but that is something the installer folks can do
on their own. Just make a fake /selinux directory in the chroot with
"load" as a hard link to /dev/null?
I do expect we'll run into other issues, but we won't really know what
they all are until we try using this kernel patch first. Can we get the
patch (w/ Casey's suggested change) put into a Fedora kernel for initial
testing before upstreaming?
--
Stephen Smalley
National Security Agency
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [RFC][PATCH v2] selinux: support deferred mapping of contexts
2008-05-02 16:14 ` Stephen Smalley
@ 2008-05-02 16:22 ` Stephen Smalley
2008-05-02 16:45 ` Stephen Smalley
0 siblings, 1 reply; 16+ messages in thread
From: Stephen Smalley @ 2008-05-02 16:22 UTC (permalink / raw)
To: Daniel J Walsh; +Cc: James Morris, selinux, Eric Paris
On Fri, 2008-05-02 at 12:14 -0400, Stephen Smalley wrote:
> On Fri, 2008-05-02 at 11:47 -0400, Daniel J Walsh wrote:
> > -----BEGIN PGP SIGNED MESSAGE-----
> > Hash: SHA1
> >
> > Stephen Smalley wrote:
> > > On Thu, 2008-05-01 at 23:22 +1000, James Morris wrote:
> > >> On Thu, 1 May 2008, Stephen Smalley wrote:
> > >>
> > >>> the build host with no way to define it). Or a mechanism for a
> > >>> hierarchy of policies (complex, and not clear how to handle objects as
> > >>> they may be visible to processes operating under more than one policy,
> > >>> e.g. both inside and outside of the chroot).
> > >> Indeed, this might be helped by encoding DOIs into labels but would likely
> > >> add lots of complexity and performance overhead. AFAICT, entities in
> > >> different policy namespaces would need to be totally separated (unless
> > >> purely hierarchical).
> > >
> > > Pure isolation would be cleaner, but won't work in the buildsys example,
> > > as there we have rpm (running outside the chroot) installing files into
> > > the chroot tree and then launching scriptlets within the chroot, so we
> > > have processes both outside and within the chroot acting on the files.
> > >
> > > In any event, of the available alternatives, I think the
> > > set-unknown-label option may be the only practical one. So if you have
> > > any comments on the code in the patch or if you want it split into two
> > > stages, let me know. Otherwise, I'll re-spin it with Casey's suggested
> > > change.
> > >
> > This is half the solution. Don't we need a new /selinux for inside the
> > chroot, so that when selinux-policy rpm installs the policy, it lies and
> > says the policy was loaded. Then at the end of the install , restorecon
> > is running on the entire image to make sure the labels match the
> > file_context in the chroot.
>
> I don't know offhand, but that is something the installer folks can do
> on their own. Just make a fake /selinux directory in the chroot with
> "load" as a hard link to /dev/null?
Actually, why can't we just pretend selinux is disabled within the
chroot (via a shared object that overrides is_selinux_enabled) to
suppress attempts to reload policy into the kernel? Everything else
(installing the policy files, running semanage, etc) is supposed to work
even on a selinux-disabled host.
As long as rpm itself knows that SELinux is enabled on the build host
(which it should determine at startup before chroot'ing), I don't see
the problem.
> I do expect we'll run into other issues, but we won't really know what
> they all are until we try using this kernel patch first. Can we get the
> patch (w/ Casey's suggested change) put into a Fedora kernel for initial
> testing before upstreaming?
>
--
Stephen Smalley
National Security Agency
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [RFC][PATCH v2] selinux: support deferred mapping of contexts
2008-05-02 16:22 ` Stephen Smalley
@ 2008-05-02 16:45 ` Stephen Smalley
0 siblings, 0 replies; 16+ messages in thread
From: Stephen Smalley @ 2008-05-02 16:45 UTC (permalink / raw)
To: Daniel J Walsh; +Cc: James Morris, selinux, Eric Paris
On Fri, 2008-05-02 at 12:22 -0400, Stephen Smalley wrote:
> On Fri, 2008-05-02 at 12:14 -0400, Stephen Smalley wrote:
> > On Fri, 2008-05-02 at 11:47 -0400, Daniel J Walsh wrote:
> > > -----BEGIN PGP SIGNED MESSAGE-----
> > > Hash: SHA1
> > >
> > > Stephen Smalley wrote:
> > > > On Thu, 2008-05-01 at 23:22 +1000, James Morris wrote:
> > > >> On Thu, 1 May 2008, Stephen Smalley wrote:
> > > >>
> > > >>> the build host with no way to define it). Or a mechanism for a
> > > >>> hierarchy of policies (complex, and not clear how to handle objects as
> > > >>> they may be visible to processes operating under more than one policy,
> > > >>> e.g. both inside and outside of the chroot).
> > > >> Indeed, this might be helped by encoding DOIs into labels but would likely
> > > >> add lots of complexity and performance overhead. AFAICT, entities in
> > > >> different policy namespaces would need to be totally separated (unless
> > > >> purely hierarchical).
> > > >
> > > > Pure isolation would be cleaner, but won't work in the buildsys example,
> > > > as there we have rpm (running outside the chroot) installing files into
> > > > the chroot tree and then launching scriptlets within the chroot, so we
> > > > have processes both outside and within the chroot acting on the files.
> > > >
> > > > In any event, of the available alternatives, I think the
> > > > set-unknown-label option may be the only practical one. So if you have
> > > > any comments on the code in the patch or if you want it split into two
> > > > stages, let me know. Otherwise, I'll re-spin it with Casey's suggested
> > > > change.
> > > >
> > > This is half the solution. Don't we need a new /selinux for inside the
> > > chroot, so that when selinux-policy rpm installs the policy, it lies and
> > > says the policy was loaded. Then at the end of the install , restorecon
> > > is running on the entire image to make sure the labels match the
> > > file_context in the chroot.
> >
> > I don't know offhand, but that is something the installer folks can do
> > on their own. Just make a fake /selinux directory in the chroot with
> > "load" as a hard link to /dev/null?
>
> Actually, why can't we just pretend selinux is disabled within the
> chroot (via a shared object that overrides is_selinux_enabled) to
> suppress attempts to reload policy into the kernel? Everything else
> (installing the policy files, running semanage, etc) is supposed to work
> even on a selinux-disabled host.
>
> As long as rpm itself knows that SELinux is enabled on the build host
> (which it should determine at startup before chroot'ing), I don't see
> the problem.
Or does that break scriptlet transitions?
If it is a problem, then in addition to faking the load node, I think we
need to fake the context node for context validation/canonicalization.
That one might be a little harder than just bind mounting /dev/null over
it, as userspace expects to read back the canonicalized context value
from it. But I suppose we could just make it a regular file - then when
rpm writes the context value to it and then reads it back, it will get
the identity relationship we want.
So bind mount /dev/null on top of selinux/load and touch selinux/context
within the chroot and it should mostly just work (tm).
>
> > I do expect we'll run into other issues, but we won't really know what
> > they all are until we try using this kernel patch first. Can we get the
> > patch (w/ Casey's suggested change) put into a Fedora kernel for initial
> > testing before upstreaming?
> >
--
Stephen Smalley
National Security Agency
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 16+ messages in thread
end of thread, other threads:[~2008-05-02 16:45 UTC | newest]
Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-04-30 20:56 [RFC][PATCH v2] selinux: support deferred mapping of contexts Stephen Smalley
2008-04-30 21:51 ` Casey Schaufler
2008-05-01 10:37 ` Stephen Smalley
2008-04-30 23:06 ` James Morris
2008-05-01 11:04 ` Stephen Smalley
2008-05-01 11:41 ` Stephen Smalley
2008-05-01 14:46 ` Eric Paris
2008-05-01 15:01 ` Stephen Smalley
2008-05-01 12:11 ` James Morris
2008-05-01 12:31 ` Stephen Smalley
2008-05-01 13:22 ` James Morris
2008-05-01 13:49 ` Stephen Smalley
2008-05-02 15:47 ` Daniel J Walsh
2008-05-02 16:14 ` Stephen Smalley
2008-05-02 16:22 ` Stephen Smalley
2008-05-02 16:45 ` Stephen Smalley
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.