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 /include | |
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 'include')
-rw-r--r-- | include/linux/security.h | 15 |
1 files changed, 7 insertions, 8 deletions
diff --git a/include/linux/security.h b/include/linux/security.h index fd4d55fb8845..d47a4c24b3e4 100644 --- a/include/linux/security.h +++ b/include/linux/security.h | |||
@@ -796,8 +796,9 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts) | |||
796 | * @unix_stream_connect: | 796 | * @unix_stream_connect: |
797 | * Check permissions before establishing a Unix domain stream connection | 797 | * Check permissions before establishing a Unix domain stream connection |
798 | * between @sock and @other. | 798 | * between @sock and @other. |
799 | * @sock contains the socket structure. | 799 | * @sock contains the sock structure. |
800 | * @other contains the peer socket structure. | 800 | * @other contains the peer sock structure. |
801 | * @newsk contains the new sock structure. | ||
801 | * Return 0 if permission is granted. | 802 | * Return 0 if permission is granted. |
802 | * @unix_may_send: | 803 | * @unix_may_send: |
803 | * Check permissions before connecting or sending datagrams from @sock to | 804 | * Check permissions before connecting or sending datagrams from @sock to |
@@ -1568,8 +1569,7 @@ struct security_operations { | |||
1568 | int (*inode_getsecctx)(struct inode *inode, void **ctx, u32 *ctxlen); | 1569 | int (*inode_getsecctx)(struct inode *inode, void **ctx, u32 *ctxlen); |
1569 | 1570 | ||
1570 | #ifdef CONFIG_SECURITY_NETWORK | 1571 | #ifdef CONFIG_SECURITY_NETWORK |
1571 | int (*unix_stream_connect) (struct socket *sock, | 1572 | int (*unix_stream_connect) (struct sock *sock, struct sock *other, struct sock *newsk); |
1572 | struct socket *other, struct sock *newsk); | ||
1573 | int (*unix_may_send) (struct socket *sock, struct socket *other); | 1573 | int (*unix_may_send) (struct socket *sock, struct socket *other); |
1574 | 1574 | ||
1575 | int (*socket_create) (int family, int type, int protocol, int kern); | 1575 | int (*socket_create) (int family, int type, int protocol, int kern); |
@@ -2525,8 +2525,7 @@ static inline int security_inode_getsecctx(struct inode *inode, void **ctx, u32 | |||
2525 | 2525 | ||
2526 | #ifdef CONFIG_SECURITY_NETWORK | 2526 | #ifdef CONFIG_SECURITY_NETWORK |
2527 | 2527 | ||
2528 | int security_unix_stream_connect(struct socket *sock, struct socket *other, | 2528 | int security_unix_stream_connect(struct sock *sock, struct sock *other, struct sock *newsk); |
2529 | struct sock *newsk); | ||
2530 | int security_unix_may_send(struct socket *sock, struct socket *other); | 2529 | int security_unix_may_send(struct socket *sock, struct socket *other); |
2531 | int security_socket_create(int family, int type, int protocol, int kern); | 2530 | int security_socket_create(int family, int type, int protocol, int kern); |
2532 | int security_socket_post_create(struct socket *sock, int family, | 2531 | int security_socket_post_create(struct socket *sock, int family, |
@@ -2567,8 +2566,8 @@ void security_tun_dev_post_create(struct sock *sk); | |||
2567 | int security_tun_dev_attach(struct sock *sk); | 2566 | int security_tun_dev_attach(struct sock *sk); |
2568 | 2567 | ||
2569 | #else /* CONFIG_SECURITY_NETWORK */ | 2568 | #else /* CONFIG_SECURITY_NETWORK */ |
2570 | static inline int security_unix_stream_connect(struct socket *sock, | 2569 | static inline int security_unix_stream_connect(struct sock *sock, |
2571 | struct socket *other, | 2570 | struct sock *other, |
2572 | struct sock *newsk) | 2571 | struct sock *newsk) |
2573 | { | 2572 | { |
2574 | return 0; | 2573 | return 0; |