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..
next prev parent 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.