Re: [PATCH net 1/2] ipv4: mcast: getsockopt: do not overwrite past optlen
From: Breno Leitao
Date: Thu Aug 13 2026 - 10:46:51 EST
Hello Jakub,
On Tue, Aug 11, 2026 at 08:15:43AM -0700, Jakub Kicinski wrote:
> On Tue, 11 Aug 2026 05:19:17 -0700 Breno Leitao wrote:
> > So my question to you: can you point me to actual software that
> > passes a "small" optlen and expects the kernel to write past it? That
> > would help to decide about the two options above.
>
> If you are very confident that no such SW exists - we can try to queue
> this up for -next. (TBH I'm not, mcast specifically may be full of
> strange one off manually written user space (as opposed to common libraries)).
> If we decide to change the behavior- we will probably have to wait
> until this makes it to an LTS release + some time for people to deploy.
> It can't be a fix.
>
> So practically speaking it may be more expedient to add some hacks to
> cater to this case in the conversion, and then remove the hack. That'd
> be easier to revert if someone pipes up later that we broke their SW.
Thanks. I was mostly trying to find out whether this is a real problem
before creating this quirk, and your intuition is helpful here. I will
proceed with the quirk then.
For the sockopt_t conversion I can expand the iterator mid-air for the
few options that size their reply from a count in the header, so the
conversion stays a no-op for userspace.
Expanding is only safe for a user buffer, though - a kernel-backed
optval might be too risky, I would say. And it will not break anything,
given we don't have in-kernel users for this yet (given the __user
params)
I might come up with a helper like this one:
static inline void sockopt_expand_out(sockopt_t *opt, size_t len)
{
if (len < iov_iter_count(&opt->iter_out))
// No quirk required
return;
/* Only a user buffer can be larger than the caller
* declared; a kernel-backed optval has nothing behind it.
*/
if (WARN_ON_ONCE(!iter_is_ubuf(&opt->iter_out)))
return;
iov_iter_reexpand(&opt->iter_out, len);
}
and then, at the call site, right after the header is read and before
anything is written back:
/* The reply is sized by gf_numsrc, not by optlen, which only has
* to cover the fixed header. Grow the output iterator to what the
* header declares, or the source list gets truncated.
*/
sockopt_expand_out(opt, size_add(size0,
size_mul(gsf.gf_numsrc,
sizeof(gsf.gf_slist_flex[0]))));
(All completely untested so far.)
Thanks for the suggestion,
--breno