aboutsummaryrefslogtreecommitdiff
path: root/security/selinux/hooks.c
diff options
context:
space:
mode:
authorJames Bottomley <jejb@mulgrave.il.steeleye.com>2006-03-21 13:05:45 -0600
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>2006-03-21 13:05:45 -0600
commitd04cdb64212eb5ae6a98026a97dda626e40e8e9a (patch)
treeb6a7dbb21ccfceb915844e9a330b3d3dfcaf3c5b /security/selinux/hooks.c
parent2f8600dff2b140096a7df781884e918a16aa90e0 (diff)
parentec1248e70edc5cf7b485efcc7b41e44e10f422e5 (diff)
Merge ../linux-2.6
Diffstat (limited to 'security/selinux/hooks.c')
-rw-r--r--security/selinux/hooks.c46
1 files changed, 39 insertions, 7 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index b65c201e9ff..5b16196f282 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -3318,24 +3318,38 @@ out:
return err;
}
-static int selinux_socket_getpeersec(struct socket *sock, char __user *optval,
- int __user *optlen, unsigned len)
+static int selinux_socket_getpeersec_stream(struct socket *sock, char __user *optval,
+ int __user *optlen, unsigned len)
{
int err = 0;
char *scontext;
u32 scontext_len;
struct sk_security_struct *ssec;
struct inode_security_struct *isec;
+ u32 peer_sid = 0;
isec = SOCK_INODE(sock)->i_security;
- if (isec->sclass != SECCLASS_UNIX_STREAM_SOCKET) {
+
+ /* if UNIX_STREAM check peer_sid, if TCP check dst for labelled sa */
+ if (isec->sclass == SECCLASS_UNIX_STREAM_SOCKET) {
+ ssec = sock->sk->sk_security;
+ peer_sid = ssec->peer_sid;
+ }
+ else if (isec->sclass == SECCLASS_TCP_SOCKET) {
+ peer_sid = selinux_socket_getpeer_stream(sock->sk);
+
+ if (peer_sid == SECSID_NULL) {
+ err = -ENOPROTOOPT;
+ goto out;
+ }
+ }
+ else {
err = -ENOPROTOOPT;
goto out;
}
- ssec = sock->sk->sk_security;
-
- err = security_sid_to_context(ssec->peer_sid, &scontext, &scontext_len);
+ err = security_sid_to_context(peer_sid, &scontext, &scontext_len);
+
if (err)
goto out;
@@ -3356,6 +3370,23 @@ out:
return err;
}
+static int selinux_socket_getpeersec_dgram(struct sk_buff *skb, char **secdata, u32 *seclen)
+{
+ int err = 0;
+ u32 peer_sid = selinux_socket_getpeer_dgram(skb);
+
+ if (peer_sid == SECSID_NULL)
+ return -EINVAL;
+
+ err = security_sid_to_context(peer_sid, secdata, seclen);
+ if (err)
+ return err;
+
+ return 0;
+}
+
+
+
static int selinux_sk_alloc_security(struct sock *sk, int family, gfp_t priority)
{
return sk_alloc_security(sk, family, priority);
@@ -4344,7 +4375,8 @@ static struct security_operations selinux_ops = {
.socket_setsockopt = selinux_socket_setsockopt,
.socket_shutdown = selinux_socket_shutdown,
.socket_sock_rcv_skb = selinux_socket_sock_rcv_skb,
- .socket_getpeersec = selinux_socket_getpeersec,
+ .socket_getpeersec_stream = selinux_socket_getpeersec_stream,
+ .socket_getpeersec_dgram = selinux_socket_getpeersec_dgram,
.sk_alloc_security = selinux_sk_alloc_security,
.sk_free_security = selinux_sk_free_security,
.sk_getsid = selinux_sk_getsid_security,