* [PATCH 00/13] NetLabel cleanups for 2.6.20
@ 2006-11-17 22:38 paul.moore
2006-11-17 22:38 ` [PATCH 01/13] NetLabel: use gfp_t instead of int where it makes sense paul.moore
` (13 more replies)
0 siblings, 14 replies; 20+ messages in thread
From: paul.moore @ 2006-11-17 22:38 UTC (permalink / raw)
To: netdev, selinux; +Cc: jmorris
This patchset consists of a lot of small-ish cleanups for NetLabel and in some
cases labeled networking in general. I've tested these patches for the past
few days and I haven't seen any regressions so please consider them for the
net-2.6.20 git tree.
The patches are fairly varied so it doesn't make sense to go into too much
details here, please see each patch for an explanation of what it does.
--
paul moore
linux security @ hp
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH 01/13] NetLabel: use gfp_t instead of int where it makes sense
2006-11-17 22:38 [PATCH 00/13] NetLabel cleanups for 2.6.20 paul.moore
@ 2006-11-17 22:38 ` paul.moore
2006-11-17 22:38 ` [PATCH 02/13] NetLabel: convert the unlabeled accept flag to use RCU paul.moore
` (12 subsequent siblings)
13 siblings, 0 replies; 20+ messages in thread
From: paul.moore @ 2006-11-17 22:38 UTC (permalink / raw)
To: netdev, selinux; +Cc: jmorris, Paul Moore
[-- Attachment #1: netlabel-secattr_gfpflags --]
[-- Type: text/plain, Size: 924 bytes --]
From: Paul Moore <paul.moore@hp.com>
There were a few places in the NetLabel code where the int type was being used
instead of the gfp_t type, this patch corrects this mistake.
Signed-off-by: Paul Moore <paul.moore@hp.com>
---
include/net/netlabel.h | 2 +-
1 files changed, 1 insertion(+), 1 deletion(-)
Index: net-2.6.20_netlabel-base-work/include/net/netlabel.h
===================================================================
--- net-2.6.20_netlabel-base-work.orig/include/net/netlabel.h
+++ net-2.6.20_netlabel-base-work/include/net/netlabel.h
@@ -205,7 +205,7 @@ static inline void netlbl_secattr_destro
* pointer on success, or NULL on failure.
*
*/
-static inline struct netlbl_lsm_secattr *netlbl_secattr_alloc(int flags)
+static inline struct netlbl_lsm_secattr *netlbl_secattr_alloc(gfp_t flags)
{
return kzalloc(sizeof(struct netlbl_lsm_secattr), flags);
}
--
paul moore
linux security @ hp
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH 02/13] NetLabel: convert the unlabeled accept flag to use RCU
2006-11-17 22:38 [PATCH 00/13] NetLabel cleanups for 2.6.20 paul.moore
2006-11-17 22:38 ` [PATCH 01/13] NetLabel: use gfp_t instead of int where it makes sense paul.moore
@ 2006-11-17 22:38 ` paul.moore
2006-11-17 22:38 ` [PATCH 03/13] NetLabel: change netlbl_secattr_init() to return void paul.moore
` (11 subsequent siblings)
13 siblings, 0 replies; 20+ messages in thread
From: paul.moore @ 2006-11-17 22:38 UTC (permalink / raw)
To: netdev, selinux; +Cc: jmorris, Paul Moore
[-- Attachment #1: netlabel-unlbl_rculocking --]
[-- Type: text/plain, Size: 2441 bytes --]
From: Paul Moore <paul.moore@hp.com>
Currently the NetLabel unlabeled packet accept flag is an atomic type and it
is checked for every non-NetLabel packet which comes into the system but rarely
ever changed. This patch changes this flag to a normal integer and protects it
with RCU locking.
Signed-off-by: Paul Moore <paul.moore@hp.com>
---
net/netlabel/netlabel_unlabeled.c | 28 +++++++++++++++++++++-------
1 files changed, 21 insertions(+), 7 deletions(-)
Index: net-2.6.20_netlabel-base-work/net/netlabel/netlabel_unlabeled.c
===================================================================
--- net-2.6.20_netlabel-base-work.orig/net/netlabel/netlabel_unlabeled.c
+++ net-2.6.20_netlabel-base-work/net/netlabel/netlabel_unlabeled.c
@@ -47,7 +47,8 @@
#include "netlabel_unlabeled.h"
/* Accept unlabeled packets flag */
-static atomic_t netlabel_unlabel_accept_flg = ATOMIC_INIT(0);
+static DEFINE_SPINLOCK(netlabel_unlabel_acceptflg_lock);
+static u8 netlabel_unlabel_acceptflg = 0;
/* NetLabel Generic NETLINK CIPSOv4 family */
static struct genl_family netlbl_unlabel_gnl_family = {
@@ -82,8 +83,12 @@ static void netlbl_unlabel_acceptflg_set
struct audit_buffer *audit_buf;
u8 old_val;
- old_val = atomic_read(&netlabel_unlabel_accept_flg);
- atomic_set(&netlabel_unlabel_accept_flg, value);
+ rcu_read_lock();
+ old_val = netlabel_unlabel_acceptflg;
+ spin_lock(&netlabel_unlabel_acceptflg_lock);
+ netlabel_unlabel_acceptflg = value;
+ spin_unlock(&netlabel_unlabel_acceptflg_lock);
+ rcu_read_unlock();
audit_buf = netlbl_audit_start_common(AUDIT_MAC_UNLBL_ALLOW,
audit_info);
@@ -148,9 +153,11 @@ static int netlbl_unlabel_list(struct sk
goto list_failure;
}
+ rcu_read_lock();
ret_val = nla_put_u8(ans_skb,
NLBL_UNLABEL_A_ACPTFLG,
- atomic_read(&netlabel_unlabel_accept_flg));
+ netlabel_unlabel_acceptflg);
+ rcu_read_unlock();
if (ret_val != 0)
goto list_failure;
@@ -236,10 +243,17 @@ int netlbl_unlabel_genl_init(void)
*/
int netlbl_unlabel_getattr(struct netlbl_lsm_secattr *secattr)
{
- if (atomic_read(&netlabel_unlabel_accept_flg) == 1)
- return netlbl_secattr_init(secattr);
+ int ret_val;
+
+ rcu_read_lock();
+ if (netlabel_unlabel_acceptflg == 1) {
+ netlbl_secattr_init(secattr);
+ ret_val = 0;
+ } else
+ ret_val = -ENOMSG;
+ rcu_read_unlock();
- return -ENOMSG;
+ return ret_val;
}
/**
--
paul moore
linux security @ hp
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH 03/13] NetLabel: change netlbl_secattr_init() to return void
2006-11-17 22:38 [PATCH 00/13] NetLabel cleanups for 2.6.20 paul.moore
2006-11-17 22:38 ` [PATCH 01/13] NetLabel: use gfp_t instead of int where it makes sense paul.moore
2006-11-17 22:38 ` [PATCH 02/13] NetLabel: convert the unlabeled accept flag to use RCU paul.moore
@ 2006-11-17 22:38 ` paul.moore
2006-11-17 22:38 ` [PATCH 04/13] NetLabel: make netlbl_lsm_secattr struct easier/quicker to understand paul.moore
` (10 subsequent siblings)
13 siblings, 0 replies; 20+ messages in thread
From: paul.moore @ 2006-11-17 22:38 UTC (permalink / raw)
To: netdev, selinux; +Cc: jmorris, Paul Moore
[-- Attachment #1: netlabel-secattr_retval --]
[-- Type: text/plain, Size: 1140 bytes --]
From: Paul Moore <paul.moore@hp.com>
The netlbl_secattr_init() function would always return 0 making it pointless
to have a return value. This patch changes the function to return void.
Signed-off-by: Paul Moore <paul.moore@hp.com>
---
include/net/netlabel.h | 6 ++----
1 files changed, 2 insertions(+), 4 deletions(-)
Index: net-2.6.20_netlabel-base-work/include/net/netlabel.h
===================================================================
--- net-2.6.20_netlabel-base-work.orig/include/net/netlabel.h
+++ net-2.6.20_netlabel-base-work/include/net/netlabel.h
@@ -169,14 +169,12 @@ static inline void netlbl_secattr_cache_
* @secattr: the struct to initialize
*
* Description:
- * Initialize an already allocated netlbl_lsm_secattr struct. Returns zero on
- * success, negative values on error.
+ * Initialize an already allocated netlbl_lsm_secattr struct.
*
*/
-static inline int netlbl_secattr_init(struct netlbl_lsm_secattr *secattr)
+static inline void netlbl_secattr_init(struct netlbl_lsm_secattr *secattr)
{
memset(secattr, 0, sizeof(*secattr));
- return 0;
}
/**
--
paul moore
linux security @ hp
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH 04/13] NetLabel: make netlbl_lsm_secattr struct easier/quicker to understand
2006-11-17 22:38 [PATCH 00/13] NetLabel cleanups for 2.6.20 paul.moore
` (2 preceding siblings ...)
2006-11-17 22:38 ` [PATCH 03/13] NetLabel: change netlbl_secattr_init() to return void paul.moore
@ 2006-11-17 22:38 ` paul.moore
2006-11-17 22:38 ` [PATCH 05/13] NetLabel: check for a CIPSOv4 option before we do call into the CIPSOv4 layer paul.moore
` (9 subsequent siblings)
13 siblings, 0 replies; 20+ messages in thread
From: paul.moore @ 2006-11-17 22:38 UTC (permalink / raw)
To: netdev, selinux; +Cc: jmorris, Paul Moore
[-- Attachment #1: netlabel-secattr_update --]
[-- Type: text/plain, Size: 8573 bytes --]
From: Paul Moore <paul.moore@hp.com>
The existing netlbl_lsm_secattr struct required the LSM to check all of the
fields to determine if any security attributes were present resulting in a lot
of work in the common case of no attributes. This patch adds a 'flags' field
which is used to indicate which attributes are present in the structure; this
should allow the LSM to do a quick comparison to determine if the structure
holds any security attributes.
Example:
if (netlbl_lsm_secattr->flags)
/* security attributes present */
else
/* NO security attributes present */
Signed-off-by: Paul Moore <paul.moore@hp.com>
---
include/net/netlabel.h | 13 +++++++++++--
net/ipv4/cipso_ipv4.c | 22 ++++++++++++++--------
net/netlabel/netlabel_kapi.c | 5 ++++-
security/selinux/ss/services.c | 24 ++++++++++++++++--------
4 files changed, 45 insertions(+), 19 deletions(-)
Index: net-2.6.20_netlabel-base-work/include/net/netlabel.h
===================================================================
--- net-2.6.20_netlabel-base-work.orig/include/net/netlabel.h
+++ net-2.6.20_netlabel-base-work/include/net/netlabel.h
@@ -111,11 +111,17 @@ struct netlbl_lsm_cache {
void (*free) (const void *data);
void *data;
};
+#define NETLBL_SECATTR_NONE 0x00000000
+#define NETLBL_SECATTR_DOMAIN 0x00000001
+#define NETLBL_SECATTR_CACHE 0x00000002
+#define NETLBL_SECATTR_MLS_LVL 0x00000004
+#define NETLBL_SECATTR_MLS_CAT 0x00000008
struct netlbl_lsm_secattr {
+ u32 flags;
+
char *domain;
u32 mls_lvl;
- u32 mls_lvl_vld;
unsigned char *mls_cat;
size_t mls_cat_len;
@@ -174,7 +180,10 @@ static inline void netlbl_secattr_cache_
*/
static inline void netlbl_secattr_init(struct netlbl_lsm_secattr *secattr)
{
- memset(secattr, 0, sizeof(*secattr));
+ secattr->flags = 0;
+ secattr->domain = NULL;
+ secattr->mls_cat = NULL;
+ secattr->cache = NULL;
}
/**
Index: net-2.6.20_netlabel-base-work/net/ipv4/cipso_ipv4.c
===================================================================
--- net-2.6.20_netlabel-base-work.orig/net/ipv4/cipso_ipv4.c
+++ net-2.6.20_netlabel-base-work/net/ipv4/cipso_ipv4.c
@@ -319,6 +319,7 @@ static int cipso_v4_cache_check(const un
entry->activity += 1;
atomic_inc(&entry->lsm_data->refcount);
secattr->cache = entry->lsm_data;
+ secattr->flags |= NETLBL_SECATTR_CACHE;
if (prev_entry == NULL) {
spin_unlock_bh(&cipso_v4_cache[bkt].lock);
return 0;
@@ -992,12 +993,15 @@ static int cipso_v4_gentag_rbm(const str
unsigned char **buffer,
u32 *buffer_len)
{
- int ret_val = -EPERM;
+ int ret_val;
unsigned char *buf = NULL;
u32 buf_len;
u32 level;
- if (secattr->mls_cat) {
+ if ((secattr->flags & NETLBL_SECATTR_MLS_LVL) == 0)
+ return -EPERM;
+
+ if (secattr->flags & NETLBL_SECATTR_MLS_CAT) {
buf = kzalloc(CIPSO_V4_HDR_LEN + 4 + CIPSO_V4_TAG1_CAT_LEN,
GFP_ATOMIC);
if (buf == NULL)
@@ -1014,10 +1018,10 @@ static int cipso_v4_gentag_rbm(const str
/* This will send packets using the "optimized" format when
* possibile as specified in section 3.4.2.6 of the
* CIPSO draft. */
- if (cipso_v4_rbm_optfmt && (ret_val > 0 && ret_val < 10))
- ret_val = 10;
-
- buf_len = 4 + ret_val;
+ if (cipso_v4_rbm_optfmt && ret_val > 0 && ret_val <= 10)
+ buf_len = 14;
+ else
+ buf_len = 4 + ret_val;
} else {
buf = kzalloc(CIPSO_V4_HDR_LEN + 4, GFP_ATOMIC);
if (buf == NULL)
@@ -1071,7 +1075,7 @@ static int cipso_v4_parsetag_rbm(const s
if (ret_val != 0)
return ret_val;
secattr->mls_lvl = level;
- secattr->mls_lvl_vld = 1;
+ secattr->flags |= NETLBL_SECATTR_MLS_LVL;
if (tag_len > 4) {
switch (doi_def->type) {
@@ -1095,8 +1099,10 @@ static int cipso_v4_parsetag_rbm(const s
if (ret_val < 0) {
kfree(secattr->mls_cat);
return ret_val;
+ } else if (ret_val > 0) {
+ secattr->mls_cat_len = ret_val;
+ secattr->flags |= NETLBL_SECATTR_MLS_CAT;
}
- secattr->mls_cat_len = ret_val;
}
return 0;
Index: net-2.6.20_netlabel-base-work/net/netlabel/netlabel_kapi.c
===================================================================
--- net-2.6.20_netlabel-base-work.orig/net/netlabel/netlabel_kapi.c
+++ net-2.6.20_netlabel-base-work/net/netlabel/netlabel_kapi.c
@@ -62,6 +62,9 @@ int netlbl_socket_setattr(const struct s
int ret_val = -ENOENT;
struct netlbl_dom_map *dom_entry;
+ if ((secattr->flags & NETLBL_SECATTR_DOMAIN) == 0)
+ return -ENOENT;
+
rcu_read_lock();
dom_entry = netlbl_domhsh_getentry(secattr->domain);
if (dom_entry == NULL)
@@ -200,7 +203,7 @@ void netlbl_cache_invalidate(void)
int netlbl_cache_add(const struct sk_buff *skb,
const struct netlbl_lsm_secattr *secattr)
{
- if (secattr->cache == NULL)
+ if ((secattr->flags & NETLBL_SECATTR_CACHE) == 0)
return -ENOMSG;
if (CIPSO_V4_OPTEXIST(skb))
Index: net-2.6.20_netlabel-base-work/security/selinux/ss/services.c
===================================================================
--- net-2.6.20_netlabel-base-work.orig/security/selinux/ss/services.c
+++ net-2.6.20_netlabel-base-work/security/selinux/ss/services.c
@@ -2209,8 +2209,6 @@ static void selinux_netlbl_cache_add(str
cache = kzalloc(sizeof(*cache), GFP_ATOMIC);
if (cache == NULL)
goto netlbl_cache_add_return;
- secattr.cache->free = selinux_netlbl_cache_free;
- secattr.cache->data = (void *)cache;
cache->type = NETLBL_CACHE_T_MLS;
if (ebitmap_cpy(&cache->data.mls_label.level[0].cat,
@@ -2223,6 +2221,10 @@ static void selinux_netlbl_cache_add(str
cache->data.mls_label.level[0].sens = ctx->range.level[0].sens;
cache->data.mls_label.level[1].sens = ctx->range.level[0].sens;
+ secattr.cache->free = selinux_netlbl_cache_free;
+ secattr.cache->data = (void *)cache;
+ secattr.flags = NETLBL_SECATTR_CACHE;
+
netlbl_cache_add(skb, &secattr);
netlbl_cache_add_return:
@@ -2268,7 +2270,7 @@ static int selinux_netlbl_secattr_to_sid
POLICY_RDLOCK;
- if (secattr->cache) {
+ if (secattr->flags & NETLBL_SECATTR_CACHE) {
cache = NETLBL_CACHE(secattr->cache->data);
switch (cache->type) {
case NETLBL_CACHE_T_SID:
@@ -2301,7 +2303,7 @@ static int selinux_netlbl_secattr_to_sid
default:
goto netlbl_secattr_to_sid_return;
}
- } else if (secattr->mls_lvl_vld) {
+ } else if (secattr->flags & NETLBL_SECATTR_MLS_LVL) {
ctx = sidtab_search(&sidtab, base_sid);
if (ctx == NULL)
goto netlbl_secattr_to_sid_return;
@@ -2310,7 +2312,7 @@ static int selinux_netlbl_secattr_to_sid
ctx_new.role = ctx->role;
ctx_new.type = ctx->type;
mls_import_lvl(&ctx_new, secattr->mls_lvl, secattr->mls_lvl);
- if (secattr->mls_cat) {
+ if (secattr->flags & NETLBL_SECATTR_MLS_CAT) {
if (mls_import_cat(&ctx_new,
secattr->mls_cat,
secattr->mls_cat_len,
@@ -2369,11 +2371,13 @@ static int selinux_netlbl_skbuff_getsid(
netlbl_secattr_init(&secattr);
rc = netlbl_skbuff_getattr(skb, &secattr);
- if (rc == 0)
+ if (rc == 0 && secattr.flags != NETLBL_SECATTR_NONE)
rc = selinux_netlbl_secattr_to_sid(skb,
&secattr,
base_sid,
sid);
+ else
+ *sid = SECSID_NULL;
netlbl_secattr_destroy(&secattr);
return rc;
@@ -2410,7 +2414,6 @@ static int selinux_netlbl_socket_setsid(
secattr.domain = kstrdup(policydb.p_type_val_to_name[ctx->type - 1],
GFP_ATOMIC);
mls_export_lvl(ctx, &secattr.mls_lvl, NULL);
- secattr.mls_lvl_vld = 1;
rc = mls_export_cat(ctx,
&secattr.mls_cat,
&secattr.mls_cat_len,
@@ -2419,6 +2422,10 @@ static int selinux_netlbl_socket_setsid(
if (rc != 0)
goto netlbl_socket_setsid_return;
+ secattr.flags |= NETLBL_SECATTR_DOMAIN | NETLBL_SECATTR_MLS_LVL;
+ if (secattr.mls_cat)
+ secattr.flags |= NETLBL_SECATTR_MLS_CAT;
+
rc = netlbl_socket_setattr(sock, &secattr);
if (rc == 0)
sksec->nlbl_state = NLBL_LABELED;
@@ -2519,6 +2526,7 @@ void selinux_netlbl_sock_graft(struct so
netlbl_secattr_init(&secattr);
if (netlbl_sock_getattr(sk, &secattr) == 0 &&
+ secattr.flags != NETLBL_SECATTR_NONE &&
selinux_netlbl_secattr_to_sid(NULL,
&secattr,
SECINITSID_UNLABELED,
@@ -2711,7 +2719,7 @@ int selinux_netlbl_socket_setsockopt(str
sksec->nlbl_state == NLBL_LABELED) {
netlbl_secattr_init(&secattr);
rc = netlbl_socket_getattr(sock, &secattr);
- if (rc == 0 && (secattr.cache || secattr.mls_lvl_vld))
+ if (rc == 0 && secattr.flags != NETLBL_SECATTR_NONE)
rc = -EACCES;
netlbl_secattr_destroy(&secattr);
}
--
paul moore
linux security @ hp
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH 05/13] NetLabel: check for a CIPSOv4 option before we do call into the CIPSOv4 layer
2006-11-17 22:38 [PATCH 00/13] NetLabel cleanups for 2.6.20 paul.moore
` (3 preceding siblings ...)
2006-11-17 22:38 ` [PATCH 04/13] NetLabel: make netlbl_lsm_secattr struct easier/quicker to understand paul.moore
@ 2006-11-17 22:38 ` paul.moore
2006-11-17 22:38 ` [PATCH 06/13] NetLabel: add tag verification when adding new CIPSOv4 DOI definitions paul.moore
` (8 subsequent siblings)
13 siblings, 0 replies; 20+ messages in thread
From: paul.moore @ 2006-11-17 22:38 UTC (permalink / raw)
To: netdev, selinux; +Cc: jmorris, Paul Moore
[-- Attachment #1: netlabel-cipso_earlycheck --]
[-- Type: text/plain, Size: 1744 bytes --]
From: Paul Moore <paul.moore@hp.com>
Right now the NetLabel code always jumps into the CIPSOv4 layer to determine if
a CIPSO IP option is present. However, we can do this check directly in the
NetLabel code by making use of the CIPSO_V4_OPTEXIST() macro which should save
us a function call in the common case of not having a CIPSOv4 option present.
Signed-off-by: Paul Moore <paul.moore@hp.com>
---
net/ipv4/cipso_ipv4.c | 2 --
net/netlabel/netlabel_kapi.c | 6 ++----
2 files changed, 2 insertions(+), 6 deletions(-)
Index: net-2.6.20_netlabel-base-work/net/ipv4/cipso_ipv4.c
===================================================================
--- net-2.6.20_netlabel-base-work.orig/net/ipv4/cipso_ipv4.c
+++ net-2.6.20_netlabel-base-work/net/ipv4/cipso_ipv4.c
@@ -1436,8 +1436,6 @@ int cipso_v4_skbuff_getattr(const struct
u32 doi;
struct cipso_v4_doi *doi_def;
- if (!CIPSO_V4_OPTEXIST(skb))
- return -ENOMSG;
cipso_ptr = CIPSO_V4_OPTPTR(skb);
if (cipso_v4_cache_check(cipso_ptr, cipso_ptr[1], secattr) == 0)
return 0;
Index: net-2.6.20_netlabel-base-work/net/netlabel/netlabel_kapi.c
===================================================================
--- net-2.6.20_netlabel-base-work.orig/net/netlabel/netlabel_kapi.c
+++ net-2.6.20_netlabel-base-work/net/netlabel/netlabel_kapi.c
@@ -149,10 +149,8 @@ int netlbl_socket_getattr(const struct s
int netlbl_skbuff_getattr(const struct sk_buff *skb,
struct netlbl_lsm_secattr *secattr)
{
- int ret_val;
-
- ret_val = cipso_v4_skbuff_getattr(skb, secattr);
- if (ret_val == 0)
+ if (CIPSO_V4_OPTEXIST(skb) &&
+ cipso_v4_skbuff_getattr(skb, secattr) == 0)
return 0;
return netlbl_unlabel_getattr(secattr);
--
paul moore
linux security @ hp
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH 06/13] NetLabel: add tag verification when adding new CIPSOv4 DOI definitions
2006-11-17 22:38 [PATCH 00/13] NetLabel cleanups for 2.6.20 paul.moore
` (4 preceding siblings ...)
2006-11-17 22:38 ` [PATCH 05/13] NetLabel: check for a CIPSOv4 option before we do call into the CIPSOv4 layer paul.moore
@ 2006-11-17 22:38 ` paul.moore
2006-11-17 22:38 ` [PATCH 07/13] NetLabel: fixup the handling of CIPSOv4 tags to allow for multiple tag types paul.moore
` (7 subsequent siblings)
13 siblings, 0 replies; 20+ messages in thread
From: paul.moore @ 2006-11-17 22:38 UTC (permalink / raw)
To: netdev, selinux; +Cc: jmorris, Paul Moore
[-- Attachment #1: netlabel-cipso_add_verification --]
[-- Type: text/plain, Size: 1402 bytes --]
From: Paul Moore <paul.moore@hp.com>
Currently the CIPSOv4 engine does not do any sort of checking when a new DOI
definition is added. The tags are still verified but only as a side effect of
normal NetLabel operation (packet processing, socket labeling, etc.) which
would cause application errors due to the faulty configuration. This patch
adds tag checking when new DOI definition are added allowing us to catch these
configuration problems when they happen.
Signed-off-by: Paul Moore <paul.moore@hp.com>
---
net/ipv4/cipso_ipv4.c | 14 ++++++++++++++
1 files changed, 14 insertions(+)
Index: net-2.6.20_netlabel-base-work/net/ipv4/cipso_ipv4.c
===================================================================
--- net-2.6.20_netlabel-base-work.orig/net/ipv4/cipso_ipv4.c
+++ net-2.6.20_netlabel-base-work/net/ipv4/cipso_ipv4.c
@@ -448,8 +448,22 @@ static struct cipso_v4_doi *cipso_v4_doi
*/
int cipso_v4_doi_add(struct cipso_v4_doi *doi_def)
{
+ u32 iter;
+
if (doi_def == NULL || doi_def->doi == CIPSO_V4_DOI_UNKNOWN)
return -EINVAL;
+ for (iter = 0; iter < CIPSO_V4_TAG_MAXCNT; iter++) {
+ switch (doi_def->tags[iter]) {
+ case CIPSO_V4_TAG_RBITMAP:
+ break;
+ case CIPSO_V4_TAG_INVALID:
+ if (iter == 0)
+ return -EINVAL;
+ break;
+ default:
+ return -EINVAL;
+ }
+ }
doi_def->valid = 1;
INIT_RCU_HEAD(&doi_def->rcu);
--
paul moore
linux security @ hp
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH 07/13] NetLabel: fixup the handling of CIPSOv4 tags to allow for multiple tag types
2006-11-17 22:38 [PATCH 00/13] NetLabel cleanups for 2.6.20 paul.moore
` (5 preceding siblings ...)
2006-11-17 22:38 ` [PATCH 06/13] NetLabel: add tag verification when adding new CIPSOv4 DOI definitions paul.moore
@ 2006-11-17 22:38 ` paul.moore
2006-11-17 22:38 ` [PATCH 08/13] NetLabel: return the correct error for translated CIPSOv4 tags paul.moore
` (6 subsequent siblings)
13 siblings, 0 replies; 20+ messages in thread
From: paul.moore @ 2006-11-17 22:38 UTC (permalink / raw)
To: netdev, selinux; +Cc: jmorris, Paul Moore
[-- Attachment #1: netlabel-cipso_tagcleanup --]
[-- Type: text/plain, Size: 7106 bytes --]
From: Paul Moore <paul.moore@hp.com>
While the original CIPSOv4 code had provisions for multiple tag types the
implementation was not as great as it could be, pushing a lot of non-tag
specific processing into the tag specific code blocks. This patch fixes that
issue making it easier to support multiple tag types in the future.
Signed-off-by: Paul Moore <paul.moore@hp.com>
---
net/ipv4/cipso_ipv4.c | 115 +++++++++++++++++++++++---------------------------
1 files changed, 54 insertions(+), 61 deletions(-)
Index: net-2.6.20_netlabel-base-work/net/ipv4/cipso_ipv4.c
===================================================================
--- net-2.6.20_netlabel-base-work.orig/net/ipv4/cipso_ipv4.c
+++ net-2.6.20_netlabel-base-work/net/ipv4/cipso_ipv4.c
@@ -959,35 +959,28 @@ static int cipso_v4_map_cat_rbm_ntoh(con
* Protocol Handling Functions
*/
+#define CIPSO_V4_OPT_LEN_MAX 40
#define CIPSO_V4_HDR_LEN 6
/**
* cipso_v4_gentag_hdr - Generate a CIPSO option header
* @doi_def: the DOI definition
- * @len: the total tag length in bytes
+ * @len: the total tag length in bytes, not including this header
* @buf: the CIPSO option buffer
*
* Description:
- * Write a CIPSO header into the beginning of @buffer. Return zero on success,
- * negative values on failure.
+ * Write a CIPSO header into the beginning of @buffer.
*
*/
-static int cipso_v4_gentag_hdr(const struct cipso_v4_doi *doi_def,
- u32 len,
- unsigned char *buf)
+static void cipso_v4_gentag_hdr(const struct cipso_v4_doi *doi_def,
+ unsigned char *buf,
+ u32 len)
{
- if (CIPSO_V4_HDR_LEN + len > 40)
- return -ENOSPC;
-
buf[0] = IPOPT_CIPSO;
buf[1] = CIPSO_V4_HDR_LEN + len;
*(__be32 *)&buf[2] = htonl(doi_def->doi);
-
- return 0;
}
-#define CIPSO_V4_TAG1_CAT_LEN 30
-
/**
* cipso_v4_gentag_rbm - Generate a CIPSO restricted bitmap tag (type #1)
* @doi_def: the DOI definition
@@ -998,71 +991,50 @@ static int cipso_v4_gentag_hdr(const str
* Description:
* Generate a CIPSO option using the restricted bitmap tag, tag type #1. The
* actual buffer length may be larger than the indicated size due to
- * translation between host and network category bitmaps. Returns zero on
- * success, negative values on failure.
+ * translation between host and network category bitmaps. Returns the size of
+ * the tag on success, negative values on failure.
*
*/
static int cipso_v4_gentag_rbm(const struct cipso_v4_doi *doi_def,
const struct netlbl_lsm_secattr *secattr,
- unsigned char **buffer,
- u32 *buffer_len)
+ unsigned char *buffer,
+ u32 buffer_len)
{
int ret_val;
- unsigned char *buf = NULL;
- u32 buf_len;
+ u32 tag_len;
u32 level;
if ((secattr->flags & NETLBL_SECATTR_MLS_LVL) == 0)
return -EPERM;
- if (secattr->flags & NETLBL_SECATTR_MLS_CAT) {
- buf = kzalloc(CIPSO_V4_HDR_LEN + 4 + CIPSO_V4_TAG1_CAT_LEN,
- GFP_ATOMIC);
- if (buf == NULL)
- return -ENOMEM;
+ ret_val = cipso_v4_map_lvl_hton(doi_def, secattr->mls_lvl, &level);
+ if (ret_val != 0)
+ return ret_val;
+ if (secattr->flags & NETLBL_SECATTR_MLS_CAT) {
ret_val = cipso_v4_map_cat_rbm_hton(doi_def,
secattr->mls_cat,
secattr->mls_cat_len,
- &buf[CIPSO_V4_HDR_LEN + 4],
- CIPSO_V4_TAG1_CAT_LEN);
+ &buffer[4],
+ buffer_len - 4);
if (ret_val < 0)
- goto gentag_failure;
+ return ret_val;
/* This will send packets using the "optimized" format when
* possibile as specified in section 3.4.2.6 of the
* CIPSO draft. */
if (cipso_v4_rbm_optfmt && ret_val > 0 && ret_val <= 10)
- buf_len = 14;
+ tag_len = 14;
else
- buf_len = 4 + ret_val;
- } else {
- buf = kzalloc(CIPSO_V4_HDR_LEN + 4, GFP_ATOMIC);
- if (buf == NULL)
- return -ENOMEM;
- buf_len = 4;
- }
-
- ret_val = cipso_v4_map_lvl_hton(doi_def, secattr->mls_lvl, &level);
- if (ret_val != 0)
- goto gentag_failure;
-
- ret_val = cipso_v4_gentag_hdr(doi_def, buf_len, buf);
- if (ret_val != 0)
- goto gentag_failure;
-
- buf[CIPSO_V4_HDR_LEN] = 0x01;
- buf[CIPSO_V4_HDR_LEN + 1] = buf_len;
- buf[CIPSO_V4_HDR_LEN + 3] = level;
+ tag_len = 4 + ret_val;
+ } else
+ tag_len = 4;
+
+ buffer[0] = 0x01;
+ buffer[1] = tag_len;
+ buffer[3] = level;
- *buffer = buf;
- *buffer_len = CIPSO_V4_HDR_LEN + buf_len;
-
- return 0;
-
-gentag_failure:
- kfree(buf);
- return ret_val;
+ return tag_len;
}
/**
@@ -1285,7 +1257,7 @@ int cipso_v4_socket_setattr(const struct
{
int ret_val = -EPERM;
u32 iter;
- unsigned char *buf = NULL;
+ unsigned char *buf;
u32 buf_len = 0;
u32 opt_len;
struct ip_options *opt = NULL;
@@ -1301,17 +1273,28 @@ int cipso_v4_socket_setattr(const struct
if (sk == NULL)
return 0;
+ /* We allocate the maximum CIPSO option size here so we are probably
+ * being a little wasteful, but it makes our life _much_ easier later
+ * on and after all we are only talking about 40 bytes. */
+ buf_len = CIPSO_V4_OPT_LEN_MAX;
+ buf = kmalloc(buf_len, GFP_ATOMIC);
+ if (buf == NULL) {
+ ret_val = -ENOMEM;
+ goto socket_setattr_failure;
+ }
+
/* XXX - This code assumes only one tag per CIPSO option which isn't
* really a good assumption to make but since we only support the MAC
* tags right now it is a safe assumption. */
iter = 0;
do {
+ memset(buf, 0, buf_len);
switch (doi_def->tags[iter]) {
case CIPSO_V4_TAG_RBITMAP:
ret_val = cipso_v4_gentag_rbm(doi_def,
- secattr,
- &buf,
- &buf_len);
+ secattr,
+ &buf[CIPSO_V4_HDR_LEN],
+ buf_len - CIPSO_V4_HDR_LEN);
break;
default:
ret_val = -EPERM;
@@ -1319,11 +1302,13 @@ int cipso_v4_socket_setattr(const struct
}
iter++;
- } while (ret_val != 0 &&
+ } while (ret_val < 0 &&
iter < CIPSO_V4_TAG_MAXCNT &&
doi_def->tags[iter] != CIPSO_V4_TAG_INVALID);
- if (ret_val != 0)
+ if (ret_val < 0)
goto socket_setattr_failure;
+ cipso_v4_gentag_hdr(doi_def, buf, ret_val);
+ buf_len = CIPSO_V4_HDR_LEN + ret_val;
/* We can't use ip_options_get() directly because it makes a call to
* ip_options_get_alloc() which allocates memory with GFP_KERNEL and
@@ -1397,6 +1382,10 @@ int cipso_v4_sock_getattr(struct sock *s
rcu_read_unlock();
return -ENOMSG;
}
+
+ /* XXX - This code assumes only one tag per CIPSO option which isn't
+ * really a good assumption to make but since we only support the MAC
+ * tags right now it is a safe assumption. */
switch (cipso_ptr[6]) {
case CIPSO_V4_TAG_RBITMAP:
ret_val = cipso_v4_parsetag_rbm(doi_def,
@@ -1459,6 +1448,10 @@ int cipso_v4_skbuff_getattr(const struct
doi_def = cipso_v4_doi_getdef(doi);
if (doi_def == NULL)
goto skbuff_getattr_return;
+
+ /* XXX - This code assumes only one tag per CIPSO option which isn't
+ * really a good assumption to make but since we only support the MAC
+ * tags right now it is a safe assumption. */
switch (cipso_ptr[6]) {
case CIPSO_V4_TAG_RBITMAP:
ret_val = cipso_v4_parsetag_rbm(doi_def,
--
paul moore
linux security @ hp
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH 08/13] NetLabel: return the correct error for translated CIPSOv4 tags
2006-11-17 22:38 [PATCH 00/13] NetLabel cleanups for 2.6.20 paul.moore
` (6 preceding siblings ...)
2006-11-17 22:38 ` [PATCH 07/13] NetLabel: fixup the handling of CIPSOv4 tags to allow for multiple tag types paul.moore
@ 2006-11-17 22:38 ` paul.moore
2006-11-17 22:38 ` [PATCH 09/13] NetLabel: use the correct CIPSOv4 MLS label limits paul.moore
` (5 subsequent siblings)
13 siblings, 0 replies; 20+ messages in thread
From: paul.moore @ 2006-11-17 22:38 UTC (permalink / raw)
To: netdev, selinux; +Cc: jmorris, Paul Moore
[-- Attachment #1: netlabel-cipso_errcode --]
[-- Type: text/plain, Size: 1457 bytes --]
From: Paul Moore <paul.moore@hp.com>
The CIPSOv4 translated tag #1 mapping does not always return the correct error
code if the desired mapping does not exist; instead of returning -EPERM it
returns -ENOSPC indicating that the buffer is not large enough to hold the
translated value. This was caused by failing to check a specific error
condition. This patch fixes this so that unknown mappings return
-EPERM which is consistent with the rest of the related CIPSOv4 code.
Signed-off-by: Paul Moore <paul.moore@hp.com>
---
net/ipv4/cipso_ipv4.c | 4 ++++
1 files changed, 4 insertions(+)
Index: net-2.6.20_netlabel-base-work/net/ipv4/cipso_ipv4.c
===================================================================
--- net-2.6.20_netlabel-base-work.orig/net/ipv4/cipso_ipv4.c
+++ net-2.6.20_netlabel-base-work/net/ipv4/cipso_ipv4.c
@@ -868,6 +868,8 @@ static int cipso_v4_map_cat_rbm_hton(con
return -EPERM;
net_spot = host_cat_array[host_spot];
+ if (net_spot >= CIPSO_V4_INV_CAT)
+ return -EPERM;
if (net_spot >= net_clen_bits)
return -ENOSPC;
cipso_v4_bitmap_setbit(net_cat, net_spot, 1);
@@ -936,6 +938,8 @@ static int cipso_v4_map_cat_rbm_ntoh(con
return -EPERM;
host_spot = net_cat_array[net_spot];
+ if (host_spot >= CIPSO_V4_INV_CAT)
+ return -EPERM;
if (host_spot >= host_clen_bits)
return -ENOSPC;
cipso_v4_bitmap_setbit(host_cat, host_spot, 1);
--
paul moore
linux security @ hp
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH 09/13] NetLabel: use the correct CIPSOv4 MLS label limits
2006-11-17 22:38 [PATCH 00/13] NetLabel cleanups for 2.6.20 paul.moore
` (7 preceding siblings ...)
2006-11-17 22:38 ` [PATCH 08/13] NetLabel: return the correct error for translated CIPSOv4 tags paul.moore
@ 2006-11-17 22:38 ` paul.moore
2006-11-17 22:38 ` [PATCH 10/13] NetLabel: use cipso_v4_doi_search() for local CIPSOv4 functions paul.moore
` (4 subsequent siblings)
13 siblings, 0 replies; 20+ messages in thread
From: paul.moore @ 2006-11-17 22:38 UTC (permalink / raw)
To: netdev, selinux; +Cc: jmorris, Paul Moore
[-- Attachment #1: netlabel-cipso_mlslimits --]
[-- Type: text/plain, Size: 1164 bytes --]
From: Paul Moore <paul.moore@hp.com>
The CIPSOv4 engine currently has MLS label limits which are slightly larger
than what the draft allows. This is not a major problem due to the current
implementation but we should fix this so it doesn't bite us later.
Signed-off-by: Paul Moore <paul.moore@hp.com>
---
include/net/cipso_ipv4.h | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
Index: net-2.6.20_netlabel-base-work/include/net/cipso_ipv4.h
===================================================================
--- net-2.6.20_netlabel-base-work.orig/include/net/cipso_ipv4.h
+++ net-2.6.20_netlabel-base-work/include/net/cipso_ipv4.h
@@ -58,10 +58,10 @@
#define CIPSO_V4_MAP_PASS 2
/* limits */
-#define CIPSO_V4_MAX_REM_LVLS 256
+#define CIPSO_V4_MAX_REM_LVLS 255
#define CIPSO_V4_INV_LVL 0x80000000
#define CIPSO_V4_MAX_LOC_LVLS (CIPSO_V4_INV_LVL - 1)
-#define CIPSO_V4_MAX_REM_CATS 65536
+#define CIPSO_V4_MAX_REM_CATS 65534
#define CIPSO_V4_INV_CAT 0x80000000
#define CIPSO_V4_MAX_LOC_CATS (CIPSO_V4_INV_CAT - 1)
--
paul moore
linux security @ hp
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH 10/13] NetLabel: use cipso_v4_doi_search() for local CIPSOv4 functions
2006-11-17 22:38 [PATCH 00/13] NetLabel cleanups for 2.6.20 paul.moore
` (8 preceding siblings ...)
2006-11-17 22:38 ` [PATCH 09/13] NetLabel: use the correct CIPSOv4 MLS label limits paul.moore
@ 2006-11-17 22:38 ` paul.moore
2006-11-24 1:24 ` Eric Paris
2006-11-17 22:38 ` [PATCH 11/13] NetLabel: SELinux cleanups paul.moore
` (3 subsequent siblings)
13 siblings, 1 reply; 20+ messages in thread
From: paul.moore @ 2006-11-17 22:38 UTC (permalink / raw)
To: netdev, selinux; +Cc: jmorris
[-- Attachment #1: netlabel-cipso_staticfuncs --]
[-- Type: text/plain, Size: 1428 bytes --]
From: Paul Moore <paul.moore@hp.com>
The cipso_v4_doi_search() function behaves the same as cipso_v4_doi_getdef()
but is a local, static function so use it whenever possibile in the CIPSOv4
code base.
Signed-of-by: Paul Moore <paul.moore@hp.com>
---
net/ipv4/cipso_ipv4.c | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
Index: net-2.6.20_netlabel-base-work/net/ipv4/cipso_ipv4.c
===================================================================
--- net-2.6.20_netlabel-base-work.orig/net/ipv4/cipso_ipv4.c
+++ net-2.6.20_netlabel-base-work/net/ipv4/cipso_ipv4.c
@@ -1136,7 +1136,7 @@ int cipso_v4_validate(unsigned char **op
}
rcu_read_lock();
- doi_def = cipso_v4_doi_getdef(ntohl(*((__be32 *)&opt[2])));
+ doi_def = cipso_v4_doi_search(ntohl(*((u32 *)&opt[2])));
if (doi_def == NULL) {
err_offset = 2;
goto validate_return_locked;
@@ -1381,7 +1381,7 @@ int cipso_v4_sock_getattr(struct sock *s
doi = ntohl(*(__be32 *)&cipso_ptr[2]);
rcu_read_lock();
- doi_def = cipso_v4_doi_getdef(doi);
+ doi_def = cipso_v4_doi_search(doi);
if (doi_def == NULL) {
rcu_read_unlock();
return -ENOMSG;
@@ -1449,7 +1449,7 @@ int cipso_v4_skbuff_getattr(const struct
doi = ntohl(*(__be32 *)&cipso_ptr[2]);
rcu_read_lock();
- doi_def = cipso_v4_doi_getdef(doi);
+ doi_def = cipso_v4_doi_search(doi);
if (doi_def == NULL)
goto skbuff_getattr_return;
--
paul moore
linux security @ hp
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH 11/13] NetLabel: SELinux cleanups
2006-11-17 22:38 [PATCH 00/13] NetLabel cleanups for 2.6.20 paul.moore
` (9 preceding siblings ...)
2006-11-17 22:38 ` [PATCH 10/13] NetLabel: use cipso_v4_doi_search() for local CIPSOv4 functions paul.moore
@ 2006-11-17 22:38 ` paul.moore
2006-11-17 22:38 ` [PATCH 12/13] SELinux: peer secid consolidation for external network labeling paul.moore
` (2 subsequent siblings)
13 siblings, 0 replies; 20+ messages in thread
From: paul.moore @ 2006-11-17 22:38 UTC (permalink / raw)
To: netdev, selinux; +Cc: jmorris, Paul Moore
[-- Attachment #1: netlabel-selinux_cleanup --]
[-- Type: text/plain, Size: 12253 bytes --]
From: Paul Moore <paul.moore@hp.com>
This patch does a lot of cleanup in the SELinux NetLabel support code. A
summary of the changes include:
* Use RCU locking for the NetLabel state variable in the skk_security_struct
instead of using the inode_security_struct mutex.
* Remove unnecessary parameters in selinux_netlbl_socket_post_create().
* Rename selinux_netlbl_sk_clone_security() to
selinux_netlbl_sk_security_clone() to better fit the other NetLabel
sk_security functions.
* Improvements to selinux_netlbl_inode_permission() to help reduce the cost of
the common case.
Signed-off-by: Paul Moore <paul.moore@hp.com>
---
security/selinux/hooks.c | 10 +-
security/selinux/include/objsec.h | 2
security/selinux/include/selinux_netlabel.h | 21 +++--
security/selinux/ss/services.c | 107 +++++++++++++++++-----------
4 files changed, 86 insertions(+), 54 deletions(-)
Index: net-2.6.20_netlabel-base-work/security/selinux/hooks.c
===================================================================
--- net-2.6.20_netlabel-base-work.orig/security/selinux/hooks.c
+++ net-2.6.20_netlabel-base-work/security/selinux/hooks.c
@@ -3139,9 +3139,7 @@ static int selinux_socket_post_create(st
if (sock->sk) {
sksec = sock->sk->sk_security;
sksec->sid = isec->sid;
- err = selinux_netlbl_socket_post_create(sock,
- family,
- isec->sid);
+ err = selinux_netlbl_socket_post_create(sock);
}
return err;
@@ -3660,7 +3658,7 @@ static void selinux_sk_clone_security(co
newssec->sid = ssec->sid;
newssec->peer_sid = ssec->peer_sid;
- selinux_netlbl_sk_clone_security(ssec, newssec);
+ selinux_netlbl_sk_security_clone(ssec, newssec);
}
static void selinux_sk_getsecid(struct sock *sk, u32 *secid)
@@ -3729,7 +3727,9 @@ static void selinux_inet_csk_clone(struc
So we will wait until sock_graft to do it, by which
time it will have been created and available. */
- selinux_netlbl_sk_security_init(newsksec, req->rsk_ops->family);
+ /* We don't need to take any sort of lock here as we are the only
+ * thread with access to newsksec */
+ selinux_netlbl_sk_security_reset(newsksec, req->rsk_ops->family);
}
static void selinux_inet_conn_established(struct sock *sk,
Index: net-2.6.20_netlabel-base-work/security/selinux/include/objsec.h
===================================================================
--- net-2.6.20_netlabel-base-work.orig/security/selinux/include/objsec.h
+++ net-2.6.20_netlabel-base-work/security/selinux/include/objsec.h
@@ -23,6 +23,7 @@
#include <linux/fs.h>
#include <linux/binfmts.h>
#include <linux/in.h>
+#include <linux/spinlock.h>
#include "flask.h"
#include "avc.h"
@@ -108,6 +109,7 @@ struct sk_security_struct {
NLBL_REQUIRE,
NLBL_LABELED,
} nlbl_state;
+ spinlock_t nlbl_lock; /* protects nlbl_state */
#endif
};
Index: net-2.6.20_netlabel-base-work/security/selinux/include/selinux_netlabel.h
===================================================================
--- net-2.6.20_netlabel-base-work.orig/security/selinux/include/selinux_netlabel.h
+++ net-2.6.20_netlabel-base-work/security/selinux/include/selinux_netlabel.h
@@ -38,9 +38,7 @@
#ifdef CONFIG_NETLABEL
void selinux_netlbl_cache_invalidate(void);
-int selinux_netlbl_socket_post_create(struct socket *sock,
- int sock_family,
- u32 sid);
+int selinux_netlbl_socket_post_create(struct socket *sock);
void selinux_netlbl_sock_graft(struct sock *sk, struct socket *sock);
u32 selinux_netlbl_inet_conn_request(struct sk_buff *skb, u32 sock_sid);
int selinux_netlbl_sock_rcv_skb(struct sk_security_struct *sksec,
@@ -48,9 +46,11 @@ int selinux_netlbl_sock_rcv_skb(struct s
struct avc_audit_data *ad);
u32 selinux_netlbl_socket_getpeersec_stream(struct socket *sock);
u32 selinux_netlbl_socket_getpeersec_dgram(struct sk_buff *skb);
+void selinux_netlbl_sk_security_reset(struct sk_security_struct *ssec,
+ int family);
void selinux_netlbl_sk_security_init(struct sk_security_struct *ssec,
int family);
-void selinux_netlbl_sk_clone_security(struct sk_security_struct *ssec,
+void selinux_netlbl_sk_security_clone(struct sk_security_struct *ssec,
struct sk_security_struct *newssec);
int selinux_netlbl_inode_permission(struct inode *inode, int mask);
int selinux_netlbl_socket_setsockopt(struct socket *sock,
@@ -62,9 +62,7 @@ static inline void selinux_netlbl_cache_
return;
}
-static inline int selinux_netlbl_socket_post_create(struct socket *sock,
- int sock_family,
- u32 sid)
+static inline int selinux_netlbl_socket_post_create(struct socket *sock)
{
return 0;
}
@@ -98,6 +96,13 @@ static inline u32 selinux_netlbl_socket_
return SECSID_NULL;
}
+static inline void selinux_netlbl_sk_security_reset(
+ struct sk_security_struct *ssec,
+ int family)
+{
+ return;
+}
+
static inline void selinux_netlbl_sk_security_init(
struct sk_security_struct *ssec,
int family)
@@ -105,7 +110,7 @@ static inline void selinux_netlbl_sk_sec
return;
}
-static inline void selinux_netlbl_sk_clone_security(
+static inline void selinux_netlbl_sk_security_clone(
struct sk_security_struct *ssec,
struct sk_security_struct *newssec)
{
Index: net-2.6.20_netlabel-base-work/security/selinux/ss/services.c
===================================================================
--- net-2.6.20_netlabel-base-work.orig/security/selinux/ss/services.c
+++ net-2.6.20_netlabel-base-work/security/selinux/ss/services.c
@@ -29,6 +29,7 @@
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/spinlock.h>
+#include <linux/rcupdate.h>
#include <linux/errno.h>
#include <linux/in.h>
#include <linux/sched.h>
@@ -2390,7 +2391,9 @@ static int selinux_netlbl_skbuff_getsid(
*
* Description:
* Attempt to label a socket using the NetLabel mechanism using the given
- * SID. Returns zero values on success, negative values on failure.
+ * SID. Returns zero values on success, negative values on failure. The
+ * caller is responsibile for calling rcu_read_lock() before calling this
+ * this function and rcu_read_unlock() after this function returns.
*
*/
static int selinux_netlbl_socket_setsid(struct socket *sock, u32 sid)
@@ -2427,8 +2430,11 @@ static int selinux_netlbl_socket_setsid(
secattr.flags |= NETLBL_SECATTR_MLS_CAT;
rc = netlbl_socket_setattr(sock, &secattr);
- if (rc == 0)
+ if (rc == 0) {
+ spin_lock(&sksec->nlbl_lock);
sksec->nlbl_state = NLBL_LABELED;
+ spin_unlock(&sksec->nlbl_lock);
+ }
netlbl_socket_setsid_return:
POLICY_RDUNLOCK;
@@ -2437,6 +2443,25 @@ netlbl_socket_setsid_return:
}
/**
+ * selinux_netlbl_sk_security_reset - Reset the NetLabel fields
+ * @ssec: the sk_security_struct
+ * @family: the socket family
+ *
+ * Description:
+ * Called when the NetLabel state of a sk_security_struct needs to be reset.
+ * The caller is responsibile for all the NetLabel sk_security_struct locking.
+ *
+ */
+void selinux_netlbl_sk_security_reset(struct sk_security_struct *ssec,
+ int family)
+{
+ if (family == PF_INET)
+ ssec->nlbl_state = NLBL_REQUIRE;
+ else
+ ssec->nlbl_state = NLBL_UNSET;
+}
+
+/**
* selinux_netlbl_sk_security_init - Setup the NetLabel fields
* @ssec: the sk_security_struct
* @family: the socket family
@@ -2449,14 +2474,13 @@ netlbl_socket_setsid_return:
void selinux_netlbl_sk_security_init(struct sk_security_struct *ssec,
int family)
{
- if (family == PF_INET)
- ssec->nlbl_state = NLBL_REQUIRE;
- else
- ssec->nlbl_state = NLBL_UNSET;
+ /* No locking needed, we are the only one who has access to ssec */
+ selinux_netlbl_sk_security_reset(ssec, family);
+ spin_lock_init(&ssec->nlbl_lock);
}
/**
- * selinux_netlbl_sk_clone_security - Copy the NetLabel fields
+ * selinux_netlbl_sk_security_clone - Copy the NetLabel fields
* @ssec: the original sk_security_struct
* @newssec: the cloned sk_security_struct
*
@@ -2465,41 +2489,41 @@ void selinux_netlbl_sk_security_init(str
* @newssec.
*
*/
-void selinux_netlbl_sk_clone_security(struct sk_security_struct *ssec,
+void selinux_netlbl_sk_security_clone(struct sk_security_struct *ssec,
struct sk_security_struct *newssec)
{
+ /* We don't need to take newssec->nlbl_lock because we are the only
+ * thread with access to newssec, but we do need to take the RCU read
+ * lock as other threads could have access to ssec */
+ rcu_read_lock();
+ selinux_netlbl_sk_security_reset(newssec, ssec->sk->sk_family);
newssec->sclass = ssec->sclass;
- if (ssec->nlbl_state != NLBL_UNSET)
- newssec->nlbl_state = NLBL_REQUIRE;
- else
- newssec->nlbl_state = NLBL_UNSET;
+ rcu_read_unlock();
}
/**
* selinux_netlbl_socket_post_create - Label a socket using NetLabel
* @sock: the socket to label
- * @sock_family: the socket family
- * @sid: the SID to use
*
* Description:
* Attempt to label a socket using the NetLabel mechanism using the given
* SID. Returns zero values on success, negative values on failure.
*
*/
-int selinux_netlbl_socket_post_create(struct socket *sock,
- int sock_family,
- u32 sid)
+int selinux_netlbl_socket_post_create(struct socket *sock)
{
+ int rc = 0;
struct inode_security_struct *isec = SOCK_INODE(sock)->i_security;
struct sk_security_struct *sksec = sock->sk->sk_security;
sksec->sclass = isec->sclass;
- if (sock_family != PF_INET)
- return 0;
+ rcu_read_lock();
+ if (sksec->nlbl_state == NLBL_REQUIRE)
+ rc = selinux_netlbl_socket_setsid(sock, sksec->sid);
+ rcu_read_unlock();
- sksec->nlbl_state = NLBL_REQUIRE;
- return selinux_netlbl_socket_setsid(sock, sid);
+ return rc;
}
/**
@@ -2521,8 +2545,12 @@ void selinux_netlbl_sock_graft(struct so
sksec->sclass = isec->sclass;
- if (sk->sk_family != PF_INET)
+ rcu_read_lock();
+
+ if (sksec->nlbl_state != NLBL_REQUIRE) {
+ rcu_read_unlock();
return;
+ }
netlbl_secattr_init(&secattr);
if (netlbl_sock_getattr(sk, &secattr) == 0 &&
@@ -2534,12 +2562,12 @@ void selinux_netlbl_sock_graft(struct so
sksec->peer_sid = nlbl_peer_sid;
netlbl_secattr_destroy(&secattr);
- sksec->nlbl_state = NLBL_REQUIRE;
-
/* Try to set the NetLabel on the socket to save time later, if we fail
* here we will pick up the pieces in later calls to
* selinux_netlbl_inode_permission(). */
selinux_netlbl_socket_setsid(sock, sksec->sid);
+
+ rcu_read_unlock();
}
/**
@@ -2580,25 +2608,24 @@ u32 selinux_netlbl_inet_conn_request(str
int selinux_netlbl_inode_permission(struct inode *inode, int mask)
{
int rc;
- struct inode_security_struct *isec;
struct sk_security_struct *sksec;
struct socket *sock;
- if (!S_ISSOCK(inode->i_mode))
+ if (!S_ISSOCK(inode->i_mode) ||
+ ((mask & (MAY_WRITE | MAY_APPEND)) == 0))
return 0;
-
sock = SOCKET_I(inode);
- isec = inode->i_security;
sksec = sock->sk->sk_security;
- mutex_lock(&isec->lock);
- if (unlikely(sksec->nlbl_state == NLBL_REQUIRE &&
- (mask & (MAY_WRITE | MAY_APPEND)))) {
- lock_sock(sock->sk);
- rc = selinux_netlbl_socket_setsid(sock, sksec->sid);
- release_sock(sock->sk);
- } else
- rc = 0;
- mutex_unlock(&isec->lock);
+
+ rcu_read_lock();
+ if (sksec->nlbl_state != NLBL_REQUIRE) {
+ rcu_read_unlock();
+ return 0;
+ }
+ lock_sock(sock->sk);
+ rc = selinux_netlbl_socket_setsid(sock, sksec->sid);
+ release_sock(sock->sk);
+ rcu_read_unlock();
return rc;
}
@@ -2709,12 +2736,10 @@ int selinux_netlbl_socket_setsockopt(str
int optname)
{
int rc = 0;
- struct inode *inode = SOCK_INODE(sock);
struct sk_security_struct *sksec = sock->sk->sk_security;
- struct inode_security_struct *isec = inode->i_security;
struct netlbl_lsm_secattr secattr;
- mutex_lock(&isec->lock);
+ rcu_read_lock();
if (level == IPPROTO_IP && optname == IP_OPTIONS &&
sksec->nlbl_state == NLBL_LABELED) {
netlbl_secattr_init(&secattr);
@@ -2723,7 +2748,7 @@ int selinux_netlbl_socket_setsockopt(str
rc = -EACCES;
netlbl_secattr_destroy(&secattr);
}
- mutex_unlock(&isec->lock);
+ rcu_read_unlock();
return rc;
}
--
paul moore
linux security @ hp
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH 12/13] SELinux: peer secid consolidation for external network labeling
2006-11-17 22:38 [PATCH 00/13] NetLabel cleanups for 2.6.20 paul.moore
` (10 preceding siblings ...)
2006-11-17 22:38 ` [PATCH 11/13] NetLabel: SELinux cleanups paul.moore
@ 2006-11-17 22:38 ` paul.moore
2006-11-17 22:38 ` [PATCH 13/13] NetLabel: honor the audit_enabled flag paul.moore
2006-11-18 4:12 ` [PATCH 00/13] NetLabel cleanups for 2.6.20 [GIT] James Morris
13 siblings, 0 replies; 20+ messages in thread
From: paul.moore @ 2006-11-17 22:38 UTC (permalink / raw)
To: netdev, selinux; +Cc: jmorris, Paul Moore
[-- Attachment #1: netlabel-selinux_peersec --]
[-- Type: text/plain, Size: 12270 bytes --]
From: Paul Moore <paul.moore@hp.com>
Now that labeled IPsec makes use of the peer_sid field in the
sk_security_struct we can remove a lot of the special cases between labeled
IPsec and NetLabel. In addition, create a new function,
security_skb_extlbl_sid(), which we can use in several places to get the
security context of the packet's external label which allows us to further
simplify the code in a few places.
Signed-off-by: Paul Moore <paul.moore@hp.com>
---
security/selinux/hooks.c | 43 +++----------
security/selinux/include/security.h | 3
security/selinux/include/selinux_netlabel.h | 28 ++------
security/selinux/include/xfrm.h | 5 -
security/selinux/ss/services.c | 90 ++++++++--------------------
security/selinux/xfrm.c | 33 ----------
6 files changed, 52 insertions(+), 150 deletions(-)
Index: net-2.6.20_netlabel-base-work/security/selinux/hooks.c
===================================================================
--- net-2.6.20_netlabel-base-work.orig/security/selinux/hooks.c
+++ net-2.6.20_netlabel-base-work/security/selinux/hooks.c
@@ -3573,27 +3573,16 @@ static int selinux_socket_getpeersec_str
u32 scontext_len;
struct sk_security_struct *ssec;
struct inode_security_struct *isec;
- u32 peer_sid = 0;
+ u32 peer_sid = SECSID_NULL;
isec = SOCK_INODE(sock)->i_security;
- /* if UNIX_STREAM check peer_sid, if TCP check dst for labelled sa */
- if (isec->sclass == SECCLASS_UNIX_STREAM_SOCKET) {
+ if (isec->sclass == SECCLASS_UNIX_STREAM_SOCKET ||
+ isec->sclass == SECCLASS_TCP_SOCKET) {
ssec = sock->sk->sk_security;
peer_sid = ssec->peer_sid;
}
- else if (isec->sclass == SECCLASS_TCP_SOCKET) {
- peer_sid = selinux_netlbl_socket_getpeersec_stream(sock);
- if (peer_sid == SECSID_NULL) {
- ssec = sock->sk->sk_security;
- peer_sid = ssec->peer_sid;
- }
- if (peer_sid == SECSID_NULL) {
- err = -ENOPROTOOPT;
- goto out;
- }
- }
- else {
+ if (peer_sid == SECSID_NULL) {
err = -ENOPROTOOPT;
goto out;
}
@@ -3625,13 +3614,12 @@ static int selinux_socket_getpeersec_dgr
u32 peer_secid = SECSID_NULL;
int err = 0;
- if (sock && (sock->sk->sk_family == PF_UNIX))
+ if (sock && sock->sk->sk_family == PF_UNIX)
selinux_get_inode_sid(SOCK_INODE(sock), &peer_secid);
- else if (skb) {
- peer_secid = selinux_netlbl_socket_getpeersec_dgram(skb);
- if (peer_secid == SECSID_NULL)
- peer_secid = selinux_socket_getpeer_dgram(skb);
- }
+ else if (skb)
+ security_skb_extlbl_sid(skb,
+ SECINITSID_UNLABELED,
+ &peer_secid);
if (peer_secid == SECSID_NULL)
err = -EINVAL;
@@ -3692,17 +3680,10 @@ static int selinux_inet_conn_request(str
u32 newsid;
u32 peersid;
- newsid = selinux_netlbl_inet_conn_request(skb, sksec->sid);
- if (newsid != SECSID_NULL) {
- req->secid = newsid;
- return 0;
- }
-
- selinux_skb_xfrm_sid(skb, &peersid);
-
+ security_skb_extlbl_sid(skb, SECINITSID_UNLABELED, &peersid);
if (peersid == SECSID_NULL) {
req->secid = sksec->sid;
- req->peer_secid = 0;
+ req->peer_secid = SECSID_NULL;
return 0;
}
@@ -3737,7 +3718,7 @@ static void selinux_inet_conn_establishe
{
struct sk_security_struct *sksec = sk->sk_security;
- selinux_skb_xfrm_sid(skb, &sksec->peer_sid);
+ security_skb_extlbl_sid(skb, SECINITSID_UNLABELED, &sksec->peer_sid);
}
static void selinux_req_classify_flow(const struct request_sock *req,
Index: net-2.6.20_netlabel-base-work/security/selinux/include/security.h
===================================================================
--- net-2.6.20_netlabel-base-work.orig/security/selinux/include/security.h
+++ net-2.6.20_netlabel-base-work/security/selinux/include/security.h
@@ -8,6 +8,7 @@
#ifndef _SELINUX_SECURITY_H_
#define _SELINUX_SECURITY_H_
+#include <linux/skbuff.h>
#include "flask.h"
#define SECSID_NULL 0x00000000 /* unspecified SID */
@@ -80,6 +81,8 @@ int security_netif_sid(char *name, u32 *
int security_node_sid(u16 domain, void *addr, u32 addrlen,
u32 *out_sid);
+void security_skb_extlbl_sid(struct sk_buff *skb, u32 base_sid, u32 *sid);
+
int security_validate_transition(u32 oldsid, u32 newsid, u32 tasksid,
u16 tclass);
Index: net-2.6.20_netlabel-base-work/security/selinux/include/selinux_netlabel.h
===================================================================
--- net-2.6.20_netlabel-base-work.orig/security/selinux/include/selinux_netlabel.h
+++ net-2.6.20_netlabel-base-work/security/selinux/include/selinux_netlabel.h
@@ -38,14 +38,12 @@
#ifdef CONFIG_NETLABEL
void selinux_netlbl_cache_invalidate(void);
+int selinux_netlbl_skbuff_getsid(struct sk_buff *skb, u32 base_sid, u32 *sid);
int selinux_netlbl_socket_post_create(struct socket *sock);
void selinux_netlbl_sock_graft(struct sock *sk, struct socket *sock);
-u32 selinux_netlbl_inet_conn_request(struct sk_buff *skb, u32 sock_sid);
int selinux_netlbl_sock_rcv_skb(struct sk_security_struct *sksec,
struct sk_buff *skb,
struct avc_audit_data *ad);
-u32 selinux_netlbl_socket_getpeersec_stream(struct socket *sock);
-u32 selinux_netlbl_socket_getpeersec_dgram(struct sk_buff *skb);
void selinux_netlbl_sk_security_reset(struct sk_security_struct *ssec,
int family);
void selinux_netlbl_sk_security_init(struct sk_security_struct *ssec,
@@ -62,6 +60,14 @@ static inline void selinux_netlbl_cache_
return;
}
+static inline int selinux_netlbl_skbuff_getsid(struct sk_buff *skb,
+ u32 base_sid,
+ u32 *sid)
+{
+ *sid = SECSID_NULL;
+ return 0;
+}
+
static inline int selinux_netlbl_socket_post_create(struct socket *sock)
{
return 0;
@@ -73,12 +79,6 @@ static inline void selinux_netlbl_sock_g
return;
}
-static inline u32 selinux_netlbl_inet_conn_request(struct sk_buff *skb,
- u32 sock_sid)
-{
- return SECSID_NULL;
-}
-
static inline int selinux_netlbl_sock_rcv_skb(struct sk_security_struct *sksec,
struct sk_buff *skb,
struct avc_audit_data *ad)
@@ -86,16 +86,6 @@ static inline int selinux_netlbl_sock_rc
return 0;
}
-static inline u32 selinux_netlbl_socket_getpeersec_stream(struct socket *sock)
-{
- return SECSID_NULL;
-}
-
-static inline u32 selinux_netlbl_socket_getpeersec_dgram(struct sk_buff *skb)
-{
- return SECSID_NULL;
-}
-
static inline void selinux_netlbl_sk_security_reset(
struct sk_security_struct *ssec,
int family)
Index: net-2.6.20_netlabel-base-work/security/selinux/include/xfrm.h
===================================================================
--- net-2.6.20_netlabel-base-work.orig/security/selinux/include/xfrm.h
+++ net-2.6.20_netlabel-base-work/security/selinux/include/xfrm.h
@@ -36,7 +36,6 @@ int selinux_xfrm_sock_rcv_skb(u32 sid, s
struct avc_audit_data *ad);
int selinux_xfrm_postroute_last(u32 isec_sid, struct sk_buff *skb,
struct avc_audit_data *ad, u8 proto);
-u32 selinux_socket_getpeer_dgram(struct sk_buff *skb);
int selinux_xfrm_decode_session(struct sk_buff *skb, u32 *sid, int ckall);
#else
static inline int selinux_xfrm_sock_rcv_skb(u32 isec_sid, struct sk_buff *skb,
@@ -51,10 +50,6 @@ static inline int selinux_xfrm_postroute
return 0;
}
-static inline int selinux_socket_getpeer_dgram(struct sk_buff *skb)
-{
- return SECSID_NULL;
-}
static inline int selinux_xfrm_decode_session(struct sk_buff *skb, u32 *sid, int ckall)
{
*sid = SECSID_NULL;
Index: net-2.6.20_netlabel-base-work/security/selinux/ss/services.c
===================================================================
--- net-2.6.20_netlabel-base-work.orig/security/selinux/ss/services.c
+++ net-2.6.20_netlabel-base-work/security/selinux/ss/services.c
@@ -50,6 +50,7 @@
#include "mls.h"
#include "objsec.h"
#include "selinux_netlabel.h"
+#include "xfrm.h"
extern void selnl_notify_policyload(u32 seqno);
unsigned int policydb_loaded_version;
@@ -2146,6 +2147,32 @@ void selinux_audit_set_callback(int (*ca
aurule_callback = callback;
}
+/**
+ * security_skb_extlbl_sid - Determine the external label of a packet
+ * @skb: the packet
+ * @base_sid: the SELinux SID to use as a context for MLS only external labels
+ * @sid: the packet's SID
+ *
+ * Description:
+ * Check the various different forms of external packet labeling and determine
+ * the external SID for the packet.
+ *
+ */
+void security_skb_extlbl_sid(struct sk_buff *skb, u32 base_sid, u32 *sid)
+{
+ u32 xfrm_sid;
+ u32 nlbl_sid;
+
+ selinux_skb_xfrm_sid(skb, &xfrm_sid);
+ if (selinux_netlbl_skbuff_getsid(skb,
+ (xfrm_sid == SECSID_NULL ?
+ base_sid : xfrm_sid),
+ &nlbl_sid) != 0)
+ nlbl_sid = SECSID_NULL;
+
+ *sid = (nlbl_sid == SECSID_NULL ? xfrm_sid : nlbl_sid);
+}
+
#ifdef CONFIG_NETLABEL
/*
* This is the structure we store inside the NetLabel cache block.
@@ -2363,9 +2390,7 @@ netlbl_secattr_to_sid_return_cleanup:
* assign to the packet. Returns zero on success, negative values on failure.
*
*/
-static int selinux_netlbl_skbuff_getsid(struct sk_buff *skb,
- u32 base_sid,
- u32 *sid)
+int selinux_netlbl_skbuff_getsid(struct sk_buff *skb, u32 base_sid, u32 *sid)
{
int rc;
struct netlbl_lsm_secattr secattr;
@@ -2571,29 +2596,6 @@ void selinux_netlbl_sock_graft(struct so
}
/**
- * selinux_netlbl_inet_conn_request - Handle a new connection request
- * @skb: the packet
- * @sock_sid: the SID of the parent socket
- *
- * Description:
- * If present, use the security attributes of the packet in @skb and the
- * parent sock's SID to arrive at a SID for the new child sock. Returns the
- * SID of the connection or SECSID_NULL on failure.
- *
- */
-u32 selinux_netlbl_inet_conn_request(struct sk_buff *skb, u32 sock_sid)
-{
- int rc;
- u32 peer_sid;
-
- rc = selinux_netlbl_skbuff_getsid(skb, sock_sid, &peer_sid);
- if (rc != 0)
- return SECSID_NULL;
-
- return peer_sid;
-}
-
-/**
* selinux_netlbl_inode_permission - Verify the socket is NetLabel labeled
* @inode: the file descriptor's inode
* @mask: the permission mask
@@ -2683,42 +2685,6 @@ int selinux_netlbl_sock_rcv_skb(struct s
}
/**
- * selinux_netlbl_socket_getpeersec_stream - Return the connected peer's SID
- * @sock: the socket
- *
- * Description:
- * Examine @sock to find the connected peer's SID. Returns the SID on success
- * or SECSID_NULL on error.
- *
- */
-u32 selinux_netlbl_socket_getpeersec_stream(struct socket *sock)
-{
- struct sk_security_struct *sksec = sock->sk->sk_security;
- return sksec->peer_sid;
-}
-
-/**
- * selinux_netlbl_socket_getpeersec_dgram - Return the SID of a NetLabel packet
- * @skb: the packet
- *
- * Description:
- * Examine @skb to find the SID assigned to it by NetLabel. Returns the SID on
- * success, SECSID_NULL on error.
- *
- */
-u32 selinux_netlbl_socket_getpeersec_dgram(struct sk_buff *skb)
-{
- int peer_sid;
-
- if (selinux_netlbl_skbuff_getsid(skb,
- SECINITSID_UNLABELED,
- &peer_sid) != 0)
- return SECSID_NULL;
-
- return peer_sid;
-}
-
-/**
* selinux_netlbl_socket_setsockopt - Do not allow users to remove a NetLabel
* @sock: the socket
* @level: the socket level or protocol
Index: net-2.6.20_netlabel-base-work/security/selinux/xfrm.c
===================================================================
--- net-2.6.20_netlabel-base-work.orig/security/selinux/xfrm.c
+++ net-2.6.20_netlabel-base-work/security/selinux/xfrm.c
@@ -372,39 +372,6 @@ void selinux_xfrm_state_free(struct xfrm
kfree(ctx);
}
-/*
- * SELinux internal function to retrieve the context of a UDP packet
- * based on its security association.
- *
- * Retrieve via setsockopt IP_PASSSEC and recvmsg with control message
- * type SCM_SECURITY.
- */
-u32 selinux_socket_getpeer_dgram(struct sk_buff *skb)
-{
- struct sec_path *sp;
-
- if (skb == NULL)
- return SECSID_NULL;
-
- if (skb->sk->sk_protocol != IPPROTO_UDP)
- return SECSID_NULL;
-
- sp = skb->sp;
- if (sp) {
- int i;
-
- for (i = sp->len-1; i >= 0; i--) {
- struct xfrm_state *x = sp->xvec[i];
- if (selinux_authorizable_xfrm(x)) {
- struct xfrm_sec_ctx *ctx = x->security;
- return ctx->ctx_sid;
- }
- }
- }
-
- return SECSID_NULL;
-}
-
/*
* LSM hook implementation that authorizes deletion of labeled SAs.
*/
--
paul moore
linux security @ hp
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH 13/13] NetLabel: honor the audit_enabled flag
2006-11-17 22:38 [PATCH 00/13] NetLabel cleanups for 2.6.20 paul.moore
` (11 preceding siblings ...)
2006-11-17 22:38 ` [PATCH 12/13] SELinux: peer secid consolidation for external network labeling paul.moore
@ 2006-11-17 22:38 ` paul.moore
2006-11-18 4:12 ` [PATCH 00/13] NetLabel cleanups for 2.6.20 [GIT] James Morris
13 siblings, 0 replies; 20+ messages in thread
From: paul.moore @ 2006-11-17 22:38 UTC (permalink / raw)
To: netdev, selinux; +Cc: jmorris, Paul Moore
[-- Attachment #1: netlabel-audit_disabled --]
[-- Type: text/plain, Size: 6245 bytes --]
From: Paul Moore <paul.moore@hp.com>
The audit_enabled flag is used to signal when syscall auditing is to be
performed. While NetLabel uses a Netlink interface instead of syscalls, it is
reasonable to consider the NetLabel Netlink interface as a form of syscall so
pay attention to the audit_enabled flag when generating audit messages in
NetLabel.
Signed-off-by: Paul Moore <paul.moore@hp.com>
---
net/netlabel/netlabel_cipso_v4.c | 26 +++++++++++---------
net/netlabel/netlabel_domainhash.c | 48 ++++++++++++++++---------------------
net/netlabel/netlabel_unlabeled.c | 8 ++++--
net/netlabel/netlabel_user.c | 7 +++++
4 files changed, 50 insertions(+), 39 deletions(-)
Index: net-2.6.20_netlabel-base-work/net/netlabel/netlabel_cipso_v4.c
===================================================================
--- net-2.6.20_netlabel-base-work.orig/net/netlabel/netlabel_cipso_v4.c
+++ net-2.6.20_netlabel-base-work/net/netlabel/netlabel_cipso_v4.c
@@ -407,12 +407,14 @@ static int netlbl_cipsov4_add(struct sk_
audit_buf = netlbl_audit_start_common(AUDIT_MAC_CIPSOV4_ADD,
&audit_info);
- audit_log_format(audit_buf,
- " cipso_doi=%u cipso_type=%s res=%u",
- doi,
- type_str,
- ret_val == 0 ? 1 : 0);
- audit_log_end(audit_buf);
+ if (audit_buf != NULL) {
+ audit_log_format(audit_buf,
+ " cipso_doi=%u cipso_type=%s res=%u",
+ doi,
+ type_str,
+ ret_val == 0 ? 1 : 0);
+ audit_log_end(audit_buf);
+ }
return ret_val;
}
@@ -680,11 +682,13 @@ static int netlbl_cipsov4_remove(struct
audit_buf = netlbl_audit_start_common(AUDIT_MAC_CIPSOV4_DEL,
&audit_info);
- audit_log_format(audit_buf,
- " cipso_doi=%u res=%u",
- doi,
- ret_val == 0 ? 1 : 0);
- audit_log_end(audit_buf);
+ if (audit_buf != NULL) {
+ audit_log_format(audit_buf,
+ " cipso_doi=%u res=%u",
+ doi,
+ ret_val == 0 ? 1 : 0);
+ audit_log_end(audit_buf);
+ }
return ret_val;
}
Index: net-2.6.20_netlabel-base-work/net/netlabel/netlabel_domainhash.c
===================================================================
--- net-2.6.20_netlabel-base-work.orig/net/netlabel/netlabel_domainhash.c
+++ net-2.6.20_netlabel-base-work/net/netlabel/netlabel_domainhash.c
@@ -202,7 +202,6 @@ int netlbl_domhsh_add(struct netlbl_dom_
int ret_val;
u32 bkt;
struct audit_buffer *audit_buf;
- char *audit_domain;
switch (entry->type) {
case NETLBL_NLTYPE_UNLABELED:
@@ -243,24 +242,24 @@ int netlbl_domhsh_add(struct netlbl_dom_
} else
ret_val = -EINVAL;
- if (entry->domain != NULL)
- audit_domain = entry->domain;
- else
- audit_domain = "(default)";
audit_buf = netlbl_audit_start_common(AUDIT_MAC_MAP_ADD, audit_info);
- audit_log_format(audit_buf, " nlbl_domain=%s", audit_domain);
- switch (entry->type) {
- case NETLBL_NLTYPE_UNLABELED:
- audit_log_format(audit_buf, " nlbl_protocol=unlbl");
- break;
- case NETLBL_NLTYPE_CIPSOV4:
+ if (audit_buf != NULL) {
audit_log_format(audit_buf,
- " nlbl_protocol=cipsov4 cipso_doi=%u",
- entry->type_def.cipsov4->doi);
- break;
+ " nlbl_domain=%s",
+ entry->domain ? entry->domain : "(default)");
+ switch (entry->type) {
+ case NETLBL_NLTYPE_UNLABELED:
+ audit_log_format(audit_buf, " nlbl_protocol=unlbl");
+ break;
+ case NETLBL_NLTYPE_CIPSOV4:
+ audit_log_format(audit_buf,
+ " nlbl_protocol=cipsov4 cipso_doi=%u",
+ entry->type_def.cipsov4->doi);
+ break;
+ }
+ audit_log_format(audit_buf, " res=%u", ret_val == 0 ? 1 : 0);
+ audit_log_end(audit_buf);
}
- audit_log_format(audit_buf, " res=%u", ret_val == 0 ? 1 : 0);
- audit_log_end(audit_buf);
rcu_read_unlock();
@@ -310,7 +309,6 @@ int netlbl_domhsh_remove(const char *dom
int ret_val = -ENOENT;
struct netlbl_dom_map *entry;
struct audit_buffer *audit_buf;
- char *audit_domain;
rcu_read_lock();
if (domain != NULL)
@@ -348,16 +346,14 @@ int netlbl_domhsh_remove(const char *dom
spin_unlock(&netlbl_domhsh_def_lock);
}
- if (entry->domain != NULL)
- audit_domain = entry->domain;
- else
- audit_domain = "(default)";
audit_buf = netlbl_audit_start_common(AUDIT_MAC_MAP_DEL, audit_info);
- audit_log_format(audit_buf,
- " nlbl_domain=%s res=%u",
- audit_domain,
- ret_val == 0 ? 1 : 0);
- audit_log_end(audit_buf);
+ if (audit_buf != NULL) {
+ audit_log_format(audit_buf,
+ " nlbl_domain=%s res=%u",
+ entry->domain ? entry->domain : "(default)",
+ ret_val == 0 ? 1 : 0);
+ audit_log_end(audit_buf);
+ }
if (ret_val == 0)
call_rcu(&entry->rcu, netlbl_domhsh_free_entry);
Index: net-2.6.20_netlabel-base-work/net/netlabel/netlabel_unlabeled.c
===================================================================
--- net-2.6.20_netlabel-base-work.orig/net/netlabel/netlabel_unlabeled.c
+++ net-2.6.20_netlabel-base-work/net/netlabel/netlabel_unlabeled.c
@@ -35,6 +35,7 @@
#include <linux/socket.h>
#include <linux/string.h>
#include <linux/skbuff.h>
+#include <linux/audit.h>
#include <net/sock.h>
#include <net/netlink.h>
#include <net/genetlink.h>
@@ -92,8 +93,11 @@ static void netlbl_unlabel_acceptflg_set
audit_buf = netlbl_audit_start_common(AUDIT_MAC_UNLBL_ALLOW,
audit_info);
- audit_log_format(audit_buf, " unlbl_accept=%u old=%u", value, old_val);
- audit_log_end(audit_buf);
+ if (audit_buf != NULL) {
+ audit_log_format(audit_buf,
+ " unlbl_accept=%u old=%u", value, old_val);
+ audit_log_end(audit_buf);
+ }
}
/*
Index: net-2.6.20_netlabel-base-work/net/netlabel/netlabel_user.c
===================================================================
--- net-2.6.20_netlabel-base-work.orig/net/netlabel/netlabel_user.c
+++ net-2.6.20_netlabel-base-work/net/netlabel/netlabel_user.c
@@ -46,6 +46,10 @@
#include "netlabel_cipso_v4.h"
#include "netlabel_user.h"
+/* do not do any auditing if audit_enabled == 0, see kernel/audit.c for
+ * details */
+extern int audit_enabled;
+
/*
* NetLabel NETLINK Setup Functions
*/
@@ -101,6 +105,9 @@ struct audit_buffer *netlbl_audit_start_
char *secctx;
u32 secctx_len;
+ if (audit_enabled == 0)
+ return NULL;
+
audit_buf = audit_log_start(audit_ctx, GFP_ATOMIC, type);
if (audit_buf == NULL)
return NULL;
--
paul moore
linux security @ hp
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 00/13] NetLabel cleanups for 2.6.20 [GIT]
2006-11-17 22:38 [PATCH 00/13] NetLabel cleanups for 2.6.20 paul.moore
` (12 preceding siblings ...)
2006-11-17 22:38 ` [PATCH 13/13] NetLabel: honor the audit_enabled flag paul.moore
@ 2006-11-18 4:12 ` James Morris
2006-11-18 16:10 ` Paul Moore
13 siblings, 1 reply; 20+ messages in thread
From: James Morris @ 2006-11-18 4:12 UTC (permalink / raw)
To: Paul Moore; +Cc: netdev, selinux
On Fri, 17 Nov 2006, paul.moore@hp.com wrote:
> This patchset consists of a lot of small-ish cleanups for NetLabel and in some
> cases labeled networking in general. I've tested these patches for the past
> few days and I haven't seen any regressions so please consider them for the
> net-2.6.20 git tree.
Thanks, excellent!
There was one minor compilation issue caused by including linux/skbuff.h
in an SELinux header, which I fixed (see below).
Applied to
git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/selinux-net-2.6.20
---
diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h
index 015f697..210eec7 100644
--- a/security/selinux/include/security.h
+++ b/security/selinux/include/security.h
@@ -8,7 +8,6 @@
#ifndef _SELINUX_SECURITY_H_
#define _SELINUX_SECURITY_H_
-#include <linux/skbuff.h>
#include "flask.h"
#define SECSID_NULL 0x00000000 /* unspecified SID */
@@ -35,6 +34,8 @@ #else
#define POLICYDB_VERSION_MAX POLICYDB_VERSION_RANGETRANS
#endif
+struct sk_buff;
+
extern int selinux_enabled;
extern int selinux_mls_enabled;
^ permalink raw reply related [flat|nested] 20+ messages in thread
* Re: [PATCH 00/13] NetLabel cleanups for 2.6.20 [GIT]
2006-11-18 4:12 ` [PATCH 00/13] NetLabel cleanups for 2.6.20 [GIT] James Morris
@ 2006-11-18 16:10 ` Paul Moore
2006-11-19 3:19 ` James Morris
0 siblings, 1 reply; 20+ messages in thread
From: Paul Moore @ 2006-11-18 16:10 UTC (permalink / raw)
To: James Morris; +Cc: netdev, selinux
On Friday 17 November 2006 11:12 pm, James Morris wrote:
> On Fri, 17 Nov 2006, paul.moore@hp.com wrote:
> > This patchset consists of a lot of small-ish cleanups for NetLabel and in
> > some cases labeled networking in general. I've tested these patches for
> > the past few days and I haven't seen any regressions so please consider
> > them for the net-2.6.20 git tree.
>
> Thanks, excellent!
>
> There was one minor compilation issue caused by including linux/skbuff.h
> in an SELinux header, which I fixed (see below).
<scratching head>
Huh, sorry about that ... thanks for accepting the patches and making the fix.
</scratching head>
--
paul moore
linux security @ hp
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 00/13] NetLabel cleanups for 2.6.20 [GIT]
2006-11-18 16:10 ` Paul Moore
@ 2006-11-19 3:19 ` James Morris
0 siblings, 0 replies; 20+ messages in thread
From: James Morris @ 2006-11-19 3:19 UTC (permalink / raw)
To: Paul Moore; +Cc: netdev, selinux
[-- Attachment #1: Type: TEXT/PLAIN, Size: 522 bytes --]
On Sat, 18 Nov 2006, Paul Moore wrote:
> > There was one minor compilation issue caused by including linux/skbuff.h
> > in an SELinux header, which I fixed (see below).
>
> <scratching head>
> Huh, sorry about that ... thanks for accepting the patches and making the fix.
> </scratching head>
Here's the error:
security/selinux/ss/policydb.c:472: error: conflicting types for
â'class_destroy'
include/linux/device.h:295: error: previous declaration of
â'class_destroy' was here
--
James Morris
<jmorris@namei.org>
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 10/13] NetLabel: use cipso_v4_doi_search() for local CIPSOv4 functions
2006-11-17 22:38 ` [PATCH 10/13] NetLabel: use cipso_v4_doi_search() for local CIPSOv4 functions paul.moore
@ 2006-11-24 1:24 ` Eric Paris
2006-11-24 5:53 ` Al Viro
0 siblings, 1 reply; 20+ messages in thread
From: Eric Paris @ 2006-11-24 1:24 UTC (permalink / raw)
To: paul.moore; +Cc: netdev, selinux, jmorris, Alexander Viro
On Fri, 2006-11-17 at 17:38 -0500, paul.moore@hp.com wrote:
> Index: net-2.6.20_netlabel-base-work/net/ipv4/cipso_ipv4.c
> ===================================================================
> --- net-2.6.20_netlabel-base-work.orig/net/ipv4/cipso_ipv4.c
> +++ net-2.6.20_netlabel-base-work/net/ipv4/cipso_ipv4.c
> @@ -1136,7 +1136,7 @@ int cipso_v4_validate(unsigned char **op
> }
>
> rcu_read_lock();
> - doi_def = cipso_v4_doi_getdef(ntohl(*((__be32 *)&opt[2])));
> + doi_def = cipso_v4_doi_search(ntohl(*((u32 *)&opt[2])));
> if (doi_def == NULL) {
> err_offset = 2;
> goto validate_return_locked;
This appears to reverse the previous endian work by Al Viro, was this
intended?
http://www.kernel.org/git/?p=linux/kernel/git/davem/net-2.6.20.git;a=commitdiff;h=8d7d47b647d7bc05443f1a8a5012e6b41be1c827
-Eric
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 10/13] NetLabel: use cipso_v4_doi_search() for local CIPSOv4 functions
2006-11-24 1:24 ` Eric Paris
@ 2006-11-24 5:53 ` Al Viro
0 siblings, 0 replies; 20+ messages in thread
From: Al Viro @ 2006-11-24 5:53 UTC (permalink / raw)
To: Eric Paris; +Cc: paul.moore, netdev, selinux, jmorris, Alexander Viro
On Thu, Nov 23, 2006 at 08:24:34PM -0500, Eric Paris wrote:
> On Fri, 2006-11-17 at 17:38 -0500, paul.moore@hp.com wrote:
>
> > Index: net-2.6.20_netlabel-base-work/net/ipv4/cipso_ipv4.c
> > ===================================================================
> > --- net-2.6.20_netlabel-base-work.orig/net/ipv4/cipso_ipv4.c
> > +++ net-2.6.20_netlabel-base-work/net/ipv4/cipso_ipv4.c
> > @@ -1136,7 +1136,7 @@ int cipso_v4_validate(unsigned char **op
> > }
> >
> > rcu_read_lock();
> > - doi_def = cipso_v4_doi_getdef(ntohl(*((__be32 *)&opt[2])));
> > + doi_def = cipso_v4_doi_search(ntohl(*((u32 *)&opt[2])));
> > if (doi_def == NULL) {
> > err_offset = 2;
> > goto validate_return_locked;
>
>
> This appears to reverse the previous endian work by Al Viro, was this
> intended?
Mismerge, most likely. Fixed in net-2.6.20 since then (
commit 835ec2525544c744333bf0da00049f323eb75c58
Author: Al Viro <viro@zeniv.linux.org.uk>
Date: Mon Nov 20 18:08:37 2006 -0800
[CIPSO]: Missing annotation in cipso_ipv4 update.
)
Note that there are two changes in that line - u32 -> __be32 and
..._getdef -> ..._search. They do not really conflict, but any merge
tool would throw a conflict at that point and apparently it got
resolved the dumb way...
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 10/13] NetLabel: use cipso_v4_doi_search() for local CIPSOv4 functions
@ 2006-11-24 18:59 Paul Moore
0 siblings, 0 replies; 20+ messages in thread
From: Paul Moore @ 2006-11-24 18:59 UTC (permalink / raw)
To: viro; +Cc: eparis, netdev, selinux, jmorris, aviro
-----Original Message-----
From: Al Viro <viro@ftp.linux.org.uk>
Date: Friday, Nov 24, 2006 2:07 am
Subject: Re: [PATCH 10/13] NetLabel: use cipso_v4_doi_search() for local CIPSOv4 functions
On Thu, Nov 23, 2006 at 08:24:34PM -0500, Eric Paris wrote:
> On Fri, 2006-11-17 at 17:38 -0500, paul.moore@hp.com wrote:
>
> > Index: net-2.6.20_netlabel-base-work/net/ipv4/cipso_ipv4.c
> > ===================================================================
> > --- net-2.6.20_netlabel-base-work.orig/net/ipv4/cipso_ipv4.c
> > +++ net-2.6.20_netlabel-base-work/net/ipv4/cipso_ipv4.c
> > @@ -1136,7 +1136,7 @@ int cipso_v4_validate(unsigned char **op
> > }
> >
> > rcu_read_lock();
> > - doi_def = cipso_v4_doi_getdef(ntohl(*((__be32 *)&opt[2])));
> > + doi_def = cipso_v4_doi_search(ntohl(*((u32 *)&opt[2])));
> > if (doi_def == NULL) {
> > err_offset = 2;
> > goto validate_return_locked;
>
>
> This appears to reverse the previous endian work by Al Viro, was this
> intended?
>
>Mismerge, most likely. Fixed in net-2.6.20 since then (
>commit 835ec2525544c744333bf0da00049f323eb75c58
>Author: Al Viro <viro@zeniv.linux.org.uk>
>Date: Mon Nov 20 18:08:37 2006 -0800
>
> [CIPSO]: Missing annotation in cipso_ipv4 update.
>)
>
>Note that there are two changes in that line - u32 -> __be32 and
>..._getdef -> ..._search. They do not really conflict, but any merge tool would throw a conflict at that point and apparently it got
>resolved the dumb way...
>
Yep, Al is right, I just made a dumb mistake when merging my code with the latest net-2.6.20 tree. I thought I caught everything but it looks like I missed one. Sorry.
. paul moore
. linux security @ hp
^ permalink raw reply [flat|nested] 20+ messages in thread
end of thread, other threads:[~2006-11-24 19:00 UTC | newest]
Thread overview: 20+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-11-17 22:38 [PATCH 00/13] NetLabel cleanups for 2.6.20 paul.moore
2006-11-17 22:38 ` [PATCH 01/13] NetLabel: use gfp_t instead of int where it makes sense paul.moore
2006-11-17 22:38 ` [PATCH 02/13] NetLabel: convert the unlabeled accept flag to use RCU paul.moore
2006-11-17 22:38 ` [PATCH 03/13] NetLabel: change netlbl_secattr_init() to return void paul.moore
2006-11-17 22:38 ` [PATCH 04/13] NetLabel: make netlbl_lsm_secattr struct easier/quicker to understand paul.moore
2006-11-17 22:38 ` [PATCH 05/13] NetLabel: check for a CIPSOv4 option before we do call into the CIPSOv4 layer paul.moore
2006-11-17 22:38 ` [PATCH 06/13] NetLabel: add tag verification when adding new CIPSOv4 DOI definitions paul.moore
2006-11-17 22:38 ` [PATCH 07/13] NetLabel: fixup the handling of CIPSOv4 tags to allow for multiple tag types paul.moore
2006-11-17 22:38 ` [PATCH 08/13] NetLabel: return the correct error for translated CIPSOv4 tags paul.moore
2006-11-17 22:38 ` [PATCH 09/13] NetLabel: use the correct CIPSOv4 MLS label limits paul.moore
2006-11-17 22:38 ` [PATCH 10/13] NetLabel: use cipso_v4_doi_search() for local CIPSOv4 functions paul.moore
2006-11-24 1:24 ` Eric Paris
2006-11-24 5:53 ` Al Viro
2006-11-17 22:38 ` [PATCH 11/13] NetLabel: SELinux cleanups paul.moore
2006-11-17 22:38 ` [PATCH 12/13] SELinux: peer secid consolidation for external network labeling paul.moore
2006-11-17 22:38 ` [PATCH 13/13] NetLabel: honor the audit_enabled flag paul.moore
2006-11-18 4:12 ` [PATCH 00/13] NetLabel cleanups for 2.6.20 [GIT] James Morris
2006-11-18 16:10 ` Paul Moore
2006-11-19 3:19 ` James Morris
-- strict thread matches above, loose matches on Subject: below --
2006-11-24 18:59 [PATCH 10/13] NetLabel: use cipso_v4_doi_search() for local CIPSOv4 functions Paul Moore
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).