Christos Zoulas <chris...@netbsd.org> writes: > Log Message: > make sure that we have enough space, don't require the exact size > (Tom Ivar Helbekkmo)
Oops. That wasn't enough. If we're going to allow the caller of getsockopt(2) to supply an oversized buffer for receiving the option data, we need to keep track of both the size of the allocated kmem buffer, so we can free it afterwards, and the actual size of the data written into it, so we can return that to the caller. As far as I can tell, there's nothing for it but to expand the sockopt struct, adding either a field for the alloc'ed size, or one for the actual size of what's being returned to the caller. I went for the latter, because it's the simplest change to make. Here's what I'm running with at the moment: Index: sys/sys/socketvar.h =================================================================== RCS file: /cvsroot/src/sys/sys/socketvar.h,v retrieving revision 1.145 diff -u -u -r1.145 socketvar.h --- sys/sys/socketvar.h 6 Jul 2017 17:08:57 -0000 1.145 +++ sys/sys/socketvar.h 3 Jan 2018 10:53:17 -0000 @@ -224,6 +224,7 @@ int sopt_level; /* option level */ int sopt_name; /* option name */ size_t sopt_size; /* data length */ + size_t sopt_retsize; /* returned data length */ void * sopt_data; /* data pointer */ uint8_t sopt_buf[sizeof(int)]; /* internal storage */ }; Index: sys/kern/uipc_socket.c =================================================================== RCS file: /cvsroot/src/sys/kern/uipc_socket.c,v retrieving revision 1.258 diff -u -u -r1.258 uipc_socket.c --- sys/kern/uipc_socket.c 1 Jan 2018 00:45:12 -0000 1.258 +++ sys/kern/uipc_socket.c 3 Jan 2018 10:53:23 -0000 @@ -2113,6 +2113,8 @@ return EINVAL; memcpy(sopt->sopt_data, buf, len); + sopt->sopt_retsize = len; + return 0; } @@ -2176,6 +2178,7 @@ m_copydata(m, 0, len, sopt->sopt_data); m_freem(m); + sopt->sopt_retsize = len; return 0; } Index: sys/kern/uipc_syscalls.c =================================================================== RCS file: /cvsroot/src/sys/kern/uipc_syscalls.c,v retrieving revision 1.189 diff -u -u -r1.189 uipc_syscalls.c --- sys/kern/uipc_syscalls.c 31 Dec 2017 19:39:57 -0000 1.189 +++ sys/kern/uipc_syscalls.c 3 Jan 2018 10:53:24 -0000 @@ -1249,7 +1249,7 @@ goto out; if (valsize > 0) { - len = min(valsize, sopt.sopt_size); + len = min(valsize, sopt.sopt_retsize); error = copyout(sopt.sopt_data, SCARG(uap, val), len); if (error) goto out; Index: share/man/man9/sockopt.9 =================================================================== RCS file: /cvsroot/src/share/man/man9/sockopt.9,v retrieving revision 1.10 diff -u -u -r1.10 sockopt.9 --- share/man/man9/sockopt.9 16 Jan 2017 12:54:25 -0000 1.10 +++ share/man/man9/sockopt.9 3 Jan 2018 10:53:33 -0000 @@ -57,6 +57,7 @@ int sopt_level; /* option level */ int sopt_name; /* option name */ size_t sopt_size; /* data length */ + size_t sopt_retsize; /* returned data length */ void * sopt_data; /* data pointer */ uint8_t sopt_buf[sizeof(int)]; /* internal storage */ }; @@ -133,7 +134,7 @@ which will not fail. .It Fn sockopt_setint "sopt" "value" Common case of set sockopt integer value. -The sockpt structure must contain an int sized data field or be previously +The sockopt structure must contain an int sized data field or be previously unset, in which case the data pointer will be set to the internal storage. .El .Sh CODE REFERENCES -tih -- Most people who graduate with CS degrees don't understand the significance of Lisp. Lisp is the most important idea in computer science. --Alan Kay