* [RFC][PATCH] selinux: introduce support for deferred mapping of inode security contexts
@ 2006-05-15 16:35 Stephen Smalley
2006-05-15 17:41 ` Stephen Smalley
` (3 more replies)
0 siblings, 4 replies; 33+ messages in thread
From: Stephen Smalley @ 2006-05-15 16:35 UTC (permalink / raw)
To: selinux; +Cc: Thomas Bleher, Daniel J Walsh, SELinux-dev, James Morris
Hi,
During the earlier thread on splitting policy into individual packages
(using policy modules), it was requested that SELinux provide a way for
a privileged process (like a package manager) to label an inode with a
not-yet-defined security context (treating it as having the unlabeled
SID until defined in the policy) and then automatically update the
in-memory state when a policy that defines the security context is
loaded such that the inode immediately becomes accessible under the
rules governing access to that context in the new policy. More
generally, the same behavior is desired for any case where a security
context that was once valid becomes invalid and then becomes valid again
through a series of policy reloads, to address issues in the past where
removing and re-adding types or other context components has caused
problems when inodes are labeled with those context components. This is
a RFC and patch for the SELinux kernel "module" changes required to
support that functionality.
With this patch applied, the following sequence is possible, subject to
policy, which must allow <domain> security_t:security labelpriv; and
allow unlabeled_t fs_t:filesystem associate; in order for this to work
in enforcing mode. Note that unconfined_t implicitly picks up all
security permissions at present due to the use of a wildcard for the
permission set in its rule. However, you still need the second allow
rule as well in order for this to succeed in enforcing mode.
# touch foo
# chcon -t foo_exec_t foo
# ls -Z foo
-rw-r--r-- root root system_u:object_r:unlabeled_t foo
# semodule -i foo.pp # defines foo_exec_t
# ls -Z foo
-rw-r--r-- root root user_u:object_r:foo_exec_t foo
# semodule -r foo
# ls -Z foo
-rw-r--r-- root root system_u:object_r:unlabeled_t foo
# semodule -i foo.pp
# ls -Z foo
-rw-r--r-- root root user_u:object_r:foo_exec_t foo
Logically, there are two separate changes here. The first logical
change is to support deferred mapping of security contexts in the SID
table, storing their string representations when they cannot be mapped
under the current policy, and treating them the same as the unlabeled
SID while they are in this state. Upon policy reloads, if a valid
context becomes invalid under the new policy, rather than removing it
from the SID table, we convert it to its string representation under the
old policy and store that in the SID table until such a time as it
becomes valid again, and if an invalid context becomes valid, we map it
to its internal structure representation. This change alone is
worthwhile irrespective of the second change, as it addresses the
longstanding issue with removing and re-adding types to policy when they
are assigned to inodes. The second logical change introduces the
support for setting invalid contexts by privileged processes, both via
setxattr() and via /proc/self/attr/fscreate, which is the more
controversial aspect. Note that contrary to my earlier expectations, no
walking of the inode security structs is required, as the SIDs
themselves remain invariant under such changes.
---<snip>---
Introduce support for deferring 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 'labelpriv' permission to the 'security' class 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 | 16 ++
security/selinux/include/av_permissions.h | 1
security/selinux/include/objsec.h | 3
security/selinux/include/security.h | 2
security/selinux/selinuxfs.c | 4
security/selinux/ss/context.h | 27 ++++
security/selinux/ss/mls.c | 11 -
security/selinux/ss/mls.h | 3
security/selinux/ss/services.c | 183 ++++++++++++++++++++----------
security/selinux/ss/sidtab.c | 4
10 files changed, 183 insertions(+), 71 deletions(-)
diff -X /home/sds/dontdiff -rup linux-2.6.17-rc3-mm1/security/selinux/hooks.c linux-2.6.17-rc3-mm1-x/security/selinux/hooks.c
--- linux-2.6.17-rc3-mm1/security/selinux/hooks.c 2006-05-04 14:08:36.000000000 -0400
+++ linux-2.6.17-rc3-mm1-x/security/selinux/hooks.c 2006-05-15 09:07:33.000000000 -0400
@@ -2160,6 +2160,11 @@ static int selinux_inode_setxattr(struct
return rc;
rc = security_context_to_sid(value, size, &newsid);
+ if (rc == -EINVAL) {
+ if (task_has_security(current, SECURITY__LABELPRIV))
+ return rc;
+ rc = security_context_to_sid_force(value, size, &newsid);
+ }
if (rc)
return rc;
@@ -2193,10 +2198,11 @@ static void selinux_inode_post_setxattr(
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", __FUNCTION__, (char*)value, -rc);
+ "%s on (%s, %lu), rc=%d\n", __FUNCTION__, (char*)value,
+ inode->i_sb->s_id, inode->i_ino, -rc);
return;
}
@@ -4158,6 +4164,12 @@ static int selinux_setprocattr(struct ta
size--;
}
error = security_context_to_sid(value, size, &sid);
+ if (error == -EINVAL && !strcmp(name, "fscreate")) {
+ if (task_has_security(current, SECURITY__LABELPRIV))
+ return error;
+ error = security_context_to_sid_force(value, size,
+ &sid);
+ }
if (error)
return error;
}
diff -X /home/sds/dontdiff -rup linux-2.6.17-rc3-mm1/security/selinux/include/av_permissions.h linux-2.6.17-rc3-mm1-x/security/selinux/include/av_permissions.h
--- linux-2.6.17-rc3-mm1/security/selinux/include/av_permissions.h 2006-05-04 14:08:36.000000000 -0400
+++ linux-2.6.17-rc3-mm1-x/security/selinux/include/av_permissions.h 2006-05-12 09:48:56.000000000 -0400
@@ -526,6 +526,7 @@
#define SECURITY__SETBOOL 0x00000100UL
#define SECURITY__SETSECPARAM 0x00000200UL
#define SECURITY__SETCHECKREQPROT 0x00000400UL
+#define SECURITY__LABELPRIV 0x00000800UL
#define SYSTEM__IPC_INFO 0x00000001UL
#define SYSTEM__SYSLOG_READ 0x00000002UL
diff -X /home/sds/dontdiff -rup linux-2.6.17-rc3-mm1/security/selinux/include/objsec.h linux-2.6.17-rc3-mm1-x/security/selinux/include/objsec.h
--- linux-2.6.17-rc3-mm1/security/selinux/include/objsec.h 2006-03-20 00:53:29.000000000 -0500
+++ linux-2.6.17-rc3-mm1-x/security/selinux/include/objsec.h 2006-05-12 09:48:56.000000000 -0400
@@ -101,4 +101,7 @@ struct sk_security_struct {
extern unsigned int selinux_checkreqprot;
+extern int task_has_security(struct task_struct *tsk,
+ u32 perms);
+
#endif /* _SELINUX_OBJSEC_H_ */
diff -X /home/sds/dontdiff -rup linux-2.6.17-rc3-mm1/security/selinux/include/security.h linux-2.6.17-rc3-mm1-x/security/selinux/include/security.h
--- linux-2.6.17-rc3-mm1/security/selinux/include/security.h 2006-03-20 00:53:29.000000000 -0500
+++ linux-2.6.17-rc3-mm1-x/security/selinux/include/security.h 2006-05-12 09:46:19.000000000 -0400
@@ -68,6 +68,8 @@ int security_context_to_sid(char *sconte
int security_context_to_sid_default(char *scontext, u32 scontext_len, u32 *out_sid, u32 def_sid);
+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 -X /home/sds/dontdiff -rup linux-2.6.17-rc3-mm1/security/selinux/selinuxfs.c linux-2.6.17-rc3-mm1-x/security/selinux/selinuxfs.c
--- linux-2.6.17-rc3-mm1/security/selinux/selinuxfs.c 2006-05-02 08:06:00.000000000 -0400
+++ linux-2.6.17-rc3-mm1-x/security/selinux/selinuxfs.c 2006-05-12 09:48:56.000000000 -0400
@@ -56,8 +56,8 @@ static int *bool_pending_values = NULL;
extern void selnl_notify_setenforce(int val);
/* Check whether a task is allowed to use a security operation. */
-static int task_has_security(struct task_struct *tsk,
- u32 perms)
+int task_has_security(struct task_struct *tsk,
+ u32 perms)
{
struct task_security_struct *tsec;
diff -X /home/sds/dontdiff -rup linux-2.6.17-rc3-mm1/security/selinux/ss/context.h linux-2.6.17-rc3-mm1-x/security/selinux/ss/context.h
--- linux-2.6.17-rc3-mm1/security/selinux/ss/context.h 2006-03-20 00:53:29.000000000 -0500
+++ linux-2.6.17-rc3-mm1-x/security/selinux/ss/context.h 2006-05-15 08:39:39.000000000 -0400
@@ -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)
@@ -83,20 +85,43 @@ static inline void context_init(struct 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 -X /home/sds/dontdiff -rup linux-2.6.17-rc3-mm1/security/selinux/ss/mls.c linux-2.6.17-rc3-mm1-x/security/selinux/ss/mls.c
--- linux-2.6.17-rc3-mm1/security/selinux/ss/mls.c 2006-05-02 08:47:04.000000000 -0400
+++ linux-2.6.17-rc3-mm1-x/security/selinux/ss/mls.c 2006-05-12 10:08:35.000000000 -0400
@@ -249,7 +249,8 @@ static inline int mls_copy_context(struc
* 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,
@@ -296,7 +297,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;
@@ -320,7 +321,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;
@@ -336,7 +337,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;
@@ -404,7 +405,7 @@ int mls_from_string(char *str, struct co
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 -X /home/sds/dontdiff -rup linux-2.6.17-rc3-mm1/security/selinux/ss/mls.h linux-2.6.17-rc3-mm1-x/security/selinux/ss/mls.h
--- linux-2.6.17-rc3-mm1/security/selinux/ss/mls.h 2006-05-02 08:47:04.000000000 -0400
+++ linux-2.6.17-rc3-mm1-x/security/selinux/ss/mls.h 2006-05-12 09:03:23.000000000 -0400
@@ -21,7 +21,8 @@ int mls_compute_context_len(struct conte
void mls_sid_to_context(struct context *context, char **scontext);
int mls_context_isvalid(struct policydb *p, struct context *c);
-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 -X /home/sds/dontdiff -rup linux-2.6.17-rc3-mm1/security/selinux/ss/services.c linux-2.6.17-rc3-mm1-x/security/selinux/ss/services.c
--- linux-2.6.17-rc3-mm1/security/selinux/ss/services.c 2006-05-02 08:47:04.000000000 -0400
+++ linux-2.6.17-rc3-mm1-x/security/selinux/ss/services.c 2006-05-15 10:01:01.000000000 -0400
@@ -619,36 +619,24 @@ out:
}
-static int security_context_to_sid_core(char *scontext, u32 scontext_len, u32 *sid, u32 def_sid)
+static int string_to_context_struct(struct policydb *pol,
+ struct sidtab *sidtabp,
+ char *scontext,
+ u32 scontext_len,
+ struct context *ctx,
+ u32 def_sid)
{
- 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. */
- scontext2 = kmalloc(scontext_len+1,GFP_KERNEL);
+ /* Copy the string so that we can modify the copy as we parse it. */
+ scontext2 = kmalloc(scontext_len+1, GFP_ATOMIC);
if (!scontext2) {
rc = -ENOMEM;
goto out;
@@ -656,11 +644,6 @@ static int security_context_to_sid_core(
memcpy(scontext2, scontext, scontext_len);
scontext2[scontext_len] = 0;
- context_init(&context);
- *sid = SECSID_NULL;
-
- POLICY_RDLOCK;
-
/* Parse the security context. */
rc = -EINVAL;
@@ -672,15 +655,15 @@ static int security_context_to_sid_core(
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;
@@ -688,14 +671,14 @@ static int security_context_to_sid_core(
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;
@@ -704,33 +687,72 @@ static int security_context_to_sid_core(
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, 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);
+ if (rc == -EINVAL && force) {
+ context.str = kmalloc(scontext_len+1,GFP_ATOMIC);
+ 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;
}
@@ -748,7 +770,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);
+ sid, SECSID_NULL, 0);
}
/**
@@ -765,13 +787,20 @@ int security_context_to_sid(char *sconte
* 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.
*/
int security_context_to_sid_default(char *scontext, u32 scontext_len, u32 *sid, u32 def_sid)
{
return security_context_to_sid_core(scontext, scontext_len,
- sid, def_sid);
+ sid, def_sid, 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, 1);
}
static int compute_sid_handle_invalid_context(
@@ -1108,9 +1137,10 @@ static inline int convert_context_handle
char *s;
u32 len;
- context_struct_to_string(context, &s, &len);
- printk(KERN_ERR "security: 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;
}
@@ -1142,6 +1172,27 @@ 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);
+ if (!rc) {
+ printk(KERN_INFO "SELinux: Context %s became valid under new policy.\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: Failed trying to map context %s (rc %d) under new policy, leaving unmapped.\n", c->str, -rc);
+ goto out;
+ }
+ }
+
rc = context_cpy(&oldc, c);
if (rc)
goto out;
@@ -1184,13 +1235,19 @@ 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 "security: invalidating context %s\n", s);
- kfree(s);
+ context_destroy(c);
+ c->str = s;
+ c->len = len;
+ printk(KERN_INFO "SELinux: Context %s became invalid under new policy.\n", c->str);
+ rc = 0;
goto out;
}
@@ -1249,7 +1306,11 @@ int security_load_policy(void *data, siz
return -EINVAL;
}
- sidtab_init(&newsidtab);
+ if (sidtab_init(&newsidtab)) {
+ LOAD_UNLOCK;
+ policydb_destroy(&newpolicydb);
+ return -ENOMEM;
+ }
/* Verify that the existing classes did not change. */
if (hashtab_map(policydb.p_classes.table, validate_class, &newpolicydb)) {
@@ -1267,10 +1328,12 @@ int security_load_policy(void *data, siz
}
/* Convert the internal representations of contexts
- in the new SID table and remove invalid SIDs. */
+ 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);
@@ -1520,6 +1583,8 @@ int security_get_user_sids(u32 fromsid,
POLICY_RDLOCK;
+ context_init(&usercon);
+
fromcon = sidtab_search(&sidtab, fromsid);
if (!fromcon) {
rc = -EINVAL;
diff -X /home/sds/dontdiff -rup linux-2.6.17-rc3-mm1/security/selinux/ss/sidtab.c linux-2.6.17-rc3-mm1-x/security/selinux/ss/sidtab.c
--- linux-2.6.17-rc3-mm1/security/selinux/ss/sidtab.c 2006-03-20 00:53:29.000000000 -0500
+++ linux-2.6.17-rc3-mm1-x/security/selinux/ss/sidtab.c 2006-05-15 10:20:08.000000000 -0400
@@ -100,7 +100,7 @@ struct context *sidtab_search(struct 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);
@@ -218,6 +218,8 @@ int sidtab_context_to_sid(struct sidtab
goto unlock_out;
}
sid = s->next_sid++;
+ if (context->len)
+ printk(KERN_INFO "SELinux: Context %s is not valid under current policy, adding as unmapped value.\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 [flat|nested] 33+ messages in thread* Re: [RFC][PATCH] selinux: introduce support for deferred mapping of inode security contexts 2006-05-15 16:35 [RFC][PATCH] selinux: introduce support for deferred mapping of inode security contexts Stephen Smalley @ 2006-05-15 17:41 ` Stephen Smalley 2006-05-16 12:15 ` Stephen Smalley ` (2 subsequent siblings) 3 siblings, 0 replies; 33+ messages in thread From: Stephen Smalley @ 2006-05-15 17:41 UTC (permalink / raw) To: selinux; +Cc: Thomas Bleher, Daniel J Walsh, SELinux-dev, James Morris On Mon, 2006-05-15 at 12:35 -0400, Stephen Smalley wrote: > Introduce support for deferring 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 'labelpriv' permission to the 'security' class 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. Also requires this diff on top of the other one to map labelpriv to a string in avc messages: diff -X /home/sds/dontdiff -rup linux-2.6.17-rc3-mm1/security/selinux/include/av_perm_to_string.h linux-2.6.17-rc3-mm1-x/security/selinux/include/av_perm_to_string.h --- linux-2.6.17-rc3-mm1/security/selinux/include/av_perm_to_string.h 2006-05-15 13:22:03.000000000 -0400 +++ linux-2.6.17-rc3-mm1-x/security/selinux/include/av_perm_to_string.h 2006-05-15 12:26:56.000000000 -0400 @@ -87,6 +87,7 @@ S_(SECCLASS_SECURITY, SECURITY__SETBOOL, "setbool") S_(SECCLASS_SECURITY, SECURITY__SETSECPARAM, "setsecparam") S_(SECCLASS_SECURITY, SECURITY__SETCHECKREQPROT, "setcheckreqprot") + S_(SECCLASS_SECURITY, SECURITY__LABELPRIV, "labelpriv") S_(SECCLASS_SYSTEM, SYSTEM__IPC_INFO, "ipc_info") S_(SECCLASS_SYSTEM, SYSTEM__SYSLOG_READ, "syslog_read") S_(SECCLASS_SYSTEM, SYSTEM__SYSLOG_MOD, "syslog_mod") -- 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] 33+ messages in thread
* Re: [RFC][PATCH] selinux: introduce support for deferred mapping of inode security contexts 2006-05-15 16:35 [RFC][PATCH] selinux: introduce support for deferred mapping of inode security contexts Stephen Smalley 2006-05-15 17:41 ` Stephen Smalley @ 2006-05-16 12:15 ` Stephen Smalley 2006-05-17 7:54 ` Thomas Bleher 2006-05-19 13:44 ` Stephen Smalley 3 siblings, 0 replies; 33+ messages in thread From: Stephen Smalley @ 2006-05-16 12:15 UTC (permalink / raw) To: selinux; +Cc: Thomas Bleher, Daniel J Walsh, SELinux-dev, James Morris On Mon, 2006-05-15 at 12:35 -0400, Stephen Smalley wrote: > # touch foo > # chcon -t foo_exec_t foo > # ls -Z foo > -rw-r--r-- root root system_u:object_r:unlabeled_t foo Note that an alternative would be to modify security_sid_to_context() to return the unmapped string representation if it exists rather than just falling through to the unlabeled SID's context. In that case, getxattr() would return the unmapped string, and userspace would see user_u:object_r:foo_exec_t throughout the example even though the kernel would internally be applying access checks based on the unlabeled SID's context. That seems useful for programs that want to check the attributes (e.g. restore), but prevents rpm from easily checking whether the attribute has been validated by a subsequent policy load (although it could use security_check_context(3) for that purpose). Likewise, if an audit message is generated for a SID that has been invalidated, having security_sid_to_context() return the unmapped string representation would preserve the original string label in the audit message rather than degenerating to the unlabeled SID's context. Thoughts? > # semodule -i foo.pp # defines foo_exec_t > # ls -Z foo > -rw-r--r-- root root user_u:object_r:foo_exec_t foo > # semodule -r foo > # ls -Z foo > -rw-r--r-- root root system_u:object_r:unlabeled_t foo > # semodule -i foo.pp > # ls -Z foo > -rw-r--r-- root root user_u:object_r:foo_exec_t foo > > Logically, there are two separate changes here. The first logical > change is to support deferred mapping of security contexts in the SID > table, storing their string representations when they cannot be mapped > under the current policy, and treating them the same as the unlabeled > SID while they are in this state. Upon policy reloads, if a valid > context becomes invalid under the new policy, rather than removing it > from the SID table, we convert it to its string representation under the > old policy and store that in the SID table until such a time as it > becomes valid again, and if an invalid context becomes valid, we map it > to its internal structure representation. This change alone is > worthwhile irrespective of the second change, as it addresses the > longstanding issue with removing and re-adding types to policy when they > are assigned to inodes. The second logical change introduces the > support for setting invalid contexts by privileged processes, both via > setxattr() and via /proc/self/attr/fscreate, which is the more > controversial aspect. Note that contrary to my earlier expectations, no > walking of the inode security structs is required, as the SIDs > themselves remain invariant under such changes. -- 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] 33+ messages in thread
* Re: [RFC][PATCH] selinux: introduce support for deferred mapping of inode security contexts 2006-05-15 16:35 [RFC][PATCH] selinux: introduce support for deferred mapping of inode security contexts Stephen Smalley 2006-05-15 17:41 ` Stephen Smalley 2006-05-16 12:15 ` Stephen Smalley @ 2006-05-17 7:54 ` Thomas Bleher 2006-05-17 17:52 ` Karl MacMillan 2006-05-17 18:26 ` Stephen Smalley 2006-05-19 13:44 ` Stephen Smalley 3 siblings, 2 replies; 33+ messages in thread From: Thomas Bleher @ 2006-05-17 7:54 UTC (permalink / raw) To: Stephen Smalley Cc: selinux, Daniel J Walsh, SELinux-dev, James Morris, Jeremy Katz, Paul Nasrat, James Antill [-- Attachment #1: Type: text/plain, Size: 2141 bytes --] [Added CCs from earlier thread] * Stephen Smalley <sds@tycho.nsa.gov> [2006-05-15 18:31]: > During the earlier thread on splitting policy into individual packages > (using policy modules), it was requested that SELinux provide a way for > a privileged process (like a package manager) to label an inode with a > not-yet-defined security context (treating it as having the unlabeled > SID until defined in the policy) and then automatically update the > in-memory state when a policy that defines the security context is > loaded such that the inode immediately becomes accessible under the > rules governing access to that context in the new policy. [...] > The second logical change introduces the > support for setting invalid contexts by privileged processes, both via > setxattr() and via /proc/self/attr/fscreate, which is the more > controversial aspect. I am still not convinced that we actually need this second change. In http://marc.theaimsgroup.com/?l=selinux&m=114677075207486&w=2, I outlined how rpm could work with the current kernel. I think this scheme is preferable to changing the kernel, mainly because of two points: * It makes it possible to later confine rpm more strictly: If you load policy before installing the package, you can use the policy server to prevent rpm from loading certain policies; rpm will only be able to put labels on disk it is allowed to by policy. If you load policy after package installation, rpm needs the labelpriv privilege, so you can't confine rpm in any meaningful sense. * It allows rpm to know beforehand if the policy module will actually apply on top of the current system policy (which is important if you think of the differences between strict and targeted policy). It is better to abort install before than to have invalid labels on disk later. As I didn't receive any response regarding my posting, I'd like to ask: What prevents you from implementing it in a way similar to what I described? RPM already has trigger scripts so from the outside it looks like it shouldn't be that hard to implement. Thomas [-- Attachment #2: Digital signature --] [-- Type: application/pgp-signature, Size: 191 bytes --] ^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [RFC][PATCH] selinux: introduce support for deferred mapping of inode security contexts 2006-05-17 7:54 ` Thomas Bleher @ 2006-05-17 17:52 ` Karl MacMillan 2006-05-17 19:01 ` Stephen Smalley 2006-05-18 18:14 ` Thomas Bleher 2006-05-17 18:26 ` Stephen Smalley 1 sibling, 2 replies; 33+ messages in thread From: Karl MacMillan @ 2006-05-17 17:52 UTC (permalink / raw) To: Thomas Bleher Cc: Stephen Smalley, selinux, Daniel J Walsh, SELinux-dev, James Morris, Jeremy Katz, Paul Nasrat, James Antill On Wed, 2006-05-17 at 09:54 +0200, Thomas Bleher wrote: > [Added CCs from earlier thread] > > * Stephen Smalley <sds@tycho.nsa.gov> [2006-05-15 18:31]: > > During the earlier thread on splitting policy into individual packages > > (using policy modules), it was requested that SELinux provide a way for > > a privileged process (like a package manager) to label an inode with a > > not-yet-defined security context (treating it as having the unlabeled > > SID until defined in the policy) and then automatically update the > > in-memory state when a policy that defines the security context is > > loaded such that the inode immediately becomes accessible under the > > rules governing access to that context in the new policy. > [...] > > The second logical change introduces the > > support for setting invalid contexts by privileged processes, both via > > setxattr() and via /proc/self/attr/fscreate, which is the more > > controversial aspect. > > I am still not convinced that we actually need this second change. > > In http://marc.theaimsgroup.com/?l=selinux&m=114677075207486&w=2, I > outlined how rpm could work with the current kernel. I think this scheme > is preferable to changing the kernel, mainly because of two points: > > * It makes it possible to later confine rpm more strictly: > If you load policy before installing the package, you can use the > policy server to prevent rpm from loading certain policies; rpm will > only be able to put labels on disk it is allowed to by policy. > If you load policy after package installation, rpm needs the labelpriv > privilege, so you can't confine rpm in any meaningful sense. > > * It allows rpm to know beforehand if the policy module will actually > apply on top of the current system policy (which is important if you > think of the differences between strict and targeted policy). It is > better to abort install before than to have invalid labels on disk > later. > > As I didn't receive any response regarding my posting, I'd like to ask: > What prevents you from implementing it in a way similar to what I > described? > RPM already has trigger scripts so from the outside it looks like it > shouldn't be that hard to implement. > To get some realtime discussion going on this issue a telecon was held with Red Hat, Tresys, and Steve participating. I'll try to summarize the problems with the approaches that you, Josh, and I were pushing that came out during that telecom. This is in the context of rpm, but I believe that the problems are more general. There are two basic ways to ensure that the policy needed by an rpm is installed before that rpm: use package dependencies to make certain that separate policy rpms are installed before rpms that require them or, as you suggest, collect and install all of the policies from all of the rpms at the start of the transaction. The first solution does not work because it is not possible to order rpm installation within a transaction based on dependencies because of mutual and circular dependencies. There is _no_ general solution to sorting packages so that dependencies are met at every step of the transaction in the face of circular or mutual dependencies. Basically, topological sorting only works for directed _acyclic_ graphs (see http://en.wikipedia.org/wiki/Topological_sorting). Instead, rpm makes a more general guarantee that the dependencies will be met at the end of the transaction, which is not sufficient for our needs. The second solution, which you describe, has two problems. As rpm works now there are many circumstances, like network installations, where a transaction begins without all of the rpms. Changing this would not only be difficult, it is not clear that it would be desirable. Even if all of the rpms were available, there are many potential problems when a policy upgrade depends on a library or tool upgrade (e.g., libsepol or semodule). This leads directly back to the dependency problems. This leads me to conclude that package managers may need to be able to set raw contexts that are not currently valid. It is not a pleasant trade-off, but it does have potential side benefits for backup and restore tools. Karl -- Karl MacMillan Tresys Technology www.tresys.com > Thomas > -- 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] 33+ messages in thread
* Re: [RFC][PATCH] selinux: introduce support for deferred mapping of inode security contexts 2006-05-17 17:52 ` Karl MacMillan @ 2006-05-17 19:01 ` Stephen Smalley 2006-05-18 18:14 ` Thomas Bleher 1 sibling, 0 replies; 33+ messages in thread From: Stephen Smalley @ 2006-05-17 19:01 UTC (permalink / raw) To: Karl MacMillan Cc: Thomas Bleher, selinux, Daniel J Walsh, SELinux-dev, James Morris, Jeremy Katz, Paul Nasrat, James Antill On Wed, 2006-05-17 at 13:52 -0400, Karl MacMillan wrote: > This leads me to conclude that package managers may need to be able to > set raw contexts that are not currently valid. It is not a pleasant > trade-off, but it does have potential side benefits for backup and > restore tools. I don't think it is useful for restore(8), as lgetxattr() will show it as unlabeled_t and compares will still fail. Per the earlier discussion on this thread. It might have some utility in creating filesystems for a system running a different policy than the build/host system. -- 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] 33+ messages in thread
* Re: [RFC][PATCH] selinux: introduce support for deferred mapping of inode security contexts 2006-05-17 17:52 ` Karl MacMillan 2006-05-17 19:01 ` Stephen Smalley @ 2006-05-18 18:14 ` Thomas Bleher 2006-05-19 12:59 ` Stephen Smalley 1 sibling, 1 reply; 33+ messages in thread From: Thomas Bleher @ 2006-05-18 18:14 UTC (permalink / raw) To: Karl MacMillan Cc: Stephen Smalley, selinux, Daniel J Walsh, SELinux-dev, James Morris, Jeremy Katz, Paul Nasrat, James Antill [-- Attachment #1: Type: text/plain, Size: 5436 bytes --] * Karl MacMillan <kmacmillan@tresys.com> [2006-05-17 19:55]: > On Wed, 2006-05-17 at 09:54 +0200, Thomas Bleher wrote: > > [Added CCs from earlier thread] > > > > * Stephen Smalley <sds@tycho.nsa.gov> [2006-05-15 18:31]: > > > During the earlier thread on splitting policy into individual packages > > > (using policy modules), it was requested that SELinux provide a way for > > > a privileged process (like a package manager) to label an inode with a > > > not-yet-defined security context (treating it as having the unlabeled > > > SID until defined in the policy) and then automatically update the > > > in-memory state when a policy that defines the security context is > > > loaded such that the inode immediately becomes accessible under the > > > rules governing access to that context in the new policy. > > [...] > > > The second logical change introduces the > > > support for setting invalid contexts by privileged processes, both via > > > setxattr() and via /proc/self/attr/fscreate, which is the more > > > controversial aspect. > > > > I am still not convinced that we actually need this second change. > > > > In http://marc.theaimsgroup.com/?l=selinux&m=114677075207486&w=2, I > > outlined how rpm could work with the current kernel. I think this scheme > > is preferable to changing the kernel, mainly because of two points: > > > > * It makes it possible to later confine rpm more strictly: > > If you load policy before installing the package, you can use the > > policy server to prevent rpm from loading certain policies; rpm will > > only be able to put labels on disk it is allowed to by policy. > > If you load policy after package installation, rpm needs the labelpriv > > privilege, so you can't confine rpm in any meaningful sense. > > > > * It allows rpm to know beforehand if the policy module will actually > > apply on top of the current system policy (which is important if you > > think of the differences between strict and targeted policy). It is > > better to abort install before than to have invalid labels on disk > > later. > > > > As I didn't receive any response regarding my posting, I'd like to ask: > > What prevents you from implementing it in a way similar to what I > > described? > > RPM already has trigger scripts so from the outside it looks like it > > shouldn't be that hard to implement. > > > > To get some realtime discussion going on this issue a telecon was held > with Red Hat, Tresys, and Steve participating. I'll try to summarize the > problems with the approaches that you, Josh, and I were pushing that > came out during that telecom. This is in the context of rpm, but I > believe that the problems are more general. > > There are two basic ways to ensure that the policy needed by an rpm is > installed before that rpm: use package dependencies to make certain that > separate policy rpms are installed before rpms that require them or, as > you suggest, collect and install all of the policies from all of the > rpms at the start of the transaction. > > The first solution does not work because it is not possible to order rpm > installation within a transaction based on dependencies because of > mutual and circular dependencies. There is _no_ general solution to > sorting packages so that dependencies are met at every step of the > transaction in the face of circular or mutual dependencies. Basically, > topological sorting only works for directed _acyclic_ graphs (see > http://en.wikipedia.org/wiki/Topological_sorting). Instead, rpm makes a > more general guarantee that the dependencies will be met at the end of > the transaction, which is not sufficient for our needs. > > The second solution, which you describe, has two problems. As rpm works > now there are many circumstances, like network installations, where a > transaction begins without all of the rpms. Changing this would not only > be difficult, it is not clear that it would be desirable. > > Even if all of the rpms were available, there are many potential > problems when a policy upgrade depends on a library or tool upgrade > (e.g., libsepol or semodule). This leads directly back to the dependency > problems. > > This leads me to conclude that package managers may need to be able to > set raw contexts that are not currently valid. It is not a pleasant > trade-off, but it does have potential side benefits for backup and > restore tools. Thank you for your explanation. I see that these are very difficult issues, but I must admit that I still feel very uneasy about the proposed changes. So let me suggest one more possibility: rpm installs the package, puts the labels on disk and afterwards installs the policy (like Dan proposed originally). EXCEPT: Whenever rpm finds that the label it wants to put on disk is not valid in the current policy, it labels the file as unlabeled_t (or some other special label). After rpm has installed the policy, it relabels the guilty files. This adds no overhead - rpm already knows the paths and the labels, and it would have had to visit the files anyway to verify their labels -, looks exactly the same from the outside, doesn't require kernel changes and makes it possible to later restrict rpm. Now, you can't decline such an offer, can you? ;-) Or am I missing something fundamental here? Thomas [-- Attachment #2: Digital signature --] [-- Type: application/pgp-signature, Size: 191 bytes --] ^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [RFC][PATCH] selinux: introduce support for deferred mapping of inode security contexts 2006-05-18 18:14 ` Thomas Bleher @ 2006-05-19 12:59 ` Stephen Smalley 2006-05-19 13:18 ` Joshua Brindle 2006-05-19 13:18 ` Karl MacMillan 0 siblings, 2 replies; 33+ messages in thread From: Stephen Smalley @ 2006-05-19 12:59 UTC (permalink / raw) To: Thomas Bleher Cc: Karl MacMillan, selinux, Daniel J Walsh, SELinux-dev, James Morris, Jeremy Katz, Paul Nasrat, James Antill On Thu, 2006-05-18 at 20:14 +0200, Thomas Bleher wrote: > Thank you for your explanation. > I see that these are very difficult issues, but I must admit that I > still feel very uneasy about the proposed changes. > > So let me suggest one more possibility: > rpm installs the package, puts the labels on disk and afterwards > installs the policy (like Dan proposed originally). > EXCEPT: Whenever rpm finds that the label it wants to put on disk is not > valid in the current policy, it labels the file as unlabeled_t (or some > other special label). After rpm has installed the policy, it relabels > the guilty files. This adds no overhead - rpm already knows the paths and > the labels, and it would have had to visit the files anyway to verify > their labels -, looks exactly the same from the outside, doesn't require > kernel changes and makes it possible to later restrict rpm. > > Now, you can't decline such an offer, can you? ;-) > > Or am I missing something fundamental here? In the labelpriv model, rpm doesn't have to visit the individual files afterward in the common case; it just calls security_check_context(3) on each distinct context stored in the rpm header (once per context, not per file) after the module insertion phase, and if any of them are still invalid (the uncommon case), rpm then takes corrective action (whether that means relabeling files that had those invalid labels to truly be unlabeled_t, removing those files, or reverting the install altogether - the latter seems cleanest to me). If we can't get a guarantee that rpm will perform such checking and take corrective action, then I'd agree that the kernel change is a no-go. With regard to restricting rpm, under both models, rpm is being allowed to set down unlabeled_t files and to insert policy modules. Restricting rpm meaningfully under either model requires fine-grained mediation of what those policy modules may contain, which requires the use of the policy management server as the libsemanage back end to enforce such mediation. Restricting rpm meaningfully under either model also requires decomposition of rpm, so that not all of rpm has to run with the same rights and the core rpm processing can run with different rights depending on the package characteristics. Given such mediation and decomposition, having a small rpm helper in its own domain that verifies that the header contexts are valid after module insertion, taking corrective action if necessary, would address the linkage between the header contexts and the module contents. -- 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] 33+ messages in thread
* Re: [RFC][PATCH] selinux: introduce support for deferred mapping of inode security contexts 2006-05-19 12:59 ` Stephen Smalley @ 2006-05-19 13:18 ` Joshua Brindle 2006-05-19 13:18 ` Karl MacMillan 1 sibling, 0 replies; 33+ messages in thread From: Joshua Brindle @ 2006-05-19 13:18 UTC (permalink / raw) To: Stephen Smalley Cc: Thomas Bleher, Karl MacMillan, selinux, Daniel J Walsh, SELinux-dev, James Morris, Jeremy Katz, Paul Nasrat, James Antill Stephen Smalley wrote: > On Thu, 2006-05-18 at 20:14 +0200, Thomas Bleher wrote: > >> Thank you for your explanation. >> I see that these are very difficult issues, but I must admit that I >> still feel very uneasy about the proposed changes. >> >> So let me suggest one more possibility: >> rpm installs the package, puts the labels on disk and afterwards >> installs the policy (like Dan proposed originally). >> EXCEPT: Whenever rpm finds that the label it wants to put on disk is not >> valid in the current policy, it labels the file as unlabeled_t (or some >> other special label). After rpm has installed the policy, it relabels >> the guilty files. This adds no overhead - rpm already knows the paths and >> the labels, and it would have had to visit the files anyway to verify >> their labels -, looks exactly the same from the outside, doesn't require >> kernel changes and makes it possible to later restrict rpm. >> >> Now, you can't decline such an offer, can you? ;-) >> >> Or am I missing something fundamental here? >> > In the labelpriv model, rpm doesn't have to visit the individual files > afterward in the common case; it just calls security_check_context(3) on > each distinct context stored in the rpm header (once per context, not > per file) after the module insertion phase, and if any of them are still > invalid (the uncommon case), rpm then takes corrective action (whether > that means relabeling files that had those invalid labels to truly be > unlabeled_t, removing those files, or reverting the install altogether - > the latter seems cleanest to me). If we can't get a guarantee that rpm > will perform such checking and take corrective action, then I'd agree > that the kernel change is a no-go. > Or just use matchpathcon() to label it. The installed file contexts are implicitly trusted anyway, I don't see how it could hurt to revert to defaults. Then again, an unlabeled file after the reload could indicate an error in the package, policy, etc. On this note, how do you expect this helper to work? I don't think that rpm maintains a list of files per-transaction and since the post-script order can't be guaranteed you never know when a particular policy has been reloaded (mutual dependency problem, mta policy declares sendmail_t but sendmail package puts down the file). There are probably other cases where this is problematic. > With regard to restricting rpm, under both models, rpm is being allowed > to set down unlabeled_t files and to insert policy modules. Restricting > rpm meaningfully under either model requires fine-grained mediation of > what those policy modules may contain, which requires the use of the > policy management server as the libsemanage back end to enforce such > mediation. Restricting rpm meaningfully under either model also > requires decomposition of rpm, so that not all of rpm has to run with > the same rights and the core rpm processing can run with different > rights depending on the package characteristics. Given such mediation > and decomposition, having a small rpm helper in its own domain that > verifies that the header contexts are valid after module insertion, > taking corrective action if necessary, would address the linkage between > the header contexts and the module contents. > Right, unfortunately it looks like rpm will have this capability long before the policy management server is ready to be dropped in. We also haven't solved the hierarchal -policy-in-refpolicy problem which is necessary for any meaningful policy enforcement. -- 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] 33+ messages in thread
* Re: [RFC][PATCH] selinux: introduce support for deferred mapping of inode security contexts 2006-05-19 12:59 ` Stephen Smalley 2006-05-19 13:18 ` Joshua Brindle @ 2006-05-19 13:18 ` Karl MacMillan 2006-05-23 17:15 ` Stephen Smalley 1 sibling, 1 reply; 33+ messages in thread From: Karl MacMillan @ 2006-05-19 13:18 UTC (permalink / raw) To: Stephen Smalley Cc: Thomas Bleher, selinux, Daniel J Walsh, SELinux-dev, James Morris, Jeremy Katz, Paul Nasrat, James Antill On Fri, 2006-05-19 at 08:59 -0400, Stephen Smalley wrote: > On Thu, 2006-05-18 at 20:14 +0200, Thomas Bleher wrote: > > Thank you for your explanation. > > I see that these are very difficult issues, but I must admit that I > > still feel very uneasy about the proposed changes. > > > > So let me suggest one more possibility: > > rpm installs the package, puts the labels on disk and afterwards > > installs the policy (like Dan proposed originally). > > EXCEPT: Whenever rpm finds that the label it wants to put on disk is not > > valid in the current policy, it labels the file as unlabeled_t (or some > > other special label). After rpm has installed the policy, it relabels > > the guilty files. This adds no overhead - rpm already knows the paths and > > the labels, and it would have had to visit the files anyway to verify > > their labels -, looks exactly the same from the outside, doesn't require > > kernel changes and makes it possible to later restrict rpm. > > > > Now, you can't decline such an offer, can you? ;-) > > > > Or am I missing something fundamental here? > > In the labelpriv model, rpm doesn't have to visit the individual files > afterward in the common case; it just calls security_check_context(3) on > each distinct context stored in the rpm header (once per context, not > per file) after the module insertion phase, and if any of them are still > invalid (the uncommon case), rpm then takes corrective action (whether > that means relabeling files that had those invalid labels to truly be > unlabeled_t, removing those files, or reverting the install altogether - > the latter seems cleanest to me). If we can't get a guarantee that rpm > will perform such checking and take corrective action, then I'd agree > that the kernel change is a no-go. > The question is when the labels will become valid. Thinking through this more I realized that if we cannot guarantee ordering within a transaction we cannot commit any policy modules until the end of the transaction. Otherwise it will not be possible to have _any_ dependencies between policy modules, which doesn't seem likely based on my recent investigations into refpolicy dependencies. If policy modules are only committed at the end of the transaction, verification of the rpms will require going back through the headers of every rpm in the transaction. Dan, Jeremy, Paul, any thoughts about when the policy modules will be committed? Karl -- Karl MacMillan Tresys Technology www.tresys.com > With regard to restricting rpm, under both models, rpm is being allowed > to set down unlabeled_t files and to insert policy modules. Restricting > rpm meaningfully under either model requires fine-grained mediation of > what those policy modules may contain, which requires the use of the > policy management server as the libsemanage back end to enforce such > mediation. Restricting rpm meaningfully under either model also > requires decomposition of rpm, so that not all of rpm has to run with > the same rights and the core rpm processing can run with different > rights depending on the package characteristics. Given such mediation > and decomposition, having a small rpm helper in its own domain that > verifies that the header contexts are valid after module insertion, > taking corrective action if necessary, would address the linkage between > the header contexts and the module contents. > -- 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] 33+ messages in thread
* Re: [RFC][PATCH] selinux: introduce support for deferred mapping of inode security contexts 2006-05-19 13:18 ` Karl MacMillan @ 2006-05-23 17:15 ` Stephen Smalley 2006-05-23 18:23 ` Daniel J Walsh 2006-05-24 17:24 ` Jeremy Katz 0 siblings, 2 replies; 33+ messages in thread From: Stephen Smalley @ 2006-05-23 17:15 UTC (permalink / raw) To: Karl MacMillan Cc: Thomas Bleher, selinux, Daniel J Walsh, SELinux-dev, James Morris, Jeremy Katz, Paul Nasrat, James Antill On Fri, 2006-05-19 at 09:18 -0400, Karl MacMillan wrote: > On Fri, 2006-05-19 at 08:59 -0400, Stephen Smalley wrote: > > In the labelpriv model, rpm doesn't have to visit the individual files > > afterward in the common case; it just calls security_check_context(3) on > > each distinct context stored in the rpm header (once per context, not > > per file) after the module insertion phase, and if any of them are still > > invalid (the uncommon case), rpm then takes corrective action (whether > > that means relabeling files that had those invalid labels to truly be > > unlabeled_t, removing those files, or reverting the install altogether - > > the latter seems cleanest to me). If we can't get a guarantee that rpm > > will perform such checking and take corrective action, then I'd agree > > that the kernel change is a no-go. > > > > The question is when the labels will become valid. > > Thinking through this more I realized that if we cannot guarantee > ordering within a transaction we cannot commit any policy modules until > the end of the transaction. Otherwise it will not be possible to have > _any_ dependencies between policy modules, which doesn't seem likely > based on my recent investigations into refpolicy dependencies. > > If policy modules are only committed at the end of the transaction, > verification of the rpms will require going back through the headers of > every rpm in the transaction. > > Dan, Jeremy, Paul, any thoughts about when the policy modules will be > committed? Below is an updated version of the kernel patch to support rpm labeling of files before policy load, with a couple of bug fixes and a re-base to 2.6.17-rc4-mm3. Note that before we can upstream this, we need to resolve the issues of how rpm will check file label validity after policy load (e.g. calling security_check_context(3) on each label from the header), what corrective action rpm will take if a file label is invalid (options suggested include relabeling to unlabeled_t, relabeling to the context returned by the system policy via matchpathcon, or reverting the install), and the issues raised by Karl above (as they also affect the ability of rpm to perform such verification and correction sanely). ---<snip>--- Introduce support for deferring 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 'labelpriv' permission to the 'security' class 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 | 16 +- security/selinux/include/av_perm_to_string.h | 1 security/selinux/include/av_permissions.h | 1 security/selinux/include/objsec.h | 3 security/selinux/include/security.h | 2 security/selinux/selinuxfs.c | 4 security/selinux/ss/context.h | 17 ++ security/selinux/ss/mls.c | 11 - security/selinux/ss/mls.h | 3 security/selinux/ss/services.c | 213 +++++++++++++++++---------- security/selinux/ss/sidtab.c | 4 11 files changed, 189 insertions(+), 86 deletions(-) diff -X /home/sds/dontdiff -rup linux-2.6.17-rc4-mm3/security/selinux/hooks.c linux-2.6.17-rc4-mm3-x/security/selinux/hooks.c --- linux-2.6.17-rc4-mm3/security/selinux/hooks.c 2006-05-22 09:09:46.000000000 -0400 +++ linux-2.6.17-rc4-mm3-x/security/selinux/hooks.c 2006-05-23 08:57:55.000000000 -0400 @@ -2165,6 +2165,11 @@ static int selinux_inode_setxattr(struct return rc; rc = security_context_to_sid(value, size, &newsid); + if (rc == -EINVAL) { + if (task_has_security(current, SECURITY__LABELPRIV)) + return rc; + rc = security_context_to_sid_force(value, size, &newsid); + } if (rc) return rc; @@ -2198,10 +2203,11 @@ static void selinux_inode_post_setxattr( 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", __FUNCTION__, (char*)value, -rc); + "%s on (%s, %lu), rc=%d\n", __FUNCTION__, (char*)value, + inode->i_sb->s_id, inode->i_ino, -rc); return; } @@ -4186,6 +4192,12 @@ static int selinux_setprocattr(struct ta size--; } error = security_context_to_sid(value, size, &sid); + if (error == -EINVAL && !strcmp(name, "fscreate")) { + if (task_has_security(current, SECURITY__LABELPRIV)) + return error; + error = security_context_to_sid_force(value, size, + &sid); + } if (error) return error; } diff -X /home/sds/dontdiff -rup linux-2.6.17-rc4-mm3/security/selinux/include/av_permissions.h linux-2.6.17-rc4-mm3-x/security/selinux/include/av_permissions.h --- linux-2.6.17-rc4-mm3/security/selinux/include/av_permissions.h 2006-05-22 09:09:46.000000000 -0400 +++ linux-2.6.17-rc4-mm3-x/security/selinux/include/av_permissions.h 2006-05-23 08:57:55.000000000 -0400 @@ -526,6 +526,7 @@ #define SECURITY__SETBOOL 0x00000100UL #define SECURITY__SETSECPARAM 0x00000200UL #define SECURITY__SETCHECKREQPROT 0x00000400UL +#define SECURITY__LABELPRIV 0x00000800UL #define SYSTEM__IPC_INFO 0x00000001UL #define SYSTEM__SYSLOG_READ 0x00000002UL diff -X /home/sds/dontdiff -rup linux-2.6.17-rc4-mm3/security/selinux/include/av_perm_to_string.h linux-2.6.17-rc4-mm3-x/security/selinux/include/av_perm_to_string.h --- linux-2.6.17-rc4-mm3/security/selinux/include/av_perm_to_string.h 2006-05-22 09:09:46.000000000 -0400 +++ linux-2.6.17-rc4-mm3-x/security/selinux/include/av_perm_to_string.h 2006-05-23 08:57:55.000000000 -0400 @@ -87,6 +87,7 @@ S_(SECCLASS_SECURITY, SECURITY__SETBOOL, "setbool") S_(SECCLASS_SECURITY, SECURITY__SETSECPARAM, "setsecparam") S_(SECCLASS_SECURITY, SECURITY__SETCHECKREQPROT, "setcheckreqprot") + S_(SECCLASS_SECURITY, SECURITY__LABELPRIV, "labelpriv") S_(SECCLASS_SYSTEM, SYSTEM__IPC_INFO, "ipc_info") S_(SECCLASS_SYSTEM, SYSTEM__SYSLOG_READ, "syslog_read") S_(SECCLASS_SYSTEM, SYSTEM__SYSLOG_MOD, "syslog_mod") diff -X /home/sds/dontdiff -rup linux-2.6.17-rc4-mm3/security/selinux/include/objsec.h linux-2.6.17-rc4-mm3-x/security/selinux/include/objsec.h --- linux-2.6.17-rc4-mm3/security/selinux/include/objsec.h 2006-03-20 00:53:29.000000000 -0500 +++ linux-2.6.17-rc4-mm3-x/security/selinux/include/objsec.h 2006-05-23 08:57:55.000000000 -0400 @@ -101,4 +101,7 @@ struct sk_security_struct { extern unsigned int selinux_checkreqprot; +extern int task_has_security(struct task_struct *tsk, + u32 perms); + #endif /* _SELINUX_OBJSEC_H_ */ diff -X /home/sds/dontdiff -rup linux-2.6.17-rc4-mm3/security/selinux/include/security.h linux-2.6.17-rc4-mm3-x/security/selinux/include/security.h --- linux-2.6.17-rc4-mm3/security/selinux/include/security.h 2006-05-22 09:09:22.000000000 -0400 +++ linux-2.6.17-rc4-mm3-x/security/selinux/include/security.h 2006-05-23 08:57:55.000000000 -0400 @@ -63,6 +63,8 @@ int security_context_to_sid(char *sconte int security_context_to_sid_default(char *scontext, u32 scontext_len, u32 *out_sid, u32 def_sid); +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 -X /home/sds/dontdiff -rup linux-2.6.17-rc4-mm3/security/selinux/selinuxfs.c linux-2.6.17-rc4-mm3-x/security/selinux/selinuxfs.c --- linux-2.6.17-rc4-mm3/security/selinux/selinuxfs.c 2006-05-22 09:09:46.000000000 -0400 +++ linux-2.6.17-rc4-mm3-x/security/selinux/selinuxfs.c 2006-05-23 08:57:55.000000000 -0400 @@ -71,8 +71,8 @@ static int *bool_pending_values = NULL; extern void selnl_notify_setenforce(int val); /* Check whether a task is allowed to use a security operation. */ -static int task_has_security(struct task_struct *tsk, - u32 perms) +int task_has_security(struct task_struct *tsk, + u32 perms) { struct task_security_struct *tsec; diff -X /home/sds/dontdiff -rup linux-2.6.17-rc4-mm3/security/selinux/ss/context.h linux-2.6.17-rc4-mm3-x/security/selinux/ss/context.h --- linux-2.6.17-rc4-mm3/security/selinux/ss/context.h 2006-03-20 00:53:29.000000000 -0500 +++ linux-2.6.17-rc4-mm3-x/security/selinux/ss/context.h 2006-05-23 12:16:28.000000000 -0400 @@ -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, including NUL byte. */ }; static inline void mls_context_init(struct context *c) @@ -83,6 +85,14 @@ static inline void context_init(struct c static inline int context_cpy(struct context *dst, struct context *src) { + context_init(dst); + if (src->len) { + dst->str = kstrdup(src->str, GFP_ATOMIC); + if (!dst->str) + return -ENOMEM; + dst->len = src->len; + return 0; + } dst->user = src->user; dst->role = src->role; dst->type = src->type; @@ -91,12 +101,17 @@ static inline int context_cpy(struct con static inline void context_destroy(struct context *c) { - c->user = c->role = c->type = 0; + kfree(c->str); mls_context_destroy(c); + context_init(c); } static inline int context_cmp(struct context *c1, struct context *c2) { + if (c1->len && c2->len) + return (c1->len == c2->len && !memcmp(c1->str, c2->str, c1->len)); + if (c1->len || c2->len) + return 0; return ((c1->user == c2->user) && (c1->role == c2->role) && (c1->type == c2->type) && diff -X /home/sds/dontdiff -rup linux-2.6.17-rc4-mm3/security/selinux/ss/mls.c linux-2.6.17-rc4-mm3-x/security/selinux/ss/mls.c --- linux-2.6.17-rc4-mm3/security/selinux/ss/mls.c 2006-05-22 09:09:22.000000000 -0400 +++ linux-2.6.17-rc4-mm3-x/security/selinux/ss/mls.c 2006-05-23 08:57:55.000000000 -0400 @@ -249,7 +249,8 @@ static inline int mls_copy_context(struc * 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, @@ -296,7 +297,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; @@ -320,7 +321,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; @@ -336,7 +337,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; @@ -404,7 +405,7 @@ int mls_from_string(char *str, struct co 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 -X /home/sds/dontdiff -rup linux-2.6.17-rc4-mm3/security/selinux/ss/mls.h linux-2.6.17-rc4-mm3-x/security/selinux/ss/mls.h --- linux-2.6.17-rc4-mm3/security/selinux/ss/mls.h 2006-05-22 09:09:22.000000000 -0400 +++ linux-2.6.17-rc4-mm3-x/security/selinux/ss/mls.h 2006-05-23 08:57:55.000000000 -0400 @@ -21,7 +21,8 @@ int mls_compute_context_len(struct conte void mls_sid_to_context(struct context *context, char **scontext); int mls_context_isvalid(struct policydb *p, struct context *c); -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 -X /home/sds/dontdiff -rup linux-2.6.17-rc4-mm3/security/selinux/ss/services.c linux-2.6.17-rc4-mm3-x/security/selinux/ss/services.c --- linux-2.6.17-rc4-mm3/security/selinux/ss/services.c 2006-05-22 09:09:46.000000000 -0400 +++ linux-2.6.17-rc4-mm3-x/security/selinux/ss/services.c 2006-05-23 12:17:26.000000000 -0400 @@ -623,48 +623,31 @@ out: } -static int security_context_to_sid_core(char *scontext, u32 scontext_len, u32 *sid, u32 def_sid) +static int string_to_context_struct(struct policydb *pol, + struct sidtab *sidtabp, + char *scontext, + u32 scontext_len, + struct context *ctx, + u32 def_sid) { - 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; - - 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; + context_init(ctx); - /* 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. */ - scontext2 = kmalloc(scontext_len+1,GFP_KERNEL); + /* Copy the string so that we can modify the copy as we parse it. */ + scontext2 = kmalloc(scontext_len+1, GFP_ATOMIC); if (!scontext2) { rc = -ENOMEM; - goto out; + goto err; } memcpy(scontext2, scontext, scontext_len); scontext2[scontext_len] = 0; - context_init(&context); - *sid = SECSID_NULL; - - POLICY_RDLOCK; - /* Parse the security context. */ rc = -EINVAL; @@ -676,15 +659,15 @@ static int security_context_to_sid_core( p++; if (*p == 0) - goto out_unlock; + goto err; *p++ = 0; - usrdatum = hashtab_search(policydb.p_users.table, scontextp); + usrdatum = hashtab_search(pol->p_users.table, scontextp); if (!usrdatum) - goto out_unlock; + goto err; - context.user = usrdatum->value; + ctx->user = usrdatum->value; /* Extract role. */ scontextp = p; @@ -692,14 +675,14 @@ static int security_context_to_sid_core( p++; if (*p == 0) - goto out_unlock; + goto err; *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 err; + ctx->role = role->value; /* Extract type. */ scontextp = p; @@ -708,32 +691,74 @@ static int security_context_to_sid_core( 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 err; - 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 err; - if ((p - scontext2) < scontext_len) { - rc = -EINVAL; - goto out_unlock; - } + rc = -EINVAL; + if ((p - scontext2) < scontext_len) + goto err; /* Check the validity of the new context. */ - if (!policydb_context_isvalid(&policydb, &context)) { - rc = -EINVAL; - goto out_unlock; + if (!policydb_context_isvalid(pol, ctx)) + goto err; + + rc = 0; +out: + kfree(scontext2); + return rc; +err: + context_destroy(ctx); + goto out; +} + +static int security_context_to_sid_core(char *scontext, u32 scontext_len, u32 *sid, u32 def_sid, 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; } - /* Obtain the new sid. */ + *sid = SECSID_NULL; + + POLICY_RDLOCK; + rc = string_to_context_struct(&policydb, &sidtab, + scontext, scontext_len, + &context, def_sid); + if (rc == -EINVAL && force && scontext_len) { + context_init(&context); + context.len = scontext_len; + if (scontext[scontext_len-1]) + context.len++; /* extend for NUL. */ + context.str = kmalloc(context.len, GFP_ATOMIC); + if (!context.str) { + rc = -ENOMEM; + goto out_unlock; + } + memcpy(context.str, scontext, scontext_len); + context.str[context.len-1] = 0; + } else if (rc) + goto out_unlock; rc = sidtab_context_to_sid(&sidtab, &context, sid); + context_destroy(&context); out_unlock: POLICY_RDUNLOCK; - context_destroy(&context); - kfree(scontext2); out: return rc; } @@ -752,7 +777,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); + sid, SECSID_NULL, 0); } /** @@ -769,13 +794,21 @@ int security_context_to_sid(char *sconte * 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). + * Adds the string representation if the context cannot be mapped under + * current policy. * Returns -%EINVAL if the context is invalid, -%ENOMEM if insufficient * memory is available, or 0 on success. */ int security_context_to_sid_default(char *scontext, u32 scontext_len, u32 *sid, u32 def_sid) { return security_context_to_sid_core(scontext, scontext_len, - sid, def_sid); + sid, def_sid, 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, 1); } static int compute_sid_handle_invalid_context( @@ -1112,9 +1145,10 @@ static inline int convert_context_handle char *s; u32 len; - context_struct_to_string(context, &s, &len); - printk(KERN_ERR "security: 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; } @@ -1146,6 +1180,27 @@ 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); + if (!rc) { + printk(KERN_INFO "SELinux: Context %s became valid under new policy.\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: Failed trying to map context %s (rc %d) under new policy, leaving unmapped.\n", c->str, -rc); + goto out; + } + } + rc = context_cpy(&oldc, c); if (rc) goto out; @@ -1155,46 +1210,48 @@ static int convert_context(u32 key, /* Convert the user. */ usrdatum = hashtab_search(args->newp->p_users.table, args->oldp->p_user_val_to_name[c->user - 1]); - if (!usrdatum) { - goto bad; - } + if (!usrdatum) + goto map; c->user = usrdatum->value; /* Convert the role. */ role = hashtab_search(args->newp->p_roles.table, args->oldp->p_role_val_to_name[c->role - 1]); - if (!role) { - goto bad; - } + if (!role) + goto map; c->role = role->value; /* Convert the type. */ typdatum = hashtab_search(args->newp->p_types.table, args->oldp->p_type_val_to_name[c->type - 1]); - if (!typdatum) { - goto bad; - } + if (!typdatum) + goto map; c->type = typdatum->value; rc = mls_convert_context(args->oldp, args->newp, c); if (rc) - goto bad; + goto map; /* Check the validity of the new context. */ if (!policydb_context_isvalid(args->newp, c)) { rc = convert_context_handle_invalid_context(&oldc); if (rc) - goto bad; + goto map; } context_destroy(&oldc); out: return rc; -bad: - context_struct_to_string(&oldc, &s, &len); +map: + /* Map old representation to string and save it. */ + if (context_struct_to_string(&oldc, &s, &len)) + return -ENOMEM; context_destroy(&oldc); - printk(KERN_ERR "security: invalidating context %s\n", s); - kfree(s); + context_destroy(c); + c->str = s; + c->len = len; + printk(KERN_INFO "SELinux: Context %s became invalid under new policy.\n", c->str); + rc = 0; goto out; } @@ -1253,7 +1310,11 @@ int security_load_policy(void *data, siz return -EINVAL; } - sidtab_init(&newsidtab); + if (sidtab_init(&newsidtab)) { + LOAD_UNLOCK; + policydb_destroy(&newpolicydb); + return -ENOMEM; + } /* Verify that the existing classes did not change. */ if (hashtab_map(policydb.p_classes.table, validate_class, &newpolicydb)) { @@ -1271,10 +1332,12 @@ int security_load_policy(void *data, siz } /* Convert the internal representations of contexts - in the new SID table and remove invalid SIDs. */ + 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); @@ -1524,6 +1587,8 @@ int security_get_user_sids(u32 fromsid, POLICY_RDLOCK; + context_init(&usercon); + fromcon = sidtab_search(&sidtab, fromsid); if (!fromcon) { rc = -EINVAL; diff -X /home/sds/dontdiff -rup linux-2.6.17-rc4-mm3/security/selinux/ss/sidtab.c linux-2.6.17-rc4-mm3-x/security/selinux/ss/sidtab.c --- linux-2.6.17-rc4-mm3/security/selinux/ss/sidtab.c 2006-03-20 00:53:29.000000000 -0500 +++ linux-2.6.17-rc4-mm3-x/security/selinux/ss/sidtab.c 2006-05-23 08:57:55.000000000 -0400 @@ -100,7 +100,7 @@ struct context *sidtab_search(struct 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); @@ -218,6 +218,8 @@ int sidtab_context_to_sid(struct sidtab goto unlock_out; } sid = s->next_sid++; + if (context->len) + printk(KERN_INFO "SELinux: Context %s is not valid under current policy, adding as unmapped value.\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 [flat|nested] 33+ messages in thread
* Re: [RFC][PATCH] selinux: introduce support for deferred mapping of inode security contexts 2006-05-23 17:15 ` Stephen Smalley @ 2006-05-23 18:23 ` Daniel J Walsh 2006-05-23 18:50 ` Stephen Smalley 2006-05-24 17:24 ` Jeremy Katz 1 sibling, 1 reply; 33+ messages in thread From: Daniel J Walsh @ 2006-05-23 18:23 UTC (permalink / raw) To: Stephen Smalley Cc: Karl MacMillan, Thomas Bleher, selinux, SELinux-dev, James Morris, Jeremy Katz, Paul Nasrat, James Antill Stephen Smalley wrote: > On Fri, 2006-05-19 at 09:18 -0400, Karl MacMillan wrote: > >> On Fri, 2006-05-19 at 08:59 -0400, Stephen Smalley wrote: >> >>> In the labelpriv model, rpm doesn't have to visit the individual files >>> afterward in the common case; it just calls security_check_context(3) on >>> each distinct context stored in the rpm header (once per context, not >>> per file) after the module insertion phase, and if any of them are still >>> invalid (the uncommon case), rpm then takes corrective action (whether >>> that means relabeling files that had those invalid labels to truly be >>> unlabeled_t, removing those files, or reverting the install altogether - >>> the latter seems cleanest to me). If we can't get a guarantee that rpm >>> will perform such checking and take corrective action, then I'd agree >>> that the kernel change is a no-go. >>> >>> >> The question is when the labels will become valid. >> >> Thinking through this more I realized that if we cannot guarantee >> ordering within a transaction we cannot commit any policy modules until >> the end of the transaction. Otherwise it will not be possible to have >> _any_ dependencies between policy modules, which doesn't seem likely >> based on my recent investigations into refpolicy dependencies. >> >> If policy modules are only committed at the end of the transaction, >> verification of the rpms will require going back through the headers of >> every rpm in the transaction. >> >> Dan, Jeremy, Paul, any thoughts about when the policy modules will be >> committed? >> > > Below is an updated version of the kernel patch to support rpm labeling > of files before policy load, with a couple of bug fixes and a re-base to > 2.6.17-rc4-mm3. Note that before we can upstream this, we need to > resolve the issues of how rpm will check file label validity after > policy load (e.g. calling security_check_context(3) on each label from > the header), what corrective action rpm will take if a file label is > invalid (options suggested include relabeling to unlabeled_t, relabeling > to the context returned by the system policy via matchpathcon, or > reverting the install), and the issues raised by Karl above (as they > also affect the ability of rpm to perform such verification and > correction sanely). > > As far as I understand it, rpm will not go back and check the whether the context are sane. If the postinstall of policy fails, the context on disk will be incorrect and treated like unlabeled_t. Jeremy and Paul is that your understanding? Dan > ---<snip>--- > > Introduce support for deferring 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 'labelpriv' permission to the 'security' class 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 | 16 +- > security/selinux/include/av_perm_to_string.h | 1 > security/selinux/include/av_permissions.h | 1 > security/selinux/include/objsec.h | 3 > security/selinux/include/security.h | 2 > security/selinux/selinuxfs.c | 4 > security/selinux/ss/context.h | 17 ++ > security/selinux/ss/mls.c | 11 - > security/selinux/ss/mls.h | 3 > security/selinux/ss/services.c | 213 +++++++++++++++++---------- > security/selinux/ss/sidtab.c | 4 > 11 files changed, 189 insertions(+), 86 deletions(-) > > diff -X /home/sds/dontdiff -rup linux-2.6.17-rc4-mm3/security/selinux/hooks.c linux-2.6.17-rc4-mm3-x/security/selinux/hooks.c > --- linux-2.6.17-rc4-mm3/security/selinux/hooks.c 2006-05-22 09:09:46.000000000 -0400 > +++ linux-2.6.17-rc4-mm3-x/security/selinux/hooks.c 2006-05-23 08:57:55.000000000 -0400 > @@ -2165,6 +2165,11 @@ static int selinux_inode_setxattr(struct > return rc; > > rc = security_context_to_sid(value, size, &newsid); > + if (rc == -EINVAL) { > + if (task_has_security(current, SECURITY__LABELPRIV)) > + return rc; > + rc = security_context_to_sid_force(value, size, &newsid); > + } > if (rc) > return rc; > > @@ -2198,10 +2203,11 @@ static void selinux_inode_post_setxattr( > 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", __FUNCTION__, (char*)value, -rc); > + "%s on (%s, %lu), rc=%d\n", __FUNCTION__, (char*)value, > + inode->i_sb->s_id, inode->i_ino, -rc); > return; > } > > @@ -4186,6 +4192,12 @@ static int selinux_setprocattr(struct ta > size--; > } > error = security_context_to_sid(value, size, &sid); > + if (error == -EINVAL && !strcmp(name, "fscreate")) { > + if (task_has_security(current, SECURITY__LABELPRIV)) > + return error; > + error = security_context_to_sid_force(value, size, > + &sid); > + } > if (error) > return error; > } > diff -X /home/sds/dontdiff -rup linux-2.6.17-rc4-mm3/security/selinux/include/av_permissions.h linux-2.6.17-rc4-mm3-x/security/selinux/include/av_permissions.h > --- linux-2.6.17-rc4-mm3/security/selinux/include/av_permissions.h 2006-05-22 09:09:46.000000000 -0400 > +++ linux-2.6.17-rc4-mm3-x/security/selinux/include/av_permissions.h 2006-05-23 08:57:55.000000000 -0400 > @@ -526,6 +526,7 @@ > #define SECURITY__SETBOOL 0x00000100UL > #define SECURITY__SETSECPARAM 0x00000200UL > #define SECURITY__SETCHECKREQPROT 0x00000400UL > +#define SECURITY__LABELPRIV 0x00000800UL > > #define SYSTEM__IPC_INFO 0x00000001UL > #define SYSTEM__SYSLOG_READ 0x00000002UL > diff -X /home/sds/dontdiff -rup linux-2.6.17-rc4-mm3/security/selinux/include/av_perm_to_string.h linux-2.6.17-rc4-mm3-x/security/selinux/include/av_perm_to_string.h > --- linux-2.6.17-rc4-mm3/security/selinux/include/av_perm_to_string.h 2006-05-22 09:09:46.000000000 -0400 > +++ linux-2.6.17-rc4-mm3-x/security/selinux/include/av_perm_to_string.h 2006-05-23 08:57:55.000000000 -0400 > @@ -87,6 +87,7 @@ > S_(SECCLASS_SECURITY, SECURITY__SETBOOL, "setbool") > S_(SECCLASS_SECURITY, SECURITY__SETSECPARAM, "setsecparam") > S_(SECCLASS_SECURITY, SECURITY__SETCHECKREQPROT, "setcheckreqprot") > + S_(SECCLASS_SECURITY, SECURITY__LABELPRIV, "labelpriv") > S_(SECCLASS_SYSTEM, SYSTEM__IPC_INFO, "ipc_info") > S_(SECCLASS_SYSTEM, SYSTEM__SYSLOG_READ, "syslog_read") > S_(SECCLASS_SYSTEM, SYSTEM__SYSLOG_MOD, "syslog_mod") > diff -X /home/sds/dontdiff -rup linux-2.6.17-rc4-mm3/security/selinux/include/objsec.h linux-2.6.17-rc4-mm3-x/security/selinux/include/objsec.h > --- linux-2.6.17-rc4-mm3/security/selinux/include/objsec.h 2006-03-20 00:53:29.000000000 -0500 > +++ linux-2.6.17-rc4-mm3-x/security/selinux/include/objsec.h 2006-05-23 08:57:55.000000000 -0400 > @@ -101,4 +101,7 @@ struct sk_security_struct { > > extern unsigned int selinux_checkreqprot; > > +extern int task_has_security(struct task_struct *tsk, > + u32 perms); > + > #endif /* _SELINUX_OBJSEC_H_ */ > diff -X /home/sds/dontdiff -rup linux-2.6.17-rc4-mm3/security/selinux/include/security.h linux-2.6.17-rc4-mm3-x/security/selinux/include/security.h > --- linux-2.6.17-rc4-mm3/security/selinux/include/security.h 2006-05-22 09:09:22.000000000 -0400 > +++ linux-2.6.17-rc4-mm3-x/security/selinux/include/security.h 2006-05-23 08:57:55.000000000 -0400 > @@ -63,6 +63,8 @@ int security_context_to_sid(char *sconte > > int security_context_to_sid_default(char *scontext, u32 scontext_len, u32 *out_sid, u32 def_sid); > > +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 -X /home/sds/dontdiff -rup linux-2.6.17-rc4-mm3/security/selinux/selinuxfs.c linux-2.6.17-rc4-mm3-x/security/selinux/selinuxfs.c > --- linux-2.6.17-rc4-mm3/security/selinux/selinuxfs.c 2006-05-22 09:09:46.000000000 -0400 > +++ linux-2.6.17-rc4-mm3-x/security/selinux/selinuxfs.c 2006-05-23 08:57:55.000000000 -0400 > @@ -71,8 +71,8 @@ static int *bool_pending_values = NULL; > extern void selnl_notify_setenforce(int val); > > /* Check whether a task is allowed to use a security operation. */ > -static int task_has_security(struct task_struct *tsk, > - u32 perms) > +int task_has_security(struct task_struct *tsk, > + u32 perms) > { > struct task_security_struct *tsec; > > diff -X /home/sds/dontdiff -rup linux-2.6.17-rc4-mm3/security/selinux/ss/context.h linux-2.6.17-rc4-mm3-x/security/selinux/ss/context.h > --- linux-2.6.17-rc4-mm3/security/selinux/ss/context.h 2006-03-20 00:53:29.000000000 -0500 > +++ linux-2.6.17-rc4-mm3-x/security/selinux/ss/context.h 2006-05-23 12:16:28.000000000 -0400 > @@ -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, including NUL byte. */ > }; > > static inline void mls_context_init(struct context *c) > @@ -83,6 +85,14 @@ static inline void context_init(struct c > > static inline int context_cpy(struct context *dst, struct context *src) > { > + context_init(dst); > + if (src->len) { > + dst->str = kstrdup(src->str, GFP_ATOMIC); > + if (!dst->str) > + return -ENOMEM; > + dst->len = src->len; > + return 0; > + } > dst->user = src->user; > dst->role = src->role; > dst->type = src->type; > @@ -91,12 +101,17 @@ static inline int context_cpy(struct con > > static inline void context_destroy(struct context *c) > { > - c->user = c->role = c->type = 0; > + kfree(c->str); > mls_context_destroy(c); > + context_init(c); > } > > static inline int context_cmp(struct context *c1, struct context *c2) > { > + if (c1->len && c2->len) > + return (c1->len == c2->len && !memcmp(c1->str, c2->str, c1->len)); > + if (c1->len || c2->len) > + return 0; > return ((c1->user == c2->user) && > (c1->role == c2->role) && > (c1->type == c2->type) && > diff -X /home/sds/dontdiff -rup linux-2.6.17-rc4-mm3/security/selinux/ss/mls.c linux-2.6.17-rc4-mm3-x/security/selinux/ss/mls.c > --- linux-2.6.17-rc4-mm3/security/selinux/ss/mls.c 2006-05-22 09:09:22.000000000 -0400 > +++ linux-2.6.17-rc4-mm3-x/security/selinux/ss/mls.c 2006-05-23 08:57:55.000000000 -0400 > @@ -249,7 +249,8 @@ static inline int mls_copy_context(struc > * 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, > @@ -296,7 +297,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; > @@ -320,7 +321,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; > @@ -336,7 +337,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; > @@ -404,7 +405,7 @@ int mls_from_string(char *str, struct co > 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 -X /home/sds/dontdiff -rup linux-2.6.17-rc4-mm3/security/selinux/ss/mls.h linux-2.6.17-rc4-mm3-x/security/selinux/ss/mls.h > --- linux-2.6.17-rc4-mm3/security/selinux/ss/mls.h 2006-05-22 09:09:22.000000000 -0400 > +++ linux-2.6.17-rc4-mm3-x/security/selinux/ss/mls.h 2006-05-23 08:57:55.000000000 -0400 > @@ -21,7 +21,8 @@ int mls_compute_context_len(struct conte > void mls_sid_to_context(struct context *context, char **scontext); > int mls_context_isvalid(struct policydb *p, struct context *c); > > -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 -X /home/sds/dontdiff -rup linux-2.6.17-rc4-mm3/security/selinux/ss/services.c linux-2.6.17-rc4-mm3-x/security/selinux/ss/services.c > --- linux-2.6.17-rc4-mm3/security/selinux/ss/services.c 2006-05-22 09:09:46.000000000 -0400 > +++ linux-2.6.17-rc4-mm3-x/security/selinux/ss/services.c 2006-05-23 12:17:26.000000000 -0400 > @@ -623,48 +623,31 @@ out: > > } > > -static int security_context_to_sid_core(char *scontext, u32 scontext_len, u32 *sid, u32 def_sid) > +static int string_to_context_struct(struct policydb *pol, > + struct sidtab *sidtabp, > + char *scontext, > + u32 scontext_len, > + struct context *ctx, > + u32 def_sid) > { > - 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; > - > - 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; > + context_init(ctx); > > - /* 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. */ > - scontext2 = kmalloc(scontext_len+1,GFP_KERNEL); > + /* Copy the string so that we can modify the copy as we parse it. */ > + scontext2 = kmalloc(scontext_len+1, GFP_ATOMIC); > if (!scontext2) { > rc = -ENOMEM; > - goto out; > + goto err; > } > memcpy(scontext2, scontext, scontext_len); > scontext2[scontext_len] = 0; > > - context_init(&context); > - *sid = SECSID_NULL; > - > - POLICY_RDLOCK; > - > /* Parse the security context. */ > > rc = -EINVAL; > @@ -676,15 +659,15 @@ static int security_context_to_sid_core( > p++; > > if (*p == 0) > - goto out_unlock; > + goto err; > > *p++ = 0; > > - usrdatum = hashtab_search(policydb.p_users.table, scontextp); > + usrdatum = hashtab_search(pol->p_users.table, scontextp); > if (!usrdatum) > - goto out_unlock; > + goto err; > > - context.user = usrdatum->value; > + ctx->user = usrdatum->value; > > /* Extract role. */ > scontextp = p; > @@ -692,14 +675,14 @@ static int security_context_to_sid_core( > p++; > > if (*p == 0) > - goto out_unlock; > + goto err; > > *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 err; > + ctx->role = role->value; > > /* Extract type. */ > scontextp = p; > @@ -708,32 +691,74 @@ static int security_context_to_sid_core( > 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 err; > > - 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 err; > > - if ((p - scontext2) < scontext_len) { > - rc = -EINVAL; > - goto out_unlock; > - } > + rc = -EINVAL; > + if ((p - scontext2) < scontext_len) > + goto err; > > /* Check the validity of the new context. */ > - if (!policydb_context_isvalid(&policydb, &context)) { > - rc = -EINVAL; > - goto out_unlock; > + if (!policydb_context_isvalid(pol, ctx)) > + goto err; > + > + rc = 0; > +out: > + kfree(scontext2); > + return rc; > +err: > + context_destroy(ctx); > + goto out; > +} > + > +static int security_context_to_sid_core(char *scontext, u32 scontext_len, u32 *sid, u32 def_sid, 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; > } > - /* Obtain the new sid. */ > + *sid = SECSID_NULL; > + > + POLICY_RDLOCK; > + rc = string_to_context_struct(&policydb, &sidtab, > + scontext, scontext_len, > + &context, def_sid); > + if (rc == -EINVAL && force && scontext_len) { > + context_init(&context); > + context.len = scontext_len; > + if (scontext[scontext_len-1]) > + context.len++; /* extend for NUL. */ > + context.str = kmalloc(context.len, GFP_ATOMIC); > + if (!context.str) { > + rc = -ENOMEM; > + goto out_unlock; > + } > + memcpy(context.str, scontext, scontext_len); > + context.str[context.len-1] = 0; > + } else if (rc) > + goto out_unlock; > rc = sidtab_context_to_sid(&sidtab, &context, sid); > + context_destroy(&context); > out_unlock: > POLICY_RDUNLOCK; > - context_destroy(&context); > - kfree(scontext2); > out: > return rc; > } > @@ -752,7 +777,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); > + sid, SECSID_NULL, 0); > } > > /** > @@ -769,13 +794,21 @@ int security_context_to_sid(char *sconte > * 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). > + * Adds the string representation if the context cannot be mapped under > + * current policy. > * Returns -%EINVAL if the context is invalid, -%ENOMEM if insufficient > * memory is available, or 0 on success. > */ > int security_context_to_sid_default(char *scontext, u32 scontext_len, u32 *sid, u32 def_sid) > { > return security_context_to_sid_core(scontext, scontext_len, > - sid, def_sid); > + sid, def_sid, 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, 1); > } > > static int compute_sid_handle_invalid_context( > @@ -1112,9 +1145,10 @@ static inline int convert_context_handle > char *s; > u32 len; > > - context_struct_to_string(context, &s, &len); > - printk(KERN_ERR "security: 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; > } > @@ -1146,6 +1180,27 @@ 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); > + if (!rc) { > + printk(KERN_INFO "SELinux: Context %s became valid under new policy.\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: Failed trying to map context %s (rc %d) under new policy, leaving unmapped.\n", c->str, -rc); > + goto out; > + } > + } > + > rc = context_cpy(&oldc, c); > if (rc) > goto out; > @@ -1155,46 +1210,48 @@ static int convert_context(u32 key, > /* Convert the user. */ > usrdatum = hashtab_search(args->newp->p_users.table, > args->oldp->p_user_val_to_name[c->user - 1]); > - if (!usrdatum) { > - goto bad; > - } > + if (!usrdatum) > + goto map; > c->user = usrdatum->value; > > /* Convert the role. */ > role = hashtab_search(args->newp->p_roles.table, > args->oldp->p_role_val_to_name[c->role - 1]); > - if (!role) { > - goto bad; > - } > + if (!role) > + goto map; > c->role = role->value; > > /* Convert the type. */ > typdatum = hashtab_search(args->newp->p_types.table, > args->oldp->p_type_val_to_name[c->type - 1]); > - if (!typdatum) { > - goto bad; > - } > + if (!typdatum) > + goto map; > c->type = typdatum->value; > > rc = mls_convert_context(args->oldp, args->newp, c); > if (rc) > - goto bad; > + goto map; > > /* Check the validity of the new context. */ > if (!policydb_context_isvalid(args->newp, c)) { > rc = convert_context_handle_invalid_context(&oldc); > if (rc) > - goto bad; > + goto map; > } > > context_destroy(&oldc); > out: > return rc; > -bad: > - context_struct_to_string(&oldc, &s, &len); > +map: > + /* Map old representation to string and save it. */ > + if (context_struct_to_string(&oldc, &s, &len)) > + return -ENOMEM; > context_destroy(&oldc); > - printk(KERN_ERR "security: invalidating context %s\n", s); > - kfree(s); > + context_destroy(c); > + c->str = s; > + c->len = len; > + printk(KERN_INFO "SELinux: Context %s became invalid under new policy.\n", c->str); > + rc = 0; > goto out; > } > > @@ -1253,7 +1310,11 @@ int security_load_policy(void *data, siz > return -EINVAL; > } > > - sidtab_init(&newsidtab); > + if (sidtab_init(&newsidtab)) { > + LOAD_UNLOCK; > + policydb_destroy(&newpolicydb); > + return -ENOMEM; > + } > > /* Verify that the existing classes did not change. */ > if (hashtab_map(policydb.p_classes.table, validate_class, &newpolicydb)) { > @@ -1271,10 +1332,12 @@ int security_load_policy(void *data, siz > } > > /* Convert the internal representations of contexts > - in the new SID table and remove invalid SIDs. */ > + 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); > @@ -1524,6 +1587,8 @@ int security_get_user_sids(u32 fromsid, > > POLICY_RDLOCK; > > + context_init(&usercon); > + > fromcon = sidtab_search(&sidtab, fromsid); > if (!fromcon) { > rc = -EINVAL; > diff -X /home/sds/dontdiff -rup linux-2.6.17-rc4-mm3/security/selinux/ss/sidtab.c linux-2.6.17-rc4-mm3-x/security/selinux/ss/sidtab.c > --- linux-2.6.17-rc4-mm3/security/selinux/ss/sidtab.c 2006-03-20 00:53:29.000000000 -0500 > +++ linux-2.6.17-rc4-mm3-x/security/selinux/ss/sidtab.c 2006-05-23 08:57:55.000000000 -0400 > @@ -100,7 +100,7 @@ struct context *sidtab_search(struct 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); > @@ -218,6 +218,8 @@ int sidtab_context_to_sid(struct sidtab > goto unlock_out; > } > sid = s->next_sid++; > + if (context->len) > + printk(KERN_INFO "SELinux: Context %s is not valid under current policy, adding as unmapped value.\n", context->str); > ret = sidtab_insert(s, sid, context); > if (ret) > s->next_sid--; > > -- 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] 33+ messages in thread
* Re: [RFC][PATCH] selinux: introduce support for deferred mapping of inode security contexts 2006-05-23 18:23 ` Daniel J Walsh @ 2006-05-23 18:50 ` Stephen Smalley 2006-05-23 20:11 ` Stephen Smalley 2006-05-24 17:24 ` Jeremy Katz 0 siblings, 2 replies; 33+ messages in thread From: Stephen Smalley @ 2006-05-23 18:50 UTC (permalink / raw) To: Daniel J Walsh Cc: Karl MacMillan, Thomas Bleher, selinux, SELinux-dev, James Morris, Jeremy Katz, Paul Nasrat, James Antill On Tue, 2006-05-23 at 14:23 -0400, Daniel J Walsh wrote: > Stephen Smalley wrote: > > Below is an updated version of the kernel patch to support rpm labeling > > of files before policy load, with a couple of bug fixes and a re-base to > > 2.6.17-rc4-mm3. Note that before we can upstream this, we need to > > resolve the issues of how rpm will check file label validity after > > policy load (e.g. calling security_check_context(3) on each label from > > the header), what corrective action rpm will take if a file label is > > invalid (options suggested include relabeling to unlabeled_t, relabeling > > to the context returned by the system policy via matchpathcon, or > > reverting the install), and the issues raised by Karl above (as they > > also affect the ability of rpm to perform such verification and > > correction sanely). > > > > > As far as I understand it, rpm will not go back and check the whether > the context are sane. If the > postinstall of policy fails, the context on disk will be incorrect and > treated like unlabeled_t. I don't think that is really a viable option. It is undesirable from both a robustness POV and a security POV. rpm shouldn't leave the filesystem littered with files that have invalid contexts (which could later be turned into valid contexts by another package's policy module, suddenly granting access to those files or permissions to those executables unexpectedly), nor should it leave the system littered with packages whose policy couldn't be installed, as the package software may then run with the wrong permissions. > Jeremy and Paul is that your understanding? -- 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] 33+ messages in thread
* Re: [RFC][PATCH] selinux: introduce support for deferred mapping of inode security contexts 2006-05-23 18:50 ` Stephen Smalley @ 2006-05-23 20:11 ` Stephen Smalley 2006-05-24 17:24 ` Jeremy Katz 2006-05-24 17:24 ` Jeremy Katz 1 sibling, 1 reply; 33+ messages in thread From: Stephen Smalley @ 2006-05-23 20:11 UTC (permalink / raw) To: Daniel J Walsh Cc: Karl MacMillan, Thomas Bleher, selinux, SELinux-dev, James Morris, Jeremy Katz, Paul Nasrat, James Antill On Tue, 2006-05-23 at 14:50 -0400, Stephen Smalley wrote: > On Tue, 2006-05-23 at 14:23 -0400, Daniel J Walsh wrote: > > Stephen Smalley wrote: > > > Below is an updated version of the kernel patch to support rpm labeling > > > of files before policy load, with a couple of bug fixes and a re-base to > > > 2.6.17-rc4-mm3. Note that before we can upstream this, we need to > > > resolve the issues of how rpm will check file label validity after > > > policy load (e.g. calling security_check_context(3) on each label from > > > the header), what corrective action rpm will take if a file label is > > > invalid (options suggested include relabeling to unlabeled_t, relabeling > > > to the context returned by the system policy via matchpathcon, or > > > reverting the install), and the issues raised by Karl above (as they > > > also affect the ability of rpm to perform such verification and > > > correction sanely). > > > > > > > > As far as I understand it, rpm will not go back and check the whether > > the context are sane. If the > > postinstall of policy fails, the context on disk will be incorrect and > > treated like unlabeled_t. > > I don't think that is really a viable option. It is undesirable from > both a robustness POV and a security POV. rpm shouldn't leave the > filesystem littered with files that have invalid contexts (which could > later be turned into valid contexts by another package's policy module, > suddenly granting access to those files or permissions to those > executables unexpectedly), nor should it leave the system littered with > packages whose policy couldn't be installed, as the package software may > then run with the wrong permissions. By the way, reverting the install altogether makes the most sense to me as a recovery action, i.e. either the package is installed with policy successfully loaded and all files with valid labels or the package is not installed at all. > > Jeremy and Paul is that your understanding? -- 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] 33+ messages in thread
* Re: [RFC][PATCH] selinux: introduce support for deferred mapping of inode security contexts 2006-05-23 20:11 ` Stephen Smalley @ 2006-05-24 17:24 ` Jeremy Katz 0 siblings, 0 replies; 33+ messages in thread From: Jeremy Katz @ 2006-05-24 17:24 UTC (permalink / raw) To: Stephen Smalley; +Cc: selinux, SELinux-dev, Paul Nasrat On Tue, 2006-05-23 at 16:11 -0400, Stephen Smalley wrote: > On Tue, 2006-05-23 at 14:50 -0400, Stephen Smalley wrote: > > On Tue, 2006-05-23 at 14:23 -0400, Daniel J Walsh wrote: > > > Stephen Smalley wrote: > > > > Below is an updated version of the kernel patch to support rpm labeling > > > > of files before policy load, with a couple of bug fixes and a re-base to > > > > 2.6.17-rc4-mm3. Note that before we can upstream this, we need to > > > > resolve the issues of how rpm will check file label validity after > > > > policy load (e.g. calling security_check_context(3) on each label from > > > > the header), what corrective action rpm will take if a file label is > > > > invalid (options suggested include relabeling to unlabeled_t, relabeling > > > > to the context returned by the system policy via matchpathcon, or > > > > reverting the install), and the issues raised by Karl above (as they > > > > also affect the ability of rpm to perform such verification and > > > > correction sanely). > > > > > > > > > > > As far as I understand it, rpm will not go back and check the whether > > > the context are sane. If the > > > postinstall of policy fails, the context on disk will be incorrect and > > > treated like unlabeled_t. > > > > I don't think that is really a viable option. It is undesirable from > > both a robustness POV and a security POV. rpm shouldn't leave the > > filesystem littered with files that have invalid contexts (which could > > later be turned into valid contexts by another package's policy module, > > suddenly granting access to those files or permissions to those > > executables unexpectedly), nor should it leave the system littered with > > packages whose policy couldn't be installed, as the package software may > > then run with the wrong permissions. > > By the way, reverting the install altogether makes the most sense to me > as a recovery action, i.e. either the package is installed with policy > successfully loaded and all files with valid labels or the package is > not installed at all. There is no way to just "revert" a package install -- the scriptlets can do arbitrary things and so there isn't a way to just revert that Jeremy -- 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] 33+ messages in thread
* Re: [RFC][PATCH] selinux: introduce support for deferred mapping of inode security contexts 2006-05-23 18:50 ` Stephen Smalley 2006-05-23 20:11 ` Stephen Smalley @ 2006-05-24 17:24 ` Jeremy Katz 2006-05-24 18:01 ` Stephen Smalley 1 sibling, 1 reply; 33+ messages in thread From: Jeremy Katz @ 2006-05-24 17:24 UTC (permalink / raw) To: Stephen Smalley; +Cc: selinux, SELinux-dev, Paul Nasrat On Tue, 2006-05-23 at 14:50 -0400, Stephen Smalley wrote: > On Tue, 2006-05-23 at 14:23 -0400, Daniel J Walsh wrote: > > Stephen Smalley wrote: > > > Below is an updated version of the kernel patch to support rpm labeling > > > of files before policy load, with a couple of bug fixes and a re-base to > > > 2.6.17-rc4-mm3. Note that before we can upstream this, we need to > > > resolve the issues of how rpm will check file label validity after > > > policy load (e.g. calling security_check_context(3) on each label from > > > the header), what corrective action rpm will take if a file label is > > > invalid (options suggested include relabeling to unlabeled_t, relabeling > > > to the context returned by the system policy via matchpathcon, or > > > reverting the install), and the issues raised by Karl above (as they > > > also affect the ability of rpm to perform such verification and > > > correction sanely). > > > > > > > > As far as I understand it, rpm will not go back and check the whether > > the context are sane. If the > > postinstall of policy fails, the context on disk will be incorrect and > > treated like unlabeled_t. > > I don't think that is really a viable option. It is undesirable from > both a robustness POV and a security POV. rpm shouldn't leave the > filesystem littered with files that have invalid contexts (which could > later be turned into valid contexts by another package's policy module, > suddenly granting access to those files or permissions to those > executables unexpectedly), nor should it leave the system littered with > packages whose policy couldn't be installed, as the package software may > then run with the wrong permissions. So the thing not covered in my other mail is "policy couldn't be installed" -- but what would cause that to be the case? I'd rather make it so that we don't hit that (via dependencies, as I'm guessing that's the likely culprit) rather than trying to hack around it. Jeremy -- 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] 33+ messages in thread
* Re: [RFC][PATCH] selinux: introduce support for deferred mapping of inode security contexts 2006-05-24 17:24 ` Jeremy Katz @ 2006-05-24 18:01 ` Stephen Smalley 0 siblings, 0 replies; 33+ messages in thread From: Stephen Smalley @ 2006-05-24 18:01 UTC (permalink / raw) To: Jeremy Katz; +Cc: selinux, SELinux-dev, Paul Nasrat On Wed, 2006-05-24 at 13:24 -0400, Jeremy Katz wrote: > On Tue, 2006-05-23 at 14:50 -0400, Stephen Smalley wrote: > > I don't think that is really a viable option. It is undesirable from > > both a robustness POV and a security POV. rpm shouldn't leave the > > filesystem littered with files that have invalid contexts (which could > > later be turned into valid contexts by another package's policy module, > > suddenly granting access to those files or permissions to those > > executables unexpectedly), nor should it leave the system littered with > > packages whose policy couldn't be installed, as the package software may > > then run with the wrong permissions. > > So the thing not covered in my other mail is "policy couldn't be > installed" -- but what would cause that to be the case? I'd rather make > it so that we don't hit that (via dependencies, as I'm guessing that's > the likely culprit) rather than trying to hack around it. I don't think you can prevent it in general; there are many possible failure points here, from dependency issues to policy denials to conflicts with local policy modules created by users or third party policy modules to resource failures (inadequate disk space for the new policy module to be installed). It isn't within the distro's control to really guarantee that it will work. I suppose a somewhat parallel question might be how rpm handles other kinds of failures, not just from the post scriptlets, but in setting down the files and establishing their ownerships and modes normally. However, that may not be a good example, as there is no current attempt to provide a spectrum of trust vs. an all-or-nothing situation. -- 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] 33+ messages in thread
* Re: [RFC][PATCH] selinux: introduce support for deferred mapping of inode security contexts 2006-05-23 17:15 ` Stephen Smalley 2006-05-23 18:23 ` Daniel J Walsh @ 2006-05-24 17:24 ` Jeremy Katz 2006-05-24 17:48 ` Stephen Smalley 2006-05-25 15:19 ` Stephen Smalley 1 sibling, 2 replies; 33+ messages in thread From: Jeremy Katz @ 2006-05-24 17:24 UTC (permalink / raw) To: Stephen Smalley; +Cc: selinux, SELinux-dev, Paul Nasrat On Tue, 2006-05-23 at 13:15 -0400, Stephen Smalley wrote: > Below is an updated version of the kernel patch to support rpm labeling > of files before policy load, with a couple of bug fixes and a re-base to > 2.6.17-rc4-mm3. Note that before we can upstream this, we need to > resolve the issues of how rpm will check file label validity after > policy load (e.g. calling security_check_context(3) on each label from > the header), what corrective action rpm will take if a file label is > invalid (options suggested include relabeling to unlabeled_t, relabeling > to the context returned by the system policy via matchpathcon, or > reverting the install), and the issues raised by Karl above (as they > also affect the ability of rpm to perform such verification and > correction sanely). Well, given that the only labels that will end up in a header will be from a policy in that package, I'm still not really convinced what adding a verification step _really_ accomplishes. Sure, it helps in the case of someone crafting a malicious package which has random things in the header (by hand, not from rpmbuild[1]) but if someone is crafting a malicious package and getting it signed by someone you trust, then you have far larger concerns. Jeremy [1] Maybe it's just the clarification on what ends up happening that is really needed. In the case where a package contains no policy modules the behavior will be exactly what it is today. If a package contains a policy module, at rpmbuild time, we'll map contexts into the header for *only* the files covered explicitly by that policy module. So the only contexts that could end up in the header will be ones that will then be installed by the policy module. For the other files, we'll continue to just set the file contexts based on the policy as today. -- 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] 33+ messages in thread
* Re: [RFC][PATCH] selinux: introduce support for deferred mapping of inode security contexts 2006-05-24 17:24 ` Jeremy Katz @ 2006-05-24 17:48 ` Stephen Smalley 2006-05-25 15:19 ` Stephen Smalley 1 sibling, 0 replies; 33+ messages in thread From: Stephen Smalley @ 2006-05-24 17:48 UTC (permalink / raw) To: Jeremy Katz; +Cc: selinux, SELinux-dev, Paul Nasrat On Wed, 2006-05-24 at 13:24 -0400, Jeremy Katz wrote: > On Tue, 2006-05-23 at 13:15 -0400, Stephen Smalley wrote: > > Below is an updated version of the kernel patch to support rpm labeling > > of files before policy load, with a couple of bug fixes and a re-base to > > 2.6.17-rc4-mm3. Note that before we can upstream this, we need to > > resolve the issues of how rpm will check file label validity after > > policy load (e.g. calling security_check_context(3) on each label from > > the header), what corrective action rpm will take if a file label is > > invalid (options suggested include relabeling to unlabeled_t, relabeling > > to the context returned by the system policy via matchpathcon, or > > reverting the install), and the issues raised by Karl above (as they > > also affect the ability of rpm to perform such verification and > > correction sanely). > > Well, given that the only labels that will end up in a header will be > from a policy in that package, I'm still not really convinced what > adding a verification step _really_ accomplishes. > > > Sure, it helps in the case of someone crafting a malicious package which > has random things in the header (by hand, not from rpmbuild[1]) but if > someone is crafting a malicious package and getting it signed by someone > you trust, then you have far larger concerns. One would like to be able to go beyond a simple binary decision on trust and instead constrain what a package can do at finer granularity based both on the trustworthiness of the source and the function/purpose of the package (e.g. httpd has no business replacing the base policy module, nor does it need to add a policy module that adds allow rules giving access to the policy store to httpd_t or any other domain, regardless of the fact that it comes from Red Hat with suitable signature). > [1] Maybe it's just the clarification on what ends up happening that is > really needed. In the case where a package contains no policy modules > the behavior will be exactly what it is today. If a package contains a > policy module, at rpmbuild time, we'll map contexts into the header for > *only* the files covered explicitly by that policy module. So the only > contexts that could end up in the header will be ones that will then be > installed by the policy module. For the other files, we'll continue to > just set the file contexts based on the policy as today. -- 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] 33+ messages in thread
* Re: [RFC][PATCH] selinux: introduce support for deferred mapping of inode security contexts 2006-05-24 17:24 ` Jeremy Katz 2006-05-24 17:48 ` Stephen Smalley @ 2006-05-25 15:19 ` Stephen Smalley 2006-05-25 15:28 ` Stephen Smalley 1 sibling, 1 reply; 33+ messages in thread From: Stephen Smalley @ 2006-05-25 15:19 UTC (permalink / raw) To: Jeremy Katz; +Cc: selinux, SELinux-dev, Paul Nasrat On Wed, 2006-05-24 at 13:24 -0400, Jeremy Katz wrote: > Well, given that the only labels that will end up in a header will be > from a policy in that package, I'm still not really convinced what > adding a verification step _really_ accomplishes. In addition to the security aspects, think about it just from the perspective of robustness and error reporting. At present (w/o labelpriv support), programs get an immediate indication if they attempt to set a file label that is not defined by the policy, so they know when they have tried to use an invalid label. With labelpriv support, some programs (like rpm) are going to get no indications of invalid file labels when they are set, nor will they get any indication when the policy is loaded that those file labels were never made valid. Hence, if they don't perform any separate verification, they'll never know that an error occurred, and just leave the system in an inconsistent state. Compare with chown/chmod with symbolic values rather than raw integers, and note that those programs certainly report when the symbolic value is invalid. Eric Paris pointed out that if we gave user domains (i.e. unconfined_t in targeted policy) the new labelpriv permission, then they would certainly be unhappy to find that a seemingly successful chcon command actually left the file in an unlabeled state without any warning or error. If rpm doesn't do any verification/checking, then it is in the same situation - it violates the principle of least surprise. The alternative model to post checking after policy load would be to either: 1) Precheck the file contexts from the header against the .pp file in some manner at install time (in which case rpm can abort early), or 2) Have load_policy fail if any of these labelpriv-created contexts were not made valid by the new policy, reverting to the old policy and returning an error all the way back to rpm (in which case rpm still has to take some corrective action). -- 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] 33+ messages in thread
* Re: [RFC][PATCH] selinux: introduce support for deferred mapping of inode security contexts 2006-05-25 15:19 ` Stephen Smalley @ 2006-05-25 15:28 ` Stephen Smalley 2006-05-26 18:54 ` Jeremy Katz 0 siblings, 1 reply; 33+ messages in thread From: Stephen Smalley @ 2006-05-25 15:28 UTC (permalink / raw) To: Jeremy Katz; +Cc: selinux, SELinux-dev, Paul Nasrat On Thu, 2006-05-25 at 11:19 -0400, Stephen Smalley wrote: > The alternative model to post checking after policy load would be to > either: > 1) Precheck the file contexts from the header against the .pp file in > some manner at install time (in which case rpm can abort early), or And as I suspect that you'll say that since those contexts were generated from the .pp file in the first place, no such checking is required, let me note that: a) the contexts will have been generated from the file contexts part of the .pp, not from the policy module itself, so there could be an inconsistency between the two that leaves the context invalid under the new policy, and b) having rpm recheck at install time provides us with both greater robustness (in the event of a bug in rpmbuild or a package corrupted in some manner along the way) and security (in the event of a maliciously constructed package). > 2) Have load_policy fail if any of these labelpriv-created contexts were > not made valid by the new policy, reverting to the old policy and > returning an error all the way back to rpm (in which case rpm still has > to take some corrective action). -- 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] 33+ messages in thread
* Re: [RFC][PATCH] selinux: introduce support for deferred mapping of inode security contexts 2006-05-25 15:28 ` Stephen Smalley @ 2006-05-26 18:54 ` Jeremy Katz 2006-05-26 20:13 ` Stephen Smalley 0 siblings, 1 reply; 33+ messages in thread From: Jeremy Katz @ 2006-05-26 18:54 UTC (permalink / raw) To: Stephen Smalley; +Cc: selinux, SELinux-dev, Paul Nasrat On Thu, 2006-05-25 at 11:28 -0400, Stephen Smalley wrote: > On Thu, 2006-05-25 at 11:19 -0400, Stephen Smalley wrote: > > The alternative model to post checking after policy load would be to > > either: > > 1) Precheck the file contexts from the header against the .pp file in > > some manner at install time (in which case rpm can abort early), or > > And as I suspect that you'll say that since those contexts were > generated from the .pp file in the first place, no such checking is > required, let me note that: > a) the contexts will have been generated from the file contexts part of > the .pp, not from the policy module itself, so there could be an > inconsistency between the two that leaves the context invalid under the > new policy, and I still think that it's somewhat important to try to ensure that this doesn't happen before you get to installing the package, just because at that point, you're basically putting the user in the "you're hosed, do not pass go, do not collect $200" position. So I still hope that we don't end up with this being a common occurrence :-) > b) having rpm recheck at install time provides us with both greater > robustness (in the event of a bug in rpmbuild or a package corrupted in > some manner along the way) and security (in the event of a maliciously > constructed package). But I'm willing to concede that adding some form of checking here may well make sense. But I'm not convinced it will necessarily belong in rpm itself -- it may make more sense to have it in the policy_module_loader_helper which is going to end up being needed to avoid stupid scriptlet errors. But that's in the realm of it not really mattering who's checking in that it's being checked. Does that seem reasonable? Jeremy -- 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] 33+ messages in thread
* Re: [RFC][PATCH] selinux: introduce support for deferred mapping of inode security contexts 2006-05-26 18:54 ` Jeremy Katz @ 2006-05-26 20:13 ` Stephen Smalley 2006-05-26 20:16 ` Jeremy Katz 0 siblings, 1 reply; 33+ messages in thread From: Stephen Smalley @ 2006-05-26 20:13 UTC (permalink / raw) To: Jeremy Katz; +Cc: selinux, SELinux-dev, Paul Nasrat On Fri, 2006-05-26 at 14:54 -0400, Jeremy Katz wrote: > On Thu, 2006-05-25 at 11:28 -0400, Stephen Smalley wrote: > > On Thu, 2006-05-25 at 11:19 -0400, Stephen Smalley wrote: > > > The alternative model to post checking after policy load would be to > > > either: > > > 1) Precheck the file contexts from the header against the .pp file in > > > some manner at install time (in which case rpm can abort early), or > > > > And as I suspect that you'll say that since those contexts were > > generated from the .pp file in the first place, no such checking is > > required, let me note that: > > a) the contexts will have been generated from the file contexts part of > > the .pp, not from the policy module itself, so there could be an > > inconsistency between the two that leaves the context invalid under the > > new policy, and > > I still think that it's somewhat important to try to ensure that this > doesn't happen before you get to installing the package, just because at > that point, you're basically putting the user in the "you're hosed, do > not pass go, do not collect $200" position. So I still hope that we > don't end up with this being a common occurrence :-) Agreed, we want to maximize build-time checking to catch problems in advance, but we can't guarantee that it will catch all problems and we don't want to have to fully trust it. > > b) having rpm recheck at install time provides us with both greater > > robustness (in the event of a bug in rpmbuild or a package corrupted in > > some manner along the way) and security (in the event of a maliciously > > constructed package). > > But I'm willing to concede that adding some form of checking here may > well make sense. But I'm not convinced it will necessarily belong in > rpm itself -- it may make more sense to have it in the > policy_module_loader_helper which is going to end up being needed to > avoid stupid scriptlet errors. But that's in the realm of it not really > mattering who's checking in that it's being checked. Does that seem > reasonable? Only issue here is the error path in rpm if that helper fails (or whether the helper gets enough information from rpm to take corrective action itself). -- 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] 33+ messages in thread
* Re: [RFC][PATCH] selinux: introduce support for deferred mapping of inode security contexts 2006-05-26 20:13 ` Stephen Smalley @ 2006-05-26 20:16 ` Jeremy Katz 0 siblings, 0 replies; 33+ messages in thread From: Jeremy Katz @ 2006-05-26 20:16 UTC (permalink / raw) To: Stephen Smalley; +Cc: selinux, SELinux-dev, Paul Nasrat On Fri, 2006-05-26 at 16:13 -0400, Stephen Smalley wrote: > On Fri, 2006-05-26 at 14:54 -0400, Jeremy Katz wrote: > > On Thu, 2006-05-25 at 11:28 -0400, Stephen Smalley wrote: > > > On Thu, 2006-05-25 at 11:19 -0400, Stephen Smalley wrote: > > > b) having rpm recheck at install time provides us with both greater > > > robustness (in the event of a bug in rpmbuild or a package corrupted in > > > some manner along the way) and security (in the event of a maliciously > > > constructed package). > > > > But I'm willing to concede that adding some form of checking here may > > well make sense. But I'm not convinced it will necessarily belong in > > rpm itself -- it may make more sense to have it in the > > policy_module_loader_helper which is going to end up being needed to > > avoid stupid scriptlet errors. But that's in the realm of it not really > > mattering who's checking in that it's being checked. Does that seem > > reasonable? > > Only issue here is the error path in rpm if that helper fails (or > whether the helper gets enough information from rpm to take corrective > action itself). We'll make sure that the helper has enough information to fallback to relabeling as unlabeled (it might even make sense for it to be able to fall back to what the loaded policy would give so that, eg, shared libs at least end up as lib_t) Jeremy -- 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] 33+ messages in thread
* Re: [RFC][PATCH] selinux: introduce support for deferred mapping of inode security contexts 2006-05-17 7:54 ` Thomas Bleher 2006-05-17 17:52 ` Karl MacMillan @ 2006-05-17 18:26 ` Stephen Smalley 2006-05-17 18:28 ` Karl MacMillan 1 sibling, 1 reply; 33+ messages in thread From: Stephen Smalley @ 2006-05-17 18:26 UTC (permalink / raw) To: Thomas Bleher Cc: selinux, Daniel J Walsh, SELinux-dev, James Morris, Jeremy Katz, Paul Nasrat, James Antill On Wed, 2006-05-17 at 09:54 +0200, Thomas Bleher wrote: > In http://marc.theaimsgroup.com/?l=selinux&m=114677075207486&w=2, I > outlined how rpm could work with the current kernel. I think this scheme > is preferable to changing the kernel, mainly because of two points: > > * It makes it possible to later confine rpm more strictly: > If you load policy before installing the package, you can use the > policy server to prevent rpm from loading certain policies; rpm will > only be able to put labels on disk it is allowed to by policy. > If you load policy after package installation, rpm needs the labelpriv > privilege, so you can't confine rpm in any meaningful sense. >From the policy's perspective, rpm is being allowed to create/label files with unlabeled_t (as the files are treated as such while the labels are invalid) and to insert a policy module. Access control on what the policy module can contain (what types it may define and what rules it may add) is the key to confining rpm (or rather, confining the particular process spawned by rpm in a suitable domain for the package being installed if rpm ever does that), and that is true regardless of whether rpm loads policy before or after setting down the files. To close the loop between the undefined file labels and the policy module that was checked, it is important that rpm verify that all of the file labels set down by rpm became valid upon the policy load, and either warn the admin or take some corrective action (whether that means relabeling those files to truly be unlabeled_t, removing those files, or reverting the package install altogether) if they are not. I suppose calling security_check_context() on each context from the header would suffice, followed by either a warning or corrective action if it fails on any of them. > * It allows rpm to know beforehand if the policy module will actually > apply on top of the current system policy (which is important if you > think of the differences between strict and targeted policy). It is > better to abort install before than to have invalid labels on disk > later. I agree that rpm shouldn't leave invalid labels around on disk. This is similar to the above problem. -- 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] 33+ messages in thread
* Re: [RFC][PATCH] selinux: introduce support for deferred mapping of inode security contexts 2006-05-17 18:26 ` Stephen Smalley @ 2006-05-17 18:28 ` Karl MacMillan 2006-05-17 18:43 ` Stephen Smalley 0 siblings, 1 reply; 33+ messages in thread From: Karl MacMillan @ 2006-05-17 18:28 UTC (permalink / raw) To: Stephen Smalley Cc: Thomas Bleher, selinux, Daniel J Walsh, SELinux-dev, James Morris, Jeremy Katz, Paul Nasrat, James Antill On Wed, 2006-05-17 at 14:26 -0400, Stephen Smalley wrote: > On Wed, 2006-05-17 at 09:54 +0200, Thomas Bleher wrote: > > In http://marc.theaimsgroup.com/?l=selinux&m=114677075207486&w=2, I > > outlined how rpm could work with the current kernel. I think this scheme > > is preferable to changing the kernel, mainly because of two points: > > > > * It makes it possible to later confine rpm more strictly: > > If you load policy before installing the package, you can use the > > policy server to prevent rpm from loading certain policies; rpm will > > only be able to put labels on disk it is allowed to by policy. > > If you load policy after package installation, rpm needs the labelpriv > > privilege, so you can't confine rpm in any meaningful sense. > > >From the policy's perspective, rpm is being allowed to create/label > files with unlabeled_t (as the files are treated as such while the > labels are invalid) and to insert a policy module. Access control on > what the policy module can contain (what types it may define and what > rules it may add) is the key to confining rpm (or rather, confining the > particular process spawned by rpm in a suitable domain for the package > being installed if rpm ever does that), and that is true regardless of > whether rpm loads policy before or after setting down the files. To > close the loop between the undefined file labels and the policy module > that was checked, it is important that rpm verify that all of the file > labels set down by rpm became valid upon the policy load, and either > warn the admin or take some corrective action (whether that means > relabeling those files to truly be unlabeled_t, removing those files, or > reverting the package install altogether) if they are not. I suppose > calling security_check_context() on each context from the header would > suffice, followed by either a warning or corrective action if it fails > on any of them. > Only checking the contexts in the header would protect against malicious packages but not a subverted rpm, right? Karl -- Karl MacMillan Tresys Technology www.tresys.com > > * It allows rpm to know beforehand if the policy module will actually > > apply on top of the current system policy (which is important if you > > think of the differences between strict and targeted policy). It is > > better to abort install before than to have invalid labels on disk > > later. > > I agree that rpm shouldn't leave invalid labels around on disk. This is > similar to the above problem. > -- 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] 33+ messages in thread
* Re: [RFC][PATCH] selinux: introduce support for deferred mapping of inode security contexts 2006-05-17 18:28 ` Karl MacMillan @ 2006-05-17 18:43 ` Stephen Smalley 0 siblings, 0 replies; 33+ messages in thread From: Stephen Smalley @ 2006-05-17 18:43 UTC (permalink / raw) To: Karl MacMillan Cc: Thomas Bleher, selinux, Daniel J Walsh, SELinux-dev, James Morris, Jeremy Katz, Paul Nasrat, James Antill On Wed, 2006-05-17 at 14:28 -0400, Karl MacMillan wrote: > On Wed, 2006-05-17 at 14:26 -0400, Stephen Smalley wrote: > > close the loop between the undefined file labels and the policy module > > that was checked, it is important that rpm verify that all of the file > > labels set down by rpm became valid upon the policy load, and either > > warn the admin or take some corrective action (whether that means > > relabeling those files to truly be unlabeled_t, removing those files, or > > reverting the package install altogether) if they are not. I suppose > > calling security_check_context() on each context from the header would > > suffice, followed by either a warning or corrective action if it fails > > on any of them. > > > > Only checking the contexts in the header would protect against malicious > packages but not a subverted rpm, right? Yes, unless rpm itself is decomposed, with one rpm process in one domain performing the checking and one rpm process in another domain performing the install and module insertion (which you need anyway if you want to mediate policy module insertions based on package trustworthiness). -- 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] 33+ messages in thread
* Re: [RFC][PATCH] selinux: introduce support for deferred mapping of inode security contexts 2006-05-15 16:35 [RFC][PATCH] selinux: introduce support for deferred mapping of inode security contexts Stephen Smalley ` (2 preceding siblings ...) 2006-05-17 7:54 ` Thomas Bleher @ 2006-05-19 13:44 ` Stephen Smalley 2006-05-19 13:59 ` Daniel J Walsh 3 siblings, 1 reply; 33+ messages in thread From: Stephen Smalley @ 2006-05-19 13:44 UTC (permalink / raw) To: selinux; +Cc: Thomas Bleher, Daniel J Walsh, SELinux-dev, James Morris On Mon, 2006-05-15 at 12:35 -0400, Stephen Smalley wrote: > With this patch applied, the following sequence is possible, subject to > policy, which must allow <domain> security_t:security labelpriv; and > allow unlabeled_t fs_t:filesystem associate; in order for this to work > in enforcing mode. Note that unconfined_t implicitly picks up all > security permissions at present due to the use of a wildcard for the > permission set in its rule. However, you still need the second allow > rule as well in order for this to succeed in enforcing mode. > > # touch foo > # chcon -t foo_exec_t foo > # ls -Z foo > -rw-r--r-- root root system_u:object_r:unlabeled_t foo > # semodule -i foo.pp # defines foo_exec_t > # ls -Z foo > -rw-r--r-- root root user_u:object_r:foo_exec_t foo > # semodule -r foo > # ls -Z foo > -rw-r--r-- root root system_u:object_r:unlabeled_t foo > # semodule -i foo.pp > # ls -Z foo > -rw-r--r-- root root user_u:object_r:foo_exec_t foo Eric Paris pointed out that the above behavior violates the principle of least surprise for users (chcon appears to succeed but leaves the file with unlabeled_t). So to clarify: The intent would be to exclude labelpriv permission from even unconfined_t and to only allow it to specific program domains (initially only package manager domains) where the program expects such behavior and performs some verification separately once the file context is expected to be valid. Of course, this requires that rpm_t not be an alias of unconfined_t, which is true in FC5 (but not in FC4). -- 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] 33+ messages in thread
* Re: [RFC][PATCH] selinux: introduce support for deferred mapping of inode security contexts 2006-05-19 13:44 ` Stephen Smalley @ 2006-05-19 13:59 ` Daniel J Walsh 2006-05-19 14:14 ` Stephen Smalley 0 siblings, 1 reply; 33+ messages in thread From: Daniel J Walsh @ 2006-05-19 13:59 UTC (permalink / raw) To: Stephen Smalley; +Cc: selinux, Thomas Bleher, SELinux-dev, James Morris Stephen Smalley wrote: > On Mon, 2006-05-15 at 12:35 -0400, Stephen Smalley wrote: > >> With this patch applied, the following sequence is possible, subject to >> policy, which must allow <domain> security_t:security labelpriv; and >> allow unlabeled_t fs_t:filesystem associate; in order for this to work >> in enforcing mode. Note that unconfined_t implicitly picks up all >> security permissions at present due to the use of a wildcard for the >> permission set in its rule. However, you still need the second allow >> rule as well in order for this to succeed in enforcing mode. >> >> # touch foo >> # chcon -t foo_exec_t foo >> # ls -Z foo >> -rw-r--r-- root root system_u:object_r:unlabeled_t foo >> # semodule -i foo.pp # defines foo_exec_t >> # ls -Z foo >> -rw-r--r-- root root user_u:object_r:foo_exec_t foo >> # semodule -r foo >> # ls -Z foo >> -rw-r--r-- root root system_u:object_r:unlabeled_t foo >> # semodule -i foo.pp >> # ls -Z foo >> -rw-r--r-- root root user_u:object_r:foo_exec_t foo >> > > Eric Paris pointed out that the above behavior violates the principle of > least surprise for users (chcon appears to succeed but leaves the file > with unlabeled_t). So to clarify: The intent would be to exclude > labelpriv permission from even unconfined_t and to only allow it to > specific program domains (initially only package manager domains) where > the program expects such behavior and performs some verification > separately once the file context is expected to be valid. Of course, > this requires that rpm_t not be an alias of unconfined_t, which is true > in FC5 (but not in FC4). > > We already have this problem in targeted with aliases. Try # ls -lZ /lib/libselinux.so.1 -rwxr-xr-x root root system_u:object_r:lib_t /lib/libselinux.so.1 # chcon -t shlib_t /lib/libselinux.so.1 # ls -lZ /lib/libselinux.so.1 -rwxr-xr-x root root system_u:object_r:lib_t /lib/libselinux.so.1 -- 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] 33+ messages in thread
* Re: [RFC][PATCH] selinux: introduce support for deferred mapping of inode security contexts 2006-05-19 13:59 ` Daniel J Walsh @ 2006-05-19 14:14 ` Stephen Smalley 2006-05-19 14:20 ` Daniel J Walsh 0 siblings, 1 reply; 33+ messages in thread From: Stephen Smalley @ 2006-05-19 14:14 UTC (permalink / raw) To: Daniel J Walsh; +Cc: selinux, Thomas Bleher, SELinux-dev, James Morris On Fri, 2006-05-19 at 09:59 -0400, Daniel J Walsh wrote: > Stephen Smalley wrote: > > On Mon, 2006-05-15 at 12:35 -0400, Stephen Smalley wrote: > > > >> With this patch applied, the following sequence is possible, subject to > >> policy, which must allow <domain> security_t:security labelpriv; and > >> allow unlabeled_t fs_t:filesystem associate; in order for this to work > >> in enforcing mode. Note that unconfined_t implicitly picks up all > >> security permissions at present due to the use of a wildcard for the > >> permission set in its rule. However, you still need the second allow > >> rule as well in order for this to succeed in enforcing mode. > >> > >> # touch foo > >> # chcon -t foo_exec_t foo > >> # ls -Z foo > >> -rw-r--r-- root root system_u:object_r:unlabeled_t foo > >> # semodule -i foo.pp # defines foo_exec_t > >> # ls -Z foo > >> -rw-r--r-- root root user_u:object_r:foo_exec_t foo > >> # semodule -r foo > >> # ls -Z foo > >> -rw-r--r-- root root system_u:object_r:unlabeled_t foo > >> # semodule -i foo.pp > >> # ls -Z foo > >> -rw-r--r-- root root user_u:object_r:foo_exec_t foo > >> > > > > Eric Paris pointed out that the above behavior violates the principle of > > least surprise for users (chcon appears to succeed but leaves the file > > with unlabeled_t). So to clarify: The intent would be to exclude > > labelpriv permission from even unconfined_t and to only allow it to > > specific program domains (initially only package manager domains) where > > the program expects such behavior and performs some verification > > separately once the file context is expected to be valid. Of course, > > this requires that rpm_t not be an alias of unconfined_t, which is true > > in FC5 (but not in FC4). > > > > > We already have this problem in targeted with aliases. > > Try > # ls -lZ /lib/libselinux.so.1 > -rwxr-xr-x root root system_u:object_r:lib_t /lib/libselinux.so.1 > # chcon -t shlib_t /lib/libselinux.so.1 > # ls -lZ /lib/libselinux.so.1 > -rwxr-xr-x root root system_u:object_r:lib_t /lib/libselinux.so.1 Not quite the same issue. In that case, shlib_t is a valid type; it just happens to be aliased to lib_t in targeted policy. So the user gets the expected behavior, i.e. the file becomes accessible under the rules associated with that type. And if the user enters a type that is completely undefined by the policy, he still gets an error. With labelpriv, if user has a simple typo (e.g. http_sys_content_t instead of httpd_sys_content_t), he gets no error from chcon, and that string is stored with the file, but the file is treated internally as unlabeled_t. Thus it is _not_ accessible under the rules associated with the type he meant to apply. In any event, as long as we exclude this permission (via ~labelpriv or by explicitly enumerating the allowed security permissions) from unconfined_t going forward, it shouldn't be a problem. -- 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] 33+ messages in thread
* Re: [RFC][PATCH] selinux: introduce support for deferred mapping of inode security contexts 2006-05-19 14:14 ` Stephen Smalley @ 2006-05-19 14:20 ` Daniel J Walsh 0 siblings, 0 replies; 33+ messages in thread From: Daniel J Walsh @ 2006-05-19 14:20 UTC (permalink / raw) To: Stephen Smalley; +Cc: selinux, Thomas Bleher, SELinux-dev, James Morris Stephen Smalley wrote: > On Fri, 2006-05-19 at 09:59 -0400, Daniel J Walsh wrote: > >> Stephen Smalley wrote: >> >>> On Mon, 2006-05-15 at 12:35 -0400, Stephen Smalley wrote: >>> >>> >>>> With this patch applied, the following sequence is possible, subject to >>>> policy, which must allow <domain> security_t:security labelpriv; and >>>> allow unlabeled_t fs_t:filesystem associate; in order for this to work >>>> in enforcing mode. Note that unconfined_t implicitly picks up all >>>> security permissions at present due to the use of a wildcard for the >>>> permission set in its rule. However, you still need the second allow >>>> rule as well in order for this to succeed in enforcing mode. >>>> >>>> # touch foo >>>> # chcon -t foo_exec_t foo >>>> # ls -Z foo >>>> -rw-r--r-- root root system_u:object_r:unlabeled_t foo >>>> # semodule -i foo.pp # defines foo_exec_t >>>> # ls -Z foo >>>> -rw-r--r-- root root user_u:object_r:foo_exec_t foo >>>> # semodule -r foo >>>> # ls -Z foo >>>> -rw-r--r-- root root system_u:object_r:unlabeled_t foo >>>> # semodule -i foo.pp >>>> # ls -Z foo >>>> -rw-r--r-- root root user_u:object_r:foo_exec_t foo >>>> >>>> >>> Eric Paris pointed out that the above behavior violates the principle of >>> least surprise for users (chcon appears to succeed but leaves the file >>> with unlabeled_t). So to clarify: The intent would be to exclude >>> labelpriv permission from even unconfined_t and to only allow it to >>> specific program domains (initially only package manager domains) where >>> the program expects such behavior and performs some verification >>> separately once the file context is expected to be valid. Of course, >>> this requires that rpm_t not be an alias of unconfined_t, which is true >>> in FC5 (but not in FC4). >>> >>> >>> >> We already have this problem in targeted with aliases. >> >> Try >> # ls -lZ /lib/libselinux.so.1 >> -rwxr-xr-x root root system_u:object_r:lib_t /lib/libselinux.so.1 >> # chcon -t shlib_t /lib/libselinux.so.1 >> # ls -lZ /lib/libselinux.so.1 >> -rwxr-xr-x root root system_u:object_r:lib_t /lib/libselinux.so.1 >> > > Not quite the same issue. In that case, shlib_t is a valid type; it > just happens to be aliased to lib_t in targeted policy. So the user > gets the expected behavior, i.e. the file becomes accessible under the > rules associated with that type. And if the user enters a type that is > completely undefined by the policy, he still gets an error. > > With labelpriv, if user has a simple typo (e.g. http_sys_content_t > instead of httpd_sys_content_t), he gets no error from chcon, and that > string is stored with the file, but the file is treated internally as > unlabeled_t. Thus it is _not_ accessible under the rules associated > with the type he meant to apply. > > In any event, as long as we exclude this permission (via ~labelpriv or > by explicitly enumerating the allowed security permissions) from > unconfined_t going forward, it shouldn't be a problem. > > Yes the only app that should have labelpriv is the installer. (rpm_t) I am not sure if other installers would need this. -- 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] 33+ messages in thread
* RE: [RFC][PATCH] selinux: introduce support for deferred mapping of inode security contexts
@ 2006-05-19 14:05 Joshua Brindle
2006-05-19 14:18 ` Stephen Smalley
0 siblings, 1 reply; 33+ messages in thread
From: Joshua Brindle @ 2006-05-19 14:05 UTC (permalink / raw)
To: Daniel J Walsh, Stephen Smalley
Cc: selinux, Thomas Bleher, selinux-dev, James Morris
> From: Daniel J Walsh [mailto:dwalsh@redhat.com]
>
> Stephen Smalley wrote:
> > On Mon, 2006-05-15 at 12:35 -0400, Stephen Smalley wrote:
> >
> >> With this patch applied, the following sequence is
> possible, subject
> >> to policy, which must allow <domain> security_t:security
> labelpriv;
> >> and allow unlabeled_t fs_t:filesystem associate; in order
> for this to
> >> work in enforcing mode. Note that unconfined_t implicitly
> picks up
> >> all security permissions at present due to the use of a
> wildcard for
> >> the permission set in its rule. However, you still need
> the second
> >> allow rule as well in order for this to succeed in enforcing mode.
> >>
> >> # touch foo
> >> # chcon -t foo_exec_t foo
> >> # ls -Z foo
> >> -rw-r--r-- root root system_u:object_r:unlabeled_t foo
> >> # semodule -i foo.pp # defines foo_exec_t # ls -Z foo
> >> -rw-r--r-- root root user_u:object_r:foo_exec_t foo
> >> # semodule -r foo
> >> # ls -Z foo
> >> -rw-r--r-- root root system_u:object_r:unlabeled_t foo
> >> # semodule -i foo.pp
> >> # ls -Z foo
> >> -rw-r--r-- root root user_u:object_r:foo_exec_t foo
> >>
> >
> > Eric Paris pointed out that the above behavior violates the
> principle
> > of least surprise for users (chcon appears to succeed but
> leaves the
> > file with unlabeled_t). So to clarify: The intent would be to
> > exclude labelpriv permission from even unconfined_t and to
> only allow
> > it to specific program domains (initially only package manager
> > domains) where the program expects such behavior and performs some
> > verification separately once the file context is expected
> to be valid.
> > Of course, this requires that rpm_t not be an alias of
> unconfined_t,
> > which is true in FC5 (but not in FC4).
> >
> >
> We already have this problem in targeted with aliases.
>
> Try
> # ls -lZ /lib/libselinux.so.1
> -rwxr-xr-x root root system_u:object_r:lib_t
> /lib/libselinux.so.1
> # chcon -t shlib_t /lib/libselinux.so.1
> # ls -lZ /lib/libselinux.so.1
> -rwxr-xr-x root root system_u:object_r:lib_t
> /lib/libselinux.so.1
>
Another reason why canonicalizing the paths on getxattr() is non-ideal.
Why can't we use an alternate interface for canonicalizing paths
(optionally, if the client wants it).
--
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] 33+ messages in thread* RE: [RFC][PATCH] selinux: introduce support for deferred mapping of inode security contexts 2006-05-19 14:05 Joshua Brindle @ 2006-05-19 14:18 ` Stephen Smalley 0 siblings, 0 replies; 33+ messages in thread From: Stephen Smalley @ 2006-05-19 14:18 UTC (permalink / raw) To: Joshua Brindle Cc: Daniel J Walsh, selinux, Thomas Bleher, selinux-dev, James Morris On Fri, 2006-05-19 at 10:05 -0400, Joshua Brindle wrote: > > We already have this problem in targeted with aliases. > > > > Try > > # ls -lZ /lib/libselinux.so.1 > > -rwxr-xr-x root root system_u:object_r:lib_t > > /lib/libselinux.so.1 > > # chcon -t shlib_t /lib/libselinux.so.1 > > # ls -lZ /lib/libselinux.so.1 > > -rwxr-xr-x root root system_u:object_r:lib_t > > /lib/libselinux.so.1 > > > > Another reason why canonicalizing the paths on getxattr() is non-ideal. > Why can't we use an alternate interface for canonicalizing paths > (optionally, if the client wants it). The original motivation for the getxattr canonicalization was to make the transition to MCS (MLS-enabled) transparent. Which required it to be transparently applied to all callers, not just a few. It also solved our longstanding problem with not being able to see the effective MAC label of e.g. mountpoint-labeled filesystems, genfs filesystems, /proc nodes, etc. It wasn't so much about canonicalization as it was about getting the incore inode label of a given inode. Canonicalization just happens automatically when converting back and forth between SIDs and contexts because sid_to_context always returns the primary names. -- 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] 33+ messages in thread
end of thread, other threads:[~2006-05-26 20:16 UTC | newest] Thread overview: 33+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2006-05-15 16:35 [RFC][PATCH] selinux: introduce support for deferred mapping of inode security contexts Stephen Smalley 2006-05-15 17:41 ` Stephen Smalley 2006-05-16 12:15 ` Stephen Smalley 2006-05-17 7:54 ` Thomas Bleher 2006-05-17 17:52 ` Karl MacMillan 2006-05-17 19:01 ` Stephen Smalley 2006-05-18 18:14 ` Thomas Bleher 2006-05-19 12:59 ` Stephen Smalley 2006-05-19 13:18 ` Joshua Brindle 2006-05-19 13:18 ` Karl MacMillan 2006-05-23 17:15 ` Stephen Smalley 2006-05-23 18:23 ` Daniel J Walsh 2006-05-23 18:50 ` Stephen Smalley 2006-05-23 20:11 ` Stephen Smalley 2006-05-24 17:24 ` Jeremy Katz 2006-05-24 17:24 ` Jeremy Katz 2006-05-24 18:01 ` Stephen Smalley 2006-05-24 17:24 ` Jeremy Katz 2006-05-24 17:48 ` Stephen Smalley 2006-05-25 15:19 ` Stephen Smalley 2006-05-25 15:28 ` Stephen Smalley 2006-05-26 18:54 ` Jeremy Katz 2006-05-26 20:13 ` Stephen Smalley 2006-05-26 20:16 ` Jeremy Katz 2006-05-17 18:26 ` Stephen Smalley 2006-05-17 18:28 ` Karl MacMillan 2006-05-17 18:43 ` Stephen Smalley 2006-05-19 13:44 ` Stephen Smalley 2006-05-19 13:59 ` Daniel J Walsh 2006-05-19 14:14 ` Stephen Smalley 2006-05-19 14:20 ` Daniel J Walsh -- strict thread matches above, loose matches on Subject: below -- 2006-05-19 14:05 Joshua Brindle 2006-05-19 14:18 ` 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.