aboutsummaryrefslogtreecommitdiff
path: root/modules/pam_unix
diff options
context:
space:
mode:
authorChristian Göttsche <cgzones@googlemail.com>2024-01-04 18:23:59 +0100
committerDmitry V. Levin <ldv@strace.io>2024-01-15 20:01:23 +0000
commit9f19e7da7a014e022cdbba06accca171adef27e0 (patch)
treecd4fa183681f2c2725e68a4016521cacf76399ec /modules/pam_unix
parent8e577fb4c55674260143a325c01f47d8dff712af (diff)
downloadpam-9f19e7da7a014e022cdbba06accca171adef27e0.tar.gz
pam-9f19e7da7a014e022cdbba06accca171adef27e0.tar.bz2
pam-9f19e7da7a014e022cdbba06accca171adef27e0.zip
pam_unix: set close-on-exec
Since the module operates on sensitive files set the close-on-exec flag, to avoid file descriptor leaks if there is ever any sibling thread. The fopen(3) mode "e" is supported in glibc since version 2.7 (released in 2007), and ignored prior, see: https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=65d834b0add966dbbdb5ed1e916c60b2b2d87f10
Diffstat (limited to 'modules/pam_unix')
-rw-r--r--modules/pam_unix/lckpwdf.-c17
-rw-r--r--modules/pam_unix/pam_unix_passwd.c2
-rw-r--r--modules/pam_unix/passverify.c16
-rw-r--r--modules/pam_unix/support.c2
4 files changed, 13 insertions, 24 deletions
diff --git a/modules/pam_unix/lckpwdf.-c b/modules/pam_unix/lckpwdf.-c
index c3e63155..4d0f0ad3 100644
--- a/modules/pam_unix/lckpwdf.-c
+++ b/modules/pam_unix/lckpwdf.-c
@@ -35,15 +35,6 @@
static int lockfd = -1;
-static int set_close_on_exec(int fd)
-{
- int flags = fcntl(fd, F_GETFD, 0);
- if (flags == -1)
- return -1;
- flags |= FD_CLOEXEC;
- return fcntl(fd, F_SETFD, flags);
-}
-
static int do_lock(int fd)
{
struct flock fl;
@@ -70,7 +61,7 @@ static int lckpwdf(void)
#ifdef WITH_SELINUX
if(is_selinux_enabled()>0)
{
- lockfd = open(LOCKFILE, O_WRONLY);
+ lockfd = open(LOCKFILE, O_WRONLY | O_CLOEXEC);
if(lockfd == -1 && errno == ENOENT)
{
char *create_context_raw;
@@ -82,18 +73,16 @@ static int lckpwdf(void)
freecon(create_context_raw);
if(rc)
return -1;
- lockfd = open(LOCKFILE, O_CREAT | O_WRONLY, 0600);
+ lockfd = open(LOCKFILE, O_CREAT | O_WRONLY | O_CLOEXEC, 0600);
if(setfscreatecon_raw(NULL))
return -1;
}
}
else
#endif
- lockfd = open(LOCKFILE, O_CREAT | O_WRONLY, 0600);
+ lockfd = open(LOCKFILE, O_CREAT | O_WRONLY | O_CLOEXEC, 0600);
if (lockfd == -1)
return -1;
- if (set_close_on_exec(lockfd) == -1)
- goto cleanup_fd;
memset(&act, 0, sizeof act);
act.sa_handler = alarm_catch;
diff --git a/modules/pam_unix/pam_unix_passwd.c b/modules/pam_unix/pam_unix_passwd.c
index fe3f566a..3a223949 100644
--- a/modules/pam_unix/pam_unix_passwd.c
+++ b/modules/pam_unix/pam_unix_passwd.c
@@ -346,7 +346,7 @@ static int check_old_password(const char *forwho, const char *newpass)
size_t n = 0;
size_t len = strlen(forwho);
- opwfile = fopen(OLD_PASSWORDS_FILE, "r");
+ opwfile = fopen(OLD_PASSWORDS_FILE, "re");
if (opwfile == NULL)
return PAM_ABORT;
diff --git a/modules/pam_unix/passverify.c b/modules/pam_unix/passverify.c
index 60d9ceca..303929a4 100644
--- a/modules/pam_unix/passverify.c
+++ b/modules/pam_unix/passverify.c
@@ -400,7 +400,7 @@ crypt_make_salt(char *where, int length)
int fd;
int rv;
- if ((rv = fd = open(PAM_PATH_RANDOMDEV, O_RDONLY)) != -1) {
+ if ((rv = fd = open(PAM_PATH_RANDOMDEV, O_RDONLY | O_CLOEXEC)) != -1) {
while ((rv = read(fd, where, length)) != length && errno == EINTR);
close (fd);
}
@@ -557,7 +557,7 @@ unix_selinux_confined(void)
}
/* let's try opening shadow read only */
- if ((fd=open("/etc/shadow", O_RDONLY)) != -1) {
+ if ((fd=open("/etc/shadow", O_RDONLY | O_CLOEXEC)) != -1) {
close(fd);
confined = 0;
return confined;
@@ -695,14 +695,14 @@ save_old_password(pam_handle_t *pamh, const char *forwho, const char *oldpass,
freecon(passwd_context_raw);
}
#endif
- pwfile = fopen(OPW_TMPFILE, "w");
+ pwfile = fopen(OPW_TMPFILE, "we");
umask(oldmask);
if (pwfile == NULL) {
err = 1;
goto done;
}
- opwfile = fopen(OLD_PASSWORDS_FILE, "r");
+ opwfile = fopen(OLD_PASSWORDS_FILE, "re");
if (opwfile == NULL) {
fclose(pwfile);
err = 1;
@@ -858,14 +858,14 @@ PAMH_ARG_DECL(int unix_update_passwd,
freecon(passwd_context_raw);
}
#endif
- pwfile = fopen(PW_TMPFILE, "w");
+ pwfile = fopen(PW_TMPFILE, "we");
umask(oldmask);
if (pwfile == NULL) {
err = 1;
goto done;
}
- opwfile = fopen("/etc/passwd", "r");
+ opwfile = fopen("/etc/passwd", "re");
if (opwfile == NULL) {
fclose(pwfile);
err = 1;
@@ -983,14 +983,14 @@ PAMH_ARG_DECL(int unix_update_shadow,
freecon(shadow_context_raw);
}
#endif
- pwfile = fopen(SH_TMPFILE, "w");
+ pwfile = fopen(SH_TMPFILE, "we");
umask(oldmask);
if (pwfile == NULL) {
err = 1;
goto done;
}
- opwfile = fopen("/etc/shadow", "r");
+ opwfile = fopen("/etc/shadow", "re");
if (opwfile == NULL) {
fclose(pwfile);
err = 1;
diff --git a/modules/pam_unix/support.c b/modules/pam_unix/support.c
index 546ef820..d391973f 100644
--- a/modules/pam_unix/support.c
+++ b/modules/pam_unix/support.c
@@ -352,7 +352,7 @@ int _unix_getpwnam(pam_handle_t *pamh, const char *name,
if (!matched && files && strchr(name, ':') == NULL) {
FILE *passwd;
- passwd = fopen("/etc/passwd", "r");
+ passwd = fopen("/etc/passwd", "re");
if (passwd != NULL) {
size_t n = 0, userlen;
ssize_t r;