The SIGCHLD handler could have been ignored by parent process.
Make sure that we have default handling activated.
Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
This conforms to PAM documentation and it is needed to support
ambient capabilities with PAM + libcap-2.58+.
Signed-off-by: Björn Fischer <bf@CeBiTec.Uni-Bielefeld.DE>
Rename libsubid symbols to all be prefixed with subid_.
Don't export anything but the subid_*.
Closes#443
Signed-off-by: Serge Hallyn <serge@hallyn.com>
Rename list_subid_ranges to getsubids to provide a system binary to
check the sub*ids of a user. The intention is to provide this binary
with any distribution that includes the subid feature, so that system
administrators can check the subid ranges of a given user.
Finally, add a man page to explain the behaviour of getsubids.
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1980780
Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
As shadow_logfd variable is not set at the beginning of the program if
something fails and fprintf() is called a segmentation fault happens.
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2021339
Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
Always set SIGCHLD handler to default, even if the caller of vipw has
set SIGCHLD to ignore. If SIGCHLD is ignored no zombie processes would
be created, which in turn could mean that kill is called with an already
recycled pid.
Proof of Concept:
1. Compile nochld:
--
#include <signal.h>
#include <unistd.h>
int main(void) {
char *argv[] = { "vipw", NULL };
signal(SIGCHLD, SIG_IGN);
execvp("vipw", argv);
return 1;
}
--
2. Run nochld
3. Suspend child vi, which suspends vipw too:
`kill -STOP childpid`
4. Kill vi:
`kill -9 childpid`
5. You can see with ps that childpid is no zombie but disappeared
6. Bring vipw back into foreground
`fg`
The kill call sends SIGCONT to "childpid" which in turn could have been
already recycled for another process.
This is definitely not a vulnerability. It would take super user
operations, at which point an attacker would have already elevated
permissions.
Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
Change SELinux labels for files copied from the skeleton directory to
the home directory.
This could cause gnome's graphical user adding to fail without copying
the full skeleton files.
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2022658
Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
Fix segmentation fault in newgrp when xgetspnam() returns a NULL value
that is immediately freed.
The error was committed in
e65cc6aebc
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2019553
Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
Create the home and mail folders after the SELinux user has been set for
the added user. This will allow the folders to be created with the
SELinux user label.
Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
The buggy code was introduced nearly 5 years ago at the
commit 08fd4b69e8. The
desired behavior is that SIGKILL will be sent to the
child if it does not exit within 2 seconds after it
receives SIGTERM. However, SIGALRM is masked while
waiting for the child so it cannot wake the program
up after 2 seconds to send SIGKILL.
An example shows the buggy behavior, which exists in
Ubuntu 18.04 LTS (with login 1:4.5-1ubuntu2).
```bash
user1@localhost:~$ su user2 -c '
_term() {
echo SIGTERM received
}
trap _term TERM
while true; do
sleep 1
echo still alive
done'
Password:
still alive
Session terminated, terminating shell...Terminated
SIGTERM received
still alive
still alive
still alive
still alive
```
(SIGTERM is sent in another user1's terminal by
executing `killall su`.)
Here is the desired behavior, which shows what the
commit fixes.
```bash
user1@localhost:~$ su user2 -c '
_term() {
echo SIGTERM received
}
trap _term TERM
while true; do
sleep 1
echo still alive
done'
Password:
still alive
Session terminated, terminating shell...Terminated
SIGTERM received
still alive
still alive
...killed.
user1@localhost:~$ echo $?
255
```
In some circumstances I want the default behaviour of useradd to
not add user entries to the lastlog and faillog databases. Allowing
this options behaviour to be controlled by the config file
/etc/default/useradd.
`sgent` is only initialized in `get_group()` if `is_shadowgrp` is true.
So we should also only attempt to free it if this is actually the case.
Can otherwise lead to:
```
free() double free detected in tcache 2 (gpasswd)
```
subuid_count won't get used by usr_update(), but since we're passing it
as an argument we have to make sure it's always defined. So just define
it as pre-set to 0.
Closes#402
Signed-off-by: Serge Hallyn <serge@hallyn.com>
useradd generates an empty subid range when adding a new user. This is
caused because there are two variables, one local and the other one
global, that have a very similar name and they are used indistinctly in
the code. The local variable loads the SUB_*ID_COUNT configuration from
the login.defs file, while the global variable, which holds a value of
0, is used to generate the subid range. Causing the empty subid range
problem.
I've merged the two variables in the local one and removed the global
variable. I prefer to do it this way to reduce the scope of it but I'm
open to doing it the other way round.
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1990653
Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
When the -S and -a options are used for passwd to list the status
of all passwords, there is a chance the pw_passwd field of struct
passwd will be NULL. This can be due to 'files compat' being set
for passwd in /etc/nsswitch.conf and the usage of some features
not available in the 'files' mode (e.g. a plus sign at the start
of a line).
Example:
germ161:~ # grep passwd /etc/nsswitch.conf
passwd: files compat
germ161:~ # rpm -qa shadow
shadow-4.2.1-34.20.x86_64
germ161:~ # grep passwd /etc/nsswitch.conf
passwd: files compat
germ161:~ # grep + /etc/passwd
+@nisgroup
germ161:~ # passwd -S -a > /dev/null
Segmentation fault (core dumped)
With this commit:
germ161:~ # passwd -S -a > /dev/null
passwd: malformed password data obtained for user +@nisgroup
The only way of removing a group from the supplementary list is to use
-G option, and list all groups that the user is a member of except for
the one that wants to be removed. The problem lies when there's a user
that contains both local and remote groups, and the group to be removed
is a local one. As we need to include the remote group with -G option
the command will fail.
This reverts commit 140510de9d. This way,
it would be possible to remove the remote groups from the supplementary
list.
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1967641
Resolves: https://github.com/shadow-maint/shadow/issues/338
Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
new*idmap has a dependency with libeconf since commit
c464ec5570. I'm just adding it to the
Makefile to be able to compile in distributions that include libeconf.
Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
Since bbf4b79, we stopped shipping /etc/default/useradd, and therefore
install of shadow does not auto-create /etc/default. So when useradd
tries to save a new default, it needs to create the directory.
Closes#390.
Signed-off-by: Serge Hallyn <serge@hallyn.com>
There's a better way to do this, and I hope to clean that up,
but this fixes out of tree builds for me right now.
Closes#386
Signed-off-by: Serge Hallyn <serge@hallyn.com>
Error: RESOURCE_LEAK (CWE-772): [#def1]
shadow-4.8.1/lib/commonio.c:320: alloc_fn: Storage is returned from allocation function "fopen_set_perms".
shadow-4.8.1/lib/commonio.c:320: var_assign: Assigning: "bkfp" = storage returned from "fopen_set_perms(backup, "w", &sb)".
shadow-4.8.1/lib/commonio.c:329: noescape: Resource "bkfp" is not freed or pointed-to in "putc".
shadow-4.8.1/lib/commonio.c:334: noescape: Resource "bkfp" is not freed or pointed-to in "fflush".
shadow-4.8.1/lib/commonio.c:339: noescape: Resource "bkfp" is not freed or pointed-to in "fileno".
shadow-4.8.1/lib/commonio.c:342: leaked_storage: Variable "bkfp" going out of scope leaks the storage it points to.
340| || (fclose (bkfp) != 0)) {
341| /* FIXME: unlink the backup file? */
342|-> return -1;
343| }
344|
Error: RESOURCE_LEAK (CWE-772): [#def2]
shadow-4.8.1/libmisc/addgrps.c:69: alloc_fn: Storage is returned from allocation function "malloc".
shadow-4.8.1/libmisc/addgrps.c:69: var_assign: Assigning: "grouplist" = storage returned from "malloc(i * 4UL)".
shadow-4.8.1/libmisc/addgrps.c:73: noescape: Resource "grouplist" is not freed or pointed-to in "getgroups". [Note: The source code implementation of the function has been overridden by a builtin model.]
shadow-4.8.1/libmisc/addgrps.c:126: leaked_storage: Variable "grouplist" going out of scope leaks the storage it points to.
124| }
125|
126|-> return 0;
127| }
128| #else /* HAVE_SETGROUPS && !USE_PAM */
Error: RESOURCE_LEAK (CWE-772): [#def3]
shadow-4.8.1/libmisc/chowntty.c:62: alloc_fn: Storage is returned from allocation function "getgr_nam_gid".
shadow-4.8.1/libmisc/chowntty.c:62: var_assign: Assigning: "grent" = storage returned from "getgr_nam_gid(getdef_str("TTYGROUP"))".
shadow-4.8.1/libmisc/chowntty.c:98: leaked_storage: Variable "grent" going out of scope leaks the storage it points to.
96| */
97| #endif
98|-> }
99|
Error: RESOURCE_LEAK (CWE-772): [#def4]
shadow-4.8.1/libmisc/copydir.c:742: open_fn: Returning handle opened by "open". [Note: The source code implementation of the function has been overridden by a user model.]
shadow-4.8.1/libmisc/copydir.c:742: var_assign: Assigning: "ifd" = handle returned from "open(src, 0)".
shadow-4.8.1/libmisc/copydir.c:748: leaked_handle: Handle variable "ifd" going out of scope leaks the handle.
746| #ifdef WITH_SELINUX
747| if (set_selinux_file_context (dst, NULL) != 0) {
748|-> return -1;
749| }
750| #endif /* WITH_SELINUX */
Error: RESOURCE_LEAK (CWE-772): [#def5]
shadow-4.8.1/libmisc/copydir.c:751: open_fn: Returning handle opened by "open". [Note: The source code implementation of the function has been overridden by a user model.]
shadow-4.8.1/libmisc/copydir.c:751: var_assign: Assigning: "ofd" = handle returned from "open(dst, 577, statp->st_mode & 0xfffU)".
shadow-4.8.1/libmisc/copydir.c:752: noescape: Resource "ofd" is not freed or pointed-to in "fchown_if_needed".
shadow-4.8.1/libmisc/copydir.c:775: leaked_handle: Handle variable "ofd" going out of scope leaks the handle.
773| ) {
774| (void) close (ifd);
775|-> return -1;
776| }
777|
Error: RESOURCE_LEAK (CWE-772): [#def7]
shadow-4.8.1/libmisc/idmapping.c:188: alloc_fn: Storage is returned from allocation function "xmalloc".
shadow-4.8.1/libmisc/idmapping.c:188: var_assign: Assigning: "buf" = storage returned from "xmalloc(bufsize)".
shadow-4.8.1/libmisc/idmapping.c:188: var_assign: Assigning: "pos" = "buf".
shadow-4.8.1/libmisc/idmapping.c:213: noescape: Resource "buf" is not freed or pointed-to in "write".
shadow-4.8.1/libmisc/idmapping.c:219: leaked_storage: Variable "pos" going out of scope leaks the storage it points to.
shadow-4.8.1/libmisc/idmapping.c:219: leaked_storage: Variable "buf" going out of scope leaks the storage it points to.
217| }
218| close(fd);
219|-> }
Error: RESOURCE_LEAK (CWE-772): [#def8]
shadow-4.8.1/libmisc/list.c:211: alloc_fn: Storage is returned from allocation function "xstrdup".
shadow-4.8.1/libmisc/list.c:211: var_assign: Assigning: "members" = storage returned from "xstrdup(comma)".
shadow-4.8.1/libmisc/list.c:217: var_assign: Assigning: "cp" = "members".
shadow-4.8.1/libmisc/list.c:218: noescape: Resource "cp" is not freed or pointed-to in "strchr".
shadow-4.8.1/libmisc/list.c:244: leaked_storage: Variable "cp" going out of scope leaks the storage it points to.
shadow-4.8.1/libmisc/list.c:244: leaked_storage: Variable "members" going out of scope leaks the storage it points to.
242| if ('\0' == *members) {
243| *array = (char *) 0;
244|-> return array;
245| }
246|
Error: RESOURCE_LEAK (CWE-772): [#def11]
shadow-4.8.1/libmisc/myname.c:61: alloc_fn: Storage is returned from allocation function "xgetpwnam".
shadow-4.8.1/libmisc/myname.c:61: var_assign: Assigning: "pw" = storage returned from "xgetpwnam(cp)".
shadow-4.8.1/libmisc/myname.c:67: leaked_storage: Variable "pw" going out of scope leaks the storage it points to.
65| }
66|
67|-> return xgetpwuid (ruid);
68| }
69|
Error: RESOURCE_LEAK (CWE-772): [#def12]
shadow-4.8.1/libmisc/user_busy.c:260: alloc_fn: Storage is returned from allocation function "opendir".
shadow-4.8.1/libmisc/user_busy.c:260: var_assign: Assigning: "task_dir" = storage returned from "opendir(task_path)".
shadow-4.8.1/libmisc/user_busy.c:262: noescape: Resource "task_dir" is not freed or pointed-to in "readdir".
shadow-4.8.1/libmisc/user_busy.c:278: leaked_storage: Variable "task_dir" going out of scope leaks the storage it points to.
276| _("%s: user %s is currently used by process %d\n"),
277| Prog, name, pid);
278|-> return 1;
279| }
280| }
Error: RESOURCE_LEAK (CWE-772): [#def20]
shadow-4.8.1/src/newgrp.c:162: alloc_fn: Storage is returned from allocation function "xgetspnam".
shadow-4.8.1/src/newgrp.c:162: var_assign: Assigning: "spwd" = storage returned from "xgetspnam(pwd->pw_name)".
shadow-4.8.1/src/newgrp.c:234: leaked_storage: Variable "spwd" going out of scope leaks the storage it points to.
232| }
233|
234|-> return;
235|
236| failure:
Error: RESOURCE_LEAK (CWE-772): [#def21]
shadow-4.8.1/src/passwd.c:530: alloc_fn: Storage is returned from allocation function "xstrdup".
shadow-4.8.1/src/passwd.c:530: var_assign: Assigning: "cp" = storage returned from "xstrdup(crypt_passwd)".
shadow-4.8.1/src/passwd.c:551: noescape: Resource "cp" is not freed or pointed-to in "strlen".
shadow-4.8.1/src/passwd.c:554: noescape: Resource "cp" is not freed or pointed-to in "strcat". [Note: The source code implementation of the function has been overridden by a builtin model.]
shadow-4.8.1/src/passwd.c:555: overwrite_var: Overwriting "cp" in "cp = newpw" leaks the storage that "cp" points to.
553| strcpy (newpw, "!");
554| strcat (newpw, cp);
555|-> cp = newpw;
556| }
557| return cp;
Error: RESOURCE_LEAK (CWE-772): [#def28]
shadow-4.8.1/src/useradd.c:1905: open_fn: Returning handle opened by "open". [Note: The source code implementation of the function has been overridden by a user model.]
shadow-4.8.1/src/useradd.c:1905: var_assign: Assigning: "fd" = handle returned from "open("/var/log/faillog", 2)".
shadow-4.8.1/src/useradd.c:1906: noescape: Resource "fd" is not freed or pointed-to in "lseek".
shadow-4.8.1/src/useradd.c:1917: leaked_handle: Handle variable "fd" going out of scope leaks the handle.
1915| /* continue */
1916| }
1917|-> }
1918|
1919| static void lastlog_reset (uid_t uid)
Error: RESOURCE_LEAK (CWE-772): [#def29]
shadow-4.8.1/src/useradd.c:1938: open_fn: Returning handle opened by "open". [Note: The source code implementation of the function has been overridden by a user model.]
shadow-4.8.1/src/useradd.c:1938: var_assign: Assigning: "fd" = handle returned from "open("/var/log/lastlog", 2)".
shadow-4.8.1/src/useradd.c:1939: noescape: Resource "fd" is not freed or pointed-to in "lseek".
shadow-4.8.1/src/useradd.c:1950: leaked_handle: Handle variable "fd" going out of scope leaks the handle.
1948| /* continue */
1949| }
1950|-> }
1951|
1952| static void tallylog_reset (const char *user_name)
Error: RESOURCE_LEAK (CWE-772): [#def30]
shadow-4.8.1/src/useradd.c:2109: alloc_fn: Storage is returned from allocation function "strdup".
shadow-4.8.1/src/useradd.c:2109: var_assign: Assigning: "bhome" = storage returned from "strdup(prefix_user_home)".
shadow-4.8.1/src/useradd.c:2131: noescape: Resource "bhome" is not freed or pointed-to in "strtok".
shadow-4.8.1/src/useradd.c:2207: leaked_storage: Variable "bhome" going out of scope leaks the storage it points to.
2205| }
2206| #endif
2207|-> }
2208| }
2209|
Error: RESOURCE_LEAK (CWE-772): [#def31]
shadow-4.8.1/src/usermod.c:813: alloc_fn: Storage is returned from allocation function "__gr_dup".
shadow-4.8.1/src/usermod.c:813: var_assign: Assigning: "ngrp" = storage returned from "__gr_dup(grp)".
shadow-4.8.1/src/usermod.c:892: leaked_storage: Variable "ngrp" going out of scope leaks the storage it points to.
890| }
891| }
892|-> }
893|
894| #ifdef SHADOWGRP
Error: RESOURCE_LEAK (CWE-772): [#def32]
shadow-4.8.1/src/usermod.c:933: alloc_fn: Storage is returned from allocation function "__sgr_dup".
shadow-4.8.1/src/usermod.c:933: var_assign: Assigning: "nsgrp" = storage returned from "__sgr_dup(sgrp)".
shadow-4.8.1/src/usermod.c:1031: leaked_storage: Variable "nsgrp" going out of scope leaks the storage it points to.
1029| }
1030| }
1031|-> }
1032| #endif /* SHADOWGRP */
1033|
Error: RESOURCE_LEAK (CWE-772): [#def34]
shadow-4.8.1/src/usermod.c:1161: alloc_fn: Storage is returned from allocation function "getgr_nam_gid".
shadow-4.8.1/src/usermod.c:1161: var_assign: Assigning: "grp" = storage returned from "getgr_nam_gid(optarg)".
shadow-4.8.1/src/usermod.c:1495: leaked_storage: Variable "grp" going out of scope leaks the storage it points to.
1493| }
1494| #endif /* ENABLE_SUBIDS */
1495|-> }
1496|
1497| /*
Error: RESOURCE_LEAK (CWE-772): [#def35]
shadow-4.8.1/src/usermod.c:1991: open_fn: Returning handle opened by "open". [Note: The source code implementation of the function has been overridden by a user model.]
shadow-4.8.1/src/usermod.c:1991: var_assign: Assigning: "fd" = handle returned from "open("/var/log/lastlog", 2)".
shadow-4.8.1/src/usermod.c:2000: noescape: Resource "fd" is not freed or pointed-to in "lseek".
shadow-4.8.1/src/usermod.c:2000: noescape: Resource "fd" is not freed or pointed-to in "read". [Note: The source code implementation of the function has been overridden by a builtin model.]
shadow-4.8.1/src/usermod.c:2003: noescape: Resource "fd" is not freed or pointed-to in "lseek".
shadow-4.8.1/src/usermod.c:2032: leaked_handle: Handle variable "fd" going out of scope leaks the handle.
2030| }
2031| }
2032|-> }
2033|
2034| /*
Error: RESOURCE_LEAK (CWE-772): [#def36]
shadow-4.8.1/src/usermod.c:2052: open_fn: Returning handle opened by "open". [Note: The source code implementation of the function has been overridden by a user model.]
shadow-4.8.1/src/usermod.c:2052: var_assign: Assigning: "fd" = handle returned from "open("/var/log/faillog", 2)".
shadow-4.8.1/src/usermod.c:2061: noescape: Resource "fd" is not freed or pointed-to in "lseek".
shadow-4.8.1/src/usermod.c:2061: noescape: Resource "fd" is not freed or pointed-to in "read". [Note: The source code implementation of the function has been overridden by a builtin model.]
shadow-4.8.1/src/usermod.c:2064: noescape: Resource "fd" is not freed or pointed-to in "lseek".
shadow-4.8.1/src/usermod.c:2092: leaked_handle: Handle variable "fd" going out of scope leaks the handle.
2090| }
2091| }
2092|-> }
2093|
2094| #ifndef NO_MOVE_MAILBOX
Closes#331
1. drop 'has_any_range' nss method as it is not useful
2. do not try to create a subid range in newusers when using nss for
subids, since that's not possible.
Signed-off-by: Serge Hallyn <serge@hallyn.com>
(cherry picked from commit 88a434adbdcf4a8640793fd58bcd2ba77598349d)
Following alexey-tikhonov's suggestion.
Since we've dropped the 'owner' field in the data returned for
get_subid_ranges, we can just return a single allocated array of
simple structs. This means we can return a ** instead of ***, and
we can get rid of the subid_free_ranges() helper, since the caller
can just free() the returned data.
Signed-off-by: Serge Hallyn <serge@hallyn.com>
Closes: 339
struct subordinate_range is pretty closely tied to the existing
subid code and /etc/subuid format, so it includes an owner. Dropping
that or even renaming it is more painful than I'd first thought.
So introduce a 'struct subid_range' which is only the start and
count, leaving 'struct subordinate_range' as the owner, start and
count.
Signed-off-by: Serge Hallyn <serge@hallyn.com>