aboutsummaryrefslogtreecommitdiff
path: root/lib/libc
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libc')
-rw-r--r--lib/libc/gdtoa/_hdtoa.c3
-rw-r--r--lib/libc/gdtoa/_hldtoa.c3
-rw-r--r--lib/libc/gen/Symbol.map2
-rw-r--r--lib/libc/gen/gen-compat.h8
-rw-r--r--lib/libc/gen/getgrouplist.329
-rw-r--r--lib/libc/gen/initgroups.3101
-rw-r--r--lib/libc/gen/initgroups.c55
-rw-r--r--lib/libc/include/compat.h1
-rw-r--r--lib/libc/stdtime/ctime.339
-rw-r--r--lib/libc/tests/stdio/printfloat_test.c13
-rw-r--r--lib/libc/tests/tls/dso/Makefile1
-rw-r--r--lib/libc/tests/tls_dso/Makefile1
12 files changed, 205 insertions, 51 deletions
diff --git a/lib/libc/gdtoa/_hdtoa.c b/lib/libc/gdtoa/_hdtoa.c
index 8ae739acf0db..9c42630cd918 100644
--- a/lib/libc/gdtoa/_hdtoa.c
+++ b/lib/libc/gdtoa/_hdtoa.c
@@ -40,6 +40,7 @@
#define DBL_ADJ (DBL_MAX_EXP - 2)
#define SIGFIGS ((DBL_MANT_DIG + 3) / 4 + 1)
+#define MAX_HEX_DIGITS ((DBL_MANT_DIG + 3 - 1) / 4 + 1)
static const float one[] = { 1.0f, -1.0f };
@@ -111,7 +112,7 @@ __hdtoa(double d, const char *xdigs, int ndigits, int *decpt, int *sign,
s0 = rv_alloc(bufsize);
/* Round to the desired number of digits. */
- if (SIGFIGS > ndigits && ndigits > 0) {
+ if (MAX_HEX_DIGITS > ndigits && ndigits > 0) {
float redux = one[u.bits.sign];
int offset = 4 * ndigits + DBL_MAX_EXP - 4 - DBL_MANT_DIG;
u.bits.exp = offset;
diff --git a/lib/libc/gdtoa/_hldtoa.c b/lib/libc/gdtoa/_hldtoa.c
index 965d2349d103..5f10d12c5c09 100644
--- a/lib/libc/gdtoa/_hldtoa.c
+++ b/lib/libc/gdtoa/_hldtoa.c
@@ -65,6 +65,7 @@ typedef uint32_t manl_t;
#define LDBL_ADJ (LDBL_MAX_EXP - 2)
#define SIGFIGS ((LDBL_MANT_DIG + 3) / 4 + 1)
+#define MAX_HEX_DIGITS ((LDBL_MANT_DIG + 3 - 1) / 4 + 1)
static const float one[] = { 1.0f, -1.0f };
@@ -125,7 +126,7 @@ __hldtoa(long double e, const char *xdigs, int ndigits, int *decpt, int *sign,
s0 = rv_alloc(bufsize);
/* Round to the desired number of digits. */
- if (SIGFIGS > ndigits && ndigits > 0) {
+ if (MAX_HEX_DIGITS > ndigits && ndigits > 0) {
float redux = one[u.bits.sign];
int offset = 4 * ndigits + LDBL_MAX_EXP - 4 - LDBL_MANT_DIG;
#ifdef __i386__
diff --git a/lib/libc/gen/Symbol.map b/lib/libc/gen/Symbol.map
index 26f638568efc..494b65bc5cc1 100644
--- a/lib/libc/gen/Symbol.map
+++ b/lib/libc/gen/Symbol.map
@@ -193,7 +193,6 @@ FBSD_1.0 {
__isinff;
__isinfl;
isatty;
- initgroups;
jrand48;
lcong48;
ldexp;
@@ -462,6 +461,7 @@ FBSD_1.8 {
fdscandir_b;
fts_open_b;
glob_b;
+ initgroups;
inotify_add_watch;
inotify_init;
inotify_init1;
diff --git a/lib/libc/gen/gen-compat.h b/lib/libc/gen/gen-compat.h
index 08e80ede6b6e..74678301af6f 100644
--- a/lib/libc/gen/gen-compat.h
+++ b/lib/libc/gen/gen-compat.h
@@ -52,4 +52,12 @@ int freebsd11_getmntinfo(struct freebsd11_statfs **, int);
char *freebsd11_devname(__uint32_t dev, __mode_t type);
char *freebsd11_devname_r(__uint32_t dev, __mode_t type, char *buf, int len);
+#define F14SG int freebsd14_setgroups(int gidsize, const __gid_t *gidset)
+#ifdef PIC
+static F14SG __attribute__((__weakref__("setgroups@FBSD_1.0")));
+#else
+F14SG;
+#endif
+#undef F14SG
+
#endif /* _GEN_COMPAT_H_ */
diff --git a/lib/libc/gen/getgrouplist.3 b/lib/libc/gen/getgrouplist.3
index e9a980f99751..e3939fc2481a 100644
--- a/lib/libc/gen/getgrouplist.3
+++ b/lib/libc/gen/getgrouplist.3
@@ -1,5 +1,13 @@
+.\"-
+.\" SPDX-License-Identifier: BSD-3-Clause
+.\"
.\" Copyright (c) 1991, 1993
.\" The Regents of the University of California. All rights reserved.
+.\" Copyright (c) 2025 The FreeBSD Foundation
+.\"
+.\" Portions of this documentation were written by Olivier Certner
+.\" <olce@FreeBSD.org> at Kumacom SARL under sponsorship from the FreeBSD
+.\" Foundation.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
@@ -25,12 +33,12 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd October 26, 2014
+.Dd August 29, 2025
.Dt GETGROUPLIST 3
.Os
.Sh NAME
.Nm getgrouplist
-.Nd calculate group access list
+.Nd produce a user's effective group list
.Sh LIBRARY
.Lb libc
.Sh SYNOPSIS
@@ -40,16 +48,16 @@
.Sh DESCRIPTION
The
.Fn getgrouplist
-function reads through the group file and calculates
-the group access list for the user specified in
-.Fa name .
-The
+function reads through the group database to retrieve the supplementary groups
+for the user specified in
+.Fa name ,
+and returns the effective group list, whose first group is the value of
+.Fa basegid
+and the others are the retrieved supplementary groups.
.Fa basegid
-is automatically included in the groups list.
-Typically this value is given as
-the group number from the password file.
+typically is the user's group number from the password database.
.Pp
-The resulting group list is returned in the array pointed to by
+The effective group list is returned in the array pointed to by
.Fa groups .
The caller specifies the size of the
.Fa groups
@@ -70,6 +78,7 @@ Here, the group array will be filled with as many groups as will fit.
group membership list
.El
.Sh SEE ALSO
+.Xr setcred 2 ,
.Xr setgroups 2 ,
.Xr initgroups 3
.Sh HISTORY
diff --git a/lib/libc/gen/initgroups.3 b/lib/libc/gen/initgroups.3
index 03bd07494fc9..4f538fb180ec 100644
--- a/lib/libc/gen/initgroups.3
+++ b/lib/libc/gen/initgroups.3
@@ -1,5 +1,13 @@
+.\"-
+.\" SPDX-License-Identifier: BSD-3-Clause
+.\"
.\" Copyright (c) 1983, 1991, 1993
.\" The Regents of the University of California. All rights reserved.
+.\" Copyright (c) 2025 The FreeBSD Foundation
+.\"
+.\" Portions of this documentation were written by Olivier Certner
+.\" <olce@FreeBSD.org> at Kumacom SARL under sponsorship from the FreeBSD
+.\" Foundation.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
@@ -25,12 +33,12 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd October 26, 2014
+.Dd September 17, 2025
.Dt INITGROUPS 3
.Os
.Sh NAME
.Nm initgroups
-.Nd initialize group access list
+.Nd initialize supplementary groups as per the group database
.Sh LIBRARY
.Lb libc
.Sh SYNOPSIS
@@ -40,19 +48,18 @@
.Sh DESCRIPTION
The
.Fn initgroups
-function
-uses the
-.Xr getgrouplist 3
-function to calculate the group access list for the user
-specified in
+function initializes the current process' supplementary groups as prescribed by
+its arguments and the system's group database.
+.Pp
+It first uses the
+.Fn getgrouplist
+function to compute a list of groups containing the passed
+.Fa basegid ,
+which typically is the user's initial numerical group ID from the password
+database, and the supplementary groups in the group database for the user named
.Fa name .
-This group list is then setup for the current process using
-.Xr setgroups 2 .
-The
-.Fa basegid
-is automatically included in the groups list.
-Typically this value is given as
-the group number from the password file.
+It then installs this list as the current process' supplementary groups using
+.Fn setgroups .
.Sh RETURN VALUES
.Rv -std initgroups
.Sh ERRORS
@@ -60,7 +67,7 @@ The
.Fn initgroups
function may fail and set
.Va errno
-for any of the errors specified for the library function
+to any of the errors specified for the library function
.Xr setgroups 2 .
It may also return:
.Bl -tag -width Er
@@ -77,3 +84,67 @@ The
.Fn initgroups
function appeared in
.Bx 4.2 .
+.Pp
+The
+.Fn initgroups
+function changed semantics in
+.Fx 15 ,
+following that of
+.Xr setgroups 2
+in the same release.
+Before that, it would also set the effective group ID to
+.Fa basegid ,
+and would not include the latter in the supplementary groups except before
+.Fx 8 .
+Its current behavior in these respects is known to be compatible with that of
+the following systems up to the specified versions that are current at time of
+this writing:
+.Bl -dash -width "-" -compact
+.It
+Linux (up to 6.6) with the GNU libc (up to 2.42)
+.It
+.Nx 1.1 and greater (up to 10)
+.It
+.Ox (up to 7.7)
+.It
+Systems based on illumos (up to August 2025 sources)
+.El
+.Sh SECURITY CONSIDERATIONS
+As
+.Fa basegid
+is typically the user's initial numerical group ID, to which the current
+process' effective group ID is generally initialized, processes using functions
+to change their effective group ID
+.Pq via Xr setgid 2 or similar
+or that are spawned from executables with the set-group-ID mode bit set will not
+be able to relinquish the access rights deriving from being a member of
+.Fa basegid ,
+as these functions do not change the supplementary groups.
+.Pp
+This behavior is generally desirable in order to paper over the difference of
+treatment between the effective group and supplementary ones in this situation,
+as they are all in the end indiscriminately used in traditional UNIX
+discretionary access checks.
+It blends well with the practice of allocating each user its own private group,
+as processes launched from a set-group-ID executable keep the same user and
+consistently stay also in the same user's group.
+Finally, it was also chosen for compatibility with other systems
+.Po
+see the
+.Sx HISTORY
+section
+.Pc .
+.Pp
+This convention of including
+.Fa basegid
+in the supplementary groups is however only enforced by the
+.Fn initgroups
+function, and not by the
+.Xr setgroups 2
+system call, so applications expressly wanting to include in the supplementary
+groups only those specified by the group database can themselves call
+.Fn getgrouplist
+and then
+.Fn setgroups
+on the result with the first element skipped
+.Pq see Xr getgrouplist 3 .
diff --git a/lib/libc/gen/initgroups.c b/lib/libc/gen/initgroups.c
index b6697dd7ed8f..a1a7d92250e2 100644
--- a/lib/libc/gen/initgroups.c
+++ b/lib/libc/gen/initgroups.c
@@ -3,6 +3,11 @@
*
* Copyright (c) 1983, 1993
* The Regents of the University of California. All rights reserved.
+ * Copyright (c) 2025 The FreeBSD Foundation
+ *
+ * Portions of this software were developed by Olivier Certner
+ * <olce@FreeBSD.org> at Kumacom SARL under sponsorship from the FreeBSD
+ * Foundation.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -29,34 +34,52 @@
* SUCH DAMAGE.
*/
-#include <sys/param.h>
+/* For __sym_compat(). */
+#include <sys/cdefs.h>
-#include "namespace.h"
-#include <err.h>
-#include "un-namespace.h"
#include <errno.h>
-#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
-int
-initgroups(const char *uname, gid_t agroup)
+/* For freebsd14_setgroups(). */
+#include "gen-compat.h"
+
+static int
+initgroups_impl(const char *uname, gid_t agroup,
+ int (*setgroups)(int, const gid_t *))
{
- int ngroups, ret;
- long ngroups_max;
gid_t *groups;
+ long ngroups_max;
+ int ngroups, ret;
/*
- * Provide space for one group more than possible to allow
- * setgroups to fail and set errno.
+ * Provide space for one group more than possible to allow setgroups()
+ * to fail and set 'errno' in case we get back more than {NGROUPS_MAX} +
+ * 1 groups.
*/
ngroups_max = sysconf(_SC_NGROUPS_MAX) + 2;
- if ((groups = malloc(sizeof(*groups) * ngroups_max)) == NULL)
- return (ENOMEM);
+ groups = malloc(sizeof(*groups) * ngroups_max);
+ if (groups == NULL)
+ return (-1); /* malloc() set 'errno'. */
ngroups = (int)ngroups_max;
- getgrouplist(uname, agroup, groups, &ngroups);
- ret = setgroups(ngroups, groups);
+ (void)getgrouplist(uname, agroup, groups, &ngroups);
+ ret = (*setgroups)(ngroups, groups);
+
free(groups);
- return (ret);
+ return (ret); /* setgroups() set 'errno'. */
}
+
+int
+initgroups(const char *uname, gid_t agroup)
+{
+ return (initgroups_impl(uname, agroup, setgroups));
+}
+
+int
+freebsd14_initgroups(const char *uname, gid_t agroup)
+{
+ return (initgroups_impl(uname, agroup, freebsd14_setgroups));
+}
+
+__sym_compat(initgroups, freebsd14_initgroups, FBSD_1.0);
diff --git a/lib/libc/include/compat.h b/lib/libc/include/compat.h
index 97f22607ddd7..630ffe7daae3 100644
--- a/lib/libc/include/compat.h
+++ b/lib/libc/include/compat.h
@@ -80,4 +80,3 @@ __sym_compat(setgroups, freebsd14_setgroups, FBSD_1.0);
#undef __weak_reference
#endif /* __LIBC_COMPAT_H__ */
-
diff --git a/lib/libc/stdtime/ctime.3 b/lib/libc/stdtime/ctime.3
index 96b7f775535a..6384e8bd959b 100644
--- a/lib/libc/stdtime/ctime.3
+++ b/lib/libc/stdtime/ctime.3
@@ -27,7 +27,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd March 26, 2024
+.Dd September 23, 2025
.Dt CTIME 3
.Os
.Sh NAME
@@ -41,6 +41,8 @@
.Nm localtime ,
.Nm localtime_r ,
.Nm mktime ,
+.Nm offtime ,
+.Nm offtime_r ,
.Nm timegm
.Nd transform binary date and time values
.Sh LIBRARY
@@ -68,14 +70,19 @@
.Fn localtime_r "const time_t *clock" "struct tm *result"
.Ft time_t
.Fn mktime "struct tm *tm"
+.Ft struct tm *
+.Fn offtime "const time_t *clock" "long offset"
+.Ft struct tm *
+.Fn offtime_r "const time_t *clock" "long offset" "struct tm *result"
.Ft time_t
.Fn timegm "struct tm *tm"
.Sh DESCRIPTION
The
.Fn ctime ,
.Fn gmtime ,
+.Fn localtime ,
and
-.Fn localtime
+.Fn offtime
functions all take as argument a pointer to a time value representing
the time in seconds since the Epoch (00:00:00 UTC on January 1, 1970;
see
@@ -123,6 +130,18 @@ adjustment, and returns a pointer to a
.Vt struct tm .
.Pp
The
+.Fn offtime
+function similarly converts the time value with a time zone adjustment
+corresponding to the provided
+.Fa offset ,
+which is expressed in seconds, with positive values indicating a time
+zone ahead of UTC (east of the Prime Meridian).
+It does not call
+.Xr tzset 3
+or modify
+.Va tzname .
+.Pp
+The
.Fn ctime
function
adjusts the time value for the current time zone in the same manner as
@@ -155,13 +174,15 @@ except the caller must provide the output buffer
.Fa buf ,
which must be at least 26 characters long, to store the result in.
The
-.Fn localtime_r
+.Fn localtime_r ,
+.Fn gmtime_r ,
and
-.Fn gmtime_r
+.Fn offtime_r
functions provide the same functionality as
-.Fn localtime
+.Fn localtime ,
+.Fn gmtime ,
and
-.Fn gmtime
+.Fn offtime
respectively, except the caller must provide the output buffer
.Fa result .
.Pp
@@ -368,6 +389,12 @@ and
.Fn localtime_r
functions have been available since
.Fx 8.0 .
+The
+.Fn offtime
+and
+.Fn offtime_r
+functions were added in
+.Fx 15.0 .
.Sh BUGS
Except for
.Fn difftime ,
diff --git a/lib/libc/tests/stdio/printfloat_test.c b/lib/libc/tests/stdio/printfloat_test.c
index 031859124163..4493fe1c15d3 100644
--- a/lib/libc/tests/stdio/printfloat_test.c
+++ b/lib/libc/tests/stdio/printfloat_test.c
@@ -398,6 +398,18 @@ ATF_TC_BODY(subnormal_float, tc)
testfmt("-0X1P-149", "%A", negative);
}
+ATF_TC_WITHOUT_HEAD(hexadecimal_rounding_fullprec);
+ATF_TC_BODY(hexadecimal_rounding_fullprec, tc)
+{
+ /* Double: %.13a with binary64 mantissa=53 */
+ testfmt("0x1.1234567890bbbp+0", "%.13a", 0x1.1234567890bbbp+0);
+
+#if defined(__aarch64__)
+ /* On arm64, long double is IEEE binary128 (mantissa=113) */
+ testfmt("0x1.3c0ca428c59fbbbbbbbbbbbbbbbbp+0", "%.28La", 0x1.3c0ca428c59fbbbbbbbbbbbbbbbbp+0L);
+#endif
+}
+
ATF_TP_ADD_TCS(tp)
{
@@ -414,6 +426,7 @@ ATF_TP_ADD_TCS(tp)
ATF_TP_ADD_TC(tp, hexadecimal_rounding);
ATF_TP_ADD_TC(tp, subnormal_double);
ATF_TP_ADD_TC(tp, subnormal_float);
+ ATF_TP_ADD_TC(tp, hexadecimal_rounding_fullprec);
return (atf_no_error());
}
diff --git a/lib/libc/tests/tls/dso/Makefile b/lib/libc/tests/tls/dso/Makefile
index 5efd8b29a6bd..783534ff7aae 100644
--- a/lib/libc/tests/tls/dso/Makefile
+++ b/lib/libc/tests/tls/dso/Makefile
@@ -6,6 +6,7 @@ SRCS= h_tls_dlopen.c
MAN=
PACKAGE= tests
+NO_DEV_PACKAGE=
LIBDIR= ${TESTSBASE}/lib/libc/tls
SHLIB_MAJOR= 1
diff --git a/lib/libc/tests/tls_dso/Makefile b/lib/libc/tests/tls_dso/Makefile
index 89296c643695..7cb8f98b431e 100644
--- a/lib/libc/tests/tls_dso/Makefile
+++ b/lib/libc/tests/tls_dso/Makefile
@@ -7,6 +7,7 @@ LIBDIR= ${TESTSBASE}/lib/libc/tls
SHLIBDIR= ${TESTSBASE}/lib/libc/tls
SHLIB_MAJOR= 1
PACKAGE= tests
+NO_DEV_PACKAGE=
WITHOUT_STATIC=
WITHOUT_PROFILE=