[Patch] kernel memory leak fix for af_unix datagram getpeersec patch
Hi, all, Enclosed please find the updated patch incorporating comments from Stephen and Dave. Again thanks for your help! Catherine -- From: [EMAIL PROTECTED] This patch implements a cleaner fix for the memory leak problem of the original unix datagram getpeersec patch. Instead of creating a security context each time a unix datagram is sent, we only create the security context when the receiver requests it. This new design requires modification of the current unix_getsecpeer_dgram LSM hook and addition of two new hooks, namely, secid_to_secctx and release_secctx. The former retrieves the security context and the latter releases it. A hook is required for releasing the security context because it is up to the security module to decide how that's done. In the case of Selinux, it's a simple kfree operation. --- include/linux/security.h | 41 +++-- include/net/af_unix.h|6 ++ include/net/scm.h| 29 + net/ipv4/ip_sockglue.c |9 +++-- net/unix/af_unix.c | 17 + security/dummy.c | 14 -- security/selinux/hooks.c | 38 -- 7 files changed, 110 insertions(+), 44 deletions(-) diff -puN include/net/scm.h~af_unix-datagram-getpeersec-ml-fix include/net/scm.h --- linux-2.6.18-rc2/include/net/scm.h~af_unix-datagram-getpeersec-ml-fix 2006-07-22 21:28:21.0 -0400 +++ linux-2.6.18-rc2-cxzhang/include/net/scm.h 2006-08-01 22:43:50.0 -0400 @@ -3,6 +3,7 @@ #include #include +#include /* Well, we should have at least one descriptor open * to accept passed FDs 8) @@ -20,8 +21,7 @@ struct scm_cookie struct ucredcreds; /* Skb credentials */ struct scm_fp_list *fp;/* Passed files */ #ifdef CONFIG_SECURITY_NETWORK - char*secdata; /* Security context */ - u32 seclen; /* Security length */ + u32 secid; /* Passed security ID */ #endif unsigned long seq;/* Connection seqno */ }; @@ -32,6 +32,16 @@ extern int __scm_send(struct socket *soc extern void __scm_destroy(struct scm_cookie *scm); extern struct scm_fp_list * scm_fp_dup(struct scm_fp_list *fpl); +#ifdef CONFIG_SECURITY_NETWORK +static __inline__ void unix_get_peersec_dgram(struct socket *sock, struct scm_cookie *scm) +{ + security_socket_getpeersec_dgram(sock, NULL, &scm->secid); +} +#else +static __inline__ void unix_get_peersec_dgram(struct socket *sock, struct scm_cookie *scm) +{ } +#endif /* CONFIG_SECURITY_NETWORK */ + static __inline__ void scm_destroy(struct scm_cookie *scm) { if (scm && scm->fp) @@ -47,6 +57,7 @@ static __inline__ int scm_send(struct so scm->creds.pid = p->tgid; scm->fp = NULL; scm->seq = 0; + unix_get_peersec_dgram(sock, scm); if (msg->msg_controllen <= 0) return 0; return __scm_send(sock, msg, scm); @@ -55,8 +66,18 @@ static __inline__ int scm_send(struct so #ifdef CONFIG_SECURITY_NETWORK static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm) { - if (test_bit(SOCK_PASSSEC, &sock->flags) && scm->secdata != NULL) - put_cmsg(msg, SOL_SOCKET, SCM_SECURITY, scm->seclen, scm->secdata); + char *secdata; + u32 seclen; + int err; + + if (test_bit(SOCK_PASSSEC, &sock->flags)) { + err = security_secid_to_secctx(scm->secid, &secdata, &seclen); + + if (!err) { + put_cmsg(msg, SOL_SOCKET, SCM_SECURITY, seclen, secdata); + security_release_secctx(secdata, seclen); + } + } } #else static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm) diff -puN net/unix/af_unix.c~af_unix-datagram-getpeersec-ml-fix net/unix/af_unix.c --- linux-2.6.18-rc2/net/unix/af_unix.c~af_unix-datagram-getpeersec-ml-fix 2006-07-22 23:01:26.0 -0400 +++ linux-2.6.18-rc2-cxzhang/net/unix/af_unix.c 2006-08-02 02:25:00.454243480 -0400 @@ -128,23 +128,17 @@ static atomic_t unix_nr_socks = ATOMIC_I #define UNIX_ABSTRACT(sk) (unix_sk(sk)->addr->hash != UNIX_HASH_SIZE) #ifdef CONFIG_SECURITY_NETWORK -static void unix_get_peersec_dgram(struct sk_buff *skb) +static void unix_get_secdata(struct scm_cookie *scm, struct sk_buff *skb) { - int err; - - err = security_socket_getpeersec_dgram(skb, UNIXSECDATA(skb), - UNIXSECLEN(skb)); - if (err) - *(UNIXSECDATA(skb)) = NULL; + memcpy(UNIXSID(skb), &scm->secid, sizeof(u32)); } static inline void unix_set_secdata(struct scm_cookie *scm, struct sk_buff *skb) { - scm->secdata = *UNIXSECDATA(skb); - sc
RFC: kernel memory leak fix for af_unix datagram getpeersec
Hi, all, Enclosed please find the new fix for the memory leak problem, incorporating suggestions from Stephen and James. thanks all for your help! Catherine -- From: [EMAIL PROTECTED] This patch implements a cleaner fix for the memory leak problem of the original unix datagram getpeersec patch. Instead of creating a security context each time a unix datagram is sent, we only create the security context when the receiver requests it. This new design requires modification of the current unix_getsecpeer_dgram LSM hook and addition of two new hooks, namely, sid_to_secctx and release_secctx. The former retrieves the security context and the latter releases it. A hook is required for releasing the security context because it is up to the security module to decide how that's done. In the case of Selinux, it's a simple kfree operation. --- include/linux/security.h | 41 +++-- include/net/af_unix.h|6 ++ include/net/scm.h| 29 + net/ipv4/ip_sockglue.c |9 +++-- net/unix/af_unix.c | 33 ++--- security/dummy.c | 14 -- security/selinux/hooks.c | 34 ++ 7 files changed, 109 insertions(+), 57 deletions(-) diff -puN include/net/scm.h~af_unix-datagram-getpeersec-ml-fix include/net/scm.h --- linux-2.6.18-rc2/include/net/scm.h~af_unix-datagram-getpeersec-ml-fix 2006-07-22 21:28:21.0 -0400 +++ linux-2.6.18-rc2-cxzhang/include/net/scm.h 2006-07-24 11:19:54.0 -0400 @@ -3,6 +3,7 @@ #include #include +#include /* Well, we should have at least one descriptor open * to accept passed FDs 8) @@ -20,8 +21,7 @@ struct scm_cookie struct ucredcreds; /* Skb credentials */ struct scm_fp_list *fp;/* Passed files */ #ifdef CONFIG_SECURITY_NETWORK - char*secdata; /* Security context */ - u32 seclen; /* Security length */ + u32 sid;/* Passed security ID */ #endif unsigned long seq;/* Connection seqno */ }; @@ -32,6 +32,16 @@ extern int __scm_send(struct socket *soc extern void __scm_destroy(struct scm_cookie *scm); extern struct scm_fp_list * scm_fp_dup(struct scm_fp_list *fpl); +#ifdef CONFIG_SECURITY_NETWORK +static __inline__ void unix_get_peersec_dgram(struct socket *sock, struct scm_cookie *scm) +{ + security_socket_getpeersec_dgram(sock, NULL, &scm->sid); +} +#else +static __inline__ void unix_get_peersec_dgram(struct socket *sock, struct scm_cookie *scm) +{ } +#endif /* CONFIG_SECURITY_NETWORK */ + static __inline__ void scm_destroy(struct scm_cookie *scm) { if (scm && scm->fp) @@ -47,6 +57,7 @@ static __inline__ int scm_send(struct so scm->creds.pid = p->tgid; scm->fp = NULL; scm->seq = 0; + unix_get_peersec_dgram(sock, scm); if (msg->msg_controllen <= 0) return 0; return __scm_send(sock, msg, scm); @@ -55,8 +66,18 @@ static __inline__ int scm_send(struct so #ifdef CONFIG_SECURITY_NETWORK static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm) { - if (test_bit(SOCK_PASSSEC, &sock->flags) && scm->secdata != NULL) - put_cmsg(msg, SOL_SOCKET, SCM_SECURITY, scm->seclen, scm->secdata); + char *secdata; + u32 seclen; + int err; + + if (test_bit(SOCK_PASSSEC, &sock->flags)) { + err = security_sid_to_secctx(scm->sid, &secdata, &seclen); + + if (!err) { + put_cmsg(msg, SOL_SOCKET, SCM_SECURITY, seclen, secdata); + security_release_secctx(secdata, seclen); + } + } } #else static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm) diff -puN net/unix/af_unix.c~af_unix-datagram-getpeersec-ml-fix net/unix/af_unix.c --- linux-2.6.18-rc2/net/unix/af_unix.c~af_unix-datagram-getpeersec-ml-fix 2006-07-22 23:01:26.0 -0400 +++ linux-2.6.18-rc2-cxzhang/net/unix/af_unix.c 2006-07-22 23:14:15.0 -0400 @@ -127,30 +127,6 @@ static atomic_t unix_nr_socks = ATOMIC_I #define UNIX_ABSTRACT(sk) (unix_sk(sk)->addr->hash != UNIX_HASH_SIZE) -#ifdef CONFIG_SECURITY_NETWORK -static void unix_get_peersec_dgram(struct sk_buff *skb) -{ - int err; - - err = security_socket_getpeersec_dgram(skb, UNIXSECDATA(skb), - UNIXSECLEN(skb)); - if (err) - *(UNIXSECDATA(skb)) = NULL; -} - -static inline void unix_set_secdata(struct scm_cookie *scm, struct sk_buff *skb) -{ - scm->secdata = *UNIXSECDATA(skb); - scm->seclen = *UNIXSECLEN(skb); -} -#else -static inline void unix_get_peersec_dgram(struct sk_buff *sk
[Patch 1/1] AF_UNIX Datagram getpeersec (minor fix)
Hi, Minor fix (un-export selinux_get_sock_sid()). 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/net/af_unix.h|6 ++ include/net/scm.h| 17 + net/core/sock.c | 11 +++ net/unix/af_unix.c | 27 +++ security/selinux/hooks.c | 11 --- 26 files changed, 90 insertions(+), 3 deletions(-) diff -puN include/asm-alpha/socket.h~lsm-secpeer-unix include/asm-alpha/socket.h --- linux-2.6.17-rc6-mm2-JM/include/asm-alpha/socket.h~lsm-secpeer-unix 2006-06-27 18:14:52.0 -0400 +++ linux-2.6.17-rc6-mm2-JM-cxzhang/include/asm-alpha/socket.h 2006-06-27 18:16:31.0 -0400 @@ -51,6 +51,7 @@ #define SCM_TIMESTAMP SO_TIMESTAMP #define SO_PEERSEC 30 +#define SO_PASSSEC 34 /* Security levels - as per NRL IPv6 - don't actually do anything */ #define SO_SECURITY_AUTHENTICATION 19 diff -puN include/asm-arm/socket.h~lsm-secpeer-unix include/asm-arm/socket.h --- linux-2.6.17-rc6-mm2-JM/include/asm-arm/socket.h~lsm-secpeer-unix 2006-06-27 18:15:10.0 -0400 +++ linux-2.6.17-rc6-mm2-JM-cxzhang/include/asm-arm/socket.h2006-06-27 18:16:31.0 -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-arm26/socket.h~lsm-secpeer-unix include/asm-arm26/socket.h --- linux-2.6.17-rc6-mm2-JM/include/asm-arm26/socket.h~lsm-secpeer-unix 2006-06-27 18:15:10.0 -0400 +++ linux-2.6.17-rc6-mm2-JM-cxzhang/include/asm-arm26/socket.h 2006-06-27 18:16:31.0 -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-rc6-mm2-JM/include/asm-cris/socket.h~lsm-secpeer-unix 2006-06-27 18:15:10.0 -0400 +++ linux-2.6.17-rc6-mm2-JM-cxzhang/include/asm-cris/socket.h 2006-06-27 18:16:31.0 -0400 @@ -50,6 +50,7 @@ #define SO_ACCEPTCONN 30 #define SO_PEERSEC 31 +#define
[Patch 1/1] AF_UNIX Datagram getpeersec (with latest updates)
Hi, This patch combines all previous updates. Many thanks to James, Dave, and Stephen for their modifications and comments! cheers, 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 | 15 +++ include/net/af_unix.h|6 ++ include/net/scm.h| 17 + net/core/sock.c | 11 +++ net/unix/af_unix.c | 27 +++ security/selinux/exports.c | 11 +++ security/selinux/hooks.c |8 +++- 28 files changed, 115 insertions(+), 1 deletion(-) diff -puN include/asm-alpha/socket.h~lsm-secpeer-unix include/asm-alpha/socket.h --- linux-2.6.17-rc6-mm2-JM/include/asm-alpha/socket.h~lsm-secpeer-unix 2006-06-27 18:14:52.586456256 -0400 +++ linux-2.6.17-rc6-mm2-JM-cxzhang/include/asm-alpha/socket.h 2006-06-27 18:16:31.488420872 -0400 @@ -51,6 +51,7 @@ #define SCM_TIMESTAMP SO_TIMESTAMP #define SO_PEERSEC 30 +#define SO_PASSSEC 34 /* Security levels - as per NRL IPv6 - don't actually do anything */ #define SO_SECURITY_AUTHENTICATION 19 diff -puN include/asm-arm/socket.h~lsm-secpeer-unix include/asm-arm/socket.h --- linux-2.6.17-rc6-mm2-JM/include/asm-arm/socket.h~lsm-secpeer-unix 2006-06-27 18:15:10.052800968 -0400 +++ linux-2.6.17-rc6-mm2-JM-cxzhang/include/asm-arm/socket.h2006-06-27 18:16:31.489420720 -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-arm26/socket.h~lsm-secpeer-unix include/asm-arm26/socket.h --- linux-2.6.17-rc6-mm2-JM/include/asm-arm26/socket.h~lsm-secpeer-unix 2006-06-27 18:15:10.095794432 -0400 +++ linux-2.6.17-rc6-mm2-JM-cxzhang/include/asm-arm26/socket.h 2006-06-27 18:16:31.489420720 -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-rc6-mm2-JM/include/asm-cris/socket.h~lsm-secpeer-unix 2006-06-27 18:15:10.132788808 -0400 +++ linux-2.6.17-rc6-mm2-J
[Patch 1/1] AF_UNIX Datagram getpeersec
Hi, One major change as per James' comment -- calls to get the security context of a peer is done through the hook socket_getpeersec_dgram(). Again, comments are welcome! 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 | 15 +++ include/net/af_unix.h|2 ++ include/net/scm.h|4 net/core/sock.c | 11 +++ net/unix/af_unix.c |5 + security/selinux/exports.c | 11 +++ security/selinux/hooks.c |8 +++- 28 files changed, 76 insertions(+), 1 deletion(-) diff -puN include/asm-i386/socket.h~lsm-secpeer-unix include/asm-i386/socket.h --- linux-2.6.17-rc6-mm2/include/asm-i386/socket.h~lsm-secpeer-unix 2006-06-12 17:56:06.0 -0400 +++ linux-2.6.17-rc6-mm2-cxzhang/include/asm-i386/socket.h 2006-06-13 15:45:34.0 -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-rc6-mm2/include/asm-x86_64/socket.h~lsm-secpeer-unix 2006-06-12 17:56:06.0 -0400 +++ linux-2.6.17-rc6-mm2-cxzhang/include/asm-x86_64/socket.h2006-06-13 15:45:34.0 -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-rc6-mm2/include/asm-ia64/socket.h~lsm-secpeer-unix 2006-06-12 17:56:06.0 -0400 +++ linux-2.6.17-rc6-mm2-cxzhang/include/asm-ia64/socket.h 2006-06-13 15:45:34.0 -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-rc6-mm2/include/asm-powerpc/socket.h~lsm-secpeer-unix 2006-06-12 17:56:06.0 -0400 +++ linux-2.6.17-rc6-mm2-cxzhang/include/asm-powerpc/socket.h 2006-06-13 15:45:34.0 -0400 @@ -55
[Patch 1/1] AF_UNIX Datagram getpeersec (with minor fix)
Hi, I added one file (include/linux/selinux.h) which was omitted from the previous patch, and removed a couple of unnecessary changes. Again, comments are welcome! 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 | 15 +++ include/net/af_unix.h|2 ++ include/net/scm.h| 14 ++ net/core/sock.c | 11 +++ net/unix/af_unix.c |2 ++ security/selinux/exports.c | 11 +++ 27 files changed, 76 insertions(+) diff -puN include/asm-i386/socket.h~lsm-secpeer-unix include/asm-i386/socket.h --- linux-2.6.17-rc6-mm2/include/asm-i386/socket.h~lsm-secpeer-unix 2006-06-12 17:56:06.0 -0400 +++ linux-2.6.17-rc6-mm2-cxzhang/include/asm-i386/socket.h 2006-06-13 15:45:34.0 -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-rc6-mm2/include/asm-x86_64/socket.h~lsm-secpeer-unix 2006-06-12 17:56:06.0 -0400 +++ linux-2.6.17-rc6-mm2-cxzhang/include/asm-x86_64/socket.h2006-06-13 15:45:34.0 -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-rc6-mm2/include/asm-ia64/socket.h~lsm-secpeer-unix 2006-06-12 17:56:06.0 -0400 +++ linux-2.6.17-rc6-mm2-cxzhang/include/asm-ia64/socket.h 2006-06-13 15:45:34.0 -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-rc6-mm2/include/asm-powerpc/socket.h~lsm-secpeer-unix 2006-06-12 17:56:06.0 -0400 +++ linux-2.6.17-rc6-mm2-cxzhang/include/asm-powerpc/socket.h 2006-06-13 15:45:34.0 -0400 @@ -55,5 +55,6 @@ #define SO_ACCEPTCONN 30 #define SO
Re: updated [Patch 1/1] AF_UNIX Datagram getpeersec
On 6/17/06, James Morris <[EMAIL PROTECTED]> wrote: On Fri, 16 Jun 2006, Stephen Hemminger wrote: > This is so short, it would make sense to put it in scm.h > and why not have it return the value instead of call by reference? > Same goes for selinux_get_inode_sid Actually, all of the SELinux API functions are like this, and I'm not sure why for void return methods (it's a good idea when they return errnos). Yes, the reason I used void return method is consistency with the remaining SELinux API functions. Once this area has settled down (post 2.6.18), I'm planning to do some cleanups for this API anyway, and can fix these all at the same time. OK. Thanks, Catherine - 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
updated [Patch 1/1] AF_UNIX Datagram getpeersec
Hi, Enclosed please find the updated AF_UNIX patch, incorporating comments from James, Stephen, Dave, Chris, Andrew and others. The patch is now built upon the newly added SELinux functions exported in selinux/exports.c, which are also used by the auditing subsystem. One function, selinux_get_socket_sid(), is added to the list of exported functions by this patch. I have tested it with three configurations: with SELinux, w/o SELinux, and allmodconfig. 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/net/af_unix.h |2 ++ include/net/scm.h | 13 + net/core/sock.c | 11 +++ net/unix/af_unix.c |2 ++ security/selinux/exports.c | 11 +++ security/selinux/include/security.h |2 +- security/selinux/ss/services.c |4 ++-- 28 files changed, 63 insertions(+), 3 deletions(-) diff -puN include/asm-i386/socket.h~lsm-secpeer-unix include/asm-i386/socket.h --- linux-2.6.17-rc6-mm2/include/asm-i386/socket.h~lsm-secpeer-unix 2006-06-12 17:56:06.0 -0400 +++ linux-2.6.17-rc6-mm2-cxzhang/include/asm-i386/socket.h 2006-06-13 15:45:34.0 -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-rc6-mm2/include/asm-x86_64/socket.h~lsm-secpeer-unix 2006-06-12 17:56:06.0 -0400 +++ linux-2.6.17-rc6-mm2-cxzhang/include/asm-x86_64/socket.h2006-06-13 15:45:34.0 -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-rc6-mm2/include/asm-ia64/socket.h~lsm-secpeer-unix 2006-06-12 17:56:06.0 -0400 +++ linux-2.6.17-rc6-mm2-cxzhang/include/asm-ia64/
[PATCH 1/1] LSM-IPsec SELinux Authorize (with minor fix)
Hi, Minor fix per James' comment. thanks, Catherine -- This patch contains a fix for the previous patch that adds security contexts to IPsec policies and security associations. In the previous patch, no authorization (besides the check for write permissions to SAD and SPD) is required to delete IPsec policies and security assocations with security contexts. Thus a user authorized to change SAD and SPD can bypass the IPsec policy authorization by simply deleteing policies with security contexts. To fix this security hole, an additional authorization check is added for removing security policies and security associations with security contexts. Note that if no security context is supplied on add or present on policy to be deleted, the SELinux module allows the change unconditionally. The hook is called on deletion when no context is present, which we may want to change. At present, I left it up to the module. LSM changes: The patch adds two new LSM hooks: xfrm_policy_delete and xfrm_state_delete. The new hooks are necessary to authorize deletion of IPsec policies that have security contexts. The existing hooks xfrm_policy_free and xfrm_state_free lack the context to do the authorization, so I decided to split authorization of deletion and memory management of security data, as is typical in the LSM interface. Use: The new delete hooks are checked when xfrm_policy or xfrm_state are deleted by either the xfrm_user interface (xfrm_get_policy, xfrm_del_sa) or the pfkey interface (pfkey_spddelete, pfkey_delete). SELinux changes: The new policy_delete and state_delete functions are added. Signed-off-by: Trent Jaeger <[EMAIL PROTECTED]> --- include/linux/security.h| 40 ++-- net/key/af_key.c| 17 +++-- net/xfrm/xfrm_user.c| 19 --- security/dummy.c| 12 security/selinux/hooks.c|2 ++ security/selinux/include/xfrm.h |2 ++ security/selinux/xfrm.c | 39 +++ 7 files changed, 108 insertions(+), 23 deletions(-) diff -puN include/linux/security.h~lsm-secpeer-fix include/linux/security.h --- linux-2.6.17-rc4-mm3/include/linux/security.h~lsm-secpeer-fix 2006-05-31 00:01:35.0 -0400 +++ linux-2.6.17-rc4-mm3-cxzhang/include/linux/security.h 2006-05-31 00:46:13.0 -0400 @@ -805,31 +805,37 @@ struct swap_info_struct; * used by the XFRM system. * @sec_ctx contains the security context information being provided by * the user-level policy update program (e.g., setkey). - * Allocate a security structure to the xp->selector.security field. + * Allocate a security structure to the xp->security field. * The security field is initialized to NULL when the xfrm_policy is * allocated. * Return 0 if operation was successful (memory to allocate, legal context) * @xfrm_policy_clone_security: * @old contains an existing xfrm_policy in the SPD. * @new contains a new xfrm_policy being cloned from old. - * Allocate a security structure to the new->selector.security field - * that contains the information from the old->selector.security field. + * Allocate a security structure to the new->security field + * that contains the information from the old->security field. * Return 0 if operation was successful (memory to allocate). * @xfrm_policy_free_security: * @xp contains the xfrm_policy - * Deallocate xp->selector.security. + * Deallocate xp->security. + * @xfrm_policy_delete_security: + * @xp contains the xfrm_policy. + * Authorize deletion of xp->security. * @xfrm_state_alloc_security: * @x contains the xfrm_state being added to the Security Association * Database by the XFRM system. * @sec_ctx contains the security context information being provided by * the user-level SA generation program (e.g., setkey or racoon). - * Allocate a security structure to the x->sel.security field. The + * Allocate a security structure to the x->security field. The * security field is initialized to NULL when the xfrm_state is * allocated. * Return 0 if operation was successful (memory to allocate, legal context). * @xfrm_state_free_security: * @x contains the xfrm_state. - * Deallocate x>sel.security. + * Deallocate x->security. + * @xfrm_state_delete_security: + * @x contains the xfrm_state. + * Authorize deletion of x->security. * @xfrm_policy_lookup: * @xp contains the xfrm_policy for which the access control is being * checked. @@ -1298,8 +1304,10 @@ struct security_operations { int (*xfrm_policy_alloc_security) (struct xfrm_policy *xp, struct xfrm_user_sec_ctx *sec_ctx); int (*xfrm_policy_clone_security) (struct xfrm_policy *old, struct xfrm_policy *new); void (*xfrm_policy_free_security) (str
[PATCH 1/1] LSM-IPsec SELinux Authorize
Hi, This is resubmit of the LSM-IPsec fix patch rebased against Linux version 2.6.17-rc4-mm3. As always, comments are welcome! Catherine --- This patch contains a fix for the previous patch that adds security contexts to IPsec policies and security associations. In the previous patch, no authorization (besides the check for write permissions to SAD and SPD) is required to delete IPsec policies and security assocations with security contexts. Thus a user authorized to change SAD and SPD can bypass the IPsec policy authorization by simply deleteing policies with security contexts. To fix this security hole, an additional authorization check is added for removing security policies and security associations with security contexts. Note that if no security context is supplied on add or present on policy to be deleted, the SELinux module allows the change unconditionally. The hook is called on deletion when no context is present, which we may want to change. At present, I left it up to the module. LSM changes: The patch adds two new LSM hooks: xfrm_policy_delete and xfrm_state_delete. The new hooks are necessary to authorize deletion of IPsec policies that have security contexts. The existing hooks xfrm_policy_free and xfrm_state_free lack the context to do the authorization, so I decided to split authorization of deletion and memory management of security data, as is typical in the LSM interface. Use: The new delete hooks are checked when xfrm_policy or xfrm_state are deleted by either the xfrm_user interface (xfrm_get_policy, xfrm_del_sa) or the pfkey interface (pfkey_spddelete, pfkey_delete). SELinux changes: The new policy_delete and state_delete functions are added. Signed-off-by: Trent Jaeger <[EMAIL PROTECTED]> --- include/linux/security.h| 40 +-- net/key/af_key.c| 17 ++-- net/xfrm/xfrm_user.c| 19 +++--- security/dummy.c| 12 +++ security/selinux/hooks.c|2 + security/selinux/include/xfrm.h |2 + security/selinux/xfrm.c | 41 7 files changed, 110 insertions(+), 23 deletions(-) diff -puN include/linux/security.h~lsm-secpeer-fix include/linux/security.h --- linux-2.6.17-rc4-mm3/include/linux/security.h~lsm-secpeer-fix 2006-05-31 00:01:35.0 -0400 +++ linux-2.6.17-rc4-mm3-cxzhang/include/linux/security.h 2006-05-31 00:46:13.0 -0400 @@ -805,31 +805,37 @@ struct swap_info_struct; * used by the XFRM system. * @sec_ctx contains the security context information being provided by * the user-level policy update program (e.g., setkey). - * Allocate a security structure to the xp->selector.security field. + * Allocate a security structure to the xp->security field. * The security field is initialized to NULL when the xfrm_policy is * allocated. * Return 0 if operation was successful (memory to allocate, legal context) * @xfrm_policy_clone_security: * @old contains an existing xfrm_policy in the SPD. * @new contains a new xfrm_policy being cloned from old. - * Allocate a security structure to the new->selector.security field - * that contains the information from the old->selector.security field. + * Allocate a security structure to the new->security field + * that contains the information from the old->security field. * Return 0 if operation was successful (memory to allocate). * @xfrm_policy_free_security: * @xp contains the xfrm_policy - * Deallocate xp->selector.security. + * Deallocate xp->security. + * @xfrm_policy_delete_security: + * @xp contains the xfrm_policy. + * Authorize deletion of xp->security. * @xfrm_state_alloc_security: * @x contains the xfrm_state being added to the Security Association * Database by the XFRM system. * @sec_ctx contains the security context information being provided by * the user-level SA generation program (e.g., setkey or racoon). - * Allocate a security structure to the x->sel.security field. The + * Allocate a security structure to the x->security field. The * security field is initialized to NULL when the xfrm_state is * allocated. * Return 0 if operation was successful (memory to allocate, legal context). * @xfrm_state_free_security: * @x contains the xfrm_state. - * Deallocate x>sel.security. + * Deallocate x->security. + * @xfrm_state_delete_security: + * @x contains the xfrm_state. + * Authorize deletion of x->security. * @xfrm_policy_lookup: * @xp contains the xfrm_policy for which the access control is being * checked. @@ -1298,8 +1304,10 @@ struct security_operations { int (*xfrm_policy_alloc_security) (struct xfrm_policy *xp, struct xfrm_user_sec_ctx *sec_ctx); int (*xfrm_policy_clone_security) (struct xfrm_p
updated [Patch 1/1] AF_UNIX Datagram getpeersec
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.0 -0400 +++ linux-2.6.17-rc1-cxzhang/include/asm-i386/socket.h 2006-04-03 18:20:46.0 -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 inc
RFC [Patch 1/1] Unix Datagram getpeersec
Hi, As per request from Stephen, I have enclosed the patch for Unix Datagram getpeersec. As always, comments are welcome! 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-i386/socket.h|1 + include/asm-ia64/socket.h|1 + include/asm-powerpc/socket.h |1 + include/asm-x86_64/socket.h |1 + include/linux/net.h |1 + include/net/af_unix.h|2 ++ include/net/scm.h| 12 net/core/sock.c | 11 +++ net/unix/af_unix.c |2 ++ 9 files changed, 32 insertions(+) diff -puN include/linux/net.h~lsm-secpeer-unix include/linux/net.h --- linux-2.6.16-rc1/include/linux/net.h~lsm-secpeer-unix 2006-03-07 18:55:59.0 -0500 +++ linux-2.6.16-rc1-cxzhang/include/linux/net.h2006-03-07 18:57:58.0 -0500 @@ -62,6 +62,7 @@ typedef enum { #define SOCK_ASYNC_WAITDATA1 #define SOCK_NOSPACE 2 #define SOCK_PASSCRED 3 +#define SOCK_PASSSEC 4 #ifndef ARCH_HAS_SOCKET_TYPES /** diff -puN include/asm-i386/socket.h~lsm-secpeer-unix include/asm-i386/socket.h --- linux-2.6.16-rc1/include/asm-i386/socket.h~lsm-secpeer-unix 2006-03-07 18:58:38.0 -0500 +++ linux-2.6.16-rc1-cxzhang/include/asm-i386/socket.h 2006-03-07 18:59:31.0 -0500 @@ -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.16-rc1/include/asm-x86_64/socket.h~lsm-secpeer-unix 2006-03-07 19:00:58.0 -0500 +++ linux-2.6.16-rc1-cxzhang/include/asm-x86_64/socket.h2006-03-07 19:06:09.0 -0500 @@ -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.16-rc1/include/asm-ia64/socket.h~lsm-secpeer-unix 2006-03-07 19:02:27.0 -0500 +++ linux-2.6.16-rc1-cxzhang/include/asm-ia64/socket.h 2006-03-07 19:02:44.0 -0500 @@ -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.16-rc1/include/asm-powerpc/socket.h~lsm-secpeer-unix 2006-03-07 19:04:00.0 -0500 +++ linux-2.6.16-rc1-cxzhang/include/asm-powerpc/socket.h 2006-03-07 19:04:17.0 -0500 @@ -55,5 +55,6 @@ #define SO_ACCEPTCONN 30 #define SO_PEERSEC 31 +#define SO_PASSSEC 34 #endif /* _ASM_POWERPC_SOCKET_H */ diff -puN include/net/af_unix.h~lsm-secpeer-unix include/net/af_unix.h --- linux-2.6.16-rc1/include/net/af_unix.h~lsm-secpeer-unix 2006-03-07 19:19:08.0 -0500 +++ linux-2.6.16-rc1-cxzhang/include/net/af_unix.h 2006-03-
[Patch 1/1] updated: TCP/UDP getpeersec
Hi, Updated as per Herbert's comment. Catherine --- From: [EMAIL PROTECTED] This patch implements an application of the LSM-IPSec networking controls whereby an application can determine the label of the security association its TCP or UDP sockets are currently connected to via getsockopt and the auxiliary data mechanism of recvmsg. Patch purpose: This patch enables a security-aware application to retrieve the security context of an IPSec security association a particular TCP or UDP socket is using. The application can then use this security context to determine the security context for processing on behalf of the peer at the other end of this connection. In the case of UDP, the security context is for each individual packet. An example application is the inetd daemon, which could be modified to start daemons running at security contexts dependent on the remote client. Patch design approach: - Design for TCP The patch enables the SELinux LSM to set the peer security context for a socket based on the security context of the IPSec security association. The application may retrieve this context using getsockopt. When called, the kernel determines if the socket is a connected (TCP_ESTABLISHED) TCP socket and, if so, uses the dst_entry cache on the socket to retrieve the security associations. If a security association has a security context, the context string is returned, as for UNIX domain sockets. - Design for UDP Unlike TCP, UDP is connectionless. This requires a somewhat different API to retrieve the peer security context. With TCP, the peer security context stays the same throughout the connection, thus it can be retrieved at any time between when the connection is established and when it is torn down. With UDP, each read/write can have different peer and thus the security context might change every time. As a result the security context retrieval must be done TOGETHER with the packet retrieval. The solution is to 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). Patch implementation details: - Implementation for TCP The security context can be retrieved by applications using getsockopt with the existing SO_PEERSEC flag. As an example (ignoring error checking): getsockopt(sockfd, SOL_SOCKET, SO_PEERSEC, optbuf, &optlen); printf("Socket peer context is: %s\n", optbuf); The SELinux function, selinux_socket_getpeersec, is extended to check for labeled security associations for connected (TCP_ESTABLISHED == sk->sk_state) TCP sockets only. If so, the socket has a dst_cache of struct dst_entry values that may refer to security associations. If these have security associations with security contexts, the security context is returned. getsockopt returns a buffer that contains a security context string or the buffer is unmodified. - Implementation for UDP To retrieve the security context, the application first indicates to the kernel such desire by setting the IP_PASSSEC option via getsockopt. Then the application retrieves the security context using the auxiliary data mechanism. An example server application for UDP should look like this: toggle = 1; toggle_len = sizeof(toggle); setsockopt(sockfd, SOL_IP, IP_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_IP && cmsg_hdr->cmsg_type == SCM_SECURITY) { memcpy(&scontext, CMSG_DATA(cmsg_hdr), sizeof(scontext)); } } ip_setsockopt is enhanced with a new socket option IP_PASSSEC to allow a server socket to receive security context of the peer. A new ancillary message type SCM_SECURITY. When the packet is received we get the security context from the sec_path pointer which is contained in the sk_buff, and copy it to the ancillary message space. An additional LSM hook, selinux_socket_getpeersec_udp, is defined to retrieve the security context from the SELinux space. The existing function, selinux_socket_getpeersec does not suit our purpose, because the security context is copied directly to user space, rather than to kernel space. Testing: We have tested the patch by setting up TCP and UDP connections between applications on two machines using the IPSec policies that result in labeled security associations being built. For TCP, we can then extract the peer security context using getsockopt on either end. For UDP, the receiving end can retrieve the security context using the auxiliary data mechanism of recvmsg. --- include/linux/in.h |1 include/linux/security.h| 25 +++--- include/linux/socket.h |1 net/core/sock.c |2 - net/ipv4/ip_sockglue
Re: [Patch 1/1] updated: TCP/UDP getpeersec
Joy, Thanks for your comment and sorry for the delay. Did you mean a separate error code for 'null' context? The current code catches the case when the sid is SECSID_NULL, and returns ENOPROTOOPT. The question is whether we want to create a different error code for this case. Any suggestions? thanks, Catherine On 2/10/06, Joy Latten <[EMAIL PROTECTED]> wrote: > Catherine, > I am just wondering about something... > Should a peer_sid of 0 or SECSID_NULL be an error here if > the connection doesn't have a transform? I understand we only get > peer's context if a xfrm is involved, but I am thinking > most user applications may not kno or care if there is a xfrm. > If not treated as an error, it looks like security_to_sid_context() > would just return "null" for context. Would that be acceptable? > > Perhaps it is just important that we document the behaviour because > I am thinking most user apps will not care or know if ipsec is > running, so programmers may use this socket option to get peer > context and may need to understand why they received an error of > ENOPROTOOPT. > > > } > > + 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; > > > > @@ -3396,6 +3410,23 @@ out: > > return err; > > } > > > > + > > Regards, > Joy > - 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
[Patch 1/1] updated: TCP/UDP getpeersec
Hi, Updated as per James' comment. Catherine --- From: [EMAIL PROTECTED] This patch implements an application of the LSM-IPSec networking controls whereby an application can determine the label of the security association its TCP or UDP sockets are currently connected to via getsockopt and the auxiliary data mechanism of recvmsg. Patch purpose: This patch enables a security-aware application to retrieve the security context of an IPSec security association a particular TCP or UDP socket is using. The application can then use this security context to determine the security context for processing on behalf of the peer at the other end of this connection. In the case of UDP, the security context is for each individual packet. An example application is the inetd daemon, which could be modified to start daemons running at security contexts dependent on the remote client. Patch design approach: - Design for TCP The patch enables the SELinux LSM to set the peer security context for a socket based on the security context of the IPSec security association. The application may retrieve this context using getsockopt. When called, the kernel determines if the socket is a connected (TCP_ESTABLISHED) TCP socket and, if so, uses the dst_entry cache on the socket to retrieve the security associations. If a security association has a security context, the context string is returned, as for UNIX domain sockets. - Design for UDP Unlike TCP, UDP is connectionless. This requires a somewhat different API to retrieve the peer security context. With TCP, the peer security context stays the same throughout the connection, thus it can be retrieved at any time between when the connection is established and when it is torn down. With UDP, each read/write can have different peer and thus the security context might change every time. As a result the security context retrieval must be done TOGETHER with the packet retrieval. The solution is to 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). Patch implementation details: - Implementation for TCP The security context can be retrieved by applications using getsockopt with the existing SO_PEERSEC flag. As an example (ignoring error checking): getsockopt(sockfd, SOL_SOCKET, SO_PEERSEC, optbuf, &optlen); printf("Socket peer context is: %s\n", optbuf); The SELinux function, selinux_socket_getpeersec, is extended to check for labeled security associations for connected (TCP_ESTABLISHED == sk->sk_state) TCP sockets only. If so, the socket has a dst_cache of struct dst_entry values that may refer to security associations. If these have security associations with security contexts, the security context is returned. getsockopt returns a buffer that contains a security context string or the buffer is unmodified. - Implementation for UDP To retrieve the security context, the application first indicates to the kernel such desire by setting the IP_PASSSEC option via getsockopt. Then the application retrieves the security context using the auxiliary data mechanism. An example server application for UDP should look like this: toggle = 1; toggle_len = sizeof(toggle); setsockopt(sockfd, SOL_IP, IP_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_IP && cmsg_hdr->cmsg_type == SCM_SECURITY) { memcpy(&scontext, CMSG_DATA(cmsg_hdr), sizeof(scontext)); } } ip_setsockopt is enhanced with a new socket option IP_PASSSEC to allow a server socket to receive security context of the peer. A new ancillary message type SCM_SECURITY. When the packet is received we get the security context from the sec_path pointer which is contained in the sk_buff, and copy it to the ancillary message space. An additional LSM hook, selinux_socket_getpeersec_udp, is defined to retrieve the security context from the SELinux space. The existing function, selinux_socket_getpeersec does not suit our purpose, because the security context is copied directly to user space, rather than to kernel space. Testing: We have tested the patch by setting up TCP and UDP connections between applications on two machines using the IPSec policies that result in labeled security associations being built. For TCP, we can then extract the peer security context using getsockopt on either end. For UDP, the receiving end can retrieve the security context using the auxiliary data mechanism of recvmsg. --- include/linux/in.h |1 include/linux/security.h| 25 +++--- include/linux/socket.h |1 net/core/sock.c |2 - net/ipv4/ip_sockglue.c
[Patch 1/1] Resubmit: TCP/UDP getpeersec
Hi, Resubmission since the previous submission has entangled tab/spaces. thanks, Catherine -- From: [EMAIL PROTECTED] This patch implements an application of the LSM-IPSec networking controls whereby an application can determine the label of the security association its TCP or UDP sockets are currently connected to via getsockopt and the auxiliary data mechanism of recvmsg. Patch purpose: This patch enables a security-aware application to retrieve the security context of an IPSec security association a particular TCP or UDP socket is using. The application can then use this security context to determine the security context for processing on behalf of the peer at the other end of this connection. In the case of UDP, the security context is for each individual packet. An example application is the inetd daemon, which could be modified to start daemons running at security contexts dependent on the remote client. Patch design approach: - Design for TCP The patch enables the SELinux LSM to set the peer security context for a socket based on the security context of the IPSec security association. The application may retrieve this context using getsockopt. When called, the kernel determines if the socket is a connected (TCP_ESTABLISHED) TCP socket and, if so, uses the dst_entry cache on the socket to retrieve the security associations. If a security association has a security context, the context string is returned, as for UNIX domain sockets. - Design for UDP Unlike TCP, UDP is connectionless. This requires a somewhat different API to retrieve the peer security context. With TCP, the peer security context stays the same throughout the connection, thus it can be retrieved at any time between when the connection is established and when it is torn down. With UDP, each read/write can have different peer and thus the security context might change every time. As a result the security context retrieval must be done TOGETHER with the packet retrieval. The solution is to 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). Patch implementation details: - Implementation for TCP The security context can be retrieved by applications using getsockopt with the existing SO_PEERSEC flag. As an example (ignoring error checking): getsockopt(sockfd, SOL_SOCKET, SO_PEERSEC, optbuf, &optlen); printf("Socket peer context is: %s\n", optbuf); The SELinux function, selinux_socket_getpeersec, is extended to check for labeled security associations for connected (TCP_ESTABLISHED == sk->sk_state) TCP sockets only. If so, the socket has a dst_cache of struct dst_entry values that may refer to security associations. If these have security associations with security contexts, the security context is returned. getsockopt returns a buffer that contains a security context string or the buffer is unmodified. - Implementation for UDP To retrieve the security context, the application first indicates to the kernel such desire by setting the IP_PASSSEC option via getsockopt. Then the application retrieves the security context using the auxiliary data mechanism. An example server application for UDP should look like this: toggle = 1; toggle_len = sizeof(toggle); setsockopt(sockfd, SOL_IP, IP_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_IP && cmsg_hdr->cmsg_type == SCM_SECURITY) { memcpy(&scontext, CMSG_DATA(cmsg_hdr), sizeof(scontext)); } } ip_setsockopt is enhanced with a new socket option IP_PASSSEC to allow a server socket to receive security context of the peer. A new ancillary message type SCM_SECURITY. When the packet is received we get the security context from the sec_path pointer which is contained in the sk_buff, and copy it to the ancillary message space. An additional LSM hook, selinux_socket_getpeersec_udp, is defined to retrieve the security context from the SELinux space. The existing function, selinux_socket_getpeersec does not suit our purpose, because the security context is copied directly to user space, rather than to kernel space. Testing: We have tested the patch by setting up TCP and UDP connections between applications on two machines using the IPSec policies that result in labeled security associations being built. For TCP, we can then extract the peer security context using getsockopt on either end. For UDP, the receiving end can retrieve the security context using the auxiliary data mechanism of recvmsg. --- include/linux/in.h |1 include/linux/security.h| 15 + include/linux/socket.h |1 net/ipv4/ip_sockglue.c
Re: [PATCH 1/1] double xfrm_state_put bug fix
This is much better. Sorry for the confusion. With a clear comment like this, I don't think it'll happen again. thanks, Catherine On 1/17/06, Herbert Xu <[EMAIL PROTECTED]> wrote: > On Tue, Jan 17, 2006 at 06:29:26PM -0800, David S. Miller wrote: > > > > There is a big comment in __xfrm_state_delete(), would you like > > something more? :-) > > How about something like this? This should make someone think twice > before treating it as a duplicate. > > [IPSEC]: Turn first xfrm_state_put into atomic_dec > > We need to do two xfrm_state_put's in a row in order to kill a state > that's not linked into the system. Since we know that the first put > is not going to free the structure, we can turn it into an atomic_dec. > > This should also tell people that the two put's are intentional and > not a bug. > > Signed-off-by: Herbert Xu <[EMAIL PROTECTED]> > > Cheers, > -- > 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 > > > - 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