summaryrefslogtreecommitdiff
path: root/security
diff options
context:
space:
mode:
authorJames Morris <jmorris@redhat.com>2004-05-08 01:00:33 -0700
committerDavid S. Miller <davem@nuts.davemloft.net>2004-05-08 01:00:33 -0700
commite2943dca2d5b67e9578111986495483fe720d58b (patch)
tree8d4f66ec436c28816c7f5e15b28bf0f36e0f7f7e /security
parent49a1f4d43f51d534cd7246b6b117fa497ba2fdaf (diff)
[NET]: Add sock_create_kern()
Under SELinux, and potentially other LSMs, we need to be able to distinguish between user sockets and kernel sockets. For SELinux specifically, kernel sockets need to be specially labeled during creation, then bypass access control checks (they are controlled by the kernel itself and not subject to SELinux mediation). This addresses a class of potential issues in SELinux where, for example, a TCP NFS session times out, then the kernel re-establishes an RPC connection upon further user activity. We do not want such kernel created sockets to be labeled with user security contexts. sock_create() and sock_create_kern() are wrapper functions, which seems semantically clearer to me than e.g. adding a flag to sock_create(). If you prefer the latter, then let me know. The patch also adds an argument to the LSM socket creation functions indicating whether the socket being created is a kernel socket or not.
Diffstat (limited to 'security')
-rw-r--r--security/dummy.c5
-rw-r--r--security/selinux/hooks.c21
2 files changed, 18 insertions, 8 deletions
diff --git a/security/dummy.c b/security/dummy.c
index 4e12451e8a74..2a3ca3c7677a 100644
--- a/security/dummy.c
+++ b/security/dummy.c
@@ -750,13 +750,14 @@ static int dummy_unix_may_send (struct socket *sock,
return 0;
}
-static int dummy_socket_create (int family, int type, int protocol)
+static int dummy_socket_create (int family, int type,
+ int protocol, int kern)
{
return 0;
}
static void dummy_socket_post_create (struct socket *sock, int family, int type,
- int protocol)
+ int protocol, int kern)
{
return;
}
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 2b52cb6537be..8880f37ddf94 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -2810,34 +2810,43 @@ static int socket_has_perm(struct task_struct *task, struct socket *sock,
struct inode_security_struct *isec;
struct task_security_struct *tsec;
struct avc_audit_data ad;
- int err;
+ int err = 0;
tsec = task->security;
isec = SOCK_INODE(sock)->i_security;
+ if (isec->sid == SECINITSID_KERNEL)
+ goto out;
+
AVC_AUDIT_DATA_INIT(&ad,NET);
ad.u.net.sk = sock->sk;
err = avc_has_perm(tsec->sid, isec->sid, isec->sclass,
perms, &isec->avcr, &ad);
+out:
return err;
}
-static int selinux_socket_create(int family, int type, int protocol)
+static int selinux_socket_create(int family, int type,
+ int protocol, int kern)
{
- int err;
+ int err = 0;
struct task_security_struct *tsec;
- tsec = current->security;
+ if (kern)
+ goto out;
+ tsec = current->security;
err = avc_has_perm(tsec->sid, tsec->sid,
socket_type_to_security_class(family, type),
SOCKET__CREATE, NULL, NULL);
+out:
return err;
}
-static void selinux_socket_post_create(struct socket *sock, int family, int type, int protocol)
+static void selinux_socket_post_create(struct socket *sock, int family,
+ int type, int protocol, int kern)
{
int err;
struct inode_security_struct *isec;
@@ -2850,7 +2859,7 @@ static void selinux_socket_post_create(struct socket *sock, int family, int type
tsec = current->security;
isec->sclass = socket_type_to_security_class(family, type);
- isec->sid = tsec->sid;
+ isec->sid = kern ? SECINITSID_KERNEL : tsec->sid;
return;
}