Hi, James, Stephen, Dave and Chris, Enclosed please find the updated AF_UNIX patch. It addressed three major issues in the previous patch.
1. No directly calling of the SELINUX function security_sid_to_context(). The fix is to export this and other similar functions through wrapper functions in selinux/exports.c. Most of this code is copied from James' outstanding patch: http://people.redhat.com/jmorris/selinux/skfilter/kernel/12-skfilter-selinux-exports.patch 2. Potential performance problem due to the call to sk_callback_lock() in security_sk_sid(). The fix is to introduce a new function selinux_sock_ctxid() that retrieves the sid of a socket w/o locking. 3. scm_send() might generate garbage sid, if SELINUX is not enabled. The fix is to have selinux_id_to_ctx() return ENOTSUPP when SELINUX is not enabled, so that no control message will be generated. Again, my sincere apologies for the delayed response. As always, comments are appreciated! thanks, Catherine ---- From: [EMAIL PROTECTED] This patch implements an API whereby an application can determine the label of its peer's Unix datagram sockets via the auxiliary data mechanism of recvmsg. Patch purpose: This patch enables a security-aware application to retrieve the security context of the peer of a Unix datagram socket. The application can then use this security context to determine the security context for processing on behalf of the peer who sent the packet. Patch design and implementation: The design and implementation is very similar to the UDP case for INET sockets. Basically we build upon the existing Unix domain socket API for retrieving user credentials. Linux offers the API for obtaining user credentials via ancillary messages (i.e., out of band/control messages that are bundled together with a normal message). To retrieve the security context, the application first indicates to the kernel such desire by setting the SO_PASSSEC option via getsockopt. Then the application retrieves the security context using the auxiliary data mechanism. An example server application for Unix datagram socket should look like this: toggle = 1; toggle_len = sizeof(toggle); setsockopt(sockfd, SOL_SOCKET, SO_PASSSEC, &toggle, &toggle_len); recvmsg(sockfd, &msg_hdr, 0); if (msg_hdr.msg_controllen > sizeof(struct cmsghdr)) { cmsg_hdr = CMSG_FIRSTHDR(&msg_hdr); if (cmsg_hdr->cmsg_len <= CMSG_LEN(sizeof(scontext)) && cmsg_hdr->cmsg_level == SOL_SOCKET && cmsg_hdr->cmsg_type == SCM_SECURITY) { memcpy(&scontext, CMSG_DATA(cmsg_hdr), sizeof(scontext)); } } sock_setsockopt is enhanced with a new socket option SOCK_PASSSEC to allow a server socket to receive security context of the peer. Testing: We have tested the patch by setting up Unix datagram client and server applications. We verified that the server can retrieve the security context using the auxiliary data mechanism of recvmsg. --- include/asm-alpha/socket.h | 1 include/asm-arm/socket.h | 1 include/asm-arm26/socket.h | 1 include/asm-cris/socket.h | 1 include/asm-frv/socket.h | 1 include/asm-h8300/socket.h | 1 include/asm-i386/socket.h | 1 include/asm-ia64/socket.h | 1 include/asm-m32r/socket.h | 1 include/asm-m68k/socket.h | 1 include/asm-mips/socket.h | 1 include/asm-parisc/socket.h | 1 include/asm-powerpc/socket.h | 1 include/asm-s390/socket.h | 1 include/asm-sh/socket.h | 1 include/asm-sparc/socket.h | 1 include/asm-sparc64/socket.h | 1 include/asm-v850/socket.h | 1 include/asm-x86_64/socket.h | 1 include/asm-xtensa/socket.h | 1 include/linux/net.h | 1 include/linux/selinux.h | 104 ++++++++++++++++++++++++++++++++++++ include/net/af_unix.h | 2 include/net/scm.h | 13 ++++ net/core/sock.c | 11 +++ net/unix/af_unix.c | 2 security/selinux/Makefile | 2 security/selinux/exports.c | 52 ++++++++++++++++++ security/selinux/hooks.c | 40 +++++++++---- security/selinux/include/security.h | 7 ++ security/selinux/ss/services.c | 4 - 31 files changed, 240 insertions(+), 18 deletions(-) diff -puN include/asm-i386/socket.h~lsm-secpeer-unix include/asm-i386/socket.h --- linux-2.6.17-rc1/include/asm-i386/socket.h~lsm-secpeer-unix 2006-04-03 18:19:47.000000000 -0400 +++ linux-2.6.17-rc1-cxzhang/include/asm-i386/socket.h 2006-04-03 18:20:46.000000000 -0400 @@ -48,5 +48,6 @@ #define SO_ACCEPTCONN 30 #define SO_PEERSEC 31 +#define SO_PASSSEC 34 #endif /* _ASM_SOCKET_H */ diff -puN include/asm-x86_64/socket.h~lsm-secpeer-unix include/asm-x86_64/socket.h --- linux-2.6.17-rc1/include/asm-x86_64/socket.h~lsm-secpeer-unix 2006-04-03 18:19:47.000000000 -0400 +++ linux-2.6.17-rc1-cxzhang/include/asm-x86_64/socket.h 2006-04-03 18:20:46.000000000 -0400 @@ -48,5 +48,6 @@ #define SO_ACCEPTCONN 30 #define SO_PEERSEC 31 +#define SO_PASSSEC 34 #endif /* _ASM_SOCKET_H */ diff -puN include/asm-ia64/socket.h~lsm-secpeer-unix include/asm-ia64/socket.h --- linux-2.6.17-rc1/include/asm-ia64/socket.h~lsm-secpeer-unix 2006-04-03 18:19:47.000000000 -0400 +++ linux-2.6.17-rc1-cxzhang/include/asm-ia64/socket.h 2006-04-03 18:20:46.000000000 -0400 @@ -57,5 +57,6 @@ #define SO_ACCEPTCONN 30 #define SO_PEERSEC 31 +#define SO_PASSSEC 34 #endif /* _ASM_IA64_SOCKET_H */ diff -puN include/asm-powerpc/socket.h~lsm-secpeer-unix include/asm-powerpc/socket.h --- linux-2.6.17-rc1/include/asm-powerpc/socket.h~lsm-secpeer-unix 2006-04-03 18:19:47.000000000 -0400 +++ linux-2.6.17-rc1-cxzhang/include/asm-powerpc/socket.h 2006-04-03 18:20:46.000000000 -0400 @@ -55,5 +55,6 @@ #define SO_ACCEPTCONN 30 #define SO_PEERSEC 31 +#define SO_PASSSEC 34 #endif /* _ASM_POWERPC_SOCKET_H */ diff -puN include/asm-h8300/socket.h~lsm-secpeer-unix include/asm-h8300/socket.h --- linux-2.6.17-rc1/include/asm-h8300/socket.h~lsm-secpeer-unix 2006-04-03 18:19:47.000000000 -0400 +++ linux-2.6.17-rc1-cxzhang/include/asm-h8300/socket.h 2006-04-03 18:20:46.000000000 -0400 @@ -48,5 +48,6 @@ #define SO_ACCEPTCONN 30 #define SO_PEERSEC 31 +#define SO_PASSSEC 34 #endif /* _ASM_SOCKET_H */ diff -puN include/asm-s390/socket.h~lsm-secpeer-unix include/asm-s390/socket.h --- linux-2.6.17-rc1/include/asm-s390/socket.h~lsm-secpeer-unix 2006-04-03 18:19:47.000000000 -0400 +++ linux-2.6.17-rc1-cxzhang/include/asm-s390/socket.h 2006-04-03 18:20:46.000000000 -0400 @@ -56,5 +56,6 @@ #define SO_ACCEPTCONN 30 #define SO_PEERSEC 31 +#define SO_PASSSEC 34 #endif /* _ASM_SOCKET_H */ diff -puN include/asm-mips/socket.h~lsm-secpeer-unix include/asm-mips/socket.h --- linux-2.6.17-rc1/include/asm-mips/socket.h~lsm-secpeer-unix 2006-04-03 18:19:47.000000000 -0400 +++ linux-2.6.17-rc1-cxzhang/include/asm-mips/socket.h 2006-04-03 18:20:46.000000000 -0400 @@ -69,6 +69,7 @@ To add: #define SO_REUSEPORT 0x0200 /* A #define SO_PEERSEC 30 #define SO_SNDBUFFORCE 31 #define SO_RCVBUFFORCE 33 +#define SO_PASSSEC 34 #ifdef __KERNEL__ diff -puN include/asm-alpha/socket.h~lsm-secpeer-unix include/asm-alpha/socket.h --- linux-2.6.17-rc1/include/asm-alpha/socket.h~lsm-secpeer-unix 2006-04-03 18:19:47.000000000 -0400 +++ linux-2.6.17-rc1-cxzhang/include/asm-alpha/socket.h 2006-04-03 18:20:46.000000000 -0400 @@ -51,6 +51,7 @@ #define SCM_TIMESTAMP SO_TIMESTAMP #define SO_PEERSEC 30 +#define SO_PASSSEC 31 /* Security levels - as per NRL IPv6 - don't actually do anything */ #define SO_SECURITY_AUTHENTICATION 19 diff -puN include/asm-v850/socket.h~lsm-secpeer-unix include/asm-v850/socket.h --- linux-2.6.17-rc1/include/asm-v850/socket.h~lsm-secpeer-unix 2006-04-03 18:19:47.000000000 -0400 +++ linux-2.6.17-rc1-cxzhang/include/asm-v850/socket.h 2006-04-03 18:20:46.000000000 -0400 @@ -48,5 +48,6 @@ #define SO_ACCEPTCONN 30 #define SO_PEERSEC 31 +#define SO_PASSSEC 34 #endif /* __V850_SOCKET_H__ */ diff -puN include/asm-sh/socket.h~lsm-secpeer-unix include/asm-sh/socket.h --- linux-2.6.17-rc1/include/asm-sh/socket.h~lsm-secpeer-unix 2006-04-03 18:19:47.000000000 -0400 +++ linux-2.6.17-rc1-cxzhang/include/asm-sh/socket.h 2006-04-03 18:20:46.000000000 -0400 @@ -48,5 +48,6 @@ #define SO_ACCEPTCONN 30 #define SO_PEERSEC 31 +#define SO_PASSSEC 34 #endif /* __ASM_SH_SOCKET_H */ diff -puN include/asm-m68k/socket.h~lsm-secpeer-unix include/asm-m68k/socket.h --- linux-2.6.17-rc1/include/asm-m68k/socket.h~lsm-secpeer-unix 2006-04-03 18:19:47.000000000 -0400 +++ linux-2.6.17-rc1-cxzhang/include/asm-m68k/socket.h 2006-04-03 18:20:46.000000000 -0400 @@ -48,5 +48,6 @@ #define SO_ACCEPTCONN 30 #define SO_PEERSEC 31 +#define SO_PASSSEC 34 #endif /* _ASM_SOCKET_H */ diff -puN include/asm-arm/socket.h~lsm-secpeer-unix include/asm-arm/socket.h --- linux-2.6.17-rc1/include/asm-arm/socket.h~lsm-secpeer-unix 2006-04-03 18:19:47.000000000 -0400 +++ linux-2.6.17-rc1-cxzhang/include/asm-arm/socket.h 2006-04-03 18:20:46.000000000 -0400 @@ -48,5 +48,6 @@ #define SO_ACCEPTCONN 30 #define SO_PEERSEC 31 +#define SO_PASSSEC 34 #endif /* _ASM_SOCKET_H */ diff -puN include/asm-cris/socket.h~lsm-secpeer-unix include/asm-cris/socket.h --- linux-2.6.17-rc1/include/asm-cris/socket.h~lsm-secpeer-unix 2006-04-03 18:19:47.000000000 -0400 +++ linux-2.6.17-rc1-cxzhang/include/asm-cris/socket.h 2006-04-03 18:20:46.000000000 -0400 @@ -50,6 +50,7 @@ #define SO_ACCEPTCONN 30 #define SO_PEERSEC 31 +#define SO_PASSSEC 34 #endif /* _ASM_SOCKET_H */ diff -puN include/asm-arm26/socket.h~lsm-secpeer-unix include/asm-arm26/socket.h --- linux-2.6.17-rc1/include/asm-arm26/socket.h~lsm-secpeer-unix 2006-04-03 18:19:47.000000000 -0400 +++ linux-2.6.17-rc1-cxzhang/include/asm-arm26/socket.h 2006-04-03 18:20:46.000000000 -0400 @@ -48,5 +48,6 @@ #define SO_ACCEPTCONN 30 #define SO_PEERSEC 31 +#define SO_PASSSEC 34 #endif /* _ASM_SOCKET_H */ diff -puN include/asm-frv/socket.h~lsm-secpeer-unix include/asm-frv/socket.h --- linux-2.6.17-rc1/include/asm-frv/socket.h~lsm-secpeer-unix 2006-04-03 18:19:47.000000000 -0400 +++ linux-2.6.17-rc1-cxzhang/include/asm-frv/socket.h 2006-04-03 18:20:46.000000000 -0400 @@ -48,6 +48,7 @@ #define SO_ACCEPTCONN 30 #define SO_PEERSEC 31 +#define SO_PASSSEC 34 #endif /* _ASM_SOCKET_H */ diff -puN include/asm-xtensa/socket.h~lsm-secpeer-unix include/asm-xtensa/socket.h --- linux-2.6.17-rc1/include/asm-xtensa/socket.h~lsm-secpeer-unix 2006-04-03 18:19:47.000000000 -0400 +++ linux-2.6.17-rc1-cxzhang/include/asm-xtensa/socket.h 2006-04-03 18:20:46.000000000 -0400 @@ -59,5 +59,6 @@ #define SO_ACCEPTCONN 30 #define SO_PEERSEC 31 +#define SO_PASSSEC 34 #endif /* _XTENSA_SOCKET_H */ diff -puN include/asm-m32r/socket.h~lsm-secpeer-unix include/asm-m32r/socket.h --- linux-2.6.17-rc1/include/asm-m32r/socket.h~lsm-secpeer-unix 2006-04-03 18:19:48.000000000 -0400 +++ linux-2.6.17-rc1-cxzhang/include/asm-m32r/socket.h 2006-04-03 18:20:46.000000000 -0400 @@ -48,5 +48,6 @@ #define SO_ACCEPTCONN 30 #define SO_PEERSEC 31 +#define SO_PASSSEC 34 #endif /* _ASM_M32R_SOCKET_H */ diff -puN include/asm-parisc/socket.h~lsm-secpeer-unix include/asm-parisc/socket.h --- linux-2.6.17-rc1/include/asm-parisc/socket.h~lsm-secpeer-unix 2006-04-03 18:19:48.000000000 -0400 +++ linux-2.6.17-rc1-cxzhang/include/asm-parisc/socket.h 2006-04-03 18:20:46.000000000 -0400 @@ -48,5 +48,6 @@ #define SO_ACCEPTCONN 0x401c #define SO_PEERSEC 0x401d +#define SO_PASSSEC 0x401e #endif /* _ASM_SOCKET_H */ diff -puN include/asm-sparc/socket.h~lsm-secpeer-unix include/asm-sparc/socket.h --- linux-2.6.17-rc1/include/asm-sparc/socket.h~lsm-secpeer-unix 2006-04-07 19:21:24.286406168 -0400 +++ linux-2.6.17-rc1-cxzhang/include/asm-sparc/socket.h 2006-04-07 19:21:03.896505904 -0400 @@ -48,6 +48,7 @@ #define SCM_TIMESTAMP SO_TIMESTAMP #define SO_PEERSEC 0x001e +#define SO_PASSSEC 0x001f /* Security levels - as per NRL IPv6 - don't actually do anything */ #define SO_SECURITY_AUTHENTICATION 0x5001 diff -puN include/asm-sparc64/socket.h~lsm-secpeer-unix include/asm-sparc64/socket.h --- linux-2.6.17-rc1/include/asm-sparc64/socket.h~lsm-secpeer-unix 2006-04-07 19:19:50.788619992 -0400 +++ linux-2.6.17-rc1-cxzhang/include/asm-sparc64/socket.h 2006-04-07 19:19:24.046685384 -0400 @@ -48,6 +48,7 @@ #define SCM_TIMESTAMP SO_TIMESTAMP #define SO_PEERSEC 0x001e +#define SO_PASSSEC 0x001f /* Security levels - as per NRL IPv6 - don't actually do anything */ #define SO_SECURITY_AUTHENTICATION 0x5001 diff -puN include/linux/net.h~lsm-secpeer-unix include/linux/net.h --- linux-2.6.17-rc1/include/linux/net.h~lsm-secpeer-unix 2006-04-03 18:19:48.000000000 -0400 +++ linux-2.6.17-rc1-cxzhang/include/linux/net.h 2006-04-03 18:20:46.000000000 -0400 @@ -62,6 +62,7 @@ typedef enum { #define SOCK_ASYNC_WAITDATA 1 #define SOCK_NOSPACE 2 #define SOCK_PASSCRED 3 +#define SOCK_PASSSEC 4 #ifndef ARCH_HAS_SOCKET_TYPES /** diff -puN include/net/af_unix.h~lsm-secpeer-unix include/net/af_unix.h --- linux-2.6.17-rc1/include/net/af_unix.h~lsm-secpeer-unix 2006-04-03 18:19:48.000000000 -0400 +++ linux-2.6.17-rc1-cxzhang/include/net/af_unix.h 2006-04-03 18:20:46.000000000 -0400 @@ -54,10 +54,12 @@ struct unix_address { struct unix_skb_parms { struct ucred creds; /* Skb credentials */ struct scm_fp_list *fp; /* Passed files */ + u32 sid; /* Security ID */ }; #define UNIXCB(skb) (*(struct unix_skb_parms*)&((skb)->cb)) #define UNIXCREDS(skb) (&UNIXCB((skb)).creds) +#define UNIXSID(skb) (&UNIXCB((skb)).sid) #define unix_state_rlock(s) spin_lock(&unix_sk(s)->lock) #define unix_state_runlock(s) spin_unlock(&unix_sk(s)->lock) diff -puN include/net/scm.h~lsm-secpeer-unix include/net/scm.h --- linux-2.6.17-rc1/include/net/scm.h~lsm-secpeer-unix 2006-04-03 18:19:48.000000000 -0400 +++ linux-2.6.17-rc1-cxzhang/include/net/scm.h 2006-04-06 14:26:02.000000000 -0400 @@ -3,6 +3,8 @@ #include <linux/limits.h> #include <linux/net.h> +#include <linux/security.h> +#include <linux/selinux.h> /* Well, we should have at least one descriptor open * to accept passed FDs 8) @@ -19,6 +21,7 @@ struct scm_cookie { struct ucred creds; /* Skb credentials */ struct scm_fp_list *fp; /* Passed files */ + u32 sid; /* Passed security ID */ unsigned long seq; /* Connection seqno */ }; @@ -42,6 +45,7 @@ static __inline__ int scm_send(struct so scm->creds.gid = p->gid; scm->creds.pid = p->tgid; scm->fp = NULL; + selinux_sock_ctxid(sock, &scm->sid); scm->seq = 0; if (msg->msg_controllen <= 0) return 0; @@ -51,6 +55,9 @@ static __inline__ int scm_send(struct so static __inline__ void scm_recv(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm, int flags) { + char *scontext; + int scontext_len, err; + if (!msg->msg_control) { if (test_bit(SOCK_PASSCRED, &sock->flags) || scm->fp) @@ -62,6 +69,12 @@ static __inline__ void scm_recv(struct s if (test_bit(SOCK_PASSCRED, &sock->flags)) put_cmsg(msg, SOL_SOCKET, SCM_CREDENTIALS, sizeof(scm->creds), &scm->creds); + if (test_bit(SOCK_PASSSEC, &sock->flags)) { + err = selinux_id_to_ctx(scm->sid, &scontext, &scontext_len); + if (!err) + put_cmsg(msg, SOL_SOCKET, SCM_SECURITY, scontext_len, scontext); + } + if (!scm->fp) return; diff -puN net/core/sock.c~lsm-secpeer-unix net/core/sock.c --- linux-2.6.17-rc1/net/core/sock.c~lsm-secpeer-unix 2006-04-03 18:19:48.000000000 -0400 +++ linux-2.6.17-rc1-cxzhang/net/core/sock.c 2006-04-03 18:20:46.000000000 -0400 @@ -565,6 +565,13 @@ set_rcvbuf: ret = -ENONET; break; + case SO_PASSSEC: + if (valbool) + set_bit(SOCK_PASSSEC, &sock->flags); + else + clear_bit(SOCK_PASSSEC, &sock->flags); + break; + /* We implement the SO_SNDLOWAT etc to not be settable (1003.1g 5.3) */ default: @@ -723,6 +730,10 @@ int sock_getsockopt(struct socket *sock, v.val = sk->sk_state == TCP_LISTEN; break; + case SO_PASSSEC: + v.val = test_bit(SOCK_PASSSEC, &sock->flags) ? 1 : 0; + break; + case SO_PEERSEC: return security_socket_getpeersec_stream(sock, optval, optlen, len); diff -puN net/unix/af_unix.c~lsm-secpeer-unix net/unix/af_unix.c --- linux-2.6.17-rc1/net/unix/af_unix.c~lsm-secpeer-unix 2006-04-03 18:19:48.000000000 -0400 +++ linux-2.6.17-rc1-cxzhang/net/unix/af_unix.c 2006-04-03 18:20:46.000000000 -0400 @@ -1290,6 +1290,7 @@ static int unix_dgram_sendmsg(struct kio memcpy(UNIXCREDS(skb), &siocb->scm->creds, sizeof(struct ucred)); if (siocb->scm->fp) unix_attach_fds(siocb->scm, skb); + memcpy(UNIXSID(skb), &siocb->scm->sid, sizeof(u32)); skb->h.raw = skb->data; err = memcpy_fromiovec(skb_put(skb,len), msg->msg_iov, len); @@ -1570,6 +1571,7 @@ static int unix_dgram_recvmsg(struct kio memset(&tmp_scm, 0, sizeof(tmp_scm)); } siocb->scm->creds = *UNIXCREDS(skb); + siocb->scm->sid = *UNIXSID(skb); if (!(flags & MSG_PEEK)) { diff -puN security/selinux/Makefile~lsm-secpeer-unix security/selinux/Makefile --- linux-2.6.17-rc1/security/selinux/Makefile~lsm-secpeer-unix 2006-04-04 18:30:47.000000000 -0400 +++ linux-2.6.17-rc1-cxzhang/security/selinux/Makefile 2006-04-04 18:31:29.000000000 -0400 @@ -4,7 +4,7 @@ obj-$(CONFIG_SECURITY_SELINUX) := selinux.o ss/ -selinux-y := avc.o hooks.o selinuxfs.o netlink.o nlmsgtab.o netif.o +selinux-y := avc.o hooks.o selinuxfs.o netlink.o nlmsgtab.o netif.o exports.o selinux-$(CONFIG_SECURITY_NETWORK_XFRM) += xfrm.o diff -puN /dev/null security/selinux/exports.c --- /dev/null 2006-01-22 15:03:06.693899048 -0500 +++ linux-2.6.17-rc1-cxzhang/security/selinux/exports.c 2006-04-06 14:29:28.000000000 -0400 @@ -0,0 +1,52 @@ +/* + * SELinux services exported to the rest of the kernel. + * + * Author: James Morris <[EMAIL PROTECTED]> + * + * Copyright (C) 2005 Red Hat, Inc., James Morris <[EMAIL PROTECTED]> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, + * as published by the Free Software Foundation. + */ +#include <linux/types.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/selinux.h> + +#include "security.h" + +extern int ss_initialized; + +int selinux_available(void) +{ + return ss_initialized; +} + +void selinux_sk_ctxid(struct sock *sk, u32 *ctxid) +{ + *ctxid = 0; + security_sk_info(sk, ctxid, NULL); +} + +void selinux_sock_ctxid(struct socket *sock, u32 *ctxid) +{ + *ctxid = 0; + security_sock_info(sock, ctxid, NULL); +} + +int selinux_ctx_to_id(const char *ctx, u32 *ctxid) +{ + return security_context_to_sid(ctx, strlen(ctx), ctxid); +} + +int selinux_id_to_ctx(u32 ctxid, char **ctx, u32 *ctxlen) +{ + return security_sid_to_context(ctxid, ctx, ctxlen); +} + +EXPORT_SYMBOL_GPL(selinux_available); +EXPORT_SYMBOL_GPL(selinux_sk_ctxid); +EXPORT_SYMBOL_GPL(selinux_sock_ctxid); +EXPORT_SYMBOL_GPL(selinux_ctx_to_id); +EXPORT_SYMBOL_GPL(selinux_id_to_ctx); diff -puN security/selinux/hooks.c~lsm-secpeer-unix security/selinux/hooks.c --- linux-2.6.17-rc1/security/selinux/hooks.c~lsm-secpeer-unix 2006-04-04 18:36:25.000000000 -0400 +++ linux-2.6.17-rc1-cxzhang/security/selinux/hooks.c 2006-04-06 14:35:14.000000000 -0400 @@ -3212,6 +3212,29 @@ static int selinux_socket_unix_may_send( return 0; } +/* Retrieve security info. on sock */ +void security_sock_info(struct socket *sock, u32 *sid, u16 *class) +{ + if (sock) { + struct inode *inode; + inode = SOCK_INODE(sock); + if (inode) { + struct inode_security_struct *isec; + isec = inode->i_security; + if (sid) + *sid = isec->sid; + if (class) + *class = isec->sclass; + } + } +} + +/* Caller must hold sk_callback_lock */ +void security_sk_info(struct sock *sk, u32 *sid, u16 *class) +{ + security_sock_info(sk->sk_socket, sid, class); +} + static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) { u16 family; @@ -3220,7 +3243,6 @@ static int selinux_socket_sock_rcv_skb(s u32 netif_perm, node_perm, node_sid, if_sid, recv_perm = 0; u32 sock_sid = 0; u16 sock_class = 0; - struct socket *sock; struct net_device *dev; struct avc_audit_data ad; @@ -3232,19 +3254,9 @@ static int selinux_socket_sock_rcv_skb(s if (family == PF_INET6 && skb->protocol == ntohs(ETH_P_IP)) family = PF_INET; - read_lock_bh(&sk->sk_callback_lock); - sock = sk->sk_socket; - if (sock) { - struct inode *inode; - inode = SOCK_INODE(sock); - if (inode) { - struct inode_security_struct *isec; - isec = inode->i_security; - sock_sid = isec->sid; - sock_class = isec->sclass; - } - } - read_unlock_bh(&sk->sk_callback_lock); + read_lock_bh(&sk->sk_callback_lock); + security_sk_info(sk, &sock_sid, &sock_class); + read_unlock_bh(&sk->sk_callback_lock); if (!sock_sid) goto out; diff -puN security/selinux/include/security.h~lsm-secpeer-unix security/selinux/include/security.h --- linux-2.6.17-rc1/security/selinux/include/security.h~lsm-secpeer-unix 2006-04-04 18:36:25.000000000 -0400 +++ linux-2.6.17-rc1-cxzhang/security/selinux/include/security.h 2006-04-06 14:41:30.000000000 -0400 @@ -63,7 +63,7 @@ int security_change_sid(u32 ssid, u32 ts int security_sid_to_context(u32 sid, char **scontext, u32 *scontext_len); -int security_context_to_sid(char *scontext, u32 scontext_len, +int security_context_to_sid(const char *scontext, u32 scontext_len, u32 *out_sid); int security_context_to_sid_default(char *scontext, u32 scontext_len, u32 *out_sid, u32 def_sid); @@ -96,5 +96,10 @@ int security_fs_use(const char *fstype, int security_genfs_sid(const char *fstype, char *name, u16 sclass, u32 *sid); +struct sock; +struct socket; +void security_sk_info(struct sock *sk, u32 *sid, u16 *class); +void security_sock_info(struct socket *sock, u32 *sid, u16 *class); + #endif /* _SELINUX_SECURITY_H_ */ diff -puN security/selinux/ss/services.c~lsm-secpeer-unix security/selinux/ss/services.c --- linux-2.6.17-rc1/security/selinux/ss/services.c~lsm-secpeer-unix 2006-04-04 18:36:25.000000000 -0400 +++ linux-2.6.17-rc1-cxzhang/security/selinux/ss/services.c 2006-04-04 18:36:45.000000000 -0400 @@ -618,7 +618,7 @@ out: } -static int security_context_to_sid_core(char *scontext, u32 scontext_len, u32 *sid, u32 def_sid) +static int security_context_to_sid_core(const char *scontext, u32 scontext_len, u32 *sid, u32 def_sid) { char *scontext2; struct context context; @@ -744,7 +744,7 @@ out: * Returns -%EINVAL if the context is invalid, -%ENOMEM if insufficient * memory is available, or 0 on success. */ -int security_context_to_sid(char *scontext, u32 scontext_len, u32 *sid) +int security_context_to_sid(const char *scontext, u32 scontext_len, u32 *sid) { return security_context_to_sid_core(scontext, scontext_len, sid, SECSID_NULL); diff -puN /dev/null include/linux/selinux.h --- /dev/null 2006-01-22 15:03:06.693899048 -0500 +++ linux-2.6.17-rc1-cxzhang/include/linux/selinux.h 2006-04-07 12:35:49.000000000 -0400 @@ -0,0 +1,104 @@ +/* + * SELinux services exported to the rest of the kernel. + * + * Author: James Morris <[EMAIL PROTECTED]> + * + * Copyright (C) 2005 Red Hat, Inc., James Morris <[EMAIL PROTECTED]> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, + * as published by the Free Software Foundation. + */ +#ifndef _LINUX_SELINUX_H +#define _LINUX_SELINUX_H + +#ifdef CONFIG_SECURITY_SELINUX + +struct sock; +struct socket; + +/** + * selinux_available - check if SELinux is available for use. + * + * Returns true if configured, enabled, not disabled and policy loaded. + */ +int selinux_available(void); + +/** + * selinux_sk_ctxid - determine a context ID for an sk. + * @sk: the sk object + * @ctxid: ID value returned via this + * + * On return, ctxid will contain an ID for the context, with a value + * of zero to indicate no ID could be determined. Otherwise, this value + * should only be used opaquely. + * + * Caller must hold sk_callback_lock. + */ +void selinux_sk_ctxid(struct sock *sk, u32 *ctxid); + +/** + * selinux_sock_ctxid - determine a context ID for a socket. + * @sock: the socket object + * @ctxid: ID value returned via this + * + * On return, ctxid will contain an ID for the context, with a value + * of zero to indicate no ID could be determined. Otherwise, this value + * should only be used opaquely. + */ +void selinux_sock_ctxid(struct socket *sock, u32 *ctxid); + +/** + * selinux_ctx_to_id - map a security context string to an ID + * @ctx: the security context string to be mapped + * @ctxid: ID value returned via this. + * + * Returns 0 if successful, with the ID stored in ctxid. A value + * of zero for the ctxid indicates no ID could be determined (but + * no error occurred). Otherwise, this value should only be used + * opaquely (e.g. compare with value from selinux_sk_ctxid()) + */ +int selinux_ctx_to_id(const char *ctx, u32 *ctxid); + +/** + * selinux_id_to_ctx - map a security context ID to a string + * @ctxid: security context ID to be converted. + * @ctx: address of context string to be returned + * @ctxlen: length of returned context string. + * + * Returns 0 if successful, -errno if not. On success, the context + * string will be allocated internally, and the caller must call + * kfree() on it after use. + */ +int selinux_id_to_ctx(u32 ctxid, char **ctx, u32 *ctxlen); + +#else + +static inline int selinux_available(void) +{ + return 0; +} + +static inline void selinux_sk_ctxid(struct sock *sk, u32 *ctxid) +{ + *ctxid = 0; +} + +static inline void selinux_sock_ctxid(struct socket *sock, u32 *ctxid) +{ + *ctxid = 0; +} + +static inline int selinux_ctx_to_id(const char *ctx, u32 *ctxid) +{ + *ctxid = 0; + return -ENOTSUPP; +} + +static inline int selinux_id_to_ctx(u32 ctxid, char **ctx, u32 *ctxlen) +{ + return -ENOTSUPP; +} +#endif /* CONFIG_SECURITY_SELINUX */ + +#endif /* _LINUX_SELINUX_H */ _ - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html