commit: af92291786c15c4263e6fde408b75709d991ac5e
parent ac7eca22806f1d17e66b640bcebfec06a19a6bf1
Author: Haelwenn (lanodan) Monnier <contact@hacktivis.me>
Date: Mon, 10 Nov 2025 09:13:09 +0100
login: function-wrap fallible pwent processing
Fixes on-exit memory leaks due to lack of free(username_buf)
on it returning errorneously.
Diffstat:
| M | login.c | 110 | ++++++++++++++++++++++++++++++++++++++++++++----------------------------------- |
1 file changed, 61 insertions(+), 49 deletions(-)
diff --git a/login.c b/login.c
@@ -29,6 +29,60 @@
extern char **environ;
char *envclear[] = {NULL};
+static int
+process_pwent(struct passwd *pwent)
+{
+ int tty_gid = pwent->pw_gid;
+ struct group *tty_group = getgrnam(TTY_GROUP);
+ if(tty_group == NULL)
+ {
+ perror("login: warning: getgrnam");
+ }
+ else
+ {
+ tty_gid = tty_group->gr_gid;
+ }
+
+ /* considers that STDIN_FILENO is close enough to the current tty */
+ if(fchown(STDIN_FILENO, pwent->pw_uid, tty_gid) < 0)
+ {
+ perror("login: error: fchown");
+ return 1;
+ }
+ if(fchmod(STDIN_FILENO, TTY_PERMS))
+ {
+ perror("login: error: fchmod");
+ return 1;
+ }
+ if(setgid(pwent->pw_gid) < 0)
+ {
+ perror("login: error: setgid");
+ return 1;
+ }
+ if(initgroups(pwent->pw_name, pwent->pw_gid) < 0)
+ {
+ perror("login: error: initgroups");
+ return 1;
+ }
+ if(setuid(pwent->pw_uid) < 0)
+ {
+ perror("login: error: setuid");
+ return 1;
+ }
+
+ if(pwent->pw_dir != NULL)
+ {
+ setenv("HOME", pwent->pw_dir, 1);
+
+ if(chdir(pwent->pw_dir) != 0)
+ {
+ fprintf(stderr, "login: warning: Failed to change current directory to: %s\n", pwent->pw_dir);
+ }
+ }
+
+ return 0;
+}
+
int
main(int argc, char *argv[])
{
@@ -187,62 +241,20 @@ main(int argc, char *argv[])
if(pwent != NULL)
{
- int tty_gid = pwent->pw_gid;
- struct group *tty_group = getgrnam(TTY_GROUP);
- if(tty_group == NULL)
- {
- perror("login: warning: getgrnam");
- }
- else
- {
- tty_gid = tty_group->gr_gid;
- }
-
- /* considers that STDIN_FILENO is close enough to the current tty */
- if(fchown(STDIN_FILENO, pwent->pw_uid, tty_gid) < 0)
- {
- perror("login: error: fchown");
- return 1;
- }
- if(fchmod(STDIN_FILENO, TTY_PERMS))
- {
- perror("login: error: fchmod");
- return 1;
- }
- if(setgid(pwent->pw_gid) < 0)
- {
- perror("login: error: setgid");
- return 1;
- }
- if(initgroups(pwent->pw_name, pwent->pw_gid) < 0)
- {
- perror("login: error: initgroups");
- return 1;
- }
- if(setuid(pwent->pw_uid) < 0)
- {
- perror("login: error: setuid");
- return 1;
- }
-
if(pwent->pw_shell != NULL)
{
shell = pwent->pw_shell;
}
- if(pwent->pw_dir != NULL)
- {
- setenv("HOME", pwent->pw_dir, 1);
-
- if(chdir(pwent->pw_dir) != 0)
- {
- fprintf(
- stderr, "login: warning: Failed to change current directory to: %s\n", pwent->pw_dir);
- }
- }
-
+ int ret = process_pwent(pwent);
explicit_bzero(pwent, sizeof(pwent));
pwent = NULL;
+
+ if(ret != 0)
+ {
+ free(username_buf);
+ return ret;
+ }
}
setenv("USER", username, 1);