diff options
| author | Catherine Zhang <cxzhang@watson.ibm.com> | 2006-08-02 14:12:06 -0700 | 
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2006-08-02 14:12:06 -0700 | 
| commit | dc49c1f94e3469d94b952e8f5160dd4ccd791d79 (patch) | |
| tree | e47b1974c262a03dbabf0a148325d9089817e78e /include/linux/security.h | |
| parent | 2b7e24b66d31d677d76b49918e711eb360c978b6 (diff) | |
| download | olio-linux-3.10-dc49c1f94e3469d94b952e8f5160dd4ccd791d79.tar.xz olio-linux-3.10-dc49c1f94e3469d94b952e8f5160dd4ccd791d79.zip  | |
[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/linux/security.h')
| -rw-r--r-- | include/linux/security.h | 41 | 
1 files changed, 35 insertions, 6 deletions
diff --git a/include/linux/security.h b/include/linux/security.h index f75303831d0..aa5b8043dc3 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -1109,6 +1109,16 @@ struct swap_info_struct;   *	@name contains the name of the security module being unstacked.   *	@ops contains a pointer to the struct security_operations of the module to unstack.   *  + * @secid_to_secctx: + *	Convert secid to security context. + *	@secid contains the security ID. + *	@secdata contains the pointer that stores the converted security context. + * + * @release_secctx: + *	Release the security context. + *	@secdata contains the security context. + *	@seclen contains the length of the security context. + *   * This is the main security structure.   */  struct security_operations { @@ -1289,6 +1299,8 @@ struct security_operations {   	int (*getprocattr)(struct task_struct *p, char *name, void *value, size_t size);   	int (*setprocattr)(struct task_struct *p, char *name, void *value, size_t size); +	int (*secid_to_secctx)(u32 secid, char **secdata, u32 *seclen); +	void (*release_secctx)(char *secdata, u32 seclen);  #ifdef CONFIG_SECURITY_NETWORK  	int (*unix_stream_connect) (struct socket * sock, @@ -1317,7 +1329,7 @@ struct security_operations {  	int (*socket_shutdown) (struct socket * sock, int how);  	int (*socket_sock_rcv_skb) (struct sock * sk, struct sk_buff * skb);  	int (*socket_getpeersec_stream) (struct socket *sock, char __user *optval, int __user *optlen, unsigned len); -	int (*socket_getpeersec_dgram) (struct sk_buff *skb, char **secdata, u32 *seclen); +	int (*socket_getpeersec_dgram) (struct socket *sock, struct sk_buff *skb, u32 *secid);  	int (*sk_alloc_security) (struct sock *sk, int family, gfp_t priority);  	void (*sk_free_security) (struct sock *sk);  	unsigned int (*sk_getsid) (struct sock *sk, struct flowi *fl, u8 dir); @@ -2059,6 +2071,16 @@ static inline int security_netlink_recv(struct sk_buff * skb, int cap)  	return security_ops->netlink_recv(skb, cap);  } +static inline int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen) +{ +	return security_ops->secid_to_secctx(secid, secdata, seclen); +} + +static inline void security_release_secctx(char *secdata, u32 seclen) +{ +	return security_ops->release_secctx(secdata, seclen); +} +  /* prototypes */  extern int security_init	(void);  extern int register_security	(struct security_operations *ops); @@ -2725,6 +2747,15 @@ static inline void securityfs_remove(struct dentry *dentry)  {  } +static inline int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen) +{ +	return -EOPNOTSUPP; +} + +static inline void security_release_secctx(char *secdata, u32 seclen) +{ +	return -EOPNOTSUPP; +}  #endif	/* CONFIG_SECURITY */  #ifdef CONFIG_SECURITY_NETWORK @@ -2840,10 +2871,9 @@ static inline int security_socket_getpeersec_stream(struct socket *sock, char __  	return security_ops->socket_getpeersec_stream(sock, optval, optlen, len);  } -static inline int security_socket_getpeersec_dgram(struct sk_buff *skb, char **secdata, -						   u32 *seclen) +static inline int security_socket_getpeersec_dgram(struct socket *sock, struct sk_buff *skb, u32 *secid)  { -	return security_ops->socket_getpeersec_dgram(skb, secdata, seclen); +	return security_ops->socket_getpeersec_dgram(sock, skb, secid);  }  static inline int security_sk_alloc(struct sock *sk, int family, gfp_t priority) @@ -2968,8 +2998,7 @@ static inline int security_socket_getpeersec_stream(struct socket *sock, char __  	return -ENOPROTOOPT;  } -static inline int security_socket_getpeersec_dgram(struct sk_buff *skb, char **secdata, -						   u32 *seclen) +static inline int security_socket_getpeersec_dgram(struct socket *sock, struct sk_buff *skb, u32 *secid)  {  	return -ENOPROTOOPT;  }  |