Commit Graph

3280 Commits

Author SHA1 Message Date
Christian Göttsche
7f20bb88ad lib/utmp: merge file access
Avoid checking if the file exists before opening it.

Resolves a CodeQL report of Time-of-check time-of-use filesystem race
condition.
2023-12-14 07:40:40 -06:00
Christian Göttsche
0d7cb003b7 src/useradd: avoid usage of sprintf
sprintf(3) does not take the destination buffer into account. Although
the destination in these case is large enough, sprintf(3) indicates a
code smell.

Use the xasprintf() wrapper.
2023-12-14 07:40:40 -06:00
Christian Göttsche
95a8de2a0a src/usermod,groups: use checked malloc
usermod.c:2165:24: warning: dereference of possibly-NULL ‘user_groups’ [CWE-690] [-Wanalyzer-possible-null-dereference]
2023-12-14 07:40:40 -06:00
Alejandro Colomar
76bbce3564 lib/, src/: Align variable definitions
This is just a cosmetic patch in preparation for others.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2023-12-13 10:06:34 -06:00
Alejandro Colomar
ce0fc161b4 src/login.c: Group preprocessor conditionals
Group them at the end of the list of variable definitions, and use
'#if defined()' instead of '#if[n]def'.  Also indent nested ones.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2023-12-13 09:15:09 -06:00
Tobias Stoeckmann
ab260fcd1f lib/defines.h: Remove ITI_AGING
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>
2023-12-13 09:08:12 -06:00
Alejandro Colomar
ef95bb7ed1 src/su.c: Fix type of variable
su.c:678:26: warning: format ‘%s’ expects argument of type ‘char *’, but argument 4 has type ‘const void *’ [-Wformat=]
su.c:681:44: warning: format ‘%s’ expects argument of type ‘char *’, but argument 3 has type ‘const void *’ [-Wformat=]
su.c:683:46: warning: format ‘%s’ expects argument of type ‘char *’, but argument 3 has type ‘const void *’ [-Wformat=]

Reported-by: Christian Göttsche <cgzones@googlemail.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2023-12-13 09:06:59 -06:00
Alejandro Colomar
9858133cc6 lib/, src/: snprintf(3) already terminates strings with NUL
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>
2023-12-13 12:34:30 +01:00
Alejandro Colomar
93a5c47c2c lib/: Use ATTR_STRING() on stpecpy() and strtcpy()
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>
2023-12-04 12:22:47 +01:00
Alejandro Colomar
a61cf0068b lib/attr.h: Add ATTR_STRING() attribute macro
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>
2023-12-04 12:22:47 +01:00
Alejandro Colomar
1c464d9a2d lib/, src/: Fix error handling after strto[u]l[l](3)
-  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>
2023-12-04 12:21:55 +01:00
Alejandro Colomar
f6701d3efa lib/prefix_flag.c: Invert conditional to remove a branch
This simplifies the code, and is preparation for a following commit.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2023-12-04 12:21:55 +01:00
Alejandro Colomar
ad1e0e9f96 lib/string/strtcpy.h: Don't use a ternary op, to silence a -Wsign-compare warning
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2023-12-04 11:45:09 +01:00
Alejandro Colomar
62772039b7 src/gpasswd.c: Simplify cpp conditional
Since failure() is [[noreturn]], we can invert the conditional so that
we don't need an else.  This silences a -Wunused-parameter warning.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2023-12-04 11:45:09 +01:00
Alejandro Colomar
0c1ca49be3 src/gpasswd.c: Reduce scope of cpp conditional
This prepares for the next patch, which will invert the logic of the
conditional.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2023-12-04 11:45:09 +01:00
Alejandro Colomar
9035f90510 src/gpasswd.c: Mark failure() as [[noreturn]]
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2023-12-04 11:45:09 +01:00
Alejandro Colomar
ccc055d9d9 src/gpasswd.c: Move if out of cpp conditional
This simplifies the code a little bit, and prepares for the next
commits, which will clean up further.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2023-12-04 11:45:09 +01:00
Alejandro Colomar
1fcf807949 src/login_nopam.c: Add missing 'const'
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2023-12-04 11:45:09 +01:00
Alejandro Colomar
d2aa177c50 autogen.sh: CFLAGS: Add -Wno-expansion-to-defined
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2023-12-04 11:45:09 +01:00
Alejandro Colomar
82484117b3 lib/obscure.c: Mark parameter as [[maybe_unused]]
It's only used in certain builds.  This is to silence a -Wunused-parameter warning.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2023-12-04 11:45:09 +01:00
Alejandro Colomar
5ba6cd8545 lib/loginprompt.c: Remove dead code
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2023-12-04 11:45:09 +01:00
Alejandro Colomar
5e0c61cce3 lib/limits.c: Check for overflow without invoking UB
The multiplication was already invoking UB.  The test was flawed.
Use __builtin_mul_overflow() instead.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2023-12-04 11:45:09 +01:00
Alejandro Colomar
9b798b584a lib/limits.c: Fix wrong error check
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>
2023-12-04 11:45:09 +01:00
Alejandro Colomar
00e4e0c735 lib/copydir.c: Cosmetic
I was investigating a warning in this function, but the code was
inscrutable.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2023-12-04 11:45:09 +01:00
Alejandro Colomar
97e9d60133 lib/commonio.c: Use uintmax_t to print nlink_t
See uintmax_t(3type).

While at it, remove the useless cast to (void).

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2023-12-04 11:45:09 +01:00
Alejandro Colomar
6be85b0baf lib/chkname.c: Use tmp variable to avoid a -Wsign-compare warning
I used size_t because:

sysconf(3) can return -1 if the value is not supported, but then it can
only mean that there's no limit.  Having no limit is the same as having
a limit of SIZE_MAX (to which -1 is converted).

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2023-12-04 11:45:09 +01:00
Alejandro Colomar
028e3e2764 autogen.sh: CFLAGS: Add -Wextra
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2023-12-04 11:45:09 +01:00
Alejandro Colomar
fc8389331e lib/string/: Fortify source of strtcpy(), stpecpy(), and zustr2stp()
By writing the terminating null byte via stpcpy(3), we take advantage of
_FORTIFY_SOURCE for the last byte, which was unprotected before this
commit.

Reported-by: Serge Hallyn <serge@hallyn.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2023-12-03 22:24:29 -06:00
Alejandro Colomar
72060a2b2b lib/env.c: Replace strncpy(3) call by stpcpy(mempcpy(), "")
We were using strncpy(3), which is designed to copy from a string into a
(null-padded) fixed-size character array.  However, we were doing the
opposite: copying from a known-size array (which was a prefix of a
string), into a string.  That's why we had to manually zero the buffer
afterwards.

Use instead mempcpy(3) to copy the non-null bytes, and then terminate
with a null byte with stpcpy(..., "").

Cc: "Serge E. Hallyn" <serge@hallyn.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2023-12-03 22:24:29 -06:00
Alejandro Colomar
dbb37b1b31 lib/string/: Move string-related files to string/ subdir
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2023-12-03 12:22:11 -06:00
Alejandro Colomar
d1ad64b40f configure.ac: AM_INIT_AUTOMAKE: Use [subdir-objects]
This will allow using subdirs.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2023-12-03 12:22:11 -06:00
Alejandro Colomar
4f16458b6c lib/, src/: Say 'long' instead of 'long int'
We were using 'long' in most places, so be consistent and use it
everywhere.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2023-12-03 09:58:19 -06:00
Alejandro Colomar
44b8f7b3ef lib/attr.h, lib/, src/: Move attributes to new header file
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2023-12-03 09:56:13 -06:00
Sergei Trofimovich
5abe0811b8 src: add missing declaration of getdef_bool
Upcoming `gcc-14` enabled a few warnings into errors, like
`-Wimplicit-function-declaration`. This caused `shadow` build to fail
as:

    pwunconv.c: In function 'main':
    pwunconv.c:132:13: error: implicit declaration of function 'getdef_bool' [-Wimplicit-function-declaration]
      132 |         if (getdef_bool("USE_TCB")) {
          |             ^~~~~~~~~~~

The change adds missing include headers.
2023-12-02 11:04:35 -06:00
Alejandro Colomar
0d2fa501ec lib/defines.h: Remove condition on __STRICT_ANSI__
We require C11 since a few releases ago.  It seems I missed this
reminder of ANSI C (C89) back then.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2023-11-28 17:00:46 +01:00
Alejandro Colomar
218235e9dd tests/unit/test_chkname.c: Test is_valid_user_name()
Suggested-by: Iker Pedrosa <ipedrosa@redhat.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2023-11-28 16:57:54 +01:00
Tobias Stoeckmann
4b89ac41cb chsh: limit acceptable shells to absolute paths
If an entry in /etc/shells is not an absolute path (comments or
partial reads due to fgets), the line should not be considered as
a valid login shell.

In general all systems should have getusershells, but let's better
be safe than sorry.

Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
2023-11-27 09:16:08 +01:00
Alejandro Colomar
721b9096eb lib/: Use NITEMS() instead of SIZEOF_ARRAY() where number of elements is meant
For arrays of char, both NITEMS() and SIZEOF_ARRAY() return the same
value.  However, NITEMS() is more appropriate.  Think of wide-character
equivalents of the same code; with NITEMS(), they would continue to be
valid, while with SIZEOF_ARRAY(), they would be wrong.

In the implementation of ZUSTR2STP(), we want SIZEOF_ARRAY() within the
static assert, because we're just comparing the sizes of the source and
destination buffers, and we don't care if we compare sizes or numbers of
elements, and using sizes is just simpler.  But we want NITEMS() in the
zustr2stp() call, where we want to copy a specific number of characters.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2023-11-26 21:01:05 -06:00
Alejandro Colomar
a5cddf243a lib/chkname.c: Update regex for valid names
The maximum length of 32 wasn't being enforced in the code, and POSIX
doesn't specify that maximum length either, so it seems it was an
arbitrary limit of the past that doesn't exist any more.  Use a regex
that has no length limit.

Closes: <https://github.com/shadow-maint/shadow/issues/836>
Link: <https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap09.html>
Cc: Iker Pedrosa <ipedrosa@redhat.com>
Cc: Mike Frysinger <vapier@gentoo.org>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2023-11-26 06:56:33 -06:00
Alejandro Colomar
fe62fc48bf tests/unit/test_strncpy.c: Test STRNCPY()
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2023-11-26 06:48:18 -06:00
Alejandro Colomar
ce30dfe255 lib/: Use STRNCPY() instead of strncpy(3)
We've recently fixed several bugs in the calculation of the size in this
function call.  Use this wrapper to prevent similar mistakes in the
future.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2023-11-26 06:48:18 -06:00
Alejandro Colomar
225530b7e1 lib/strncpy.h: Add STRNCPY() wrapper for strncpy(3)
This wrapper calculates the destination buffer's size, to avoid errors
in the size calculation.

A curious fact: this macro did exist in Version 7 Unix (with a slightly
different name).  I found it by chance, investigating the origins of
strncpy(3) and strncat(3) in V7, after Branden suggested me to do so,
related to recent discussions about string_copying(7).

	alx@debian:~/src/unix/unix/Research-V7$ grepc SCPYN .
	./usr/src/cmd/login.c:#define SCPYN(a, b)	strncpy(a, b, sizeof(a))

Our implementation is slightly better, because using nitems() we're
protected against passing a pointer instead of an array, and it's also
conceptually more appropriate: for wide characters, it would be

	#define WCSNCPY(dst, src)  wcsncpy(dst, src, NITEMS(dst))

Cc: "G. Branden Robinson" <branden@debian.org>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2023-11-26 06:48:18 -06:00
Alejandro Colomar
07ab1af55c lib/: Remove off-by-one bugs in calls to strncpy(3)
We're not even zeroing the last byte after this call.  This was a
completely gratuitous truncation of one byte, and the resulting
character array still wasn't guaranteed to be null terminated, because
strncpy(3) can't do that.

Just to clarify, none of these structures needed zeroing, as they are
treated as null-padded fixed-size character arrays.  Calling strncpy(3)
was actually the correct call, and the only problem was unnecessarily
truncating strings by one byte more than necessary.

Cc: Matthew House <mattlloydhouse@gmail.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2023-11-26 06:48:18 -06:00
Alejandro Colomar
81f0e6a30f lib/log.c: Replace strncpy(3) call by STRTCPY()
This call was too clever.  It relied on the last byte of ll_line
being 0 due to a previous memzero() and not writing to it later.
Write an explicit terminating null byte, by using STRTCPY().

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2023-11-26 06:48:18 -06:00
Alejandro Colomar
09957c6d27 lib/failure.c: Replace strncpy(3) call by STRTCPY()
This call was way too clever.  It relied on the last byte of fail_line
being 0 due to it being in a static structure and never writing to it.
Write an explicit terminating null byte, by using STRTCPY().

Cc: Matthew House <mattlloydhouse@gmail.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2023-11-26 06:48:18 -06:00
Alejandro Colomar
8a1a097afa lib/utmp.c: Replace strncpy(3) call by ZUSTR2STP()
We were copying from a (zero-padded) fixed-width character array to a
string, but strncpy(3) is meant to do the opposite thing.  ZUSTR2STP()
is designed to be used in this case (like strncat(3)).

Fixes: f40bdfa66a ("libmisc: implement `get_session_host()`")
Cc: Iker Pedrosa <ipedrosa@redhat.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2023-11-26 06:48:18 -06:00
Alejandro Colomar
751f8e055b tests/: Remove references to cracklib
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2023-11-25 21:24:38 -06:00
Alejandro Colomar
45f34ee8c1 Remove libcrack support
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2023-11-25 21:24:38 -06:00
Alejandro Colomar
43b4e5a6c4 Remove FascistHistory() and FascistHistoryPw() calls
These functions don't seem to exist anymore.  I can't find them in
Debian, nor in a web search.  They probably were functions from an
ancient implementation of cracklib that doesn't exist anymore.

$ git remote -v
origin	git@github.com:cracklib/cracklib.git (fetch)
origin	git@github.com:cracklib/cracklib.git (push)
$ grep -rni fascisthistory
$ git log --grep FascistHistory
$ git log -S FascistHistory

Closes: <https://codesearch.debian.net/search?q=FascistHistory&literal=1>
Cc: Mike Frysinger <vapier@gentoo.org>
Acked-by: Michael Vetter <jubalh@iodoru.org>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2023-11-25 21:24:38 -06:00
Alejandro Colomar
1c50a44db6 lib/date_to_str.c: strftime(3) leaves the buffer undefined on failure
strftime(3) makes no guarantees about the contents of the buffer if the
formatted string wouldn't fit in the buffer.  It simply returns 0, and
it's the programmer's responsibility to do the right thing after that.

Let's write the string "future" if there's an error, similar to what we
do with gmtime(3)'s errors.

Also, `buf[size - 1] = '\0';` didn't make sense.  If the copy fits,
strftime(3) guarantees to terminate with NUL.  If it doesn't, the entire
contents of buf are undefined, so adding a NUL at the end of the buffer
would be dangerous: the string could contain anything, such as
"gimme root access now".  Remove that, now that we set the string to
"future", as with gmtime(3) errors.  This setting to '\0' comes from the
times when we used strncpy(3) in the implementation, and should have
been removed when I changed it to use strlcpy(3); however, I didn't
check we didn't need it anymore.

Cc: Serge Hallyn <serge@hallyn.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2023-11-23 08:04:39 -06:00