]> Savannah Git Hosting - gnulib.git/commitdiff
file-has-acl: improve port to Fedora 39
authorPaul Eggert <eggert@cs.ucla.edu>
Mon, 15 May 2023 15:40:27 +0000 (08:40 -0700)
committerPaul Eggert <eggert@cs.ucla.edu>
Mon, 15 May 2023 15:41:34 +0000 (08:41 -0700)
Problem reported by Ondrej Valousek in:
https://lists.gnu.org/r/bug-gnulib/2023-05/msg00078.html
* lib/file-has-acl.c: Include minmax.h.
[USE_ACL && HAVE_LINUX_XATTR_H && HAVE_LISTXATTR]: Include stdckdint.h.
(file_has_acl) [USE_ACL && HAVE_LINUX_XATTR_H && HAVE_LISTXATTR]:
If the file has NFSv4 ACLs, ignore any POSIX ACLs, for Fedora 39.
Return a bit faster when listxattr returns 0.
Don’t loop forever if an attacker is fiddling with ACLs.
* modules/file-has-acl (Depends-on): Add minmax, stdckdint.

ChangeLog
lib/file-has-acl.c
modules/file-has-acl

index 7c5f70d8e6271527c7ba77691babf7bcf9129c82..ade908c9720f490cbf1b4fac1bf25108a4a4af48 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2023-05-15  Paul Eggert  <eggert@cs.ucla.edu>
+
+       file-has-acl: improve port to Fedora 39
+       Problem reported by Ondrej Valousek in:
+       https://lists.gnu.org/r/bug-gnulib/2023-05/msg00078.html
+       * lib/file-has-acl.c: Include minmax.h.
+       [USE_ACL && HAVE_LINUX_XATTR_H && HAVE_LISTXATTR]: Include stdckdint.h.
+       (file_has_acl) [USE_ACL && HAVE_LINUX_XATTR_H && HAVE_LISTXATTR]:
+       If the file has NFSv4 ACLs, ignore any POSIX ACLs, for Fedora 39.
+       Return a bit faster when listxattr returns 0.
+       Don’t loop forever if an attacker is fiddling with ACLs.
+       * modules/file-has-acl (Depends-on): Add minmax, stdckdint.
+
 2023-05-15  Bruno Haible  <bruno@clisp.org>
 
        Work around https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82283 .
index 38bc806dc49662a7982d8b320e07296a6a603629..4cddc80bd137a1231e2d8ba50359073ab2a0e776 100644 (file)
 
 #include "acl-internal.h"
 
+#include "minmax.h"
+
 #if USE_ACL && HAVE_LINUX_XATTR_H && HAVE_LISTXATTR
+# include <stdckdint.h>
 # include <string.h>
 # include <arpa/inet.h>
 # include <sys/xattr.h>
@@ -181,32 +184,44 @@ file_has_acl (char const *name, struct stat const *sb)
              && errno == ERANGE)
         {
           free (heapbuf);
-          listbufsize = listxattr (name, NULL, 0);
-          if (listbufsize < 0)
-            return -1;
-          if (SIZE_MAX < listbufsize)
+          ssize_t newsize = listxattr (name, NULL, 0);
+          if (newsize <= 0)
+            return newsize;
+
+          /* Grow LISTBUFSIZE to at least NEWSIZE.  Grow it by a
+             nontrivial amount too, to defend against denial of
+             service by an adversary that fiddles with ACLs.  */
+          bool overflow = ckd_add (&listbufsize, listbufsize, listbufsize >> 1);
+          listbufsize = MAX (listbufsize, newsize);
+          if (overflow || SIZE_MAX < listbufsize)
             {
               errno = ENOMEM;
               return -1;
             }
+
           listbuf = heapbuf = malloc (listbufsize);
           if (!listbuf)
             return -1;
         }
 
+      /* In Fedora 39, a file can have both NFSv4 and POSIX ACLs,
+         but if it has an NFSv4 ACL that's the one that matters.
+         In earlier Fedora the two types of ACLs were mutually exclusive.
+         Attempt to work correctly on both kinds of systems.  */
+      bool nfsv4_acl
+        = 0 < listsize && have_xattr (XATTR_NAME_NFSV4_ACL, listbuf, listsize);
       int ret
-        = (listsize < 0 ? -1
-           : (have_xattr (XATTR_NAME_POSIX_ACL_ACCESS, listbuf, listsize)
+        = (listsize <= 0 ? listsize
+           : (nfsv4_acl
+              || have_xattr (XATTR_NAME_POSIX_ACL_ACCESS, listbuf, listsize)
               || (S_ISDIR (sb->st_mode)
                   && have_xattr (XATTR_NAME_POSIX_ACL_DEFAULT,
                                  listbuf, listsize))));
-      bool nfsv4_acl_but_no_posix_acl
-        = ret == 0 && have_xattr (XATTR_NAME_NFSV4_ACL, listbuf, listsize);
       free (heapbuf);
 
-      /* If there is an NFSv4 ACL but no POSIX ACL, follow up with a
-         getxattr syscall to see whether the NFSv4 ACL is nontrivial.  */
-      if (nfsv4_acl_but_no_posix_acl)
+      /* If there is an NFSv4 ACL, follow up with a getxattr syscall
+         to see whether the NFSv4 ACL is nontrivial.  */
+      if (nfsv4_acl)
         {
           ret = getxattr (name, XATTR_NAME_NFSV4_ACL,
                           stackbuf.xattr, sizeof stackbuf.xattr);
index be1048dfe1e6501e0a7c7ed58fce8b2bf992ef33..199fccd6ca7f7971de7cec89f29b974e73874425 100644 (file)
@@ -9,9 +9,11 @@ m4/acl.m4
 Depends-on:
 acl-permissions
 extern-inline
+minmax
 free-posix
 stat
 stdbool
+stdckdint
 
 configure.ac:
 gl_FILE_HAS_ACL