dccp: limit sk_filter trim to payload
Dccp verifies packet integrity, including length, at initial rcv in
dccp_invalid_packet, later pulls headers in dccp_enqueue_skb.
A call to sk_filter in-between can cause __skb_pull to wrap skb->len.
skb_copy_datagram_msg interprets this as a negative value, so
(correctly) fails with EFAULT. The negative length is reported in
ioctl SIOCINQ or possibly in a DCCP_WARN in dccp_close.
Introduce an sk_receive_skb variant that caps how small a filter
program can trim packets, and call this in dccp with the header
length. Excessively trimmed packets are now processed normally and
queued for reception as 0B payloads.
Fixes: 7c657876b6
("[DCCP]: Initial implementation")
Signed-off-by: Willem de Bruijn <willemb@google.com>
Acked-by: Daniel Borkmann <daniel@iogearbox.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:

committed by
David S. Miller

parent
f4979fcea7
commit
4f0c40d944
@@ -1576,7 +1576,13 @@ static inline void sock_put(struct sock *sk)
|
||||
*/
|
||||
void sock_gen_put(struct sock *sk);
|
||||
|
||||
int sk_receive_skb(struct sock *sk, struct sk_buff *skb, const int nested);
|
||||
int __sk_receive_skb(struct sock *sk, struct sk_buff *skb, const int nested,
|
||||
unsigned int trim_cap);
|
||||
static inline int sk_receive_skb(struct sock *sk, struct sk_buff *skb,
|
||||
const int nested)
|
||||
{
|
||||
return __sk_receive_skb(sk, skb, nested, 1);
|
||||
}
|
||||
|
||||
static inline void sk_tx_queue_set(struct sock *sk, int tx_queue)
|
||||
{
|
||||
|
Reference in New Issue
Block a user