Re: [PATCH net-next RFC 0/3] net: move .getsockopt away from __user buffers

From: Breno Leitao

Date: Mon Feb 02 2026 - 07:34:47 EST


Hello David,

On Fri, Jan 30, 2026 at 08:52:27PM +0000, David Laight wrote:

> The system call wrapper can do the user copies, it can also suppress
> the write if the value is unchanged (which matters with clac/slac).

This aligns with my proposal: using an in-kernel optlen that protocol
functions can operate on directly:

typedef struct sockopt {
struct iov_iter iter;
int optlen;
} sockopt_t;

> The obvious change would be to pass the length itself and make the
> return value -ERRNO or the size.

I explored this approach to avoid embedding optlen in sockopt (which was
Linus' original suggestion). I attempted returning the length both via
iov_iter and as a return value, but neither proved ideal.

> #define GETSOCKOPT_RVAL(errval, size) (1 << 31 | (errval) << 20 | (size))
> which would get picked in the rval < 0 path.
> It would also let 'return 0' mean 'don't change the size' requiring
> a special return for the one (or two?) places that want to set the
> size to zero and return success.

My conclusion is that encoding both optlen and error in the return value
requires pointer manipulation that isn't justified for this slow path.
While technically feasible, the resulting "mixed pointer abomination"
won't be worth it.

> There is not much point making the 'optval' parameter more than
> a structure of a user and kernel address - one of which will be NULL.
> (This is safer than sockptr_t's discriminant union.)

This approach forces every protocol to distinguish between userspace and
kernelspace, then perform the appropriate copy:

static inline int mgetsockopt(void *kernel_optlen, void *user_optlen, ..)
{
....
if (kernel_optlen)
memcpy(kernel_optlen, newoptlen, ...
else
copy_to_user(user_optlen, newoptlen, ...
}

Additionally, you'd need safeguards ensuring callers never pass both user
and kernel pointers simultaneously. This seems significantly worse than
using sockptr.

--breno