From: Tobias Stoeckmann Date: Sat, 27 Dec 2025 14:24:45 +0000 (+0100) Subject: nss-systemd: set sg_adm/sg_mem in intrinsic groups X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=239903d44c12f10b5fe7c1f8457ae5203e47d8cc;p=thirdparty%2Fsystemd.git nss-systemd: set sg_adm/sg_mem in intrinsic groups The sg_adm and sg_mem fields are supposed to point to a NULL terminated string array. If these are NULL, some foreign tools like shadow's sg trigger NULL pointer dereferences (or fortunately their asset() calls). --- diff --git a/src/nss-systemd/nss-systemd.c b/src/nss-systemd/nss-systemd.c index ae0b5c803df..11384dbad84 100644 --- a/src/nss-systemd/nss-systemd.c +++ b/src/nss-systemd/nss-systemd.c @@ -75,6 +75,8 @@ static const struct group root_group = { static const struct sgrp root_sgrp = { .sg_namp = (char*) "root", .sg_passwd = (char*) PASSWORD_LOCKED_AND_INVALID, + .sg_adm = (char*[]) { NULL }, + .sg_mem = (char*[]) { NULL }, }; static const struct group nobody_group = { @@ -87,6 +89,8 @@ static const struct group nobody_group = { static const struct sgrp nobody_sgrp = { .sg_namp = (char*) NOBODY_GROUP_NAME, .sg_passwd = (char*) PASSWORD_LOCKED_AND_INVALID, + .sg_adm = (char*[]) { NULL }, + .sg_mem = (char*[]) { NULL }, }; typedef struct GetentData { @@ -257,12 +261,18 @@ static enum nss_status copy_synthesized_sgrp( assert(src); assert(src->sg_namp); assert(src->sg_passwd); + assert(src->sg_adm); + assert(!*src->sg_adm); /* Our synthesized records' sg_adm is always just NULL... */ + assert(src->sg_mem); + assert(!*src->sg_mem); /* Our synthesized records' sg_mem is always just NULL... */ size_t required = strlen(src->sg_namp) + 1 + - strlen(src->sg_passwd) + 1; + strlen(src->sg_passwd) + 1 + + sizeof(char*) + /* NULL terminator storage for src->sg_adm */ + sizeof(char*); /* NULL terminator storage for src->sg_mem */ - if (buflen < required) { + if (buflen < ALIGN(required)) { *errnop = ERANGE; return NSS_STATUS_TRYAGAIN; } @@ -274,7 +284,10 @@ static enum nss_status copy_synthesized_sgrp( /* String fields point into the user-provided buffer */ dest->sg_namp = buffer; dest->sg_passwd = stpcpy(dest->sg_namp, src->sg_namp) + 1; - strcpy(dest->sg_passwd, src->sg_passwd); + dest->sg_adm = ALIGN_PTR(stpcpy(dest->sg_passwd, src->sg_passwd) + 1); + *dest->sg_adm = NULL; + dest->sg_mem = dest->sg_adm + 1; + *dest->sg_mem = NULL; return NSS_STATUS_SUCCESS; }