Subject: Re: [PATCH v3] netlink: Bounds-check struct nlmsgerr creation

From: Jakub Kicinski <[email-masked]>
Date: Fri, 2 Sep 2022 19:53:24 -0700

On Fri, 2 Sep 2022 16:08:01 -0700 Kees Cook wrote:
> > -	if (extack->cookie_len)
> > -		tlvlen += nla_total_size(extack->cookie_len);
> > +	if (extack->_msg &&
> > +	    check_add_overflow(*tlvlen, nla_total_size(strlen(extack->_msg) + 1), tlvlen))
> > +		return false;  
> 
> If that's not desirable, then I guess the question I want to ask is
> "what can I put in the unsafe_memcpy() comment above that proves these
> values have been sanity checked? In other words, how do we know that
> tlvlen hasn't overflowed? (I don't know what other sanity checking may
> have already happened, so I'm looking directly at the size calculations
> here.)

The netlink helpers for adding attributes check whether there is enough
space left in the skb. So if the calculation overflows, so be it. We'll
hit EMSGSIZE in the writing phase and unwind. The writing should make
no assumptions about the skb size. In fact all dumps will routinely hit
EMSGSIZE as we try to fit as many objects into a skb as possible, so we
unwind the one that would go over. Unwinding is well exercised in a lot
of netlink code (not here, MSG_DONE/MSG_ERROR ain't a dump).

The pre-calculation is just an estimate, if the message size ends up
being insane it really doesn't matter if the calculation is 0, INT_MAX
or random(). User is not gonna get a response, anyway.

... unless someone uses the unsafe helpers like __nlmsg_put() rather
than nlmsg_put(), hence my suggestion in the other email.