Uses of this macro indicate a code smell, but in some cases, libc
functions require breaking const correctness. Use this macro to wrap
casts in such cases, so that we limit the danger of the cast.
It only permits discarding const. Discarding any other qualifiers, or
doing other type changes should result in a compile-time error.
Link: <https://software.codidact.com/posts/286575/287345#answer-287345>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
strtou[l]l(3) silently converts negative numbers into positive. This
behavior is wrong: a negative value should be parsed as a negative
value, which would underflow unsigned (long) long, and so would return
the smallest possible value, 0, and set errno to ERANGE to report an
error.
Reviewed-by: Iker Pedrosa <ipedrosa@redhat.com>
Cc: "Serge E. Hallyn" <serge@hallyn.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
These functions reject negative numbers, instead of silently converting
them into unsigned, which strtou[l]l(3) do.
Reviewed-by: Iker Pedrosa <ipedrosa@redhat.com>
Cc: "Serge E. Hallyn" <serge@hallyn.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
Add a variadic macro addsl() that accepts an arbitrary number of
addends, instead of having specific versions like addsl2() or addsl3().
It is internally implemented by the addslN() function, which itself
calls addsl2(). addsl3() is now obsolete and thus removed.
Code should just call addsl().
Link: <https://github.com/shadow-maint/shadow/pull/882#discussion_r1437155212>
Cc: Serge Hallyn <serge@hallyn.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
This is for consistency with addsl3(), and in preparation for the
following commit, which will unify the interface into a single addsl()
macro.
Signed-off-by: Alejandro Colomar <alx@kernel.org>
ISO C guarantees that #undef is a no-op if there is no such macro.
C11::6.10.3.5p2:
> A preprocessing directive of the form
>
> # undef identifier new-line
>
> causes the specified identifier no longer to be defined as a macro
> name. It is ignored if the specified identifier is not currently
> defined as a macro name.
Link: <http://port70.net/~nsz/c/c11/n1570.html#6.10.3.5p2>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
These functions (e.g., gr_free()), explicitly dereference the pointer
and read the pointee.
The /@out@/ comment, which is (almost) analogous to the
[[gnu::access(write_only, ...)]] attribute, means that the pointee can
be uninitialized, since it won't read it. There's a difference between
/@out@/ and the GCC attribute: the attribute doesn't require that the
call writes to the pointee, while /@out@/ requires that the pointee be
fully initialized after the call, so it _must_ write to it.
A guess of why it was used is that these functions are similar to
free(3), which does not read the memory it frees, and so one would
assume that if it doesn't read, write_only (or equivalents) are good.
That's wrong in several ways:
- free(3) does not read _nor_ write to the memory, so it would
be slightly inappropriate to use write_only with it. It wouldn't be
"wrong", but [[gnu::access(none, ...)]] would be more appropriate.
- Because /@out@/ requires that the call writes to the pointee, it
would be wrong to use it in free(3), which doesn't write to the
pointee.
- Our functions are similar to free(3) conceptually, but they don't
behave like free(3), since they do read the memory (pointee) (and
also write to it), and thus they're actually read_write.
Link: <https://splint.org/manual/manual.html#undefined>
Cc: Serge Hallyn <serge@hallyn.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
If reallocation fails in function list, then reset the size to 0 again.
Without the reset, the next call assumes that `members` points to
a memory location with reserved space.
Also use size_t instead of int for size to prevent signed integer
overflows. The length of group lines is not limited.
Fixes 45c0003e53 (4.14 release series)
Reviewed-by: Alejandro Colomar <alx@kernel.org>
Signed-off-by: Samanta Navarro <ferivoz@riseup.net>
Special care has to be taken for 32 bit systems with a 64 bit time_t,
since their long data type is still 32 bit.
Since this macro expresses a number of seconds, and seconds are in units
of 'time_t' in C, the appropriate type for the multiplication is
'time_t'.
Reported-by: Tobias Stoeckmann <tobias@stoeckmann.org>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
The values are retrieved from login.defs files, which normally do not
contain negative values. In fact, negative value -1 is used in many
code places as "feature disabled", which is normally achieved by
simply commenting out the key from the file.
Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
The variable declarations for the buffers have been aligned in this
commit, so that they appear in the diff, making it easier to review.
Some important but somewhat tangent changes included in this commit:
- lib/nss.c: The size was being defined as 65, but then used as 64.
That was a bug, although not an important one; we were just wasting
one byte. Fix that while we replace snprintf() by SNPRINTF(), which
will get the size from sizeof(), and thus will use the real size.
Signed-off-by: Alejandro Colomar <alx@kernel.org>
These functions are like [v]snprintf(3), but return -1 on truncation,
which makes it easier to test. In fact, the API of swprintf(3), which
was invented later than snprintf(3), and is the wide-character version
of it, is identical to this snprintf_().
snprintf(3) is iseful in two cases:
- We don't care if the output is truncated. snprintf(3) is fine for
those, and the return value can be ignored. But snprintf_() is also
fine for those.
- Truncation is bad. In that case, it's as bad as a hard error (-1)
from snprintf, so merging both problems into the same error code
makes it easier to handle errors. Return the length if no truncation
so that we can use it if necessary.
Not returning the whole length before truncation makes a better API,
which need not read the entire input, so it's less vulnerable to DoS
attacks when a malicious user controls the input.
Use these functions to implement SNPRINTF().
Cc: Samanta Navarro <ferivoz@riseup.net>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
It wraps snprintf(3) so that it performs some steps that one might
forget, or might be prone to accidents:
- It calculates the size of the destination buffer, and makes sure it's
an array (otherwise, using sizeof(s) would be very bad).
- It calculates if there's truncation or an error, returning -1 if so.
BTW, this macro doesn't have any issues of double evaluation, because
sizeof() doesn't evaluate its argument (unless it's a VLA, but then the
static_assert(3) within NITEMS() makes sure VLAs are not allowed).
This macro is very similar to STRTCPY(), defined in
<lib/string/strtcpy.h>.
Signed-off-by: Alejandro Colomar <alx@kernel.org>
commonio.c: In function 'commonio_unlock':
commonio.c:487:49: warning: '.lock' directive output may be truncated writing 5 bytes into a region of size between 1 and 1024 [-Wformat-truncation=]
487 | snprintf (lock, sizeof lock, "%s.lock", db->filename);
| ^~~~~
commonio.c:487:17: note: 'snprintf' output between 6 and 1029 bytes into a destination of size 1024
487 | snprintf (lock, sizeof lock, "%s.lock", db->filename);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Check for close(2) failure at more places closing a file descriptor
written to.
Also ignore failures with errno set to EINTR (see man:close(2) for
details).
ITI_AGING is not set through any build environment. If it would be set,
then timings in /etc/shadow would not fit anymore.
Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
We don't need to terminate them manually after the call. Remove all
that paranoid code, which in some cases was even wrong. While at it,
let's do a few more things:
- Use sizeof(buf) for the size of the buffer. I found that a few cases
were passing one less byte (probably because the last one was
manually zeroed later). This caused a double NUL. snprintf(3) wants
the size of the entire buffer to properly terminate it. Passing the
exact value hardcoded is brittle, so use sizeof().
- Align and improve style of variable declarations. This makes them
appear in this diff, which will help review the patch.
Signed-off-by: Alejandro Colomar <alx@kernel.org>
These functions consume a source string. Document that. There's no way
to mark that they also produce a string in dst, though. That will be up
to the static analyzer to guess.
Signed-off-by: Alejandro Colomar <alx@kernel.org>
It signals that a function parameter is a string _before_ the call.
Suggested-by: Serge Hallyn <serge@hallyn.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
- Set errno = 0 before the call. Otherwise, it may contain anything.
- ERANGE is not the only possible errno value of these functions. They
can also set it to EINVAL.
- Any errno value after these calls is bad; just compare against 0.
- Don't check for the return value; just errno. This function is
guaranteed to not modify errno on success (POSIX).
- Check endptr == str, which may or may not set EINVAL.
Suggested-by: Iker Pedrosa <ipedrosa@redhat.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
The multiplication was already invoking UB. The test was flawed.
Use __builtin_mul_overflow() instead.
Signed-off-by: Alejandro Colomar <alx@kernel.org>
strtol(3) doesn't specify a return value if (value == endptr).
It is always an error, if (value==endptr).
Signed-off-by: Alejandro Colomar <alx@kernel.org>