aboutsummaryrefslogtreecommitdiffstats
path: root/security/smack
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2011-01-05 18:38:53 -0500
committerDavid S. Miller <davem@davemloft.net>2011-01-05 18:38:53 -0500
commit3610cda53f247e176bcbb7a7cca64bc53b12acdb (patch)
treed780bc1e405116e75a194b2f4693a6f9bbe9f58f /security/smack
parent44b8288308ac9da27eab7d7bdbf1375a568805c3 (diff)
af_unix: Avoid socket->sk NULL OOPS in stream connect security hooks.
unix_release() can asynchornously set socket->sk to NULL, and it does so without holding the unix_state_lock() on "other" during stream connects. However, the reverse mapping, sk->sk_socket, is only transitioned to NULL under the unix_state_lock(). Therefore make the security hooks follow the reverse mapping instead of the forward mapping. Reported-by: Jeremy Fitzhardinge <jeremy@goop.org> Reported-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'security/smack')
-rw-r--r--security/smack/smack_lsm.c14
1 files changed, 7 insertions, 7 deletions
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index 489a85afa477..ccb71a044a1a 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -2408,22 +2408,22 @@ static int smack_setprocattr(struct task_struct *p, char *name,
2408 2408
2409/** 2409/**
2410 * smack_unix_stream_connect - Smack access on UDS 2410 * smack_unix_stream_connect - Smack access on UDS
2411 * @sock: one socket 2411 * @sock: one sock
2412 * @other: the other socket 2412 * @other: the other sock
2413 * @newsk: unused 2413 * @newsk: unused
2414 * 2414 *
2415 * Return 0 if a subject with the smack of sock could access 2415 * Return 0 if a subject with the smack of sock could access
2416 * an object with the smack of other, otherwise an error code 2416 * an object with the smack of other, otherwise an error code
2417 */ 2417 */
2418static int smack_unix_stream_connect(struct socket *sock, 2418static int smack_unix_stream_connect(struct sock *sock,
2419 struct socket *other, struct sock *newsk) 2419 struct sock *other, struct sock *newsk)
2420{ 2420{
2421 struct inode *sp = SOCK_INODE(sock); 2421 struct inode *sp = SOCK_INODE(sock->sk_socket);
2422 struct inode *op = SOCK_INODE(other); 2422 struct inode *op = SOCK_INODE(other->sk_socket);
2423 struct smk_audit_info ad; 2423 struct smk_audit_info ad;
2424 2424
2425 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_NET); 2425 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_NET);
2426 smk_ad_setfield_u_net_sk(&ad, other->sk); 2426 smk_ad_setfield_u_net_sk(&ad, other);
2427 return smk_access(smk_of_inode(sp), smk_of_inode(op), 2427 return smk_access(smk_of_inode(sp), smk_of_inode(op),
2428 MAY_READWRITE, &ad); 2428 MAY_READWRITE, &ad);
2429} 2429}