l2tp: do not use udp_ioctl()
udp_ioctl(), as its name suggests, is used by UDP protocols, but is also used by L2TP :( L2TP should use its own handler, because it really does not look the same. SIOCINQ for instance should not assume UDP checksum or headers. Thanks to Andrey and syzkaller team for providing the report and a nice reproducer. While crashes only happen on recent kernels (after commit7c13f97ffd
("udp: do fwd memory scheduling on dequeue")), this probably needs to be backported to older kernels. Fixes:7c13f97ffd
("udp: do fwd memory scheduling on dequeue") Fixes:8558467201
("udp: Fix udp_poll() and ioctl()") Signed-off-by: Eric Dumazet <edumazet@google.com> Reported-by: Andrey Konovalov <andreyknvl@google.com> Acked-by: Paolo Abeni <pabeni@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:

committed by
David S. Miller

parent
7447095485
commit
72fb96e7bd
@@ -11,6 +11,7 @@
|
||||
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
|
||||
#include <asm/ioctls.h>
|
||||
#include <linux/icmp.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/skbuff.h>
|
||||
@@ -553,6 +554,30 @@ out:
|
||||
return err ? err : copied;
|
||||
}
|
||||
|
||||
int l2tp_ioctl(struct sock *sk, int cmd, unsigned long arg)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
int amount;
|
||||
|
||||
switch (cmd) {
|
||||
case SIOCOUTQ:
|
||||
amount = sk_wmem_alloc_get(sk);
|
||||
break;
|
||||
case SIOCINQ:
|
||||
spin_lock_bh(&sk->sk_receive_queue.lock);
|
||||
skb = skb_peek(&sk->sk_receive_queue);
|
||||
amount = skb ? skb->len : 0;
|
||||
spin_unlock_bh(&sk->sk_receive_queue.lock);
|
||||
break;
|
||||
|
||||
default:
|
||||
return -ENOIOCTLCMD;
|
||||
}
|
||||
|
||||
return put_user(amount, (int __user *)arg);
|
||||
}
|
||||
EXPORT_SYMBOL(l2tp_ioctl);
|
||||
|
||||
static struct proto l2tp_ip_prot = {
|
||||
.name = "L2TP/IP",
|
||||
.owner = THIS_MODULE,
|
||||
@@ -561,7 +586,7 @@ static struct proto l2tp_ip_prot = {
|
||||
.bind = l2tp_ip_bind,
|
||||
.connect = l2tp_ip_connect,
|
||||
.disconnect = l2tp_ip_disconnect,
|
||||
.ioctl = udp_ioctl,
|
||||
.ioctl = l2tp_ioctl,
|
||||
.destroy = l2tp_ip_destroy_sock,
|
||||
.setsockopt = ip_setsockopt,
|
||||
.getsockopt = ip_getsockopt,
|
||||
|
Reference in New Issue
Block a user