Date: Mon, 06 Jul 2026 19:35:40 +0000 From: Rick Macklem <rmacklem@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Cc: Peter Eriksson <pen_lysator.liu.se> Subject: git: d7d71341ae7d - main - acl_from_text.c: Allow negative uid/gid numbers to be handled Message-ID: <6a4c038c.40202.3c63240e@gitrepo.freebsd.org>
index | next in thread | raw e-mail
The branch main has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=d7d71341ae7d79886143a9ce427dca0e858eda97 commit d7d71341ae7d79886143a9ce427dca0e858eda97 Author: Peter Eriksson <pen_lysator.liu.se> AuthorDate: 2026-07-06 19:33:22 +0000 Commit: Rick Macklem <rmacklem@FreeBSD.org> CommitDate: 2026-07-06 19:33:22 +0000 acl_from_text.c: Allow negative uid/gid numbers to be handled getfacl / acl_to_text() incorrectly prints uid/gid numbers as signed integers. This causes uid / gid numbers larger than 2G (2147483648) to print as negative numbers. The libc acl_from_text() function does not handle negative numbers. This diff adds a backwards compatiblity fix to allow negative numbers... Reviewed by: rmacklem MFC after: 2 weeks Differential Revision: https://reviews.freebsd.org/D57180 --- lib/libc/posix1e/acl_from_text.c | 41 +++++++++++++++++++++++++++++++--------- 1 file changed, 32 insertions(+), 9 deletions(-) diff --git a/lib/libc/posix1e/acl_from_text.c b/lib/libc/posix1e/acl_from_text.c index 765b58290a04..746338b37f0c 100644 --- a/lib/libc/posix1e/acl_from_text.c +++ b/lib/libc/posix1e/acl_from_text.c @@ -39,6 +39,7 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <inttypes.h> #include <assert.h> #include "acl_support.h" @@ -263,6 +264,24 @@ error_label: return(NULL); } +/* + * Make sure the number given fits inside an uid_t or gid_t. + * Currently (2026-05-23) uid_t & gid_t is an uint32_t. + * Special case handle uid_t/gid_t numbers specified as negative numbers. + * Assumes that uid_t and gid_t are the same types. + */ +static int +_invalid_uidgid(intmax_t v) { + if (v < 0) { + if ((-v) & ~(uintmax_t)((~(uid_t)0)>>1)) + return (2); /* Underflow, does not fit into uid_t */ + } else { + if (v & ~(uintmax_t)(~(uid_t)0)) + return (1); /* Overflow, does not fit into uid_t */ + } + return (0); +} + /* * Given a username/groupname from a text form of an ACL, return the uid/gid * XXX NOT THREAD SAFE, RELIES ON GETPWNAM, GETGRNAM @@ -274,19 +293,21 @@ _acl_name_to_id(acl_tag_t tag, char *name, uid_t *id) { struct group *g; struct passwd *p; - unsigned long l; + intmax_t v; char *endp; switch(tag) { case ACL_USER: p = getpwnam(name); if (p == NULL) { - l = strtoul(name, &endp, 0); - if (*endp != '\0' || l != (unsigned long)(uid_t)l) { - errno = EINVAL; + errno = 0; + v = strtoimax(name, &endp, 0); + if (name == endp || *endp != '\0' || + errno == ERANGE || _invalid_uidgid(v) != 0) { + errno = EINVAL; /* No or invalid number */ return (-1); } - *id = (uid_t)l; + *id = v; return (0); } *id = p->pw_uid; @@ -295,12 +316,14 @@ _acl_name_to_id(acl_tag_t tag, char *name, uid_t *id) case ACL_GROUP: g = getgrnam(name); if (g == NULL) { - l = strtoul(name, &endp, 0); - if (*endp != '\0' || l != (unsigned long)(gid_t)l) { - errno = EINVAL; + errno = 0; + v = strtoimax(name, &endp, 0); + if (name == endp || *endp != '\0' || + errno == ERANGE || _invalid_uidgid(v) != 0) { + errno = EINVAL; /* No or invalid number */ return (-1); } - *id = (gid_t)l; + *id = v; return (0); } *id = g->gr_gid;home | help
Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?6a4c038c.40202.3c63240e>
