diff options
author | Paul Eggert <eggert@cs.ucla.edu> | 2023-05-15 08:40:27 -0700 |
---|---|---|
committer | Paul Eggert <eggert@cs.ucla.edu> | 2023-05-15 08:41:34 -0700 |
commit | 735716931755c74f3788ac83fead717c0bb22dfe (patch) | |
tree | f47d49dbecac525129bc876193e0e7c66c58c9dd | |
parent | 29f9d848e5787ac488463fd85161359542ac00c3 (diff) | |
download | gnulib-735716931755c74f3788ac83fead717c0bb22dfe.tar.gz |
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.
-rw-r--r-- | ChangeLog | 13 | ||||
-rw-r--r-- | lib/file-has-acl.c | 37 | ||||
-rw-r--r-- | modules/file-has-acl | 2 |
3 files changed, 41 insertions, 11 deletions
@@ -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 . diff --git a/lib/file-has-acl.c b/lib/file-has-acl.c index 38bc806dc4..4cddc80bd1 100644 --- a/lib/file-has-acl.c +++ b/lib/file-has-acl.c @@ -29,7 +29,10 @@ #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); diff --git a/modules/file-has-acl b/modules/file-has-acl index be1048dfe1..199fccd6ca 100644 --- a/modules/file-has-acl +++ b/modules/file-has-acl @@ -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 |