]> granicus.if.org Git - linux-pam/commitdiff
Relevant BUGIDs:
authorDmitry V. Levin <ldv@altlinux.org>
Tue, 28 Sep 2010 17:11:36 +0000 (17:11 +0000)
committerDmitry V. Levin <ldv@altlinux.org>
Tue, 28 Sep 2010 17:11:36 +0000 (17:11 +0000)
Purpose of commit: bugfix

Commit summary:
---------------
2010-09-27  Dmitry V. Levin  <ldv@altlinux.org>

* modules/pam_xauth/pam_xauth.c (check_acl): Check that the given
access control file is a regular file.

ChangeLog
modules/pam_xauth/pam_xauth.c

index dd749dec94d87282abc77e224d29088cf5b666e0..abad321f9fd3fed34c80f1f6873328f008c306d7 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2010-09-27  Dmitry V. Levin  <ldv@altlinux.org>
+
+       * modules/pam_xauth/pam_xauth.c (check_acl): Ensure that the given
+       access control file is a regular file.
+
 2010-09-16  Dmitry V. Levin  <ldv@altlinux.org>
 
        * modules/pam_env/pam_env.c (handle_env): Use setfsuid() return code.
index 05ed6ee944377e95b1140dd1fee11bc5e54fb635..591dc85dc1a125ca9c50d2a56fb8d6b6acc56217 100644 (file)
@@ -37,6 +37,9 @@
 #include <sys/types.h>
 #include <sys/fsuid.h>
 #include <sys/wait.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
 #include <errno.h>
 #include <fnmatch.h>
 #include <grp.h>
@@ -232,9 +235,10 @@ check_acl(pam_handle_t *pamh,
 {
        char path[PATH_MAX];
        struct passwd *pwd;
-       FILE *fp;
-       int i, save_errno;
+       FILE *fp = NULL;
+       int i, fd = -1, save_errno;
        uid_t fsuid;
+       struct stat st;
        /* Check this user's <sense> file. */
        pwd = pam_modutil_getpwnam(pamh, this_user);
        if (pwd == NULL) {
@@ -251,10 +255,27 @@ check_acl(pam_handle_t *pamh,
                return PAM_SESSION_ERR;
        }
        fsuid = setfsuid(pwd->pw_uid);
-       fp = fopen(path, "r");
+       if (!stat(path, &st)) {
+               if (!S_ISREG(st.st_mode))
+                       errno = EINVAL;
+               else
+                       fd = open(path, O_RDONLY | O_NOCTTY);
+       }
        save_errno = errno;
        setfsuid(fsuid);
-       if (fp != NULL) {
+       if (fd >= 0) {
+               if (!fstat(fd, &st)) {
+                       if (!S_ISREG(st.st_mode))
+                               errno = EINVAL;
+                       else
+                               fp = fdopen(fd, "r");
+               }
+               if (!fp) {
+                       save_errno = errno;
+                       close(fd);
+               }
+       }
+       if (fp) {
                char buf[LINE_MAX], *tmp;
                /* Scan the file for a list of specs of users to "trust". */
                while (fgets(buf, sizeof(buf), fp) != NULL) {