diff options
Diffstat (limited to 'include/net/sock.h')
-rw-r--r-- | include/net/sock.h | 48 |
1 files changed, 31 insertions, 17 deletions
diff --git a/include/net/sock.h b/include/net/sock.h index 324b3ea233d6..edd4d73ce7f5 100644 --- a/include/net/sock.h +++ b/include/net/sock.h | |||
@@ -862,30 +862,24 @@ extern void sock_init_data(struct socket *sock, struct sock *sk); | |||
862 | * | 862 | * |
863 | */ | 863 | */ |
864 | 864 | ||
865 | static inline int sk_filter(struct sock *sk, struct sk_buff *skb, int needlock) | 865 | static inline int sk_filter(struct sock *sk, struct sk_buff *skb) |
866 | { | 866 | { |
867 | int err; | 867 | int err; |
868 | struct sk_filter *filter; | ||
868 | 869 | ||
869 | err = security_sock_rcv_skb(sk, skb); | 870 | err = security_sock_rcv_skb(sk, skb); |
870 | if (err) | 871 | if (err) |
871 | return err; | 872 | return err; |
872 | 873 | ||
873 | if (sk->sk_filter) { | 874 | rcu_read_lock_bh(); |
874 | struct sk_filter *filter; | 875 | filter = sk->sk_filter; |
875 | 876 | if (filter) { | |
876 | if (needlock) | 877 | unsigned int pkt_len = sk_run_filter(skb, filter->insns, |
877 | bh_lock_sock(sk); | 878 | filter->len); |
878 | 879 | err = pkt_len ? pskb_trim(skb, pkt_len) : -EPERM; | |
879 | filter = sk->sk_filter; | ||
880 | if (filter) { | ||
881 | unsigned int pkt_len = sk_run_filter(skb, filter->insns, | ||
882 | filter->len); | ||
883 | err = pkt_len ? pskb_trim(skb, pkt_len) : -EPERM; | ||
884 | } | ||
885 | |||
886 | if (needlock) | ||
887 | bh_unlock_sock(sk); | ||
888 | } | 880 | } |
881 | rcu_read_unlock_bh(); | ||
882 | |||
889 | return err; | 883 | return err; |
890 | } | 884 | } |
891 | 885 | ||
@@ -897,6 +891,12 @@ static inline int sk_filter(struct sock *sk, struct sk_buff *skb, int needlock) | |||
897 | * Remove a filter from a socket and release its resources. | 891 | * Remove a filter from a socket and release its resources. |
898 | */ | 892 | */ |
899 | 893 | ||
894 | static inline void sk_filter_rcu_free(struct rcu_head *rcu) | ||
895 | { | ||
896 | struct sk_filter *fp = container_of(rcu, struct sk_filter, rcu); | ||
897 | kfree(fp); | ||
898 | } | ||
899 | |||
900 | static inline void sk_filter_release(struct sock *sk, struct sk_filter *fp) | 900 | static inline void sk_filter_release(struct sock *sk, struct sk_filter *fp) |
901 | { | 901 | { |
902 | unsigned int size = sk_filter_len(fp); | 902 | unsigned int size = sk_filter_len(fp); |
@@ -904,7 +904,7 @@ static inline void sk_filter_release(struct sock *sk, struct sk_filter *fp) | |||
904 | atomic_sub(size, &sk->sk_omem_alloc); | 904 | atomic_sub(size, &sk->sk_omem_alloc); |
905 | 905 | ||
906 | if (atomic_dec_and_test(&fp->refcnt)) | 906 | if (atomic_dec_and_test(&fp->refcnt)) |
907 | kfree(fp); | 907 | call_rcu_bh(&fp->rcu, sk_filter_rcu_free); |
908 | } | 908 | } |
909 | 909 | ||
910 | static inline void sk_filter_charge(struct sock *sk, struct sk_filter *fp) | 910 | static inline void sk_filter_charge(struct sock *sk, struct sk_filter *fp) |
@@ -969,9 +969,23 @@ static inline void sock_graft(struct sock *sk, struct socket *parent) | |||
969 | sk->sk_sleep = &parent->wait; | 969 | sk->sk_sleep = &parent->wait; |
970 | parent->sk = sk; | 970 | parent->sk = sk; |
971 | sk->sk_socket = parent; | 971 | sk->sk_socket = parent; |
972 | security_sock_graft(sk, parent); | ||
972 | write_unlock_bh(&sk->sk_callback_lock); | 973 | write_unlock_bh(&sk->sk_callback_lock); |
973 | } | 974 | } |
974 | 975 | ||
976 | static inline void sock_copy(struct sock *nsk, const struct sock *osk) | ||
977 | { | ||
978 | #ifdef CONFIG_SECURITY_NETWORK | ||
979 | void *sptr = nsk->sk_security; | ||
980 | #endif | ||
981 | |||
982 | memcpy(nsk, osk, osk->sk_prot->obj_size); | ||
983 | #ifdef CONFIG_SECURITY_NETWORK | ||
984 | nsk->sk_security = sptr; | ||
985 | security_sk_clone(osk, nsk); | ||
986 | #endif | ||
987 | } | ||
988 | |||
975 | extern int sock_i_uid(struct sock *sk); | 989 | extern int sock_i_uid(struct sock *sk); |
976 | extern unsigned long sock_i_ino(struct sock *sk); | 990 | extern unsigned long sock_i_ino(struct sock *sk); |
977 | 991 | ||