This patch ensures that ulimits parses the K= value properly, and
sets the umask for its own process accordingly. This has no effect
when ulimits is called to set limits on its parent process (since
there's no way to modify the umask of any other process than our
own process), but at least it allows to honor the K= value when
ulimits is called in "exec" mode.
Only a single line (be it a user-matching, @group-matching, or
default line) is to be considered, even if there is several lines
for that user (in that case, only the first line rules) or several
lines for the group(s) the user belongs to (in that case, only the
last line rules).
There’s nothing in limits(5) suggesting that limits from several
matching lines should be merged together, and indeed that’s not the
behavior of /bin/login.
As per the limits(5) man page:
“If more than one line with limits for an user exist, only the
first line for this user will be considered.
If no lines are specified for an user, the last @group line matching
a group whose the user is a member of will be considered, or the
last line with default limits if no groups contain the user.”
So wo may stop parsing the limits file as soon as we have a line
matching the username. On the other hand, without a user-matching
line, we must continue parsing until EOF so that we have the last
default or @group-matching line, if any.
The special -1 value in the rlimit_setting array was only
initialized when actually parsing a limit string, but not when
no limit string was found. This resulted in the program walking
through unitialized memory when the /etc/limits file contained
no limit string for the calling user and no default string.