Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 113661
b: refs/heads/master
c: 6c5b3fc
h: refs/heads/master
i:
  113659: e1dffb2
v: v3
  • Loading branch information
Paul Moore committed Oct 10, 2008
1 parent ef8085d commit 1c20f7a
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 40 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 014ab19a69c325f52d7bae54ceeda73d6307ae0c
refs/heads/master: 6c5b3fc0147f79d714d2fe748b5869d7892ef2e7
1 change: 1 addition & 0 deletions trunk/security/selinux/hooks.c
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,7 @@ static void sk_free_security(struct sock *sk)
struct sk_security_struct *ssec = sk->sk_security;

sk->sk_security = NULL;
selinux_netlbl_sk_security_free(ssec);
kfree(ssec);
}

Expand Down
7 changes: 7 additions & 0 deletions trunk/security/selinux/include/netlabel.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ void selinux_netlbl_cache_invalidate(void);

void selinux_netlbl_err(struct sk_buff *skb, int error, int gateway);

void selinux_netlbl_sk_security_free(struct sk_security_struct *ssec);
void selinux_netlbl_sk_security_reset(struct sk_security_struct *ssec,
int family);

Expand Down Expand Up @@ -77,6 +78,12 @@ static inline void selinux_netlbl_err(struct sk_buff *skb,
return;
}

static inline void selinux_netlbl_sk_security_free(
struct sk_security_struct *ssec)
{
return;
}

static inline void selinux_netlbl_sk_security_reset(
struct sk_security_struct *ssec,
int family)
Expand Down
7 changes: 4 additions & 3 deletions trunk/security/selinux/include/objsec.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,9 +109,6 @@ struct netport_security_struct {
};

struct sk_security_struct {
u32 sid; /* SID of this object */
u32 peer_sid; /* SID of peer */
u16 sclass; /* sock security class */
#ifdef CONFIG_NETLABEL
enum { /* NetLabel state */
NLBL_UNSET = 0,
Expand All @@ -120,7 +117,11 @@ struct sk_security_struct {
NLBL_REQSKB,
NLBL_CONNLABELED,
} nlbl_state;
struct netlbl_lsm_secattr *nlbl_secattr; /* NetLabel sec attributes */
#endif
u32 sid; /* SID of this object */
u32 peer_sid; /* SID of peer */
u16 sclass; /* sock security class */
};

struct key_security_struct {
Expand Down
115 changes: 79 additions & 36 deletions trunk/security/selinux/netlabel.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,38 @@ static int selinux_netlbl_sidlookup_cached(struct sk_buff *skb,
return rc;
}

/**
* selinux_netlbl_sock_genattr - Generate the NetLabel socket secattr
* @sk: the socket
*
* Description:
* Generate the NetLabel security attributes for a socket, making full use of
* the socket's attribute cache. Returns a pointer to the security attributes
* on success, NULL on failure.
*
*/
static struct netlbl_lsm_secattr *selinux_netlbl_sock_genattr(struct sock *sk)
{
int rc;
struct sk_security_struct *sksec = sk->sk_security;
struct netlbl_lsm_secattr *secattr;

if (sksec->nlbl_secattr != NULL)
return sksec->nlbl_secattr;

secattr = netlbl_secattr_alloc(GFP_ATOMIC);
if (secattr == NULL)
return NULL;
rc = security_netlbl_sid_to_secattr(sksec->sid, secattr);
if (rc != 0) {
netlbl_secattr_free(secattr);
return NULL;
}
sksec->nlbl_secattr = secattr;

return secattr;
}

/**
* selinux_netlbl_sock_setsid - Label a socket using the NetLabel mechanism
* @sk: the socket to label
Expand All @@ -80,17 +112,15 @@ static int selinux_netlbl_sock_setsid(struct sock *sk)
{
int rc;
struct sk_security_struct *sksec = sk->sk_security;
struct netlbl_lsm_secattr secattr;
struct netlbl_lsm_secattr *secattr;

if (sksec->nlbl_state != NLBL_REQUIRE)
return 0;

netlbl_secattr_init(&secattr);

rc = security_netlbl_sid_to_secattr(sksec->sid, &secattr);
if (rc != 0)
goto sock_setsid_return;
rc = netlbl_sock_setattr(sk, &secattr);
secattr = selinux_netlbl_sock_genattr(sk);
if (secattr == NULL)
return -ENOMEM;
rc = netlbl_sock_setattr(sk, secattr);
switch (rc) {
case 0:
sksec->nlbl_state = NLBL_LABELED;
Expand All @@ -101,8 +131,6 @@ static int selinux_netlbl_sock_setsid(struct sock *sk)
break;
}

sock_setsid_return:
netlbl_secattr_destroy(&secattr);
return rc;
}

Expand Down Expand Up @@ -136,6 +164,20 @@ void selinux_netlbl_err(struct sk_buff *skb, int error, int gateway)
netlbl_skbuff_err(skb, error, gateway);
}

/**
* selinux_netlbl_sk_security_free - Free the NetLabel fields
* @sssec: the sk_security_struct
*
* Description:
* Free all of the memory in the NetLabel fields of a sk_security_struct.
*
*/
void selinux_netlbl_sk_security_free(struct sk_security_struct *ssec)
{
if (ssec->nlbl_secattr != NULL)
netlbl_secattr_free(ssec->nlbl_secattr);
}

/**
* selinux_netlbl_sk_security_reset - Reset the NetLabel fields
* @ssec: the sk_security_struct
Expand Down Expand Up @@ -209,7 +251,8 @@ int selinux_netlbl_skbuff_setsid(struct sk_buff *skb,
u32 sid)
{
int rc;
struct netlbl_lsm_secattr secattr;
struct netlbl_lsm_secattr secattr_storage;
struct netlbl_lsm_secattr *secattr = NULL;
struct sock *sk;

/* if this is a locally generated packet check to see if it is already
Expand All @@ -219,16 +262,21 @@ int selinux_netlbl_skbuff_setsid(struct sk_buff *skb,
struct sk_security_struct *sksec = sk->sk_security;
if (sksec->nlbl_state != NLBL_REQSKB)
return 0;
secattr = sksec->nlbl_secattr;
}
if (secattr == NULL) {
secattr = &secattr_storage;
netlbl_secattr_init(secattr);
rc = security_netlbl_sid_to_secattr(sid, secattr);
if (rc != 0)
goto skbuff_setsid_return;
}

netlbl_secattr_init(&secattr);
rc = security_netlbl_sid_to_secattr(sid, &secattr);
if (rc != 0)
goto skbuff_setsid_return;
rc = netlbl_skbuff_setattr(skb, family, &secattr);
rc = netlbl_skbuff_setattr(skb, family, secattr);

skbuff_setsid_return:
netlbl_secattr_destroy(&secattr);
if (secattr == &secattr_storage)
netlbl_secattr_destroy(secattr);
return rc;
}

Expand All @@ -245,18 +293,18 @@ void selinux_netlbl_inet_conn_established(struct sock *sk, u16 family)
{
int rc;
struct sk_security_struct *sksec = sk->sk_security;
struct netlbl_lsm_secattr secattr;
struct netlbl_lsm_secattr *secattr;
struct inet_sock *sk_inet = inet_sk(sk);
struct sockaddr_in addr;

if (sksec->nlbl_state != NLBL_REQUIRE)
return;

netlbl_secattr_init(&secattr);
if (security_netlbl_sid_to_secattr(sksec->sid, &secattr) != 0)
goto inet_conn_established_return;
secattr = selinux_netlbl_sock_genattr(sk);
if (secattr == NULL)
return;

rc = netlbl_sock_setattr(sk, &secattr);
rc = netlbl_sock_setattr(sk, secattr);
switch (rc) {
case 0:
sksec->nlbl_state = NLBL_LABELED;
Expand All @@ -266,13 +314,13 @@ void selinux_netlbl_inet_conn_established(struct sock *sk, u16 family)
* labeling protocols */
if (family != PF_INET) {
sksec->nlbl_state = NLBL_UNSET;
goto inet_conn_established_return;
return;
}

addr.sin_family = family;
addr.sin_addr.s_addr = sk_inet->daddr;
if (netlbl_conn_setattr(sk, (struct sockaddr *)&addr,
&secattr) != 0) {
secattr) != 0) {
/* we failed to label the connected socket (could be
* for a variety of reasons, the actual "why" isn't
* important here) so we have to go to our backup plan,
Expand Down Expand Up @@ -300,10 +348,6 @@ void selinux_netlbl_inet_conn_established(struct sock *sk, u16 family)
* return an error code */
break;
}

inet_conn_established_return:
netlbl_secattr_destroy(&secattr);
return;
}

/**
Expand Down Expand Up @@ -468,13 +512,12 @@ int selinux_netlbl_socket_connect(struct sock *sk, struct sockaddr *addr)
{
int rc;
struct sk_security_struct *sksec = sk->sk_security;
struct netlbl_lsm_secattr secattr;
struct netlbl_lsm_secattr *secattr;

if (sksec->nlbl_state != NLBL_REQSKB &&
sksec->nlbl_state != NLBL_CONNLABELED)
return 0;

netlbl_secattr_init(&secattr);
local_bh_disable();
bh_lock_sock_nested(sk);

Expand All @@ -487,17 +530,17 @@ int selinux_netlbl_socket_connect(struct sock *sk, struct sockaddr *addr)
rc = 0;
goto socket_connect_return;
}
rc = security_netlbl_sid_to_secattr(sksec->sid, &secattr);
if (rc != 0)
secattr = selinux_netlbl_sock_genattr(sk);
if (secattr == NULL) {
rc = -ENOMEM;
goto socket_connect_return;
rc = netlbl_conn_setattr(sk, addr, &secattr);
if (rc != 0)
goto socket_connect_return;
sksec->nlbl_state = NLBL_CONNLABELED;
}
rc = netlbl_conn_setattr(sk, addr, secattr);
if (rc == 0)
sksec->nlbl_state = NLBL_CONNLABELED;

socket_connect_return:
bh_unlock_sock(sk);
local_bh_enable();
netlbl_secattr_destroy(&secattr);
return rc;
}

0 comments on commit 1c20f7a

Please sign in to comment.