diff options
author | Samanta Navarro <ferivoz@riseup.net> | 2024-01-12 11:49:27 +0000 |
---|---|---|
committer | Alejandro Colomar <alx@kernel.org> | 2024-01-16 00:00:43 +0100 |
commit | 1c6a1206bd8bcb674c1f6d2101d2af30bdee6cd6 (patch) | |
tree | 41d2a7c5e514866a62c3fe4a1de2c32210a87ed7 | |
parent | 22656c36a2bb548b2322b8ec2c13bdf45f530c3d (diff) |
lib/sgetgrent.c: fix null pointer dereference
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 45c0003e53ab671c63dcd530fd9f3245d3b29e76 (4.14 release series)
Proof of Concept:
- Prepare a group file (one long group line and a shorter one, both with a list of users)
$ echo -n "root:x:0:" > /tmp/uwu
$ yes , | tr -d '\n' | dd of=/tmp/uwu bs=10 count=3145728 seek=1 conv=notrunc iflag=fullblock
$ echo -e "\nbin:x:1:," >> /tmp/uwu
- Run grpck with tight memory constraints
$ ulimit -d 102400
$ grpck /tmp/uwu
Segmentation fault (core dumped)
Reviewed-by: Alejandro Colomar <alx@kernel.org>
Signed-off-by: Samanta Navarro <ferivoz@riseup.net>
Cherry-picked-from: a9e07c0feb43 ("lib/sgetgrent.c: fix null pointer dereference")
Link: <https://github.com/shadow-maint/shadow/pull/904>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
-rw-r--r-- | lib/sgetgrent.c | 8 |
1 files changed, 5 insertions, 3 deletions
diff --git a/lib/sgetgrent.c b/lib/sgetgrent.c index dde75581..890e18e1 100644 --- a/lib/sgetgrent.c +++ b/lib/sgetgrent.c @@ -37,8 +37,8 @@ static char **list (char *s) { static char **members = NULL; - static int size = 0; /* max members + 1 */ - int i; + static size_t size = 0; /* max members + 1 */ + size_t i; i = 0; for (;;) { @@ -47,8 +47,10 @@ static char **list (char *s) if (i >= size) { size = i + 100; /* at least: i + 1 */ members = REALLOCF(members, size, char *); - if (!members) + if (!members) { + size = 0; return NULL; + } } if (!s || s[0] == '\0') break; |