CVE-2010-4251: packet backlog can get too large
Subsystems (2)
cover CVE-2010-4251: packet backlog can get too large
I'm still very new to this whole -stable business so please let me know if I do somethig wrong.
This patch series is to address CVE-2010-4251 for the 2.6.32 stable kernel. Here is the CVE summary:
"The socket implementation in net/core/sock.c in the Linux kernel
before 2.6.34 does not properly manage a backlog of received packets, which allows remote attackers to cause a denial of service (memory consumption) by sending a large amount of network traffic, as demonstrated by netperf UDP tests."
[patch 1/8] introduces sk_add_backlog_limited()
[patch 2-7/8] change each network protocol to use sk_add_backlog_limited()
where appropriate.
[patch 8/8] renames sk_add_backlog() to __sk_add_backlog() and
sk_add_backlog_limited() to sk_add_backlog().
The patches mostly apply without changes. The exception is:
[patch 2/8] udp: use limited socket backlog
Then the rename [patch 8/8] needed to be changed as well to match.
regards,
dan carpenter
PATCH 2/8 udp: use limited socket backlog
I had to make some changes to the first chunk in net/ipv6/udp.c to make this to apply.
Quoted 1 line
From
55349790d7cbf0d381873a7ece1dcafcffd4aaa9Mon Sep 17 00:00:00 2001
From: Zhu Yi <[email protected]>
Date: Thu, 4 Mar 2010 18:01:42 +0000
Subject: [PATCH] udp: use limited socket backlog
Make udp adapt to the limited socket backlog change.
---
net/ipv4/udp.c +4 -2
@@ -1177,8 +1177,10 @@ int udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)bh_lock_sock (sk);if (!sock_owned_by_user (sk)) rc =__udp_queue_rcv_skb (sk, skb); -else -sk_add_backlog (sk, skb); +else if (sk_add_backlog_limited (sk, skb)) { +bh_unlock_sock (sk); + goto drop; + }bh_unlock_sock (sk);return rc;
net/ipv6/udp.c +13 -6
@@ -473,16 +473,19 @@ static int __udp6_lib_mcast_deliver(struct net *net, struct sk_buff *skb,bh_lock_sock (sk2);if (!sock_owned_by_user (sk2))udpv6_queue_rcv_skb (sk2, buff); -else -sk_add_backlog (sk2, buff); +else if (sk_add_backlog_limited (sk2, buff)) { +kfree_skb (buff); +bh_unlock_sock (sk2); + goto out; + }bh_unlock_sock (sk2); } }bh_lock_sock (sk);if (!sock_owned_by_user (sk))udpv6_queue_rcv_skb (sk, skb); -else -sk_add_backlog (sk, skb); +else if (sk_add_backlog_limited (sk, skb)) +kfree_skb (skb);bh_unlock_sock (sk); out:spin_unlock (&hslot->lock);
@@ -601,8 +604,12 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,bh_lock_sock (sk);if (!sock_owned_by_user (sk))udpv6_queue_rcv_skb (sk, skb); -else -sk_add_backlog (sk, skb); +else if (sk_add_backlog_limited (sk, skb)) { +atomic_inc (&sk->sk_drops); +bh_unlock_sock (sk); +sock_put (sk); + goto discard; + }bh_unlock_sock (sk);sock_put (sk);return 0 ;
PATCH 3/8 x25: use limited socket backlog
In reply to Dan CarpenterThis applied without changes to the original patch.
Quoted 1 line
From
2499849ee8f513e795b9f2c19a42d6356e4943a4Mon Sep 17 00:00:00 2001
From: Zhu Yi <[email protected]>
Date: Thu, 4 Mar 2010 18:01:46 +0000
Subject: [PATCH] x25: use limited socket backlog
Make x25 adapt to the limited socket backlog change.
--- net/x25/x25_dev.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
net/x25/x25_dev.c +1 -1
@@ -53,7 +53,7 @@ static int x25_receive_data(struct sk_buff *skb, struct x25_neigh *nb)if (!sock_owned_by_user (sk)) { queued =x25_process_rx_frame (sk, skb); }else { -sk_add_backlog (sk, skb); + queued = !sk_add_backlog_limited (sk, skb); }bh_unlock_sock (sk);sock_put (sk);
Signature · 1 line
1.7.8.rc0.dirty
PATCH 4/8 sctp: use limited socket backlog
In reply to Dan CarpenterThis applied without changes to the original patch.
Quoted 1 line
From
50b1a782f845140f4138f14a1ce8a4a6dd0cc82fMon Sep 17 00:00:00 2001
From: Zhu Yi <[email protected]>
Date: Thu, 4 Mar 2010 18:01:44 +0000
Subject: [PATCH] sctp: use limited socket backlog
Make sctp adapt to the limited socket backlog change.
--- net/sctp/input.c | 42 +++++++++++++++++++++++++++--------------- net/sctp/socket.c | 3 +++ 2 files changed, 30 insertions(+), 15 deletions(-)
net/sctp/input.c +27 -15
@@ -75,7 +75,7 @@ static struct sctp_association *__sctp_lookup_association(const union sctp_addr *peer, struct sctp_transport **pt); -static void sctp_add_backlog (struct sock *sk,struct sk_buff *skb); +static int sctp_add_backlog (struct sock *sk,struct sk_buff *skb);/* Calculate the SCTP checksum of an SCTP packet. */
@@ -265,8 +265,13 @@ int sctp_rcv(struct sk_buff *skb) }if (sock_owned_by_user (sk)) { +if (sctp_add_backlog (sk, skb)) { +sctp_bh_unlock_sock (sk); +sctp_chunk_free (chunk); + skb =NULL ;/* sctp_chunk_free already freed the skb */ + goto discard_release; + }SCTP_INC_STATS_BH (SCTP_MIB_IN_PKT_BACKLOG ); -sctp_add_backlog (sk, skb); }else {SCTP_INC_STATS_BH (SCTP_MIB_IN_PKT_SOFTIRQ );sctp_inq_push (&chunk->rcvr->inqueue, chunk);
@@ -336,8 +341,10 @@ int sctp_backlog_rcv(struct sock *sk, struct sk_buff *skb)sctp_bh_lock_sock (sk);if (sock_owned_by_user (sk)) { -sk_add_backlog (sk, skb); - backloged =1 ; +if (sk_add_backlog_limited (sk, skb)) +sctp_chunk_free (chunk); +else + backloged =1 ; }else sctp_inq_push (inqueue, chunk);
@@ -362,22 +369,27 @@ done:return 0 ; } -static void sctp_add_backlog (struct sock *sk,struct sk_buff *skb) +static int sctp_add_backlog (struct sock *sk,struct sk_buff *skb) {struct sctp_chunk *chunk =SCTP_INPUT_CB (skb)->chunk;struct sctp_ep_common *rcvr = chunk->rcvr; +int ret; -/* Hold the assoc/ep while hanging on the backlog queue. -* This way, we know structures we need will not disappear from us -*/ -if (SCTP_EP_TYPE_ASSOCIATION == rcvr->type) -sctp_association_hold (sctp_assoc (rcvr)); -else if (SCTP_EP_TYPE_SOCKET == rcvr->type) -sctp_endpoint_hold (sctp_ep (rcvr)); -else -BUG (); + ret =sk_add_backlog_limited (sk, skb); +if (!ret) { +/* Hold the assoc/ep while hanging on the backlog queue. +* This way, we know structures we need will not disappear +* from us +*/ +if (SCTP_EP_TYPE_ASSOCIATION == rcvr->type) +sctp_association_hold (sctp_assoc (rcvr)); +else if (SCTP_EP_TYPE_SOCKET == rcvr->type) +sctp_endpoint_hold (sctp_ep (rcvr)); +else +BUG (); + } +return ret; -sk_add_backlog (sk, skb); }/* Handle icmp frag needed error. */
net/sctp/socket.c +3 -0
@@ -3720,6 +3720,9 @@ SCTP_STATIC int sctp_init_sock(struct sock *sk)SCTP_DBG_OBJCNT_INC (sock);percpu_counter_inc (&sctp_sockets_allocated); +/* Set socket backlog limit. */ + sk->sk_backlog.limit = sysctl_sctp_rmem[1 ]; +local_bh_disable ();sock_prot_inuse_add (sock_net (sk), sk->sk_prot,1 );local_bh_enable ();
Signature · 1 line
1.7.8.rc0.dirty
PATCH 5/8 tipc: use limited socket backlog
In reply to Dan CarpenterThis applied without changes to the original patch.
Quoted 1 line
From
53eecb1be5ae499d399d2923933937a9ea1a284fMon Sep 17 00:00:00 2001
From: Zhu Yi <[email protected]>
Date: Thu, 4 Mar 2010 18:01:45 +0000
Subject: [PATCH] tipc: use limited socket backlog
Make tipc adapt to the limited socket backlog change.
--- net/tipc/socket.c | 6 ++++-- 1 files changed, 4 insertions(+), 2 deletions(-)
net/tipc/socket.c +4 -2
@@ -1322,8 +1322,10 @@ static u32 dispatch(struct tipc_port *tport, struct sk_buff *buf)if (!sock_owned_by_user (sk)) { res =filter_rcv (sk, buf); }else { -sk_add_backlog (sk, buf); - res =TIPC_OK ; +if (sk_add_backlog_limited (sk, buf)) + res =TIPC_ERR_OVERLOAD ; +else + res =TIPC_OK ; }bh_unlock_sock (sk);
Signature · 1 line
1.7.8.rc0.dirty
PATCH 6/8 tcp: use limited socket backlog
In reply to Dan CarpenterThis applied without changes to the original patch.
Quoted 1 line
From
6b03a53a5ab7ccf2d5d69f96cf1c739c4d2a8fb9Mon Sep 17 00:00:00 2001
From: Zhu Yi <[email protected]>
Date: Thu, 4 Mar 2010 18:01:41 +0000
Subject: [PATCH] tcp: use limited socket backlog
Make tcp adapt to the limited socket backlog change.
--- net/ipv4/tcp_ipv4.c | 6 ++++-- net/ipv6/tcp_ipv6.c | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-)
net/ipv4/tcp_ipv4.c +4 -2
@@ -1682,8 +1682,10 @@ process:if (!tcp_prequeue (sk, skb)) ret =tcp_v4_do_rcv (sk, skb); } - }else -sk_add_backlog (sk, skb); + }else if (sk_add_backlog_limited (sk, skb)) { +bh_unlock_sock (sk); + goto discard_and_relse; + }bh_unlock_sock (sk);sock_put (sk);
net/ipv6/tcp_ipv6.c +4 -2
@@ -1740,8 +1740,10 @@ process:if (!tcp_prequeue (sk, skb)) ret =tcp_v6_do_rcv (sk, skb); } - }else -sk_add_backlog (sk, skb); + }else if (sk_add_backlog_limited (sk, skb)) { +bh_unlock_sock (sk); + goto discard_and_relse; + }bh_unlock_sock (sk);sock_put (sk);
Signature · 1 line
1.7.8.rc0.dirty
PATCH 7/8 llc: use limited socket backlog
In reply to Dan CarpenterThis applied without changes to the original patch.
Quoted 1 line
From
79545b681961d7001c1f4c3eb9ffb87bed4485dbMon Sep 17 00:00:00 2001
From: Zhu Yi <[email protected]>
Date: Thu, 4 Mar 2010 18:01:43 +0000
Subject: [PATCH] llc: use limited socket backlog
Make llc adapt to the limited socket backlog change.
--- net/llc/llc_conn.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-)
net/llc/llc_conn.c +2 -1
@@ -827,7 +827,8 @@ void llc_conn_handler(struct llc_sap *sap, struct sk_buff *skb)else {dprintk ("%s: adding to backlog...\n" , __func__);llc_set_backlog_type (skb,LLC_PACKET ); -sk_add_backlog (sk, skb); +if (sk_add_backlog_limited (sk, skb)) + goto drop_unlock; } out:bh_unlock_sock (sk);
Signature · 1 line
1.7.8.rc0.dirty
PATCH 8/8 net: backlog functions rename
In reply to Dan CarpenterI had to make some trivial changes here as a result of the changes I made in [patch 2/8 2.6.32] udp: use limited socket backlog.
Quoted 1 line
From
a3a858ff18a72a8d388e31ab0d98f7e944841a62Mon Sep 17 00:00:00 2001
From: Zhu Yi <[email protected]>
Date: Thu, 4 Mar 2010 18:01:47 +0000
Subject: [PATCH] net: backlog functions rename
sk_add_backlog -> __sk_add_backlogsk_add_backlog_limited -> sk_add_backlog
---
include/net/sock.h +3 -3
@@ -564,7 +564,7 @@ static inline int sk_stream_memory_free(struct sock *sk) }/* OOB backlog add */ -static inline void sk_add_backlog (struct sock *sk,struct sk_buff *skb) +static inline void __sk_add_backlog (struct sock *sk,struct sk_buff *skb) {if (!sk->sk_backlog.tail) { sk->sk_backlog.head = sk->sk_backlog.tail = skb;
@@ -576,12 +576,12 @@ static inline void sk_add_backlog(struct sock *sk, struct sk_buff *skb) }/* The per-socket spinlock must be held here. */ -static inline int sk_add_backlog_limited (struct sock *sk,struct sk_buff *skb) +static inline int sk_add_backlog (struct sock *sk,struct sk_buff *skb) {if (sk->sk_backlog.len >=max (sk->sk_backlog.limit, sk->sk_rcvbuf <<1 ))return -ENOBUFS ; -sk_add_backlog (sk, skb); +__sk_add_backlog (sk, skb); sk->sk_backlog.len += skb->truesize;return 0 ; }
net/core/sock.c +1 -1
@@ -336,7 +336,7 @@ int sk_receive_skb(struct sock *sk, struct sk_buff *skb, const int nested) rc =sk_backlog_rcv (sk, skb);mutex_release (&sk->sk_lock.dep_map,1 , _RET_IP_); - }else if (sk_add_backlog_limited (sk, skb)) { + }else if (sk_add_backlog (sk, skb)) {bh_unlock_sock (sk);atomic_inc (&sk->sk_drops); goto discard_and_relse;
net/dccp/minisocks.c +1 -1
@@ -254,7 +254,7 @@ int dccp_child_process(struct sock *parent, struct sock *child,* in main socket hash table and lock on listening * socket does not protect us more. */ -sk_add_backlog (child, skb); +__sk_add_backlog (child, skb); }bh_unlock_sock (child);
net/ipv4/tcp_ipv4.c +1 -1
@@ -1635,7 +1635,7 @@ process:if (!tcp_prequeue (sk, skb)) ret =tcp_v4_do_rcv (sk, skb); } - }else if (sk_add_backlog_limited (sk, skb)) { + }else if (sk_add_backlog (sk, skb)) {bh_unlock_sock (sk); goto discard_and_relse; }
net/ipv4/tcp_minisocks.c +1 -1
@@ -702,7 +702,7 @@ int tcp_child_process(struct sock *parent, struct sock *child,* in main socket hash table and lock on listening * socket does not protect us more. */ -sk_add_backlog (child, skb); +__sk_add_backlog (child, skb); }bh_unlock_sock (child);
net/ipv4/udp.c +1 -1
@@ -1177,7 +1177,7 @@ int udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)bh_lock_sock (sk);if (!sock_owned_by_user (sk)) rc =__udp_queue_rcv_skb (sk, skb); -else if (sk_add_backlog_limited (sk, skb)) { +else if (sk_add_backlog (sk, skb)) {bh_unlock_sock (sk); goto drop; }
net/ipv6/tcp_ipv6.c +1 -1
@@ -1686,7 +1686,7 @@ process:if (!tcp_prequeue (sk, skb)) ret =tcp_v6_do_rcv (sk, skb); } - }else if (sk_add_backlog_limited (sk, skb)) { + }else if (sk_add_backlog (sk, skb)) {bh_unlock_sock (sk); goto discard_and_relse; }
net/ipv6/udp.c +3 -3
@@ -473,7 +473,7 @@ static int __udp6_lib_mcast_deliver(struct net *net, struct sk_buff *skb,bh_lock_sock (sk2);if (!sock_owned_by_user (sk2))udpv6_queue_rcv_skb (sk2, buff); -else if (sk_add_backlog_limited (sk2, buff)) { +else if (sk_add_backlog (sk2, buff)) {kfree_skb (buff);bh_unlock_sock (sk2); goto out;
@@ -484,7 +484,7 @@ static int __udp6_lib_mcast_deliver(struct net *net, struct sk_buff *skb,bh_lock_sock (sk);if (!sock_owned_by_user (sk))udpv6_queue_rcv_skb (sk, skb); -else if (sk_add_backlog_limited (sk, skb)) +else if (sk_add_backlog (sk, skb))kfree_skb (skb);bh_unlock_sock (sk); out:
@@ -604,7 +604,7 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,bh_lock_sock (sk);if (!sock_owned_by_user (sk))udpv6_queue_rcv_skb (sk, skb); -else if (sk_add_backlog_limited (sk, skb)) { +else if (sk_add_backlog (sk, skb)) {atomic_inc (&sk->sk_drops);bh_unlock_sock (sk);sock_put (sk);
net/llc/llc_c_ac.c +1 -1
@@ -1437,7 +1437,7 @@ static void llc_process_tmr_ev(struct sock *sk, struct sk_buff *skb)llc_conn_state_process (sk, skb); else {llc_set_backlog_type (skb,LLC_EVENT ); -sk_add_backlog (sk, skb); +__sk_add_backlog (sk, skb); } } }
net/llc/llc_conn.c +1 -1
@@ -756,7 +756,7 @@ void llc_conn_handler(struct llc_sap *sap, struct sk_buff *skb)else {dprintk ("%s: adding to backlog...\n" , __func__);llc_set_backlog_type (skb,LLC_PACKET ); -if (sk_add_backlog_limited (sk, skb)) +if (sk_add_backlog (sk, skb)) goto drop_unlock; } out:
net/sctp/input.c +2 -2
@@ -341,7 +341,7 @@ int sctp_backlog_rcv(struct sock *sk, struct sk_buff *skb)sctp_bh_lock_sock (sk);if (sock_owned_by_user (sk)) { -if (sk_add_backlog_limited (sk, skb)) +if (sk_add_backlog (sk, skb))sctp_chunk_free (chunk);else backloged =1 ;
@@ -375,7 +375,7 @@ static int sctp_add_backlog(struct sock *sk, struct sk_buff *skb)struct sctp_ep_common *rcvr = chunk->rcvr;int ret; - ret =sk_add_backlog_limited (sk, skb); + ret =sk_add_backlog (sk, skb);if (!ret) {/* Hold the assoc/ep while hanging on the backlog queue. * This way, we know structures we need will not disappear
net/tipc/socket.c +1 -1
@@ -1323,7 +1323,7 @@ static u32 dispatch(struct tipc_port *tport, struct sk_buff *buf)if (!sock_owned_by_user (sk)) { res =filter_rcv (sk, buf); }else { -if (sk_add_backlog_limited (sk, buf)) +if (sk_add_backlog (sk, buf)) res =TIPC_ERR_OVERLOAD ;else res =TIPC_OK ;
net/x25/x25_dev.c +1 -1
@@ -53,7 +53,7 @@ static int x25_receive_data(struct sk_buff *skb, struct x25_neigh *nb)if (!sock_owned_by_user (sk)) { queued =x25_process_rx_frame (sk, skb); }else { - queued = !sk_add_backlog_limited (sk, skb); + queued = !sk_add_backlog (sk, skb); }bh_unlock_sock (sk);sock_put (sk);
David Miller
maintainerFrom: Dan Carpenter <[email protected]>
Date: Sun, 13 Nov 2011 23:13:36 +0300
Quoted 15 lines
This patch series is to address CVE-2010-4251 for the 2.6.32 stable kernel. Here is the CVE summary:
"The socket implementation in
net/core/sock.cin the Linux kernel
before 2.6.34 does not properly manage a backlog of received packets, which allows remote attackers to cause a denial of service (memory consumption) by sending a large amount of network traffic, as demonstrated by netperf UDP tests."[patch 1/8] introduces
sk_add_backlog_limited()
[patch 2-7/8] change each network protocol to usesk_add_backlog_limited()
where appropriate.
[patch 8/8] renamessk_add_backlog()to__sk_add_backlog()and
sk_add_backlog_limited()tosk_add_backlog().
Quoted 3 lines
The patches mostly apply without changes. The exception is:
[patch 2/8] udp: use limited socket backlog
Then the rename [patch 8/8] needed to be changed as well to match.
These changes are way too intrusive and potentially regression inducing for -stable inclusion, especially a kernel that is in such deep maintainence mode as 2.6.32 is.
Also, I tend to personally submit networking -stable patches, so please do not bypass me in this manner and instead recommend such submissions on the netdev list so I can evaluate the request.
Thanks.
Quoted 18 lines · David Miller
From: Dan Carpenter <[email protected]>
Date: Sun, 13 Nov 2011 23:13:36 +0300Quoted 15 lines
This patch series is to address CVE-2010-4251 for the 2.6.32 stable kernel. Here is the CVE summary:
"The socket implementation in
net/core/sock.cin the Linux kernel
before 2.6.34 does not properly manage a backlog of received packets, which allows remote attackers to cause a denial of service (memory consumption) by sending a large amount of network traffic, as demonstrated by netperf UDP tests."[patch 1/8] introduces
sk_add_backlog_limited()
[patch 2-7/8] change each network protocol to usesk_add_backlog_limited()
where appropriate.
[patch 8/8] renamessk_add_backlog()to__sk_add_backlog()and
sk_add_backlog_limited()tosk_add_backlog().
Quoted 7 lines
Quoted 3 lines
The patches mostly apply without changes. The exception is:
[patch 2/8] udp: use limited socket backlog
Then the rename [patch 8/8] needed to be changed as well to match.These changes are way too intrusive and potentially regression inducing for -stable inclusion, especially a kernel that is in such deep maintainence mode as 2.6.32 is.
Debian 6.0 based on Linux 2.6.32 has patches #1-7, except our backport of #2 (for udp) looks a bit different.
Apparently several other distributions have also applied these.
Quoted 3 lines
Also, I tend to personally submit networking -stable patches, so please do not bypass me in this manner and instead recommend such submissions on the netdev list so I can evaluate the request.
But you've previously said that you are not submitting networking patches to the longterm series. Did you change your mind?
Ben.
Signature · 2 lines
Ben Hutchings Never attribute to conspiracy what can adequately be explained by stupidity.
David Miller
maintainerFrom: Ben Hutchings <[email protected]>
Date: Sun, 13 Nov 2011 23:29:09 +0000
Quoted 2 lines
But you've previously said that you are not submitting networking patches to the longterm series. Did you change your mind?
No, I in fact haven't.
But I will say that if distributions want to apply this thing, that's fine, but it doesn't automatically make it a good idea for -stable to take it too.
Quoted 11 lines · David Miller
From: Ben Hutchings <[email protected]>
Date: Sun, 13 Nov 2011 23:29:09 +0000Quoted 2 lines
But you've previously said that you are not submitting networking patches to the longterm series. Did you change your mind?
No, I in fact haven't.
But I will say that if distributions want to apply this thing, that's fine, but it doesn't automatically make it a good idea for -stable to take it too.
Thanks for letting me know, I'll drop these from my to-apply mbox.
greg k-h