[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH] file-has-acl: scontext even if --disable-acl
From: |
Paul Eggert |
Subject: |
[PATCH] file-has-acl: scontext even if --disable-acl |
Date: |
Mon, 11 Nov 2024 07:54:07 -0800 |
Be able to get the security context even if configured with
--disable-acl, as security contexts are not ACLs, and the
main reason for --disable-acl was for efficiency with GNU ls -l,
a concern that does not apply to security contexts (which are
needed only with ls -Z). Problem reported by Pádraig Brady
<https://bugs.gnu.org/73418#52>.
* lib/acl.h (ACL_GET_SCONTEXT): New constant.
(aclinfo_free, aclinfo_scontext_free): Declare even if !USE_ACL.
* lib/file-has-acl.c (USE_LINUX_XATTR): No longer false merely
because !USE_ACL, because we need xattr to get scontext.
(get_aclinfo): Support new ACL_GET_SCONTEXT flag.
---
ChangeLog | 15 ++++++++
lib/acl.h | 17 ++++++---
lib/file-has-acl.c | 93 +++++++++++++++++++++++++---------------------
3 files changed, 77 insertions(+), 48 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index afce32cf8b..3ae5107c7a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2024-11-11 Paul Eggert <eggert@cs.ucla.edu>
+
+ file-has-acl: scontext even if --disable-acl
+ Be able to get the security context even if configured with
+ --disable-acl, as security contexts are not ACLs, and the
+ main reason for --disable-acl was for efficiency with GNU ls -l,
+ a concern that does not apply to security contexts (which are
+ needed only with ls -Z). Problem reported by Pádraig Brady
+ <https://bugs.gnu.org/73418#52>.
+ * lib/acl.h (ACL_GET_SCONTEXT): New constant.
+ (aclinfo_free, aclinfo_scontext_free): Declare even if !USE_ACL.
+ * lib/file-has-acl.c (USE_LINUX_XATTR): No longer false merely
+ because !USE_ACL, because we need xattr to get scontext.
+ (get_aclinfo): Support new ACL_GET_SCONTEXT flag.
+
2024-11-11 Bruno Haible <bruno@clisp.org>
nproc: Use affinity mask even in out-of-memory situations.
diff --git a/lib/acl.h b/lib/acl.h
index ca74fe6de8..1d52345c66 100644
--- a/lib/acl.h
+++ b/lib/acl.h
@@ -32,9 +32,16 @@
extern "C" {
#endif
-/* Follow symlinks when getting an ACL. This is a bitmask that is guaranteed
- not to collide with any <dirent.h> DT_* or _GL_DT_* value. */
-enum { ACL_SYMLINK_FOLLOW = 0x10000 };
+/* file_has_acl flags guaranteed to not collide with any <dirent.h>
+ DT_* or _GL_DT_* value. */
+enum
+ {
+ /* Get scontext information as well. */
+ ACL_GET_SCONTEXT = 0x10000,
+
+ /* Follow symlinks. */
+ ACL_SYMLINK_FOLLOW = 0x20000,
+ };
/* Information about an ACL. */
struct aclinfo
@@ -73,7 +80,7 @@ bool acl_errno_valid (int) _GL_ATTRIBUTE_CONST;
int file_has_acl (char const *, struct stat const *);
int file_has_aclinfo (char const *restrict, struct aclinfo *restrict, int);
-#if USE_ACL && HAVE_LINUX_XATTR_H && HAVE_LISTXATTR
+#if HAVE_LINUX_XATTR_H && HAVE_LISTXATTR
bool aclinfo_has_xattr (struct aclinfo const *, char const *)
_GL_ATTRIBUTE_PURE;
void aclinfo_free (struct aclinfo *);
@@ -81,7 +88,7 @@ void aclinfo_free (struct aclinfo *);
# define aclinfo_has_xattr(ai, xattr) false
# define aclinfo_free(ai) ((void) 0)
#endif
-#if (USE_ACL && HAVE_LINUX_XATTR_H && HAVE_LISTXATTR \
+#if (HAVE_LINUX_XATTR_H && HAVE_LISTXATTR \
&& (HAVE_SMACK || USE_SELINUX_SELINUX_H))
void aclinfo_scontext_free (char *);
#else
diff --git a/lib/file-has-acl.c b/lib/file-has-acl.c
index 7e05d39131..2cbc20b38d 100644
--- a/lib/file-has-acl.c
+++ b/lib/file-has-acl.c
@@ -39,7 +39,7 @@ static_assert (ACL_SYMLINK_FOLLOW & ~ (unsigned char) -1);
static char const UNKNOWN_SECURITY_CONTEXT[] = "?";
-#if USE_ACL && HAVE_LINUX_XATTR_H && HAVE_LISTXATTR
+#if HAVE_LINUX_XATTR_H && HAVE_LISTXATTR
# define USE_LINUX_XATTR true
#else
# define USE_LINUX_XATTR false
@@ -109,7 +109,8 @@ aclinfo_has_xattr (struct aclinfo const *ai, char const
*xattr)
return false;
}
-/* Get attributes of the file NAME into AI.
+/* Get attributes of the file NAME into AI, if USE_ACL.
+ If FLAGS & ACL_GET_SCONTEXT, also get security context.
If FLAGS & ACL_SYMLINK_FOLLOW, follow symbolic links. */
static void
get_aclinfo (char const *name, struct aclinfo *ai, int flags)
@@ -118,53 +119,58 @@ get_aclinfo (char const *name, struct aclinfo *ai, int
flags)
ai->buf = ai->u.__gl_acl_ch;
ssize_t acl_alloc = sizeof ai->u.__gl_acl_ch;
- ssize_t (*lsxattr) (char const *, char *, size_t)
- = (flags & ACL_SYMLINK_FOLLOW ? listxattr : llistxattr);
- while (true)
+ if (! (USE_ACL || flags & ACL_GET_SCONTEXT))
+ ai->size = 0;
+ else
{
- ai->size = lsxattr (name, ai->buf, acl_alloc);
- if (0 < ai->size)
- break;
- ai->u.err = ai->size < 0 ? errno : 0;
- if (! (ai->size < 0 && ai->u.err == ERANGE && acl_alloc < SSIZE_MAX))
- break;
-
- /* The buffer was too small. Find how large it should have been. */
- ssize_t size = lsxattr (name, NULL, 0);
- if (size <= 0)
+ ssize_t (*lsxattr) (char const *, char *, size_t)
+ = (flags & ACL_SYMLINK_FOLLOW ? listxattr : llistxattr);
+ while (true)
{
- ai->size = size;
- ai->u.err = size < 0 ? errno : 0;
- break;
- }
+ ai->size = lsxattr (name, ai->buf, acl_alloc);
+ if (0 < ai->size)
+ break;
+ ai->u.err = ai->size < 0 ? errno : 0;
+ if (! (ai->size < 0 && ai->u.err == ERANGE && acl_alloc < SSIZE_MAX))
+ break;
- /* Grow allocation to at least 'size'. Grow it by a nontrivial
- amount, to defend against denial of service by an adversary
- that fiddles with ACLs. */
- if (ai->buf != ai->u.__gl_acl_ch)
- {
- free (ai->buf);
- ai->buf = ai->u.__gl_acl_ch;
- }
- if (ckd_add (&acl_alloc, acl_alloc, acl_alloc >> 1))
- acl_alloc = SSIZE_MAX;
- if (acl_alloc < size)
- acl_alloc = size;
- if (SIZE_MAX < acl_alloc)
- {
- ai->u.err = ENOMEM;
- break;
- }
- char *newbuf = malloc (acl_alloc);
- if (!newbuf)
- {
- ai->u.err = errno;
- break;
+ /* The buffer was too small. Find how large it should have been. */
+ ssize_t size = lsxattr (name, NULL, 0);
+ if (size <= 0)
+ {
+ ai->size = size;
+ ai->u.err = size < 0 ? errno : 0;
+ break;
+ }
+
+ /* Grow allocation to at least 'size'. Grow it by a nontrivial
+ amount, to defend against denial of service by an adversary
+ that fiddles with ACLs. */
+ if (ai->buf != ai->u.__gl_acl_ch)
+ {
+ free (ai->buf);
+ ai->buf = ai->u.__gl_acl_ch;
+ }
+ if (ckd_add (&acl_alloc, acl_alloc, acl_alloc >> 1))
+ acl_alloc = SSIZE_MAX;
+ if (acl_alloc < size)
+ acl_alloc = size;
+ if (SIZE_MAX < acl_alloc)
+ {
+ ai->u.err = ENOMEM;
+ break;
+ }
+ char *newbuf = malloc (acl_alloc);
+ if (!newbuf)
+ {
+ ai->u.err = errno;
+ break;
+ }
+ ai->buf = newbuf;
}
- ai->buf = newbuf;
}
- if (0 < ai->size)
+ if (0 < ai->size && flags & ACL_GET_SCONTEXT)
{
if (is_smack_enabled ())
{
@@ -325,6 +331,7 @@ acl_nfs4_nontrivial (uint32_t *xattr, ssize_t nbytes)
Set *AI to ACL info regardless of return value.
FLAGS should be a <dirent.h> d_type value, optionally ORed with
- _GL_DT_NOTDIR if it is known that NAME is not a directory,
+ - ACL_GET_SCONTEXT to retrieve extended attributes,
- ACL_SYMLINK_FOLLOW to follow the link if NAME is a symbolic link.
If the d_type value is not known, use DT_UNKNOWN though this may be less
efficient.
--
2.47.0
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [PATCH] file-has-acl: scontext even if --disable-acl,
Paul Eggert <=