All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jakub Kicinski <kuba@kernel.org>
To: Dan Carpenter <dan.carpenter@linaro.org>
Cc: Thomas Graf <tgraf@suug.ch>,
	"David S. Miller" <davem@davemloft.net>,
	Eric Dumazet <edumazet@google.com>,
	Paolo Abeni <pabeni@redhat.com>, Simon Horman <horms@kernel.org>,
	netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
	kernel-janitors@vger.kernel.org
Subject: Re: [PATCH net] net: netlink: prevent potential integer overflow in nlmsg_new()
Date: Fri, 24 Jan 2025 08:02:10 -0800	[thread overview]
Message-ID: <20250124080210.23208829@kernel.org> (raw)
In-Reply-To: <04dbe1d5-51e8-42d5-a77d-59db4bc13957@stanley.mountain>

On Fri, 24 Jan 2025 17:35:24 +0300 Dan Carpenter wrote:
> On Wed, Jan 22, 2025 at 06:24:27AM -0800, Jakub Kicinski wrote:
> > On Wed, 22 Jan 2025 16:49:17 +0300 Dan Carpenter wrote:  
> > > The "payload" variable is type size_t, however the nlmsg_total_size()
> > > function will a few bytes to it and then truncate the result to type
> > > int.  That means that if "payload" is more than UINT_MAX the alloc_skb()
> > > function might allocate a buffer which is smaller than intended.  
> > 
> > Is there a bug, or is this theoretical?  
> 
> The rule here is that if we pass something very close to UINT_MAX to
> nlmsg_new() the it leads to an integer overflow.  I'm not a networking
> expert.  The caller that concerned me was:
> 
> *** 1 ***
> 
> net/netfilter/ipset/ip_set_core.c
>   1762                  /* Error in restore/batch mode: send back lineno */
>   1763                  struct nlmsghdr *rep, *nlh = nlmsg_hdr(skb);
>   1764                  struct sk_buff *skb2;
>   1765                  struct nlmsgerr *errmsg;
>   1766                  size_t payload = min(SIZE_MAX,
>   1767                                       sizeof(*errmsg) + nlmsg_len(nlh));
> 
> I don't know the limits of limits of nlmsg_len() here.

Practically speaking the limits are fairly small. The nlh comes from
user's request / sendmsg() call. So the user must have prepared 
a message of at least that len, and kernel must had been able to
kvmalloc() a linear buffer large enough to copy that message in.

> The min(SIZE_MAX is what scared me.  That was added to silence a Smatch
> warning.  :P  It should be fixed or removed.

Yeah, that ip_set code looks buggy. Mostly because we use @payload
for the nlmsg_put() call, but then raw nlh->nlmsg_len for memcpy() :S

>   1768                  int min_len = nlmsg_total_size(sizeof(struct nfgenmsg));
>   1769                  struct nlattr *cda[IPSET_ATTR_CMD_MAX + 1];
>   1770                  struct nlattr *cmdattr;
>   1771                  u32 *errline;
>   1772  
>   1773                  skb2 = nlmsg_new(payload, GFP_KERNEL);
>   1774                  if (!skb2)
>   1775                          return -ENOMEM;
> 
> *** 2 ***
> There is similar code in netlink_ack() where the payload comes from
> nlmsg_len(nlh).

This one is correct. Each piece of the message is nlmsg_put()
individually, which does bounds checking. So if the allocation 
of the skb was faulty and the skb is shorter than we expected 
we'll just error out on the put.

> *** 3 ***
> 
> There is a potential issue in queue_userspace_packet() when we call:
> 
> 	len = upcall_msg_size(upcall_info, hlen - cutlen, ...
>                                            ^^^^^^^^^^^^^
> 	user_skb = genlmsg_new(len, GFP_ATOMIC);
> 
> It's possible that hlen is less than cutlen.  (That's a separate bug,
> I'll send a fix for it).

Ack.

In general IMVHO the check in nlmsg_new() won't be too effective.
The callers can overflow their local message size calculation.
Not to mention that the size calculation is often inexact.
So using nla_put() and checking error codes is the best way
to prevent security issues..

  reply	other threads:[~2025-01-24 16:02 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-01-22 13:49 [PATCH net] net: netlink: prevent potential integer overflow in nlmsg_new() Dan Carpenter
2025-01-22 13:52 ` Przemek Kitszel
2025-01-23  5:48   ` Dan Carpenter
2025-01-22 14:24 ` Jakub Kicinski
2025-01-24 14:35   ` Dan Carpenter
2025-01-24 16:02     ` Jakub Kicinski [this message]
2025-01-22 15:51 ` Simon Horman

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=20250124080210.23208829@kernel.org \
    --to=kuba@kernel.org \
    --cc=dan.carpenter@linaro.org \
    --cc=davem@davemloft.net \
    --cc=edumazet@google.com \
    --cc=horms@kernel.org \
    --cc=kernel-janitors@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=tgraf@suug.ch \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.