diff options
author | David S. Miller <davem@davemloft.net> | 2011-01-05 18:38:53 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-01-05 18:38:53 -0500 |
commit | 3610cda53f247e176bcbb7a7cca64bc53b12acdb (patch) | |
tree | d780bc1e405116e75a194b2f4693a6f9bbe9f58f /security/smack | |
parent | 44b8288308ac9da27eab7d7bdbf1375a568805c3 (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.c | 14 |
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 | */ |
2418 | static int smack_unix_stream_connect(struct socket *sock, | 2418 | static 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 | } |