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>
This commit is contained in:
@@ -2408,22 +2408,22 @@ static int smack_setprocattr(struct task_struct *p, char *name,
|
||||
|
||||
/**
|
||||
* smack_unix_stream_connect - Smack access on UDS
|
||||
* @sock: one socket
|
||||
* @other: the other socket
|
||||
* @sock: one sock
|
||||
* @other: the other sock
|
||||
* @newsk: unused
|
||||
*
|
||||
* Return 0 if a subject with the smack of sock could access
|
||||
* an object with the smack of other, otherwise an error code
|
||||
*/
|
||||
static int smack_unix_stream_connect(struct socket *sock,
|
||||
struct socket *other, struct sock *newsk)
|
||||
static int smack_unix_stream_connect(struct sock *sock,
|
||||
struct sock *other, struct sock *newsk)
|
||||
{
|
||||
struct inode *sp = SOCK_INODE(sock);
|
||||
struct inode *op = SOCK_INODE(other);
|
||||
struct inode *sp = SOCK_INODE(sock->sk_socket);
|
||||
struct inode *op = SOCK_INODE(other->sk_socket);
|
||||
struct smk_audit_info ad;
|
||||
|
||||
smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_NET);
|
||||
smk_ad_setfield_u_net_sk(&ad, other->sk);
|
||||
smk_ad_setfield_u_net_sk(&ad, other);
|
||||
return smk_access(smk_of_inode(sp), smk_of_inode(op),
|
||||
MAY_READWRITE, &ad);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user