[crux-commits] ports/contrib (3.6): pam_xdg: now without lock, must ignore EEXIST race of mkdir(2)

crux at crux.nu crux at crux.nu
Mon Feb 1 17:54:49 UTC 2021


commit 60cb0edb8c2a3a114f965434a2c2787e5441066b
Author: Steffen Nurpmeso <steffen at sdaoden.eu>
Date:   Mon Feb 1 18:53:46 2021 +0100

    pam_xdg: now without lock, must ignore EEXIST race of mkdir(2)

diff --git a/pam_xdg/.signature b/pam_xdg/.signature
index 06ecf7a22..7145ad23b 100644
--- a/pam_xdg/.signature
+++ b/pam_xdg/.signature
@@ -1,7 +1,7 @@
 untrusted comment: verify with /etc/ports/contrib.pub
-RWSagIOpLGJF3/opxnSlpIKUNMt7/zCoADPQ4PYlOmbd2GckIrSxOZvjqNNRaw5n+mhVd/iOl35BH6C2CIKF12kK6df2J7zZ4Q8=
-SHA256 (Pkgfile) = ac39f667ad9c2778b25753a6265ef2705335afb9b5cde1f70d9cb86f9ee22076
+RWSagIOpLGJF3zU5kDWhhX3qLiOO1k39Qr77RTQlPHx5nQ5AZM61Q7VwupJYofPRUC254NZx4DRiSpe7m+Xomj8CAR1bi44YKAs=
+SHA256 (Pkgfile) = bb1ddb4db1eaed4c45e506b5ca6d0baed5f3e813c88b9908c27566ea93f0ed55
 SHA256 (.footprint) = 56d789b652e6167f5fb93e1e6d48243e13f598c6d9a72705a8e54a003574ba31
-SHA256 (pam_xdg.c) = 81bfedeb798bc63d33f2b44874df0d796b439e93876a4a41f94d1ee26a001c38
+SHA256 (pam_xdg.c) = 23ddd5788de1d0e76381935f0b9de1f134f26039fbfe24bb4445ce5ebff4f04c
 SHA256 (pam_xdg.8) = 2929bcd6655d28127d386215d3d8c4fed6744b65c4866ac7e49d54cb438d9133
 SHA256 (makefile) = 2466f499c3e84fd821176371fa9ff78143bf94b9ec09fd9e654b35613e4ead7d
diff --git a/pam_xdg/Pkgfile b/pam_xdg/Pkgfile
index b798857b7..22293114e 100644
--- a/pam_xdg/Pkgfile
+++ b/pam_xdg/Pkgfile
@@ -3,7 +3,7 @@
 # Maintainer:  Steffen Nurpmeso, steffen at sdaoden dot eu
 
 name=pam_xdg
-version=20210131
+version=20210201
 release=1
 source=($name.c $name.8 makefile)
 
diff --git a/pam_xdg/README b/pam_xdg/README
index 3221cb225..ec7ab9421 100644
--- a/pam_xdg/README
+++ b/pam_xdg/README
@@ -1,15 +1,14 @@
 README for pam_xdg
 
-This is a module for PAM that handles the XDG Base Directory
-Specification[1] directories, including lifetime management
-of XDG_RUNTIME_DIR and injection of according environment variables
-into the user session.
+PAM module that handles the XDG Base Directory Specification[1]
+directories, including creation of XDG_RUNTIME_DIR and injection
+of according environment variables into user sessions.
 
 For it to work it must be included in /etc/pam.d -- to make it a
 vivid part of session handling the file /etc/pam.d/common-session
 seems best.  Include the following early:
 
-	session optional pam_xdg.so [notroot] [runtime]
+   session optional pam_xdg.so [notroot] [runtime]
 
 Use notroot argument to only handle XDG for non-root users.
 Use runtime argument to only handle of XDG_RUNTIME_DIR.
diff --git a/pam_xdg/pam_xdg.c b/pam_xdg/pam_xdg.c
index 1ed589727..ce326c610 100644
--- a/pam_xdg/pam_xdg.c
+++ b/pam_xdg/pam_xdg.c
@@ -141,12 +141,14 @@ a_xdg(int isopen, pam_handle_t *pamh, int flags, int argc, const char **argv){
             goto jerr;
          }
 
-         if(mkdirat(cwdfd, a_RUNTIME_DIR_BASE, a_RUNTIME_DIR_BASE_MODE) == -1){
+         if(mkdirat(cwdfd, a_RUNTIME_DIR_BASE, a_RUNTIME_DIR_BASE_MODE
+               ) == -1 && errno != EEXIST){
             emsg = "cannot create base directory "
                   a_RUNTIME_DIR_OUTER "/" a_RUNTIME_DIR_BASE;
             goto jerr;
          }
       }
+      /* Not worth doing S_ISDIR(st.st_mode), O_DIRECTORY will bail next */
    }
 
    if((res = openat(cwdfd, a_RUNTIME_DIR_BASE,
@@ -163,38 +165,38 @@ a_xdg(int isopen, pam_handle_t *pamh, int flags, int argc, const char **argv){
          (unsigned long)pwp->pw_uid);
 
    /* We create the per-user directory on isopen time as necessary */
-   /*if(isopen)*/{
-      for(res = 0;; ++res){
-         int nfd;
-
-         if((nfd = openat(cwdfd, uidbuf, (O_PATH | O_DIRECTORY | O_NOFOLLOW))
-               ) != -1){
-            close(cwdfd);
-            cwdfd = nfd;
-            break;
+   for(res = 0;; ++res){
+      int nfd;
+
+      if((nfd = openat(cwdfd, uidbuf, (O_PATH | O_DIRECTORY | O_NOFOLLOW))
+            ) != -1){
+         close(cwdfd);
+         cwdfd = nfd;
+         break;
+      }else{
+         if(errno == ENOENT){
+            if(!isopen)
+               goto jok;
+            if(res != 0)
+               goto jeurd;
          }else{
-            if(errno == ENOENT){
-               if(!isopen)
-                  goto jok;
-               if(res != 0)
-                  goto jeurd;
-            }else{
 jeurd:
-               emsg = "per user XDG_RUNTIME_DIR not accessible";
-               goto jerr;
-            }
-         }
-
-         if(mkdirat(cwdfd, uidbuf, 0700) == -1){
-            emsg = "cannot create per user XDG_RUNTIME_DIR";
-            goto jerr;
-         }
-         if(fchownat(cwdfd, uidbuf, pwp->pw_uid, pwp->pw_gid,
-               AT_SYMLINK_NOFOLLOW) == -1){
-            emsg = "cannot chown(2) per user XDG_RUNTIME_DIR";
+            emsg = "per user XDG_RUNTIME_DIR not accessible";
             goto jerr;
          }
       }
+
+      if(mkdirat(cwdfd, uidbuf, 0700) == -1 && errno != EEXIST){
+         emsg = "cannot create per user XDG_RUNTIME_DIR";
+         goto jerr;
+      }
+
+      /* Just chown it! */
+      if(fchownat(cwdfd, uidbuf, pwp->pw_uid, pwp->pw_gid,
+            AT_SYMLINK_NOFOLLOW) == -1){
+         emsg = "cannot chown(2) per user XDG_RUNTIME_DIR";
+         goto jerr;
+      }
    }
 
    /* When opening, we want to put environment variables, too */


More information about the crux-commits mailing list