While testing the example code in the sysctl(3) man page,
sbruno noticed user.cs_path was empty (see
https://lists.freebsd.org/pipermail/freebsd-hackers/2015-June/047901.html).
It turns out sysctl(3) has been broken (returning empy/zero for all
'user.' names) since r240176 (that is, for nearly three
years). r240176 assumed that because all values in the user mib are
being supplied by sysctl(3), the __sysctl() call would result in
ENOENT for all user mib names. However, this is not the case, as
there is a dummy entry in the sysctl tree for every valid user mib
name to support name lookups and enumeration.
Another bug (hidden by the first one) was also introduced by r240176.
In using __sysctl() to validate that the supplied name was not NULL or
zero length, in the case of a valid user mib name, the length supplied
by the caller in oldlenp is overwritten with the length of the dummy
entry. When the user mib name is of string type, this always results
in a zero length in oldlenp in the value retrieval logic that follows,
causing sysctl(3) to fail with ENOMEM regardless of how much space the
caller provides.
These bugs are fixed by this patch.
I grepped base and ports for occurences of '[[:space:]'"]user' on the
same line as 'sysctl', as well as for any occurrences of CTL_USER.
The only hit was in usr.bin/whereis, whose behavior would be affected
by these bugs if PATH had been modified to not include the default
path contained in user.cs_path. It is of course possible that there
are indirect retrievals of user mib names that would not be found by
the above searches.