netfilter-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Pablo Neira Ayuso <pablo@netfilter.org>
To: Zhouyi Zhou <zhouzhouyi@gmail.com>
Cc: eric.dumazet@gmail.com, kaber@trash.net,
	kadlec@blackhole.kfki.hu, davem@davemloft.net,
	netfilter-devel@vger.kernel.org, coreteam@netfilter.org,
	netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
	fw@strlen.de, gnomes@lxorguk.ukuu.org.uk,
	sergei.shtylyov@cogentembedded.com,
	Zhouyi Zhou <yizhouzhou@ict.ac.cn>
Subject: Re: [PATCH V7] netfilter: h323: avoid potential attack
Date: Sat, 12 Mar 2016 13:19:02 +0100	[thread overview]
Message-ID: <20160312121902.GA2398@salvia> (raw)
In-Reply-To: <1455984239-5807-1-git-send-email-zhouzhouyi@gmail.com>

On Sun, Feb 21, 2016 at 12:03:59AM +0800, Zhouyi Zhou wrote:
> I think hackers chould build a malicious h323 packet to overflow
> the pointer p which will panic during the memcpy(addr, p, len)
> For example, he may fabricate a very large taddr->ipAddress.ip in
> function get_h225_addr.
> 
> To avoid above, I add buffer boundary checking both in get addr
> functions and set addr functions.
> 
> Because the temporary h323 buffer is dynamiclly allocated, I remove
> the h323 spin lock in my patch.
> 
> Signed-off-by: Zhouyi Zhou <yizhouzhou@ict.ac.cn>
> ---
>  include/linux/netfilter/nf_conntrack_h323.h |  17 +-
>  net/ipv4/netfilter/nf_nat_h323.c            |  33 ++-
>  net/netfilter/nf_conntrack_h323_main.c      | 328 +++++++++++++++++-----------
>  3 files changed, 244 insertions(+), 134 deletions(-)
> 
> diff --git a/include/linux/netfilter/nf_conntrack_h323.h b/include/linux/netfilter/nf_conntrack_h323.h
> index 858d9b2..6c6fea1 100644
> --- a/include/linux/netfilter/nf_conntrack_h323.h
> +++ b/include/linux/netfilter/nf_conntrack_h323.h
> @@ -27,11 +27,17 @@ struct nf_ct_h323_master {
>  	};
>  };
>  
> +struct h323_ct_state {
> +	unsigned char *buf;
> +	unsigned char *data;
> +	int buflen;
> +};
> +
>  struct nf_conn;
>  
>  int get_h225_addr(struct nf_conn *ct, unsigned char *data,
>  		  TransportAddress *taddr, union nf_inet_addr *addr,
> -		  __be16 *port);
> +		  __be16 *port, struct h323_ct_state *ctstate);
>  void nf_conntrack_h245_expect(struct nf_conn *new,
>  			      struct nf_conntrack_expect *this);
>  void nf_conntrack_q931_expect(struct nf_conn *new,
> @@ -50,12 +56,14 @@ extern int (*set_sig_addr_hook) (struct sk_buff *skb,
>  				 struct nf_conn *ct,
>  				 enum ip_conntrack_info ctinfo,
>  				 unsigned int protoff, unsigned char **data,
> -				 TransportAddress *taddr, int count);
> +				 TransportAddress *taddr, int count,
> +				 struct h323_ct_state *ctstate);
>  extern int (*set_ras_addr_hook) (struct sk_buff *skb,
>  				 struct nf_conn *ct,
>  				 enum ip_conntrack_info ctinfo,
>  				 unsigned int protoff, unsigned char **data,
> -				 TransportAddress *taddr, int count);
> +				 TransportAddress *taddr, int count,
> +				 struct h323_ct_state *ctstate);
>  extern int (*nat_rtp_rtcp_hook) (struct sk_buff *skb,
>  				 struct nf_conn *ct,
>  				 enum ip_conntrack_info ctinfo,
> @@ -90,7 +98,8 @@ extern int (*nat_q931_hook) (struct sk_buff *skb, struct nf_conn *ct,
>  			     unsigned int protoff,
>  			     unsigned char **data, TransportAddress *taddr,
>  			     int idx, __be16 port,
> -			     struct nf_conntrack_expect *exp);
> +			     struct nf_conntrack_expect *exp,
> +			     struct h323_ct_state *ctstate);
>  
>  #endif
>  
> diff --git a/net/ipv4/netfilter/nf_nat_h323.c b/net/ipv4/netfilter/nf_nat_h323.c
> index 574f7eb..5ed2d70 100644
> --- a/net/ipv4/netfilter/nf_nat_h323.c
> +++ b/net/ipv4/netfilter/nf_nat_h323.c
> @@ -33,12 +33,20 @@ static int set_addr(struct sk_buff *skb, unsigned int protoff,
>  	} __attribute__ ((__packed__)) buf;
>  	const struct tcphdr *th;
>  	struct tcphdr _tcph;
> +	int datalen;
> +	struct iphdr *iph = ip_hdr(skb);
>  
>  	buf.ip = ip;
>  	buf.port = port;
>  	addroff += dataoff;
>  
>  	if (ip_hdr(skb)->protocol == IPPROTO_TCP) {
> +		th = (void *)iph + iph->ihl * 4;
> +		datalen = skb->len - (iph->ihl * 4 + th->doff * 4);

You cannot trust the information that is available in the header. If
this is bogus this check will be defeated. That's why we pass this
protoff parameters to each function.

You also refer to get_h225_addr() in your description. That function
always copies 4 or 16 bytes, so I would appreciate if you can describe
the possible issue further.

Thanks.

  reply	other threads:[~2016-03-12 12:19 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-02-20 16:03 [PATCH V7] netfilter: h323: avoid potential attack Zhouyi Zhou
2016-03-12 12:19 ` Pablo Neira Ayuso [this message]
2016-03-17  6:41   ` Zhouyi Zhou

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20160312121902.GA2398@salvia \
    --to=pablo@netfilter.org \
    --cc=coreteam@netfilter.org \
    --cc=davem@davemloft.net \
    --cc=eric.dumazet@gmail.com \
    --cc=fw@strlen.de \
    --cc=gnomes@lxorguk.ukuu.org.uk \
    --cc=kaber@trash.net \
    --cc=kadlec@blackhole.kfki.hu \
    --cc=linux-kernel@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=netfilter-devel@vger.kernel.org \
    --cc=sergei.shtylyov@cogentembedded.com \
    --cc=yizhouzhou@ict.ac.cn \
    --cc=zhouzhouyi@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).