tech-kern archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: recent sysctl changes



David Laight wrote:
> > Both of these aspects of the API are now broken: reading a 4-byte
> > CTLTYPE_INT variable now works for any buffer size >= 4 *except* 8,
> 
> That wasn't the intent of the change.
> The intent was that if the size was 8 then the code would return
> a numeric value of size 8, otherwise the size would be chnaged to
> 4 and/or ENOMEM (stupid errno choice) returned.

I understand the intent; I'm talking about the unintended consequences.

> > and attempting to read an 8-byte CTLTYPE_QUAD variable into a buffer
> > of less than 8 bytes is now guaranteed to yield ENOMEM *except* if the
> > buffer size happens to be 4.
> 
> A request to read a CTLTYPE_QUAD variable into a buffer that is shorter
> than 8 bytes has always been a programming error.

An application could, for example, maintain a single, shared,
malloc'ed buffer that is reused for multiple sysctl() calls and only
resized on ENOMEM returns.  IMO, this is allowed by the API, but with
your change, a read of a CTLTYPE_QUAD variable will return the wrong
result if the buffer happened to be left with a size of 4 by a
previous read of a CTLTYPE_INT variable.

> The intent of the change was to relax that is the length happened to be 4.
> 
> > IMO, this behavior violates both the
> > letter of the sysctl() man page and the principle of least astonishment.
> 
> I'm not sure about the latter.
> I run 'sysctl -a' and find the name of the sysctl I'm interested in.
> The result is a small number so I pass the address and size of a integer
> variable and then print the result.
> (Or the value is rather large and I think it might exceed 2^31 so I
> use an int64.)
> The 'principle of least astonishment' would mean that I get the value
> that 'sysctl -a' printed.

If you use a C variable of a size different than the documented size
of the sysctl variable in case, your code is incorrect, and the
resulting undefined behavior should not astonish you.

> On a BE system I have to be extremely careful with the return values
> from sysctl() or I see garbage.

Yes, you do have to be careful, and we should not encourage
carelessness by making incorrect code work in more cases.

> Note that code calling systctl() has to either know whether the value
> it is expecting is a string, structure, or number, or use the API calls
> that expose the kernel internals in order to find out.

Not only that, but in the case of a number, it also has to know
whether it's an int or a quad, or use the appropriate API calls to
find out.

> > Also, the work-around is ineffective in the case of a caller that
> > allocates the buffer dynamically using the size given by an initial
> > sysctl() call with oldp = NULL.
> 
> Code that does that for a numeric value will be quite happy with
> either a 32bit of 64bit result.

Not if it is expecting the other one.
-- 
Andreas Gustafsson, gson%NetBSD.org@localhost


Home | Main Index | Thread Index | Old Index