diff options
author | Michael Catanzaro <mcatanzaro@redhat.com> | 2021-09-08 13:42:16 -0500 |
---|---|---|
committer | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2021-10-12 17:55:08 +0200 |
commit | fd864f9df70662a636bee5307d85a2762b8f236f (patch) | |
tree | 2019fff8c66e1195a84f02286e350cd8793da4b3 | |
parent | 0d3f41ef46f2b18a2bc4f728eeadaea81bcea48d (diff) | |
download | systemd-fd864f9df70662a636bee5307d85a2762b8f236f.tar.gz |
nss-systemd: pack pw_passwd result into supplied buffer
getpwnam_r() guarantees that the strings in the struct passwd that it
returns are pointers into the buffer allocated by the application and
passed to getpwnam_r(). This means applications may choose to modify the
strings in place, as long as the length of the strings is not increased.
So it's wrong for us to return a static string here, we really do have
to copy it into the application-provided buffer like we do for all the
other strings.
This is only a theoretical problem since it would be very weird for an
application to modify the pw_passwd field, but I spotted this when
investigating a similar crash caused by glib editing a different field.
See also:
https://gitlab.gnome.org/GNOME/glib/-/merge_requests/2244
(cherry picked from commit 92b264676ccd79c89da270aabc1ec466fa18cd0d)
(cherry picked from commit 84313bc5a262e87f49d176db169e1562d7060b33)
-rw-r--r-- | src/nss-systemd/userdb-glue.c | 6 |
1 files changed, 4 insertions, 2 deletions
diff --git a/src/nss-systemd/userdb-glue.c b/src/nss-systemd/userdb-glue.c index 8f8988579b..23d6aeef2d 100644 --- a/src/nss-systemd/userdb-glue.c +++ b/src/nss-systemd/userdb-glue.c @@ -35,6 +35,8 @@ int nss_pack_user_record( assert_se(hr->user_name); required = strlen(hr->user_name) + 1; + required += 2; /* strlen(PASSWORD_SEE_SHADOW) + 1 */ + assert_se(rn = user_record_real_name(hr)); required += strlen(rn) + 1; @@ -51,12 +53,12 @@ int nss_pack_user_record( .pw_name = buffer, .pw_uid = hr->uid, .pw_gid = user_record_gid(hr), - .pw_passwd = (char*) PASSWORD_SEE_SHADOW, }; assert(buffer); - pwd->pw_gecos = stpcpy(pwd->pw_name, hr->user_name) + 1; + pwd->pw_passwd = stpcpy(pwd->pw_name, hr->user_name) + 1; + pwd->pw_gecos = stpcpy(pwd->pw_passwd, PASSWORD_SEE_SHADOW) + 1; pwd->pw_dir = stpcpy(pwd->pw_gecos, rn) + 1; pwd->pw_shell = stpcpy(pwd->pw_dir, hd) + 1; strcpy(pwd->pw_shell, shell); |