Skip to contentSkip to conversation

MLSXFRM: Add security sid to sock

PATCH In review Venkat Yekkirala 2 participants 2 messages Jun 20, 2006 – Jun 21, 2006

Subsystems (5)
lore
Share & tools
lore
#0 lore raw

PATCH 3/6 MLSXFRM: Add security sid to sock

This adds security for IP sockets at the sock level. Security at the sock level is needed to enforce the SELinux security policy for security associations even when a sock is orphaned (such as in the TCP LAST_ACK state).

---

include/linux/security.h          |   12 ++++++++++++
include/net/sock.h                |    9 +++++++++
net/core/sock.c                   |    2 +-
security/dummy.c                  |    5 +++++
security/selinux/hooks.c          |   26 ++++++++++++++++++++------
security/selinux/include/objsec.h |    1 +
6 files changed, 48 insertions(+), 7 deletions(-)
include/linux/security.h +2 -0
@@ -799,6 +800,8 @@ struct swap_info_struct;
 *      which is used to copy security attributes between local stream sockets.
 * @sk_free_security:
 *	Deallocate security structure.
+ * @sk_clone_security:
+ *	Clone/copy security structure.
 * @sk_getsid:
 *	Retrieve the LSM-specific sid for the sock to enable caching of network
 *	authorizations.
@@ -1303,6 +1323,7 @@ struct security_operations {
	int (*socket_getpeersec_dgram) (struct sk_buff *skb, char **secdata, u32 *seclen);
	int (*sk_alloc_security) (struct sock *sk, int family, gfp_t priority);
	void (*sk_free_security) (struct sock *sk);
+	void (*sk_clone_security) (const struct sock *sk, struct sock *newsk);
	unsigned int (*sk_getsid) (struct sock *sk, struct flowi *fl, u8 dir);

#endif /* CONFIG_SECURITY_NETWORK */

@@ -2809,6 +2836,11 @@ static inline void security_sk_free(stru

	return security_ops->sk_free_security(sk);
}

+static inline void security_sk_clone(const struct sock *sk, struct sock *newsk) +{
+ return security_ops->sk_clone_security(sk, newsk);
+}
+
static inline unsigned int security_sk_sid(struct sock *sk, struct flowi *fl, u8 dir)

{
	return security_ops->sk_getsid(sk, fl, dir);

@@ -2936,6 +2968,10 @@ static inline void security_sk_free(stru {
}

+static inline void security_sk_clone(const struct sock *sk, struct sock *newsk) +{
+}
+
static inline unsigned int security_sk_sid(struct sock *sk, struct flowi *fl, u8 dir)

{
	return 0;
include/net/sock.h +0 -0
@@ -964,6 +964,15 @@ static inline void sock_graft(struct soc
	write_unlock_bh(&sk->sk_callback_lock);
}

+static inline void sock_copy(struct sock *nsk, const struct sock *osk) +{
+ void *sptr = nsk->sk_security;
+
+ memcpy(nsk, osk, osk->sk_prot->obj_size);
+ nsk->sk_security = sptr;
+ security_sk_clone(osk, nsk);
+}
+
extern int sock_i_uid(struct sock *sk);
extern unsigned long sock_i_ino(struct sock *sk);

net/core/sock.c +0 -0
@@ -841,7 +841,7 @@ struct sock *sk_clone(const struct sock 
	if (newsk != NULL) {
		struct sk_filter *filter;

- memcpy(newsk, sk, sk->sk_prot->obj_size);
+ sock_copy(newsk, sk);

		/* SANITY */
		sk_node_init(&newsk->sk_node);
security/dummy.c +0 -0
@@ -794,6 +794,10 @@ static inline void dummy_sk_free_securit

{
}

+static inline void dummy_sk_clone_security (const struct sock *sk, struct sock *newsk) +{
+}
+
static unsigned int dummy_sk_getsid(struct sock *sk, struct flowi *fl, u8 dir)

{
	return 0;
@@ -1034,6 +1056,7 @@ void security_fixup_ops (struct security
	set_to_dummy_if_null(ops, socket_getpeersec_dgram);
	set_to_dummy_if_null(ops, sk_alloc_security);
	set_to_dummy_if_null(ops, sk_free_security);
+	set_to_dummy_if_null(ops, sk_clone_security);
	set_to_dummy_if_null(ops, sk_getsid);

#endif /* CONFIG_SECURITY_NETWORK */
#ifdef CONFIG_SECURITY_NETWORK_XFRM

security/selinux/hooks.c +0 -0
@@ -268,15 +268,13 @@ static int sk_alloc_security(struct sock
{
	struct sk_security_struct *ssec;

- if (family != PF_UNIX)
- return 0;
-

	ssec = kzalloc(sizeof(*ssec), priority);
	if (!ssec)
		return -ENOMEM;

	ssec->sk = sk;
	ssec->peer_sid = SECINITSID_UNLABELED;
+	ssec->sid = SECINITSID_UNLABELED;
	sk->sk_security = ssec;

	return 0;
@@ -286,9 +284,6 @@ static void sk_free_security(struct sock
{
	struct sk_security_struct *ssec = sk->sk_security;

- if (sk->sk_family != PF_UNIX)
- return;
-

	sk->sk_security = NULL;
	kfree(ssec);
}
@@ -2939,6 +2934,7 @@ static void selinux_socket_post_create(s
{
	struct inode_security_struct *isec;
	struct task_security_struct *tsec;

+ struct sk_security_struct *sksec;

	isec = SOCK_INODE(sock)->i_security;

@@ -2947,6 +2943,10 @@ static void selinux_socket_post_create(s

	isec->sid = kern ? SECINITSID_KERNEL : tsec->sid;
	isec->initialized = 1;

+ if (sock->sk) {
+ sksec = sock->sk->sk_security;
+ sksec->sid = isec->sid;
+ }

	return;
}

@@ -3420,6 +3420,15 @@ static void selinux_sk_free_security(str

	sk_free_security(sk);
}

+static void selinux_sk_clone_security(const struct sock *sk, struct sock *newsk) +{
+ struct sk_security_struct *ssec = sk->sk_security;
+ struct sk_security_struct *newssec = newsk->sk_security;
+
+ newssec->sid = ssec->sid;
+ newssec->peer_sid = ssec->peer_sid;
+}
+
static unsigned int selinux_sk_getsid_security(struct sock *sk, struct flowi *fl, u8 dir)

{
	struct inode_security_struct *isec;

@@ -3433,6 +3442,10 @@ static unsigned int selinux_sk_getsid_se

	if (isec)
		sock_sid = isec->sid;

+ else {
+ struct sk_security_struct *sksec = sk->sk_security;
+ sock_sid = sksec->sid;
+ }

	read_unlock_bh(&sk->sk_callback_lock);
	return sock_sid;

@@ -4451,6 +4464,7 @@ static struct security_operations selinu
.socket_getpeersec_dgram = selinux_socket_getpeersec_dgram,
.sk_alloc_security = selinux_sk_alloc_security,
.sk_free_security = selinux_sk_free_security,
+ .sk_clone_security = selinux_sk_clone_security,
.sk_getsid = selinux_sk_getsid_security,

#ifdef CONFIG_SECURITY_NETWORK_XFRM

security/selinux/include/objsec.h +0 -0
@@ -96,6 +96,7 @@ struct netif_security_struct {
 

struct sk_security_struct {
struct sock *sk; /* back pointer to sk object */
+ u32 sid; /* SID of this object */

	u32 peer_sid;			/* SID of peer */
};

--
This message was distributed to subscribers of the selinux mailing list. If you no longer wish to subscribe, send mail to [email protected] with the words "unsubscribe selinux" without quotes as the message.

#1 lore raw
Quoted 5 lines · Venkat Yekkirala

--- linux-2.6.16.vanilla/include/net/sock.h 2006-06-19
17:02:23.000000000 -0500
+++ linux-2.6.16/include/net/sock.h 2006-06-19 19:48:24.000000000 -0500

Review static inline void sock_graft(struct soc · line 972

Quoted 9 lines
(quoted diff) +6 -0
@@ -964,6 +964,15 @@ static inline void sock_graft(struct soc
 	write_unlock_bh(&sk->sk_callback_lock);
 }
 
+static inline void sock_copy(struct sock *nsk, const struct sock *osk)
+{
+	void *sptr = nsk->sk_security;
+
+	memcpy(nsk, osk, osk->sk_prot->obj_size);
+	nsk->sk_security = sptr;

I don't get it. Why do you put sk_security away and then set it back. Doesn't memcpy already do this for you?

Signature · 4 lines
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <[email protected]>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt