aboutsummaryrefslogtreecommitdiffstats
path: root/include/net/scm.h
diff options
context:
space:
mode:
authorCatherine Zhang <cxzhang@watson.ibm.com>2006-08-02 17:12:06 -0400
committerDavid S. Miller <davem@davemloft.net>2006-08-02 17:12:06 -0400
commitdc49c1f94e3469d94b952e8f5160dd4ccd791d79 (patch)
treee47b1974c262a03dbabf0a148325d9089817e78e /include/net/scm.h
parent2b7e24b66d31d677d76b49918e711eb360c978b6 (diff)
[AF_UNIX]: Kernel memory leak fix for af_unix datagram getpeersec patch
From: Catherine Zhang <cxzhang@watson.ibm.com> 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. Acked-by: Stephen Smalley <sds@tycho.nsa.gov> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/net/scm.h')
-rw-r--r--include/net/scm.h29
1 files changed, 25 insertions, 4 deletions
diff --git a/include/net/scm.h b/include/net/scm.h
index 02daa097cdcd..5637d5e22d5f 100644
--- a/include/net/scm.h
+++ b/include/net/scm.h
@@ -3,6 +3,7 @@
3 3
4#include <linux/limits.h> 4#include <linux/limits.h>
5#include <linux/net.h> 5#include <linux/net.h>
6#include <linux/security.h>
6 7
7/* Well, we should have at least one descriptor open 8/* Well, we should have at least one descriptor open
8 * to accept passed FDs 8) 9 * to accept passed FDs 8)
@@ -20,8 +21,7 @@ struct scm_cookie
20 struct ucred creds; /* Skb credentials */ 21 struct ucred creds; /* Skb credentials */
21 struct scm_fp_list *fp; /* Passed files */ 22 struct scm_fp_list *fp; /* Passed files */
22#ifdef CONFIG_SECURITY_NETWORK 23#ifdef CONFIG_SECURITY_NETWORK
23 char *secdata; /* Security context */ 24 u32 secid; /* Passed security ID */
24 u32 seclen; /* Security length */
25#endif 25#endif
26 unsigned long seq; /* Connection seqno */ 26 unsigned long seq; /* Connection seqno */
27}; 27};
@@ -32,6 +32,16 @@ extern int __scm_send(struct socket *sock, struct msghdr *msg, struct scm_cookie
32extern void __scm_destroy(struct scm_cookie *scm); 32extern void __scm_destroy(struct scm_cookie *scm);
33extern struct scm_fp_list * scm_fp_dup(struct scm_fp_list *fpl); 33extern struct scm_fp_list * scm_fp_dup(struct scm_fp_list *fpl);
34 34
35#ifdef CONFIG_SECURITY_NETWORK
36static __inline__ void unix_get_peersec_dgram(struct socket *sock, struct scm_cookie *scm)
37{
38 security_socket_getpeersec_dgram(sock, NULL, &scm->secid);
39}
40#else
41static __inline__ void unix_get_peersec_dgram(struct socket *sock, struct scm_cookie *scm)
42{ }
43#endif /* CONFIG_SECURITY_NETWORK */
44
35static __inline__ void scm_destroy(struct scm_cookie *scm) 45static __inline__ void scm_destroy(struct scm_cookie *scm)
36{ 46{
37 if (scm && scm->fp) 47 if (scm && scm->fp)
@@ -47,6 +57,7 @@ static __inline__ int scm_send(struct socket *sock, struct msghdr *msg,
47 scm->creds.pid = p->tgid; 57 scm->creds.pid = p->tgid;
48 scm->fp = NULL; 58 scm->fp = NULL;
49 scm->seq = 0; 59 scm->seq = 0;
60 unix_get_peersec_dgram(sock, scm);
50 if (msg->msg_controllen <= 0) 61 if (msg->msg_controllen <= 0)
51 return 0; 62 return 0;
52 return __scm_send(sock, msg, scm); 63 return __scm_send(sock, msg, scm);
@@ -55,8 +66,18 @@ static __inline__ int scm_send(struct socket *sock, struct msghdr *msg,
55#ifdef CONFIG_SECURITY_NETWORK 66#ifdef CONFIG_SECURITY_NETWORK
56static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm) 67static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm)
57{ 68{
58 if (test_bit(SOCK_PASSSEC, &sock->flags) && scm->secdata != NULL) 69 char *secdata;
59 put_cmsg(msg, SOL_SOCKET, SCM_SECURITY, scm->seclen, scm->secdata); 70 u32 seclen;
71 int err;
72
73 if (test_bit(SOCK_PASSSEC, &sock->flags)) {
74 err = security_secid_to_secctx(scm->secid, &secdata, &seclen);
75
76 if (!err) {
77 put_cmsg(msg, SOL_SOCKET, SCM_SECURITY, seclen, secdata);
78 security_release_secctx(secdata, seclen);
79 }
80 }
60} 81}
61#else 82#else
62static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm) 83static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm)