From 3635004dcd8d0959092f9e5b36a44f6eb177bc1c Mon Sep 17 00:00:00 2001 From: Alan Carvalho de Assis Date: Tue, 28 Jul 2026 04:07:16 -0300 Subject: [PATCH] libs/libc/grp: fix getgrbuf_r() pointer-alignment padding padlen = sizeof(void *) - (addr % sizeof(void *)) never returns 0, even when addr is already pointer-aligned -- it returns a full alignment unit instead. Since callers size buflen for zero padding, the subsequent "buflen < padlen + reqdlen" check then always fails, so getgrgid()/ getgrnam() and their _r variants always return ERANGE. Found via `id` on sim:toybox, which resolves gid 0 to "root" through this path. Signed-off-by: Alan C. Assis Assisted-by: Claude Sonnet 5 --- libs/libc/grp/lib_getgrbufr.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/libs/libc/grp/lib_getgrbufr.c b/libs/libc/grp/lib_getgrbufr.c index 80bbd3b25de..0dd3e2594d8 100644 --- a/libs/libc/grp/lib_getgrbufr.c +++ b/libs/libc/grp/lib_getgrbufr.c @@ -77,7 +77,15 @@ int getgrbuf_r(gid_t gid, FAR const char *name, FAR const char *passwd, namesize = strlen(name) + 1; passwdsize = strlen(passwd) + 1; - padlen = sizeof(FAR void *) - ((uintptr_t)buf % sizeof(FAR char *)); + + /* Bytes needed to round 'buf' up to the next pointer-aligned address. + * The two's-complement modulo trick below yields 0 when 'buf' is + * already aligned; "sizeof(void *) - (addr % sizeof(void *))" (the + * previous formula) does not, always returning a full alignment unit + * in that case, which made the buflen check below always fail. + */ + + padlen = (-(uintptr_t)buf) % sizeof(FAR void *); reqdlen = sizeof(FAR void *) + namesize + passwdsize; if (buflen < padlen + reqdlen)