lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:	Mon, 18 Aug 2014 13:08:31 -0400
From:	Neil Horman <nhorman@...driver.com>
To:	Eric Dumazet <eric.dumazet@...il.com>
Cc:	David Miller <davem@...emloft.net>,
	Hannes Frederic Sowa <hannes@...essinduktion.org>,
	Daniel Borkmann <dborkman@...hat.com>,
	Jesper Dangaard Brouer <brouer@...hat.com>,
	netdev <netdev@...r.kernel.org>, Guy Harris <guy@...m.mit.edu>
Subject: Re: [PATCH v1 net] packet: handle too big packets for PACKET_V3

On Fri, Aug 15, 2014 at 09:16:04AM -0700, Eric Dumazet wrote:
> From: Eric Dumazet <edumazet@...gle.com>
> 
> af_packet can currently overwrite kernel memory by out of bound
> accesses, because it assumed a [new] block can always hold one frame.
> 
> This is not generally the case, even if most existing tools do it right.
> 
> This patch clamps too long frames as API permits, and issue a one time
> error on syslog.
> 
> [  394.357639] tpacket_rcv: packet too big, clamped from 5042 to 3966. macoff=82
> 
> In this example, packet header tp_snaplen was set to 3966,
> and tp_len was set to 5042 (skb->len)
> 
> Signed-off-by: Eric Dumazet <edumazet@...gle.com>
> Fixes: f6fb8f100b80 ("af-packet: TPACKET_V3 flexible buffer implementation.")
> ---
>  net/packet/af_packet.c |   17 +++++++++++++++++
>  net/packet/internal.h  |    1 +
>  2 files changed, 18 insertions(+)
> 
> diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
> index 8d9f8042705a..93896d2092f6 100644
> --- a/net/packet/af_packet.c
> +++ b/net/packet/af_packet.c
> @@ -632,6 +632,7 @@ static void init_prb_bdqc(struct packet_sock *po,
>  	p1->tov_in_jiffies = msecs_to_jiffies(p1->retire_blk_tov);
>  	p1->blk_sizeof_priv = req_u->req3.tp_sizeof_priv;
>  
> +	p1->max_frame_len = p1->kblk_size - BLK_PLUS_PRIV(p1->blk_sizeof_priv);
>  	prb_init_ft_ops(p1, req_u);
>  	prb_setup_retire_blk_timer(po, tx_ring);
>  	prb_open_block(p1, pbd);
> @@ -1942,6 +1943,18 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev,
>  			if ((int)snaplen < 0)
>  				snaplen = 0;
>  		}
> +	} else if (unlikely(macoff + snaplen >
> +			    GET_PBDQC_FROM_RB(&po->rx_ring)->max_frame_len)) {
> +		u32 nval;
> +
> +		nval = GET_PBDQC_FROM_RB(&po->rx_ring)->max_frame_len - macoff;
> +		pr_err_once("tpacket_rcv: packet too big, clamped from %u to %u. macoff=%u\n",
> +			    snaplen, nval, macoff);
> +		snaplen = nval;
> +		if (unlikely((int)snaplen < 0)) {
> +			snaplen = 0;
> +			macoff = GET_PBDQC_FROM_RB(&po->rx_ring)->max_frame_len;
> +		}
>  	}
>  	spin_lock(&sk->sk_receive_queue.lock);
>  	h.raw = packet_current_rx_frame(po, skb,
> @@ -3783,6 +3796,10 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u,
>  			goto out;
>  		if (unlikely(req->tp_block_size & (PAGE_SIZE - 1)))
>  			goto out;
> +		if (po->tp_version >= TPACKET_V3 &&
> +		    (int)(req->tp_block_size -
> +			  BLK_PLUS_PRIV(req_u->req3.tp_sizeof_priv)) <= 0)
> +			goto out;
>  		if (unlikely(req->tp_frame_size < po->tp_hdrlen +
>  					po->tp_reserve))
>  			goto out;
> diff --git a/net/packet/internal.h b/net/packet/internal.h
> index eb9580a6b25f..cdddf6a30399 100644
> --- a/net/packet/internal.h
> +++ b/net/packet/internal.h
> @@ -29,6 +29,7 @@ struct tpacket_kbdq_core {
>  	char		*pkblk_start;
>  	char		*pkblk_end;
>  	int		kblk_size;
> +	unsigned int	max_frame_len;
>  	unsigned int	knum_blocks;
>  	uint64_t	knxt_seq_num;
>  	char		*prev;
> 
> 
> 

Acked-by: Neil Horman <nhorman@...driver.com>

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ