diff options
Diffstat (limited to 'net/unix')
-rw-r--r-- | net/unix/af_unix.c | 66 |
1 files changed, 37 insertions, 29 deletions
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index dd419d286204..d8d98d5b508c 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c | |||
@@ -1475,6 +1475,12 @@ restart: | |||
1475 | goto out_free; | 1475 | goto out_free; |
1476 | } | 1476 | } |
1477 | 1477 | ||
1478 | if (sk_filter(other, skb) < 0) { | ||
1479 | /* Toss the packet but do not return any error to the sender */ | ||
1480 | err = len; | ||
1481 | goto out_free; | ||
1482 | } | ||
1483 | |||
1478 | unix_state_lock(other); | 1484 | unix_state_lock(other); |
1479 | err = -EPERM; | 1485 | err = -EPERM; |
1480 | if (!unix_may_send(sk, other)) | 1486 | if (!unix_may_send(sk, other)) |
@@ -1978,36 +1984,38 @@ static int unix_shutdown(struct socket *sock, int mode) | |||
1978 | 1984 | ||
1979 | mode = (mode+1)&(RCV_SHUTDOWN|SEND_SHUTDOWN); | 1985 | mode = (mode+1)&(RCV_SHUTDOWN|SEND_SHUTDOWN); |
1980 | 1986 | ||
1981 | if (mode) { | 1987 | if (!mode) |
1982 | unix_state_lock(sk); | 1988 | return 0; |
1983 | sk->sk_shutdown |= mode; | 1989 | |
1984 | other = unix_peer(sk); | 1990 | unix_state_lock(sk); |
1985 | if (other) | 1991 | sk->sk_shutdown |= mode; |
1986 | sock_hold(other); | 1992 | other = unix_peer(sk); |
1987 | unix_state_unlock(sk); | 1993 | if (other) |
1988 | sk->sk_state_change(sk); | 1994 | sock_hold(other); |
1989 | 1995 | unix_state_unlock(sk); | |
1990 | if (other && | 1996 | sk->sk_state_change(sk); |
1991 | (sk->sk_type == SOCK_STREAM || sk->sk_type == SOCK_SEQPACKET)) { | 1997 | |
1992 | 1998 | if (other && | |
1993 | int peer_mode = 0; | 1999 | (sk->sk_type == SOCK_STREAM || sk->sk_type == SOCK_SEQPACKET)) { |
1994 | 2000 | ||
1995 | if (mode&RCV_SHUTDOWN) | 2001 | int peer_mode = 0; |
1996 | peer_mode |= SEND_SHUTDOWN; | 2002 | |
1997 | if (mode&SEND_SHUTDOWN) | 2003 | if (mode&RCV_SHUTDOWN) |
1998 | peer_mode |= RCV_SHUTDOWN; | 2004 | peer_mode |= SEND_SHUTDOWN; |
1999 | unix_state_lock(other); | 2005 | if (mode&SEND_SHUTDOWN) |
2000 | other->sk_shutdown |= peer_mode; | 2006 | peer_mode |= RCV_SHUTDOWN; |
2001 | unix_state_unlock(other); | 2007 | unix_state_lock(other); |
2002 | other->sk_state_change(other); | 2008 | other->sk_shutdown |= peer_mode; |
2003 | if (peer_mode == SHUTDOWN_MASK) | 2009 | unix_state_unlock(other); |
2004 | sk_wake_async(other, SOCK_WAKE_WAITD, POLL_HUP); | 2010 | other->sk_state_change(other); |
2005 | else if (peer_mode & RCV_SHUTDOWN) | 2011 | if (peer_mode == SHUTDOWN_MASK) |
2006 | sk_wake_async(other, SOCK_WAKE_WAITD, POLL_IN); | 2012 | sk_wake_async(other, SOCK_WAKE_WAITD, POLL_HUP); |
2007 | } | 2013 | else if (peer_mode & RCV_SHUTDOWN) |
2008 | if (other) | 2014 | sk_wake_async(other, SOCK_WAKE_WAITD, POLL_IN); |
2009 | sock_put(other); | ||
2010 | } | 2015 | } |
2016 | if (other) | ||
2017 | sock_put(other); | ||
2018 | |||
2011 | return 0; | 2019 | return 0; |
2012 | } | 2020 | } |
2013 | 2021 | ||