* [PATCH net] packet: avoid panic in packet_getsockopt()
@ 2017-10-18 22:08 Eric Dumazet
2017-10-18 23:14 ` [PATCH v2 " Eric Dumazet
2017-10-21 0:50 ` [PATCH " David Miller
0 siblings, 2 replies; 7+ messages in thread
From: Eric Dumazet @ 2017-10-18 22:08 UTC (permalink / raw)
To: David Miller; +Cc: netdev, Willem de Bruijn, Eric Dumazet
From: Eric Dumazet <edumazet@google.com>
syzkaller got crashes in packet_getsockopt() processing
PACKET_ROLLOVER_STATS command while another thread was managing
to change po->rollover
Using RCU will fix this bug. We might later add proper RCU annotations
for sparse sake.
Fixes: a9b6391814d5 ("packet: rollover statistics")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Willem de Bruijn <willemb@google.com>
---
net/packet/af_packet.c | 22 +++++++++++++++-------
1 file changed, 15 insertions(+), 7 deletions(-)
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index bec01a3daf5b02bd716dbff5c9efef8d6a7982be..1d8a7add86b4f29880e11c6f4971d79319dcb426 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -1796,8 +1796,10 @@ static struct packet_fanout *fanout_release(struct sock *sk)
else
f = NULL;
- if (po->rollover)
+ if (po->rollover) {
kfree_rcu(po->rollover, rcu);
+ po->rollover = NULL;
+ }
}
mutex_unlock(&fanout_mutex);
@@ -3851,6 +3853,7 @@ static int packet_getsockopt(struct socket *sock, int level, int optname,
void *data = &val;
union tpacket_stats_u st;
struct tpacket_rollover_stats rstats;
+ struct packet_rollover *rollover;
if (level != SOL_PACKET)
return -ENOPROTOOPT;
@@ -3929,13 +3932,18 @@ static int packet_getsockopt(struct socket *sock, int level, int optname,
0);
break;
case PACKET_ROLLOVER_STATS:
- if (!po->rollover)
+ rcu_read_lock();
+ rollover = rcu_dereference(po->rollover);
+ if (rollover) {
+ rstats.tp_all = atomic_long_read(&rollover->num);
+ rstats.tp_huge = atomic_long_read(&rollover->num_huge);
+ rstats.tp_failed = atomic_long_read(&rollover->num_failed);
+ data = &rstats;
+ lv = sizeof(rstats);
+ }
+ rcu_read_unlock();
+ if (!rollover)
return -EINVAL;
- rstats.tp_all = atomic_long_read(&po->rollover->num);
- rstats.tp_huge = atomic_long_read(&po->rollover->num_huge);
- rstats.tp_failed = atomic_long_read(&po->rollover->num_failed);
- data = &rstats;
- lv = sizeof(rstats);
break;
case PACKET_TX_HAS_OFF:
val = po->tp_tx_has_off;
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH v2 net] packet: avoid panic in packet_getsockopt()
2017-10-18 22:08 [PATCH net] packet: avoid panic in packet_getsockopt() Eric Dumazet
@ 2017-10-18 23:14 ` Eric Dumazet
2017-10-20 19:11 ` kbuild test robot
2017-10-21 0:50 ` [PATCH " David Miller
1 sibling, 1 reply; 7+ messages in thread
From: Eric Dumazet @ 2017-10-18 23:14 UTC (permalink / raw)
To: David Miller; +Cc: netdev, Willem de Bruijn, Eric Dumazet, John Sperbeck
From: Eric Dumazet <edumazet@google.com>
syzkaller got crashes in packet_getsockopt() processing
PACKET_ROLLOVER_STATS command while another thread was managing
to change po->rollover
Using RCU will fix this bug. We might later add proper RCU annotations
for sparse sake.
In v2: I replaced kfree(rollover) in fanout_add() to kfree_rcu()
variant, as spotted by John.
Fixes: a9b6391814d5 ("packet: rollover statistics")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Willem de Bruijn <willemb@google.com>
Cc: John Sperbeck <jsperbeck@google.com>
---
net/packet/af_packet.c | 24 ++++++++++++++++--------
1 file changed, 16 insertions(+), 8 deletions(-)
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index bec01a3daf5b02bd716dbff5c9efef8d6a7982be..2986941164b1952b3b6014ff81d2986b504c334a 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -1769,7 +1769,7 @@ static int fanout_add(struct sock *sk, u16 id, u16 type_flags)
out:
if (err && rollover) {
- kfree(rollover);
+ kfree_rcu(rollover, rcu);
po->rollover = NULL;
}
mutex_unlock(&fanout_mutex);
@@ -1796,8 +1796,10 @@ static struct packet_fanout *fanout_release(struct sock *sk)
else
f = NULL;
- if (po->rollover)
+ if (po->rollover) {
kfree_rcu(po->rollover, rcu);
+ po->rollover = NULL;
+ }
}
mutex_unlock(&fanout_mutex);
@@ -3851,6 +3853,7 @@ static int packet_getsockopt(struct socket *sock, int level, int optname,
void *data = &val;
union tpacket_stats_u st;
struct tpacket_rollover_stats rstats;
+ struct packet_rollover *rollover;
if (level != SOL_PACKET)
return -ENOPROTOOPT;
@@ -3929,13 +3932,18 @@ static int packet_getsockopt(struct socket *sock, int level, int optname,
0);
break;
case PACKET_ROLLOVER_STATS:
- if (!po->rollover)
+ rcu_read_lock();
+ rollover = rcu_dereference(po->rollover);
+ if (rollover) {
+ rstats.tp_all = atomic_long_read(&rollover->num);
+ rstats.tp_huge = atomic_long_read(&rollover->num_huge);
+ rstats.tp_failed = atomic_long_read(&rollover->num_failed);
+ data = &rstats;
+ lv = sizeof(rstats);
+ }
+ rcu_read_unlock();
+ if (!rollover)
return -EINVAL;
- rstats.tp_all = atomic_long_read(&po->rollover->num);
- rstats.tp_huge = atomic_long_read(&po->rollover->num_huge);
- rstats.tp_failed = atomic_long_read(&po->rollover->num_failed);
- data = &rstats;
- lv = sizeof(rstats);
break;
case PACKET_TX_HAS_OFF:
val = po->tp_tx_has_off;
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH v2 net] packet: avoid panic in packet_getsockopt()
2017-10-18 23:14 ` [PATCH v2 " Eric Dumazet
@ 2017-10-20 19:11 ` kbuild test robot
2017-10-20 19:25 ` Eric Dumazet
0 siblings, 1 reply; 7+ messages in thread
From: kbuild test robot @ 2017-10-20 19:11 UTC (permalink / raw)
To: Eric Dumazet
Cc: kbuild-all, David Miller, netdev, Willem de Bruijn, Eric Dumazet,
John Sperbeck
Hi Eric,
[auto build test WARNING on net/master]
url: https://github.com/0day-ci/linux/commits/Eric-Dumazet/packet-avoid-panic-in-packet_getsockopt/20171021-003615
reproduce:
# apt-get install sparse
make ARCH=x86_64 allmodconfig
make C=1 CF=-D__CHECK_ENDIAN__
sparse warnings: (new ones prefixed by >>)
vim +3936 net/packet/af_packet.c
3845
3846 static int packet_getsockopt(struct socket *sock, int level, int optname,
3847 char __user *optval, int __user *optlen)
3848 {
3849 int len;
3850 int val, lv = sizeof(val);
3851 struct sock *sk = sock->sk;
3852 struct packet_sock *po = pkt_sk(sk);
3853 void *data = &val;
3854 union tpacket_stats_u st;
3855 struct tpacket_rollover_stats rstats;
3856 struct packet_rollover *rollover;
3857
3858 if (level != SOL_PACKET)
3859 return -ENOPROTOOPT;
3860
3861 if (get_user(len, optlen))
3862 return -EFAULT;
3863
3864 if (len < 0)
3865 return -EINVAL;
3866
3867 switch (optname) {
3868 case PACKET_STATISTICS:
3869 spin_lock_bh(&sk->sk_receive_queue.lock);
3870 memcpy(&st, &po->stats, sizeof(st));
3871 memset(&po->stats, 0, sizeof(po->stats));
3872 spin_unlock_bh(&sk->sk_receive_queue.lock);
3873
3874 if (po->tp_version == TPACKET_V3) {
3875 lv = sizeof(struct tpacket_stats_v3);
3876 st.stats3.tp_packets += st.stats3.tp_drops;
3877 data = &st.stats3;
3878 } else {
3879 lv = sizeof(struct tpacket_stats);
3880 st.stats1.tp_packets += st.stats1.tp_drops;
3881 data = &st.stats1;
3882 }
3883
3884 break;
3885 case PACKET_AUXDATA:
3886 val = po->auxdata;
3887 break;
3888 case PACKET_ORIGDEV:
3889 val = po->origdev;
3890 break;
3891 case PACKET_VNET_HDR:
3892 val = po->has_vnet_hdr;
3893 break;
3894 case PACKET_VERSION:
3895 val = po->tp_version;
3896 break;
3897 case PACKET_HDRLEN:
3898 if (len > sizeof(int))
3899 len = sizeof(int);
3900 if (len < sizeof(int))
3901 return -EINVAL;
3902 if (copy_from_user(&val, optval, len))
3903 return -EFAULT;
3904 switch (val) {
3905 case TPACKET_V1:
3906 val = sizeof(struct tpacket_hdr);
3907 break;
3908 case TPACKET_V2:
3909 val = sizeof(struct tpacket2_hdr);
3910 break;
3911 case TPACKET_V3:
3912 val = sizeof(struct tpacket3_hdr);
3913 break;
3914 default:
3915 return -EINVAL;
3916 }
3917 break;
3918 case PACKET_RESERVE:
3919 val = po->tp_reserve;
3920 break;
3921 case PACKET_LOSS:
3922 val = po->tp_loss;
3923 break;
3924 case PACKET_TIMESTAMP:
3925 val = po->tp_tstamp;
3926 break;
3927 case PACKET_FANOUT:
3928 val = (po->fanout ?
3929 ((u32)po->fanout->id |
3930 ((u32)po->fanout->type << 16) |
3931 ((u32)po->fanout->flags << 24)) :
3932 0);
3933 break;
3934 case PACKET_ROLLOVER_STATS:
3935 rcu_read_lock();
> 3936 rollover = rcu_dereference(po->rollover);
3937 if (rollover) {
3938 rstats.tp_all = atomic_long_read(&rollover->num);
3939 rstats.tp_huge = atomic_long_read(&rollover->num_huge);
3940 rstats.tp_failed = atomic_long_read(&rollover->num_failed);
3941 data = &rstats;
3942 lv = sizeof(rstats);
3943 }
3944 rcu_read_unlock();
3945 if (!rollover)
3946 return -EINVAL;
3947 break;
3948 case PACKET_TX_HAS_OFF:
3949 val = po->tp_tx_has_off;
3950 break;
3951 case PACKET_QDISC_BYPASS:
3952 val = packet_use_direct_xmit(po);
3953 break;
3954 default:
3955 return -ENOPROTOOPT;
3956 }
3957
3958 if (len > lv)
3959 len = lv;
3960 if (put_user(len, optlen))
3961 return -EFAULT;
3962 if (copy_to_user(optval, data, len))
3963 return -EFAULT;
3964 return 0;
3965 }
3966
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v2 net] packet: avoid panic in packet_getsockopt()
2017-10-20 19:11 ` kbuild test robot
@ 2017-10-20 19:25 ` Eric Dumazet
0 siblings, 0 replies; 7+ messages in thread
From: Eric Dumazet @ 2017-10-20 19:25 UTC (permalink / raw)
To: kbuild test robot
Cc: Eric Dumazet, kbuild-all, David Miller, netdev, Willem de Bruijn,
John Sperbeck
On Fri, Oct 20, 2017 at 12:11 PM, kbuild test robot <lkp@intel.com> wrote:
> Hi Eric,
>
> [auto build test WARNING on net/master]
>
> url: https://github.com/0day-ci/linux/commits/Eric-Dumazet/packet-avoid-panic-in-packet_getsockopt/20171021-003615
> reproduce:
> # apt-get install sparse
> make ARCH=x86_64 allmodconfig
> make C=1 CF=-D__CHECK_ENDIAN__
>
>
> sparse warnings: (new ones prefixed by >>)
>
Thanks, this was mentioned in the commit changelog.
We will add rcu annotations in net-next.
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH net] packet: avoid panic in packet_getsockopt()
2017-10-18 22:08 [PATCH net] packet: avoid panic in packet_getsockopt() Eric Dumazet
2017-10-18 23:14 ` [PATCH v2 " Eric Dumazet
@ 2017-10-21 0:50 ` David Miller
2017-10-21 0:53 ` David Miller
1 sibling, 1 reply; 7+ messages in thread
From: David Miller @ 2017-10-21 0:50 UTC (permalink / raw)
To: eric.dumazet; +Cc: netdev, willemb, edumazet
From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Wed, 18 Oct 2017 15:08:24 -0700
> From: Eric Dumazet <edumazet@google.com>
>
> syzkaller got crashes in packet_getsockopt() processing
> PACKET_ROLLOVER_STATS command while another thread was managing
> to change po->rollover
>
> Using RCU will fix this bug. We might later add proper RCU annotations
> for sparse sake.
>
> Fixes: a9b6391814d5 ("packet: rollover statistics")
> Signed-off-by: Eric Dumazet <edumazet@google.com>
Applied and queued up for -stable, but:
> Willem de Bruijn <willemb@google.com>
I didn't know what kind of tag you intended to use here for Willem
so just deleted the line.
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH net] packet: avoid panic in packet_getsockopt()
2017-10-21 0:50 ` [PATCH " David Miller
@ 2017-10-21 0:53 ` David Miller
2017-10-21 1:11 ` Eric Dumazet
0 siblings, 1 reply; 7+ messages in thread
From: David Miller @ 2017-10-21 0:53 UTC (permalink / raw)
To: eric.dumazet; +Cc: netdev, willemb, edumazet
From: David Miller <davem@davemloft.net>
Date: Sat, 21 Oct 2017 01:50:08 +0100 (WEST)
> From: Eric Dumazet <eric.dumazet@gmail.com>
> Date: Wed, 18 Oct 2017 15:08:24 -0700
>
>> From: Eric Dumazet <edumazet@google.com>
>>
>> syzkaller got crashes in packet_getsockopt() processing
>> PACKET_ROLLOVER_STATS command while another thread was managing
>> to change po->rollover
>>
>> Using RCU will fix this bug. We might later add proper RCU annotations
>> for sparse sake.
>>
>> Fixes: a9b6391814d5 ("packet: rollover statistics")
>> Signed-off-by: Eric Dumazet <edumazet@google.com>
>
> Applied and queued up for -stable, but:
>
>> Willem de Bruijn <willemb@google.com>
>
> I didn't know what kind of tag you intended to use here for Willem
> so just deleted the line.
I just noticed 'v2' of this patch and replaced it in time before I
pushed out :-)
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH net] packet: avoid panic in packet_getsockopt()
2017-10-21 0:53 ` David Miller
@ 2017-10-21 1:11 ` Eric Dumazet
0 siblings, 0 replies; 7+ messages in thread
From: Eric Dumazet @ 2017-10-21 1:11 UTC (permalink / raw)
To: David Miller; +Cc: Eric Dumazet, netdev, Willem de Bruijn
On Fri, Oct 20, 2017 at 5:53 PM, David Miller <davem@davemloft.net> wrote:
> From: David Miller <davem@davemloft.net>
> Date: Sat, 21 Oct 2017 01:50:08 +0100 (WEST)
>
>> From: Eric Dumazet <eric.dumazet@gmail.com>
>> Date: Wed, 18 Oct 2017 15:08:24 -0700
>>
>>> From: Eric Dumazet <edumazet@google.com>
>>>
>>> syzkaller got crashes in packet_getsockopt() processing
>>> PACKET_ROLLOVER_STATS command while another thread was managing
>>> to change po->rollover
>>>
>>> Using RCU will fix this bug. We might later add proper RCU annotations
>>> for sparse sake.
>>>
>>> Fixes: a9b6391814d5 ("packet: rollover statistics")
>>> Signed-off-by: Eric Dumazet <edumazet@google.com>
>>
>> Applied and queued up for -stable, but:
>>
>>> Willem de Bruijn <willemb@google.com>
>>
>> I didn't know what kind of tag you intended to use here for Willem
>> so just deleted the line.
>
> I just noticed 'v2' of this patch and replaced it in time before I
> pushed out :-)
Nice, thanks again !
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2017-10-21 1:11 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-10-18 22:08 [PATCH net] packet: avoid panic in packet_getsockopt() Eric Dumazet
2017-10-18 23:14 ` [PATCH v2 " Eric Dumazet
2017-10-20 19:11 ` kbuild test robot
2017-10-20 19:25 ` Eric Dumazet
2017-10-21 0:50 ` [PATCH " David Miller
2017-10-21 0:53 ` David Miller
2017-10-21 1:11 ` Eric Dumazet
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.