From ab5703b34237da7034800ec2466ceebf88a7e685 Mon Sep 17 00:00:00 2001 From: Ron Yorston Date: Tue, 18 Apr 2006 22:21:04 -0700 Subject: [PATCH] selinux: Fix MLS compatibility off-by-one bug Fix an off-by-one error in the MLS compatibility code that was causing contexts with a MLS suffix to be rejected, preventing sharing partitions between FC4 and FC5. Bug reported in https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=188068 Signed-off-by: Stephen Smalley Acked-by: James Morris Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- security/selinux/ss/mls.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'security') diff --git a/security/selinux/ss/mls.c b/security/selinux/ss/mls.c index 640d0bf..84047f6 100644 --- a/security/selinux/ss/mls.c +++ b/security/selinux/ss/mls.c @@ -264,7 +264,7 @@ int mls_context_to_sid(char oldc, if (!selinux_mls_enabled) { if (def_sid != SECSID_NULL && oldc) - *scontext += strlen(*scontext); + *scontext += strlen(*scontext)+1; return 0; } -- cgit v1.1 From 376bd9cb357ec945ac893feaeb63af7370a6e70b Mon Sep 17 00:00:00 2001 From: Darrel Goeddel Date: Fri, 24 Feb 2006 15:44:05 -0600 Subject: [PATCH] support for context based audit filtering The following patch provides selinux interfaces that will allow the audit system to perform filtering based on the process context (user, role, type, sensitivity, and clearance). These interfaces will allow the selinux module to perform efficient matches based on lower level selinux constructs, rather than relying on context retrievals and string comparisons within the audit module. It also allows for dominance checks on the mls portion of the contexts that are impossible with only string comparisons. Signed-off-by: Darrel Goeddel Signed-off-by: Al Viro --- security/selinux/Makefile | 2 +- security/selinux/avc.c | 13 +-- security/selinux/exports.c | 28 +++++ security/selinux/ss/mls.c | 30 +++++- security/selinux/ss/mls.h | 4 +- security/selinux/ss/services.c | 235 ++++++++++++++++++++++++++++++++++++++++- 6 files changed, 302 insertions(+), 10 deletions(-) create mode 100644 security/selinux/exports.c (limited to 'security') diff --git a/security/selinux/Makefile b/security/selinux/Makefile index 688c0a2..faf2e02 100644 --- a/security/selinux/Makefile +++ b/security/selinux/Makefile @@ -4,7 +4,7 @@ obj-$(CONFIG_SECURITY_SELINUX) := selinux.o ss/ -selinux-y := avc.o hooks.o selinuxfs.o netlink.o nlmsgtab.o netif.o +selinux-y := avc.o hooks.o selinuxfs.o netlink.o nlmsgtab.o netif.o exports.o selinux-$(CONFIG_SECURITY_NETWORK_XFRM) += xfrm.o diff --git a/security/selinux/avc.c b/security/selinux/avc.c index ac5d69b..a300702 100644 --- a/security/selinux/avc.c +++ b/security/selinux/avc.c @@ -800,7 +800,7 @@ out: int avc_ss_reset(u32 seqno) { struct avc_callback_node *c; - int i, rc = 0; + int i, rc = 0, tmprc; unsigned long flag; struct avc_node *node; @@ -813,15 +813,16 @@ int avc_ss_reset(u32 seqno) for (c = avc_callbacks; c; c = c->next) { if (c->events & AVC_CALLBACK_RESET) { - rc = c->callback(AVC_CALLBACK_RESET, - 0, 0, 0, 0, NULL); - if (rc) - goto out; + tmprc = c->callback(AVC_CALLBACK_RESET, + 0, 0, 0, 0, NULL); + /* save the first error encountered for the return + value and continue processing the callbacks */ + if (!rc) + rc = tmprc; } } avc_latest_notif_update(seqno, 0); -out: return rc; } diff --git a/security/selinux/exports.c b/security/selinux/exports.c new file mode 100644 index 0000000..333c4c7 --- /dev/null +++ b/security/selinux/exports.c @@ -0,0 +1,28 @@ +/* + * SELinux services exported to the rest of the kernel. + * + * Author: James Morris + * + * Copyright (C) 2005 Red Hat, Inc., James Morris + * Copyright (C) 2006 Trusted Computer Solutions, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, + * as published by the Free Software Foundation. + */ +#include +#include +#include +#include + +#include "security.h" +#include "objsec.h" + +void selinux_task_ctxid(struct task_struct *tsk, u32 *ctxid) +{ + struct task_security_struct *tsec = tsk->security; + if (selinux_enabled) + *ctxid = tsec->sid; + else + *ctxid = 0; +} diff --git a/security/selinux/ss/mls.c b/security/selinux/ss/mls.c index 84047f6..7bc5b64 100644 --- a/security/selinux/ss/mls.c +++ b/security/selinux/ss/mls.c @@ -8,7 +8,7 @@ * * Support for enhanced MLS infrastructure. * - * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc. + * Copyright (C) 2004-2006 Trusted Computer Solutions, Inc. */ #include @@ -385,6 +385,34 @@ out: } /* + * Set the MLS fields in the security context structure + * `context' based on the string representation in + * the string `str'. This function will allocate temporary memory with the + * given constraints of gfp_mask. + */ +int mls_from_string(char *str, struct context *context, gfp_t gfp_mask) +{ + char *tmpstr, *freestr; + int rc; + + if (!selinux_mls_enabled) + return -EINVAL; + + /* we need freestr because mls_context_to_sid will change + the value of tmpstr */ + tmpstr = freestr = kstrdup(str, gfp_mask); + if (!tmpstr) { + rc = -ENOMEM; + } else { + rc = mls_context_to_sid(':', &tmpstr, context, + NULL, SECSID_NULL); + kfree(freestr); + } + + return rc; +} + +/* * Copies the effective MLS range from `src' into `dst'. */ static inline int mls_scopy_context(struct context *dst, diff --git a/security/selinux/ss/mls.h b/security/selinux/ss/mls.h index 03de697..fbb42f0 100644 --- a/security/selinux/ss/mls.h +++ b/security/selinux/ss/mls.h @@ -8,7 +8,7 @@ * * Support for enhanced MLS infrastructure. * - * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc. + * Copyright (C) 2004-2006 Trusted Computer Solutions, Inc. */ #ifndef _SS_MLS_H_ @@ -27,6 +27,8 @@ int mls_context_to_sid(char oldc, struct sidtab *s, u32 def_sid); +int mls_from_string(char *str, struct context *context, gfp_t gfp_mask); + int mls_convert_context(struct policydb *oldp, struct policydb *newp, struct context *context); diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index 6149248..7177e98 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c @@ -7,12 +7,13 @@ * Updated: Trusted Computer Solutions, Inc. * * Support for enhanced MLS infrastructure. + * Support for context based audit filters. * * Updated: Frank Mayer and Karl MacMillan * * Added conditional policy language extensions * - * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc. + * Copyright (C) 2004-2006 Trusted Computer Solutions, Inc. * Copyright (C) 2003 - 2004 Tresys Technology, LLC * Copyright (C) 2003 Red Hat, Inc., James Morris * This program is free software; you can redistribute it and/or modify @@ -1811,3 +1812,235 @@ out: POLICY_RDUNLOCK; return rc; } + +struct selinux_audit_rule { + u32 au_seqno; + struct context au_ctxt; +}; + +void selinux_audit_rule_free(struct selinux_audit_rule *rule) +{ + if (rule) { + context_destroy(&rule->au_ctxt); + kfree(rule); + } +} + +int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, + struct selinux_audit_rule **rule) +{ + struct selinux_audit_rule *tmprule; + struct role_datum *roledatum; + struct type_datum *typedatum; + struct user_datum *userdatum; + int rc = 0; + + *rule = NULL; + + if (!ss_initialized) + return -ENOTSUPP; + + switch (field) { + case AUDIT_SE_USER: + case AUDIT_SE_ROLE: + case AUDIT_SE_TYPE: + /* only 'equals' and 'not equals' fit user, role, and type */ + if (op != AUDIT_EQUAL && op != AUDIT_NOT_EQUAL) + return -EINVAL; + break; + case AUDIT_SE_SEN: + case AUDIT_SE_CLR: + /* we do not allow a range, indicated by the presense of '-' */ + if (strchr(rulestr, '-')) + return -EINVAL; + break; + default: + /* only the above fields are valid */ + return -EINVAL; + } + + tmprule = kzalloc(sizeof(struct selinux_audit_rule), GFP_KERNEL); + if (!tmprule) + return -ENOMEM; + + context_init(&tmprule->au_ctxt); + + POLICY_RDLOCK; + + tmprule->au_seqno = latest_granting; + + switch (field) { + case AUDIT_SE_USER: + userdatum = hashtab_search(policydb.p_users.table, rulestr); + if (!userdatum) + rc = -EINVAL; + else + tmprule->au_ctxt.user = userdatum->value; + break; + case AUDIT_SE_ROLE: + roledatum = hashtab_search(policydb.p_roles.table, rulestr); + if (!roledatum) + rc = -EINVAL; + else + tmprule->au_ctxt.role = roledatum->value; + break; + case AUDIT_SE_TYPE: + typedatum = hashtab_search(policydb.p_types.table, rulestr); + if (!typedatum) + rc = -EINVAL; + else + tmprule->au_ctxt.type = typedatum->value; + break; + case AUDIT_SE_SEN: + case AUDIT_SE_CLR: + rc = mls_from_string(rulestr, &tmprule->au_ctxt, GFP_ATOMIC); + break; + } + + POLICY_RDUNLOCK; + + if (rc) { + selinux_audit_rule_free(tmprule); + tmprule = NULL; + } + + *rule = tmprule; + + return rc; +} + +int selinux_audit_rule_match(u32 ctxid, u32 field, u32 op, + struct selinux_audit_rule *rule, + struct audit_context *actx) +{ + struct context *ctxt; + struct mls_level *level; + int match = 0; + + if (!rule) { + audit_log(actx, GFP_ATOMIC, AUDIT_SELINUX_ERR, + "selinux_audit_rule_match: missing rule\n"); + return -ENOENT; + } + + POLICY_RDLOCK; + + if (rule->au_seqno < latest_granting) { + audit_log(actx, GFP_ATOMIC, AUDIT_SELINUX_ERR, + "selinux_audit_rule_match: stale rule\n"); + match = -ESTALE; + goto out; + } + + ctxt = sidtab_search(&sidtab, ctxid); + if (!ctxt) { + audit_log(actx, GFP_ATOMIC, AUDIT_SELINUX_ERR, + "selinux_audit_rule_match: unrecognized SID %d\n", + ctxid); + match = -ENOENT; + goto out; + } + + /* a field/op pair that is not caught here will simply fall through + without a match */ + switch (field) { + case AUDIT_SE_USER: + switch (op) { + case AUDIT_EQUAL: + match = (ctxt->user == rule->au_ctxt.user); + break; + case AUDIT_NOT_EQUAL: + match = (ctxt->user != rule->au_ctxt.user); + break; + } + break; + case AUDIT_SE_ROLE: + switch (op) { + case AUDIT_EQUAL: + match = (ctxt->role == rule->au_ctxt.role); + break; + case AUDIT_NOT_EQUAL: + match = (ctxt->role != rule->au_ctxt.role); + break; + } + break; + case AUDIT_SE_TYPE: + switch (op) { + case AUDIT_EQUAL: + match = (ctxt->type == rule->au_ctxt.type); + break; + case AUDIT_NOT_EQUAL: + match = (ctxt->type != rule->au_ctxt.type); + break; + } + break; + case AUDIT_SE_SEN: + case AUDIT_SE_CLR: + level = (op == AUDIT_SE_SEN ? + &ctxt->range.level[0] : &ctxt->range.level[1]); + switch (op) { + case AUDIT_EQUAL: + match = mls_level_eq(&rule->au_ctxt.range.level[0], + level); + break; + case AUDIT_NOT_EQUAL: + match = !mls_level_eq(&rule->au_ctxt.range.level[0], + level); + break; + case AUDIT_LESS_THAN: + match = (mls_level_dom(&rule->au_ctxt.range.level[0], + level) && + !mls_level_eq(&rule->au_ctxt.range.level[0], + level)); + break; + case AUDIT_LESS_THAN_OR_EQUAL: + match = mls_level_dom(&rule->au_ctxt.range.level[0], + level); + break; + case AUDIT_GREATER_THAN: + match = (mls_level_dom(level, + &rule->au_ctxt.range.level[0]) && + !mls_level_eq(level, + &rule->au_ctxt.range.level[0])); + break; + case AUDIT_GREATER_THAN_OR_EQUAL: + match = mls_level_dom(level, + &rule->au_ctxt.range.level[0]); + break; + } + } + +out: + POLICY_RDUNLOCK; + return match; +} + +static int (*aurule_callback)(void) = NULL; + +static int aurule_avc_callback(u32 event, u32 ssid, u32 tsid, + u16 class, u32 perms, u32 *retained) +{ + int err = 0; + + if (event == AVC_CALLBACK_RESET && aurule_callback) + err = aurule_callback(); + return err; +} + +static int __init aurule_init(void) +{ + int err; + + err = avc_add_callback(aurule_avc_callback, AVC_CALLBACK_RESET, + SECSID_NULL, SECSID_NULL, SECCLASS_NULL, 0); + if (err) + panic("avc_add_callback() failed, error %d\n", err); + + return err; +} +__initcall(aurule_init); + +void selinux_audit_set_callback(int (*callback)(void)) +{ + aurule_callback = callback; +} -- cgit v1.1 From 1b50eed9cac0e8e5e4d3a522d8aa267f7f8f8acb Mon Sep 17 00:00:00 2001 From: Steve Grubb Date: Mon, 3 Apr 2006 14:06:13 -0400 Subject: [PATCH] audit inode patch Previously, we were gathering the context instead of the sid. Now in this patch, we gather just the sid and convert to context only if an audit event is being output. This patch brings the performance hit from 146% down to 23% Signed-off-by: Al Viro --- security/selinux/exports.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'security') diff --git a/security/selinux/exports.c b/security/selinux/exports.c index 333c4c7..07ddce7 100644 --- a/security/selinux/exports.c +++ b/security/selinux/exports.c @@ -14,6 +14,7 @@ #include #include #include +#include #include "security.h" #include "objsec.h" @@ -26,3 +27,26 @@ void selinux_task_ctxid(struct task_struct *tsk, u32 *ctxid) else *ctxid = 0; } + +int selinux_ctxid_to_string(u32 ctxid, char **ctx, u32 *ctxlen) +{ + if (selinux_enabled) + return security_sid_to_context(ctxid, ctx, ctxlen); + else { + *ctx = NULL; + *ctxlen = 0; + } + + return 0; +} + +void selinux_get_inode_sid(const struct inode *inode, u32 *sid) +{ + if (selinux_enabled) { + struct inode_security_struct *isec = inode->i_security; + *sid = isec->sid; + return; + } + *sid = 0; +} + -- cgit v1.1 From 9c7aa6aa74fa8a5cda36e54cbbe4fffe0214497d Mon Sep 17 00:00:00 2001 From: Steve Grubb Date: Fri, 31 Mar 2006 15:22:49 -0500 Subject: [PATCH] change lspp ipc auditing Hi, The patch below converts IPC auditing to collect sid's and convert to context string only if it needs to output an audit record. This patch depends on the inode audit change patch already being applied. Signed-off-by: Steve Grubb Signed-off-by: Al Viro --- security/dummy.c | 6 ------ security/selinux/exports.c | 11 +++++++++++ security/selinux/hooks.c | 8 -------- 3 files changed, 11 insertions(+), 14 deletions(-) (limited to 'security') diff --git a/security/dummy.c b/security/dummy.c index fd99429..8cccccc 100644 --- a/security/dummy.c +++ b/security/dummy.c @@ -563,11 +563,6 @@ static int dummy_ipc_permission (struct kern_ipc_perm *ipcp, short flag) return 0; } -static int dummy_ipc_getsecurity(struct kern_ipc_perm *ipcp, void *buffer, size_t size) -{ - return -EOPNOTSUPP; -} - static int dummy_msg_msg_alloc_security (struct msg_msg *msg) { return 0; @@ -976,7 +971,6 @@ void security_fixup_ops (struct security_operations *ops) set_to_dummy_if_null(ops, task_reparent_to_init); set_to_dummy_if_null(ops, task_to_inode); set_to_dummy_if_null(ops, ipc_permission); - set_to_dummy_if_null(ops, ipc_getsecurity); set_to_dummy_if_null(ops, msg_msg_alloc_security); set_to_dummy_if_null(ops, msg_msg_free_security); set_to_dummy_if_null(ops, msg_queue_alloc_security); diff --git a/security/selinux/exports.c b/security/selinux/exports.c index 07ddce7..7357cf2 100644 --- a/security/selinux/exports.c +++ b/security/selinux/exports.c @@ -15,6 +15,7 @@ #include #include #include +#include #include "security.h" #include "objsec.h" @@ -50,3 +51,13 @@ void selinux_get_inode_sid(const struct inode *inode, u32 *sid) *sid = 0; } +void selinux_get_ipc_sid(const struct kern_ipc_perm *ipcp, u32 *sid) +{ + if (selinux_enabled) { + struct ipc_security_struct *isec = ipcp->security; + *sid = isec->sid; + return; + } + *sid = 0; +} + diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index b61b9554..3cf368a 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -4052,13 +4052,6 @@ static int selinux_ipc_permission(struct kern_ipc_perm *ipcp, short flag) return ipc_has_perm(ipcp, av); } -static int selinux_ipc_getsecurity(struct kern_ipc_perm *ipcp, void *buffer, size_t size) -{ - struct ipc_security_struct *isec = ipcp->security; - - return selinux_getsecurity(isec->sid, buffer, size); -} - /* module stacking operations */ static int selinux_register_security (const char *name, struct security_operations *ops) { @@ -4321,7 +4314,6 @@ static struct security_operations selinux_ops = { .task_to_inode = selinux_task_to_inode, .ipc_permission = selinux_ipc_permission, - .ipc_getsecurity = selinux_ipc_getsecurity, .msg_msg_alloc_security = selinux_msg_msg_alloc_security, .msg_msg_free_security = selinux_msg_msg_free_security, -- cgit v1.1 From e7c3497013a7e5496ce3d5fd3c73b5cf5af7a56e Mon Sep 17 00:00:00 2001 From: Steve Grubb Date: Mon, 3 Apr 2006 09:08:13 -0400 Subject: [PATCH] Reworked patch for labels on user space messages The below patch should be applied after the inode and ipc sid patches. This patch is a reworking of Tim's patch that has been updated to match the inode and ipc patches since its similar. [updated: > Stephen Smalley also wanted to change a variable from isec to tsec in the > user sid patch. ] Signed-off-by: Steve Grubb Signed-off-by: Al Viro --- security/selinux/exports.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'security') diff --git a/security/selinux/exports.c b/security/selinux/exports.c index 7357cf2..ae4c73e 100644 --- a/security/selinux/exports.c +++ b/security/selinux/exports.c @@ -5,6 +5,7 @@ * * Copyright (C) 2005 Red Hat, Inc., James Morris * Copyright (C) 2006 Trusted Computer Solutions, Inc. + * Copyright (C) 2006 IBM Corporation, Timothy R. Chavez * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2, @@ -61,3 +62,13 @@ void selinux_get_ipc_sid(const struct kern_ipc_perm *ipcp, u32 *sid) *sid = 0; } +void selinux_get_task_sid(struct task_struct *tsk, u32 *sid) +{ + if (selinux_enabled) { + struct task_security_struct *tsec = tsk->security; + *sid = tsec->sid; + return; + } + *sid = 0; +} + -- cgit v1.1 From 30d55280b867aa0cae99f836ad0181bb0bf8f9cb Mon Sep 17 00:00:00 2001 From: Stephen Smalley Date: Wed, 3 May 2006 10:52:36 -0400 Subject: [PATCH] selinux: Clear selinux_enabled flag upon runtime disable. Clear selinux_enabled flag upon runtime disable of SELinux by userspace, and make sure it is defined even if selinux= boot parameter support is not enabled in configuration. Signed-off-by: Stephen Smalley Acked-by: James Morris Tested-by: Jon Smirl Acked-by: Al Viro Signed-off-by: Linus Torvalds --- security/selinux/hooks.c | 3 +++ security/selinux/include/security.h | 5 ----- 2 files changed, 3 insertions(+), 5 deletions(-) (limited to 'security') diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 3cf368a..d987048 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -101,6 +101,8 @@ static int __init selinux_enabled_setup(char *str) return 1; } __setup("selinux=", selinux_enabled_setup); +#else +int selinux_enabled = 1; #endif /* Original (dummy) security module. */ @@ -4535,6 +4537,7 @@ int selinux_disable(void) printk(KERN_INFO "SELinux: Disabled at runtime.\n"); selinux_disabled = 1; + selinux_enabled = 0; /* Reset security_ops to the secondary module, dummy or capability. */ security_ops = secondary_ops; diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h index 5f016c9..063af47 100644 --- a/security/selinux/include/security.h +++ b/security/selinux/include/security.h @@ -29,12 +29,7 @@ #define POLICYDB_VERSION_MIN POLICYDB_VERSION_BASE #define POLICYDB_VERSION_MAX POLICYDB_VERSION_AVTAB -#ifdef CONFIG_SECURITY_SELINUX_BOOTPARAM extern int selinux_enabled; -#else -#define selinux_enabled 1 -#endif - extern int selinux_mls_enabled; int security_load_policy(void * data, size_t len); -- cgit v1.1 From 0cccca06f9870eb6daa89357b8a99ad041865553 Mon Sep 17 00:00:00 2001 From: "Serge E. Hallyn" Date: Mon, 15 May 2006 09:43:48 -0700 Subject: [PATCH] selinux: check for failed kmalloc in security_sid_to_context() Check for NULL kmalloc return value before writing to it. Signed-off-by: Serge E. Hallyn Acked-by: James Morris Cc: Stephen Smalley Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- security/selinux/ss/services.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'security') diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index 7177e98..c284dbb 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c @@ -594,6 +594,10 @@ int security_sid_to_context(u32 sid, char **scontext, u32 *scontext_len) *scontext_len = strlen(initial_sid_to_string[sid]) + 1; scontextp = kmalloc(*scontext_len,GFP_ATOMIC); + if (!scontextp) { + rc = -ENOMEM; + goto out; + } strcpy(scontextp, initial_sid_to_string[sid]); *scontext = scontextp; goto out; -- cgit v1.1 From d4e9dc63dca91cd89086b5a686d7f7635c8319e5 Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Sat, 20 May 2006 15:00:02 -0700 Subject: [PATCH] selinux: endian fix Signed-off-by: Alexey Dobriyan Cc: Stephen Smalley Acked-by: James Morris Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- security/selinux/hooks.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'security') diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index d987048..21dad41 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -3231,7 +3231,7 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) goto out; /* Handle mapped IPv4 packets arriving via IPv6 sockets */ - if (family == PF_INET6 && skb->protocol == ntohs(ETH_P_IP)) + if (family == PF_INET6 && skb->protocol == htons(ETH_P_IP)) family = PF_INET; read_lock_bh(&sk->sk_callback_lock); -- cgit v1.1 From ba0c19ed6a61a96d4b42b81cb19d4bc81b5f728c Mon Sep 17 00:00:00 2001 From: Stephen Smalley Date: Sun, 4 Jun 2006 02:51:30 -0700 Subject: [PATCH] selinux: fix sb_lock/sb_security_lock nesting From: Stephen Smalley Fix unsafe nesting of sb_lock inside sb_security_lock in selinux_complete_init. Detected by the kernel locking validator. Signed-off-by: Stephen Smalley Acked-by: James Morris Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- security/selinux/hooks.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'security') diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 21dad41..90b4cdc 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -4422,6 +4422,7 @@ void selinux_complete_init(void) /* Set up any superblocks initialized prior to the policy load. */ printk(KERN_INFO "SELinux: Setting up existing superblocks.\n"); + spin_lock(&sb_lock); spin_lock(&sb_security_lock); next_sb: if (!list_empty(&superblock_security_head)) { @@ -4430,19 +4431,20 @@ next_sb: struct superblock_security_struct, list); struct super_block *sb = sbsec->sb; - spin_lock(&sb_lock); sb->s_count++; - spin_unlock(&sb_lock); spin_unlock(&sb_security_lock); + spin_unlock(&sb_lock); down_read(&sb->s_umount); if (sb->s_root) superblock_doinit(sb, NULL); drop_super(sb); + spin_lock(&sb_lock); spin_lock(&sb_security_lock); list_del_init(&sbsec->list); goto next_sb; } spin_unlock(&sb_security_lock); + spin_unlock(&sb_lock); } /* SELinux requires early initialization in order to label -- cgit v1.1