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).
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user