Thread (8 messages) flat view 8 messages, 4 authors, 2023-12-02

Re: [PATCH] netlink: Return unsigned value for nla_len()

From: Johannes Berg <johannes@sipsolutions.net>
Date: 2023-12-01 07:45:46
Also in: linux-hardening, linux-wireless, lkml

On Thu, 2023-11-30 at 17:25 -0800, Jakub Kicinski wrote:
On Thu, 30 Nov 2023 12:01:01 -0800 Kees Cook wrote:
quoted
This has the additional benefit of being defensive in the face of nlattr
corruption or logic errors (i.e. nla_len being set smaller than
NLA_HDRLEN).
As Johannes predicted I'd rather not :(
:)
The callers should put the nlattr thru nla_ok() during validation
(nla_validate()), or walking (nla_for_each_* call nla_ok()).
Which we do, since we have just normal input validation on generic
netlink. Actually nla_validate() only does it via walking either ;-)

The thing is that's something the compiler can't really see, it happens
out-of-line in completely different code (generic netlink) before you
even get into nl80211.
quoted
-static inline int nla_len(const struct nlattr *nla)
+static inline u16 nla_len(const struct nlattr *nla)
 {
-	return nla->nla_len - NLA_HDRLEN;
+	return nla->nla_len > NLA_HDRLEN ? nla->nla_len - NLA_HDRLEN : 0;
 }
Note the the NLA_HDRLEN is the length of struct nlattr.
I mean of the @nla object that gets passed in as argument here.
So accepting that nla->nla_len may be < NLA_HDRLEN means
that we are okay with dereferencing a truncated object...

We can consider making the return unsinged without the condition maybe?
That seems problematic too though - better for an (unvalidated)
attribute with a bad size to actually show up with a negative payload
length rather than an underflow to a really big size.

Anyway I really don't mind the workaround in nl80211 (which was to make
the variables holding this unsigned), since we *do* know that we
validated there, that's not an issue wrt. the length.

johannes
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help