diff options
Diffstat (limited to 'lib/libc')
37 files changed, 565 insertions, 204 deletions
diff --git a/lib/libc/Makefile b/lib/libc/Makefile index d0c254e33396..8705568f6d34 100644 --- a/lib/libc/Makefile +++ b/lib/libc/Makefile @@ -109,7 +109,6 @@ NOASM= .include "${LIBC_SRCTOP}/inet/Makefile.inc" .include "${LIBC_SRCTOP}/isc/Makefile.inc" .include "${LIBC_SRCTOP}/locale/Makefile.inc" -.include "${LIBC_SRCTOP}/md/Makefile.inc" .include "${LIBC_SRCTOP}/nameser/Makefile.inc" .include "${LIBC_SRCTOP}/net/Makefile.inc" .include "${LIBC_SRCTOP}/nls/Makefile.inc" diff --git a/lib/libc/Versions.def b/lib/libc/Versions.def index 184e107d225a..1c7b34bef35b 100644 --- a/lib/libc/Versions.def +++ b/lib/libc/Versions.def @@ -42,6 +42,10 @@ FBSD_1.7 { FBSD_1.8 { } FBSD_1.7; +# This version was first added to 16.0-current. +FBSD_1.9 { +} FBSD_1.8; + # This is our private namespace. Any global interfaces that are # strictly for use only by other FreeBSD applications and libraries # are listed here. We use a separate namespace so we can write @@ -49,4 +53,4 @@ FBSD_1.8 { # # Please do NOT increment the version of this namespace. FBSDprivate_1.0 { -} FBSD_1.8; +} FBSD_1.9; diff --git a/lib/libc/aarch64/string/timingsafe_memcmp.S b/lib/libc/aarch64/string/timingsafe_memcmp.S index 28fdd911a387..4cc10a152aa8 100644 --- a/lib/libc/aarch64/string/timingsafe_memcmp.S +++ b/lib/libc/aarch64/string/timingsafe_memcmp.S @@ -114,4 +114,4 @@ ENTRY(timingsafe_memcmp) csetm w0, lo csinc w0, w0, wzr, ls ret -END(timingsafe_bcmp) +END(timingsafe_memcmp) 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/fts-compat.c b/lib/libc/gen/fts-compat.c index f87cabf085f7..62a1e0a81f62 100644 --- a/lib/libc/gen/fts-compat.c +++ b/lib/libc/gen/fts-compat.c @@ -44,9 +44,9 @@ #include <stdlib.h> #include <string.h> #include <unistd.h> -#include "gen-compat.h" #include "fts-compat.h" #include "un-namespace.h" +#include "gen-compat.h" #include "gen-private.h" diff --git a/lib/libc/gen/fts-compat11.c b/lib/libc/gen/fts-compat11.c index 0351ce5ac690..5abb378f5f08 100644 --- a/lib/libc/gen/fts-compat11.c +++ b/lib/libc/gen/fts-compat11.c @@ -43,9 +43,9 @@ #include <stdlib.h> #include <string.h> #include <unistd.h> -#include "gen-compat.h" #include "fts-compat11.h" #include "un-namespace.h" +#include "gen-compat.h" #include "gen-private.h" diff --git a/lib/libc/gen/fts.3 b/lib/libc/gen/fts.3 index ee558b892c8c..b937607b48e0 100644 --- a/lib/libc/gen/fts.3 +++ b/lib/libc/gen/fts.3 @@ -25,7 +25,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd June 30, 2025 +.Dd October 1, 2025 .Dt FTS 3 .Os .Sh NAME @@ -376,7 +376,44 @@ The .Fa fts_name field is always .Dv NUL Ns -terminated . -.Sh FTS_OPEN +.Ss Thread Safety +The +.Nm +functions can safely be used in multi-threaded programs provided no +two threads access the same +.Vt FTS +or +.Vt FTSENT +structure simultaneously. +However, unless the +.Dv FTS_NOCHDIR +flag was passed to +.Fn fts_open +or +.Fn fts_open_b , +calls to +.Fn fts_read +and +.Fn fts_children +may change the current working directory, which will affect all +threads. +Conversely, changing the current working directory either during or +between calls to +.Fn fts_read +or +.Fn fts_children +(even in a single-thread program) may cause +.Nm +to malfunction unless the +.Dv FTS_NOCHDIR +flag was passed to +.Fn fts_open +or +.Fn fts_open_b +and all paths in +.Va path_argv +were absolute. +.Ss Fn fts_open The .Fn fts_open function takes a pointer to an array of character pointers naming one @@ -545,7 +582,7 @@ the directory traversal order is in the order listed in .Fa path_argv for the root paths, and in the order listed in the directory for everything else. -.Sh FTS_OPEN_B +.Ss Fn fts_open_b The .Fn fts_open_b function is identical to @@ -554,7 +591,7 @@ except that it takes a block pointer instead of a function pointer. The block is copied before .Fn fts_open_b returns, so the original can safely go out of scope or be released. -.Sh FTS_READ +.Ss Fn fts_read The .Fn fts_read function returns a pointer to an @@ -605,7 +642,7 @@ after the structure has been returned by the function .Fn fts_read in post-order. -.Sh FTS_CHILDREN +.Ss Fn fts_children The .Fn fts_children function returns a pointer to an @@ -679,7 +716,7 @@ and .Fa fts_namelen fields. .El -.Sh FTS_SET +.Ss Fn fts_set The function .Fn fts_set allows the user application to determine further processing for the @@ -749,7 +786,7 @@ The file may be one of those most recently returned by either or .Fn fts_read . .El -.Sh FTS_CLOSE +.Ss Fn fts_close The .Fn fts_close function closes a file hierarchy stream diff --git a/lib/libc/gen/gen-compat.h b/lib/libc/gen/gen-compat.h index 08e80ede6b6e..19b9addb4321 100644 --- a/lib/libc/gen/gen-compat.h +++ b/lib/libc/gen/gen-compat.h @@ -40,16 +40,50 @@ struct freebsd11_statfs; struct freebsd11_dirent *freebsd11_readdir(DIR *); int freebsd11_readdir_r(DIR *, struct freebsd11_dirent *, struct freebsd11_dirent **); -int freebsd11_stat(const char *, struct freebsd11_stat *); -int freebsd11_lstat(const char *, struct freebsd11_stat *); -int freebsd11_fstat(int, struct freebsd11_stat *); -int freebsd11_fstatat(int, const char *, struct freebsd11_stat *, int); -int freebsd11_statfs(const char *, struct freebsd11_statfs *); -int freebsd11_getfsstat(struct freebsd11_statfs *, long, int); 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); +char *freebsd11_devname_r(__uint32_t dev, __mode_t type, char *buf, + int len); + +/* + * We want freebsd11_fstat in C source to result in resolution to + * - fstat@FBSD_1.0 for libc.so (but we do not need the _definition_ + * of this fstat, it is provided by libsys.so which we want to use). + * - freebsd11_fstat for libc.a (since if we make it fstat@FBSD_1.0 + * for libc.a, then final linkage into static object ignores version + * and would reference fstat, which is the current syscall, not the + * compat syscall). libc.a provides the freebsd11_fstat implementation. + * Note that freebsd11_fstat from libc.a is not used for anything, but + * we make it correct nonetheless, just in case it would. + * This is arranged by COMPAT_SYSCALL, and libc can just use freebsd11_fstat. + */ +#ifdef PIC +#define COMPAT_SYSCALL(rtype, fun, args, sym, ver) \ + rtype fun args; __sym_compat(sym, fun, ver); +#else +#define COMPAT_SYSCALL(rtype, fun, args, sym, ver) \ + rtype fun args; +#endif + +COMPAT_SYSCALL(int, freebsd11_stat, (const char *, struct freebsd11_stat *), + stat, FBSD_1.0); +COMPAT_SYSCALL(int, freebsd11_lstat, (const char *, struct freebsd11_stat *), + lstat, FBSD_1.0); +COMPAT_SYSCALL(int, freebsd11_fstat, (int, struct freebsd11_stat *), + fstat, FBSD_1.0); +COMPAT_SYSCALL(int, freebsd11_fstatat, (int, const char *, + struct freebsd11_stat *, int), fstatat, FBSD_1.1); + +COMPAT_SYSCALL(int, freebsd11_statfs, (const char *, + struct freebsd11_statfs *), statfs, FBSD_1.0); +COMPAT_SYSCALL(int, freebsd11_getfsstat, (struct freebsd11_statfs *, long, + int), getfsstat, FBSD_1.0); + +COMPAT_SYSCALL(int, freebsd14_setgroups, (int gidsize, const __gid_t *gidset), + setgroups, FBSD_1.0); + +#undef COMPAT_SYSCALL #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/getgrouplist.c b/lib/libc/gen/getgrouplist.c index 5bd06bc5121f..9c57b7031336 100644 --- a/lib/libc/gen/getgrouplist.c +++ b/lib/libc/gen/getgrouplist.c @@ -29,13 +29,8 @@ * SUCH DAMAGE. */ -/* - * get credential - */ #include <sys/types.h> -#include <grp.h> -#include <string.h> #include <unistd.h> #include <ssp/ssp.h> @@ -46,4 +41,3 @@ __ssp_real(getgrouplist)(const char *uname, gid_t agroup, gid_t *groups, int *gr { return __getgroupmembership(uname, agroup, groups, *grpcnt, grpcnt); } - 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/gen/psignal.3 b/lib/libc/gen/psignal.3 index 098b7b02a9b9..bf6a99b4b113 100644 --- a/lib/libc/gen/psignal.3 +++ b/lib/libc/gen/psignal.3 @@ -25,7 +25,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd May 10, 2025 +.Dd September 23, 2025 .Dt PSIGNAL 3 .Os .Sh NAME @@ -141,6 +141,13 @@ The name in can be either the name of the signal, with or without the .Dq SIG prefix, or a decimal number. +.Sh RETURN VALUES +The +.Fn sig2str +and +.Fn str2sig +return 0 on success and -1 on translation failure. +In the latter case the memory to store the translation result is left intact. .Sh SEE ALSO .Xr sigaction 2 , .Xr perror 3 , diff --git a/lib/libc/gen/sysconf.c b/lib/libc/gen/sysconf.c index 66562d0e29f0..b5b732eed05d 100644 --- a/lib/libc/gen/sysconf.c +++ b/lib/libc/gen/sysconf.c @@ -51,7 +51,7 @@ #include "un-namespace.h" #include "../stdlib/atexit.h" -#include "tzdir.h" /* from ../../../contrib/tzcode/stdtime */ +#include "tzdir.h" /* from ../../../contrib/tzcode */ #include "libc_private.h" #define _PATH_ZONEINFO TZDIR /* from tzfile.h */ 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/include/port_before.h b/lib/libc/include/port_before.h index cfc43c53f157..aa2cd394104a 100644 --- a/lib/libc/include/port_before.h +++ b/lib/libc/include/port_before.h @@ -5,7 +5,6 @@ #define _LIBC 1 #define DO_PTHREADS 1 #define USE_POLL 1 -#define HAVE_MD5 1 #define ISC_SOCKLEN_T socklen_t #define ISC_FORMAT_PRINTF(fmt, args) \ diff --git a/lib/libc/md/Makefile.inc b/lib/libc/md/Makefile.inc deleted file mode 100644 index 82c5f0670485..000000000000 --- a/lib/libc/md/Makefile.inc +++ /dev/null @@ -1,3 +0,0 @@ -.PATH: ${SRCTOP}/sys/kern - -SRCS+= md5c.c diff --git a/lib/libc/nls/Makefile.inc b/lib/libc/nls/Makefile.inc index f26e04c187a5..c211026aba72 100644 --- a/lib/libc/nls/Makefile.inc +++ b/lib/libc/nls/Makefile.inc @@ -12,6 +12,11 @@ MAN+= catclose.3 catgets.3 catopen.3 # for translators. NLSNAME= libc +# We don't want libc's NLS catalogues to be installed in the clibs package. +# Put them in locales instead, since anyone interested in NLS will have +# that installed. +NLSPACKAGE= locales + NLS+= be_BY.UTF-8 NLS+= ca_ES.ISO8859-1 NLS+= de_DE.ISO8859-1 diff --git a/lib/libc/resolv/Symbol.map b/lib/libc/resolv/Symbol.map index 6b9c43298fb5..26daecbe2eff 100644 --- a/lib/libc/resolv/Symbol.map +++ b/lib/libc/resolv/Symbol.map @@ -103,6 +103,5 @@ FBSD_1.0 { }; FBSD_1.4 { - __res_rndinit; __res_nrandomid; }; diff --git a/lib/libc/resolv/res_init.c b/lib/libc/resolv/res_init.c index 71ab2dcb7038..5a2fce013c8c 100644 --- a/lib/libc/resolv/res_init.c +++ b/lib/libc/resolv/res_init.c @@ -86,19 +86,6 @@ #include <unistd.h> #include <netdb.h> -#ifndef HAVE_MD5 -# include "../dst/md5.h" -#else -# ifdef SOLARIS2 -# include <sys/md5.h> -# elif _LIBC -# include <md5.h> -# endif -#endif -#ifndef _MD5_H_ -# define _MD5_H_ 1 /*%< make sure we do not include rsaref md5.h file */ -#endif - #include "un-namespace.h" #include "port_after.h" @@ -184,8 +171,6 @@ __res_vinit(res_state statp, int preinit) { statp->options = RES_DEFAULT; } - statp->_rnd = malloc(16); - res_rndinit(statp); statp->id = res_nrandomid(statp); memset(u, 0, sizeof(u)); @@ -733,48 +718,18 @@ net_mask(struct in_addr in) /*!< XXX - should really use system's version of th } #endif -static u_char srnd[16]; - void -res_rndinit(res_state statp) +freebsd15_res_rndinit(res_state statp) { - struct timeval now; - u_int32_t u32; - u_int16_t u16; - u_char *rnd = statp->_rnd == NULL ? srnd : statp->_rnd; - - gettimeofday(&now, NULL); - u32 = now.tv_sec; - memcpy(rnd, &u32, 4); - u32 = now.tv_usec; - memcpy(rnd + 4, &u32, 4); - u32 += now.tv_sec; - memcpy(rnd + 8, &u32, 4); - u16 = getpid(); - memcpy(rnd + 12, &u16, 2); + (void)statp; } +__sym_compat(__res_rndinit, freebsd15_res_rndinit, FBSD_1.4); u_int res_nrandomid(res_state statp) { - struct timeval now; - u_int16_t u16; - MD5_CTX ctx; - u_char *rnd = statp->_rnd == NULL ? srnd : statp->_rnd; - - gettimeofday(&now, NULL); - u16 = (u_int16_t) (now.tv_sec ^ now.tv_usec); - memcpy(rnd + 14, &u16, 2); -#ifndef HAVE_MD5 - MD5_Init(&ctx); - MD5_Update(&ctx, rnd, 16); - MD5_Final(rnd, &ctx); -#else - MD5Init(&ctx); - MD5Update(&ctx, rnd, 16); - MD5Final(rnd, &ctx); -#endif - memcpy(&u16, rnd + 14, 2); - return ((u_int) u16); + (void) statp; + + return ((u_int)(arc4random() & 0xffff)); } /*% @@ -808,10 +763,6 @@ res_ndestroy(res_state statp) { free(statp->_u._ext.ext); statp->_u._ext.ext = NULL; } - if (statp->_rnd != NULL) { - free(statp->_rnd); - statp->_rnd = NULL; - } statp->options &= ~RES_INIT; } diff --git a/lib/libc/rpc/rpc_generic.c b/lib/libc/rpc/rpc_generic.c index 0e563f6a5996..8019f2d8f236 100644 --- a/lib/libc/rpc/rpc_generic.c +++ b/lib/libc/rpc/rpc_generic.c @@ -610,6 +610,10 @@ __rpc_taddr2uaddr_af(int af, const struct netbuf *nbuf) return NULL; break; #endif + case AF_NETLINK: + if (asprintf(&ret, "%s", (char *)nbuf->buf) < 0) + return NULL; + break; case AF_LOCAL: sun = nbuf->buf; if (asprintf(&ret, "%.*s", (int)(sun->sun_len - diff --git a/lib/libc/stdlib/Makefile.inc b/lib/libc/stdlib/Makefile.inc index ca199a669be1..e7b9955b9646 100644 --- a/lib/libc/stdlib/Makefile.inc +++ b/lib/libc/stdlib/Makefile.inc @@ -10,7 +10,7 @@ MISRCS+=C99_Exit.c a64l.c abort.c abs.c atexit.c atof.c atoi.c atol.c atoll.c \ insque.c l64a.c labs.c ldiv.c llabs.c lldiv.c lsearch.c \ merge.c mergesort_b.c ptsname.c qsort.c qsort_r.c qsort_r_compat.c \ qsort_s.c quick_exit.c radixsort.c rand.c \ - random.c reallocarray.c reallocf.c realpath.c remque.c \ + random.c reallocarray.c reallocf.c realpath.c recallocarray.c remque.c \ set_constraint_handler_s.c strfmon.c strtoimax.c \ strtol.c strtold.c strtoll.c strtoq.c strtoul.c strtonum.c strtoull.c \ strtoumax.c strtouq.c system.c tdelete.c tfind.c tsearch.c twalk.c @@ -76,6 +76,7 @@ MLINKS+=random.3 initstate.3 \ random.3 srandom.3 \ random.3 srandomdev.3 MLINKS+=radixsort.3 sradixsort.3 +MLINKS+=reallocarray.3 recallocarray.3 MLINKS+=set_constraint_handler_s.3 abort_handler_s.3 MLINKS+=set_constraint_handler_s.3 ignore_handler_s.3 MLINKS+=strfmon.3 strfmon_l.3 diff --git a/lib/libc/stdlib/Symbol.map b/lib/libc/stdlib/Symbol.map index 2b79ca2ece8b..53d71bcafb7d 100644 --- a/lib/libc/stdlib/Symbol.map +++ b/lib/libc/stdlib/Symbol.map @@ -131,6 +131,10 @@ FBSD_1.8 { getenv_r; }; +FBSD_1.9 { + recallocarray; +}; + FBSDprivate_1.0 { __system; _system; diff --git a/lib/libc/stdlib/reallocarray.3 b/lib/libc/stdlib/reallocarray.3 index 80035c67a497..9a2ab5c7a840 100644 --- a/lib/libc/stdlib/reallocarray.3 +++ b/lib/libc/stdlib/reallocarray.3 @@ -26,7 +26,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd May 1, 2015 +.Dd October 2, 2025 .Dt REALLOCARRAY 3 .Os .Sh NAME @@ -38,6 +38,8 @@ .In stdlib.h .Ft void * .Fn reallocarray "void *ptr" "size_t nmemb" "size_t size" +.Ft void * +.Fn recallocarray "void *ptr" "size_t oldnmeb" "size_t nmemb" size_t size" .Sh DESCRIPTION The .Fn reallocarray @@ -52,6 +54,33 @@ and checks for integer overflow in the calculation .Fa nmemb * .Fa size . +.Pp +The +.Fn recallocarray +function is similar to the +.Fn reallocarray +function +except it ensures newly allocated memory is cleared similar to +.Fn calloc . +If +.Fa ptr +is +.Dv NULL , +.Fa oldnmemb +is ignored and the call is equivalent to +.Fn calloc . +If +.Fa ptr +is not +.Dv NULL , +.Fa oldnmemb +must be a value such that +.Fa oldnmemb +* +.Fa size +is the size of the earlier allocation that returned +.Fa ptr , +otherwise the behaviour is undefined. .Sh RETURN VALUES The .Fn reallocarray @@ -142,3 +171,9 @@ function first appeared in .Ox 5.6 and .Fx 11.0 . +The +.Fn recallocarray +function first appeared in +.Ox 6.1 +and +.Fx 16.0 . diff --git a/lib/libc/stdlib/reallocarray.c b/lib/libc/stdlib/reallocarray.c index 0868804486cc..3632734c84de 100644 --- a/lib/libc/stdlib/reallocarray.c +++ b/lib/libc/stdlib/reallocarray.c @@ -17,23 +17,19 @@ #include <sys/types.h> #include <errno.h> +#include <stdckdint.h> #include <stdint.h> #include <stdlib.h> -/* - * This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX - * if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW - */ -#define MUL_NO_OVERFLOW ((size_t)1 << (sizeof(size_t) * 4)) - void * reallocarray(void *optr, size_t nmemb, size_t size) { + size_t nbytes; - if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) && - nmemb > 0 && SIZE_MAX / nmemb < size) { + if (ckd_mul(&nbytes, nmemb, size)) { errno = ENOMEM; return (NULL); } - return (realloc(optr, size * nmemb)); + + return (realloc(optr, nbytes)); } diff --git a/lib/libc/stdlib/recallocarray.c b/lib/libc/stdlib/recallocarray.c new file mode 100644 index 000000000000..cbf1fb2470cf --- /dev/null +++ b/lib/libc/stdlib/recallocarray.c @@ -0,0 +1,73 @@ +/* $OpenBSD: recallocarray.c,v 1.1 2017/03/06 18:44:21 otto Exp $ */ +/* + * Copyright (c) 2008, 2017 Otto Moerbeek <otto@drijf.net> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <errno.h> +#include <stdckdint.h> +#include <stdlib.h> +#include <stdint.h> +#include <string.h> +#include <unistd.h> + +void *recallocarray(void *, size_t, size_t, size_t); + +void * +recallocarray(void *ptr, size_t oldnmemb, size_t newnmemb, size_t size) +{ + size_t oldsize, newsize; + void *newptr; + + if (ptr == NULL) + return calloc(newnmemb, size); + + if (ckd_mul(&newsize, newnmemb, size)) { + errno = ENOMEM; + return NULL; + } + + if (ckd_mul(&oldsize, oldnmemb, size)) { + errno = EINVAL; + return NULL; + } + + /* + * Don't bother too much if we're shrinking just a bit, + * we do not shrink for series of small steps, oh well. + */ + if (newsize <= oldsize) { + size_t d = oldsize - newsize; + + if (d < oldsize / 2 && d < (size_t)getpagesize()) { + memset((char *)ptr + newsize, 0, d); + return ptr; + } + } + + newptr = malloc(newsize); + if (newptr == NULL) + return NULL; + + if (newsize > oldsize) { + memcpy(newptr, ptr, oldsize); + memset((char *)newptr + oldsize, 0, newsize - oldsize); + } else + memcpy(newptr, ptr, newsize); + + explicit_bzero(ptr, oldsize); + free(ptr); + + return newptr; +} diff --git a/lib/libc/stdtime/Makefile.inc b/lib/libc/stdtime/Makefile.inc index 647cbe6f40ba..1baa39a6c0a6 100644 --- a/lib/libc/stdtime/Makefile.inc +++ b/lib/libc/stdtime/Makefile.inc @@ -32,4 +32,5 @@ MLINKS+=strftime.3 strftime_l.3 MLINKS+=strptime.3 strptime_l.3 MLINKS+=time2posix.3 posix2time.3 MLINKS+=tzset.3 daylight.3 \ - tzset.3 timezone.3 + tzset.3 timezone.3 \ + tzset.3 tzname.3 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/stdtime/tzset.3 b/lib/libc/stdtime/tzset.3 index 94ccbec9aba7..33e6a556306d 100644 --- a/lib/libc/stdtime/tzset.3 +++ b/lib/libc/stdtime/tzset.3 @@ -28,7 +28,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd December 25, 2023 +.Dd September 30, 2025 .Dt TZSET 3 .Os .Sh NAME @@ -58,8 +58,8 @@ specifies how this is done. .Pp If .Ev TZ -does not appear in the environment, the best available approximation to -local wall clock time, as specified by the +does not appear in the environment, the best available approximation +to local wall clock time, as specified by the .Xr tzfile 5 Ns -format file .Pa /etc/localtime @@ -68,9 +68,7 @@ is used. If .Ev TZ appears in the environment but its value is a null string, Coordinated -Universal Time -.Pq Tn UTC -is used (without leap second correction). +Universal Time (UTC) is used (without leap second correction). .Pp If .Ev TZ @@ -81,13 +79,12 @@ the rest of its value is used as a pathname of a file from which to read the time conversion information. If the first character of the pathname is a slash .Pq Ql / -it is used as -an absolute pathname; otherwise, it is used as a pathname relative to -the system time conversion information directory. +it is used as an absolute pathname; otherwise, it is used as a +pathname relative to the system time conversion information directory. .Pp -If its value does not begin with a colon, it is first used as the pathname -of a file (as described above) from which to read the time conversion -information. +If its value does not begin with a colon, it is first used as the +pathname of a file (as described above) from which to read the time +conversion information. If that file cannot be read, the value is then interpreted as a direct specification (the format is described below) of the time conversion information. @@ -96,24 +93,23 @@ If the .Ev TZ environment variable does not specify a .Xr tzfile 5 Ns -format -file and cannot be interpreted as a direct specification, -.Tn UTC -is used. +file and cannot be interpreted as a direct specification, UTC is used. .Pp After the first call to .Nm tzset , the .Vt timezone -variable is set to the difference, in seconds, between Coordinated Universal -Time (UTC) and the local time. +variable is set to the difference, in seconds, between Coordinated +Universal Time (UTC) and the local time. The .Vt daylight variable is set to 0 if the local timezone is observing standard time. -It is set to 1 if the local timezone ever observes an alternate time, such as summer time. +It is set to 1 if the local timezone ever observes an alternate time, +such as summer time. The first element of the .Vt tzname -array is the timezone name of standard time, while the second element is the -name of the altnerative time zone. +array is the timezone name of standard time, while the second element +is the name of the altnerative time zone. .Sh SPECIFICATION FORMAT When .Ev TZ @@ -151,8 +147,7 @@ minus .Pq Ql \- , plus .Pq Ql + , -and -.Tn ASCII +and ASCII .Dv NUL are allowed. .It Em offset @@ -294,10 +289,8 @@ by the file .Em posixrules in the system time conversion information directory are used, with the -standard and summer time offsets from -.Tn UTC -replaced by those specified by -the +standard and summer time offsets from UTC replaced by those specified +by the .Em offset values in .Ev TZ . @@ -315,20 +308,14 @@ local time zone file .It Pa /usr/share/zoneinfo time zone directory .It Pa /usr/share/zoneinfo/posixrules -rules for -.Tn POSIX Ns -style -.Tn TZ Ns 's +rules for POSIX-style TZs .It Pa /usr/share/zoneinfo/Etc/GMT -for -.Tn UTC -leap seconds +for UTC leap seconds .El .Pp If the file .Pa /usr/share/zoneinfo/UTC -does not exist, -.Tn UTC -leap seconds are loaded from +does not exist, UTC leap seconds are loaded from .Pa /usr/share/zoneinfo/posixrules . .Sh SEE ALSO .Xr date 1 , 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/stdtime/Makefile b/lib/libc/tests/stdtime/Makefile index 6b9068e1641b..590dea22da31 100644 --- a/lib/libc/tests/stdtime/Makefile +++ b/lib/libc/tests/stdtime/Makefile @@ -3,6 +3,7 @@ ATF_TESTS_C+= strptime_test ATF_TESTS_C+= detect_tz_changes_test +CFLAGS.detect_tz_changes_test+= -I${SRCTOP}/contrib/tzcode .if ${MK_DETECT_TZ_CHANGES} != "no" CFLAGS.detect_tz_changes_test+= -DDETECT_TZ_CHANGES .endif diff --git a/lib/libc/tests/stdtime/detect_tz_changes_test.c b/lib/libc/tests/stdtime/detect_tz_changes_test.c index 6648d8498cc5..06c31c9fbc3d 100644 --- a/lib/libc/tests/stdtime/detect_tz_changes_test.c +++ b/lib/libc/tests/stdtime/detect_tz_changes_test.c @@ -20,12 +20,16 @@ #include <time.h> #include <unistd.h> +#include "tzdir.h" + #include <atf-c.h> -static const struct tzcase { +struct tzcase { const char *tzfn; const char *expect; -} tzcases[] = { +}; + +static const struct tzcase tzcases[] = { /* * A handful of time zones and the expected result of * strftime("%z (%Z)", tm) when that time zone is active @@ -41,7 +45,8 @@ static const struct tzcase { { "UTC", "+0000 (UTC)" }, { 0 }, }; - +static const struct tzcase utc = { "UTC", "+0000 (UTC)" }; +static const struct tzcase invalid = { "invalid", "+0000 (-00)" }; static const time_t then = 1751328000; /* 2025-07-01 00:00:00 UTC */ static bool debugging; @@ -62,9 +67,9 @@ debug(const char *fmt, ...) static void change_tz(const char *tzn) { - static const char *zfn = "/usr/share/zoneinfo"; - static const char *tfn = "root/etc/.localtime"; - static const char *dfn = "root/etc/localtime"; + static const char *zfn = TZDIR; + static const char *tfn = "root" TZDEFAULT ".tmp"; + static const char *dfn = "root" TZDEFAULT; ssize_t clen; int zfd, sfd, dfd; @@ -96,6 +101,50 @@ test_tz(const char *expect) ATF_CHECK_STREQ(expect, buf); } +ATF_TC(tz_default); +ATF_TC_HEAD(tz_default, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test default zone"); + atf_tc_set_md_var(tc, "require.user", "root"); +} +ATF_TC_BODY(tz_default, tc) +{ + /* prepare chroot with no /etc/localtime */ + ATF_REQUIRE_EQ(0, mkdir("root", 0755)); + ATF_REQUIRE_EQ(0, mkdir("root/etc", 0755)); + /* enter chroot */ + ATF_REQUIRE_EQ(0, chroot("root")); + ATF_REQUIRE_EQ(0, chdir("/")); + /* check timezone */ + unsetenv("TZ"); + test_tz("+0000 (UTC)"); +} + +ATF_TC(tz_invalid_file); +ATF_TC_HEAD(tz_invalid_file, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test invalid zone file"); + atf_tc_set_md_var(tc, "require.user", "root"); +} +ATF_TC_BODY(tz_invalid_file, tc) +{ + static const char *dfn = "root/etc/localtime"; + int fd; + + /* prepare chroot with bogus /etc/localtime */ + ATF_REQUIRE_EQ(0, mkdir("root", 0755)); + ATF_REQUIRE_EQ(0, mkdir("root/etc", 0755)); + ATF_REQUIRE((fd = open(dfn, O_RDWR | O_CREAT, 0644)) >= 0); + ATF_REQUIRE_EQ(8, write(fd, "invalid\n", 8)); + ATF_REQUIRE_EQ(0, close(fd)); + /* enter chroot */ + ATF_REQUIRE_EQ(0, chroot("root")); + ATF_REQUIRE_EQ(0, chdir("/")); + /* check timezone */ + unsetenv("TZ"); + test_tz(invalid.expect); +} + ATF_TC(thin_jail); ATF_TC_HEAD(thin_jail, tc) { @@ -320,6 +369,30 @@ test_tz_env(const char *tzval, const char *expect) test_tz(expect); } +static void +tz_env_common(void) +{ + char path[MAXPATHLEN]; + const struct tzcase *tzcase = tzcases; + int len; + + /* relative path */ + for (tzcase = tzcases; tzcase->tzfn != NULL; tzcase++) + test_tz_env(tzcase->tzfn, tzcase->expect); + /* absolute path */ + for (tzcase = tzcases; tzcase->tzfn != NULL; tzcase++) { + len = snprintf(path, sizeof(path), "%s/%s", TZDIR, tzcase->tzfn); + ATF_REQUIRE(len > 0 && (size_t)len < sizeof(path)); + test_tz_env(path, tzcase->expect); + } + /* absolute path with additional slashes */ + for (tzcase = tzcases; tzcase->tzfn != NULL; tzcase++) { + len = snprintf(path, sizeof(path), "%s/////%s", TZDIR, tzcase->tzfn); + ATF_REQUIRE(len > 0 && (size_t)len < sizeof(path)); + test_tz_env(path, tzcase->expect); + } +} + ATF_TC(tz_env); ATF_TC_HEAD(tz_env, tc) { @@ -327,10 +400,22 @@ ATF_TC_HEAD(tz_env, tc) } ATF_TC_BODY(tz_env, tc) { - const struct tzcase *tzcase; + tz_env_common(); + /* escape from TZDIR is permitted when not setugid */ + test_tz_env("../zoneinfo/UTC", utc.expect); +} - for (tzcase = tzcases; tzcase->tzfn != NULL; tzcase++) - test_tz_env(tzcase->tzfn, tzcase->expect); + +ATF_TC(tz_invalid_env); +ATF_TC_HEAD(tz_invalid_env, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test invalid TZ value"); + atf_tc_set_md_var(tc, "require.user", "root"); +} +ATF_TC_BODY(tz_invalid_env, tc) +{ + test_tz_env("invalid", invalid.expect); + test_tz_env(":invalid", invalid.expect); } ATF_TC(setugid); @@ -367,23 +452,25 @@ ATF_TC_HEAD(tz_env_setugid, tc) } ATF_TC_BODY(tz_env_setugid, tc) { - const struct tzcase *tzcase = tzcases; - ATF_REQUIRE_EQ(0, seteuid(UID_NOBODY)); ATF_REQUIRE(issetugid()); - for (tzcase = tzcases; tzcase->tzfn != NULL; tzcase++) - test_tz_env(tzcase->tzfn, tzcase->expect); + tz_env_common(); + /* escape from TZDIR is not permitted when setugid */ + test_tz_env("../zoneinfo/UTC", invalid.expect); } ATF_TP_ADD_TCS(tp) { debugging = !getenv("__RUNNING_INSIDE_ATF_RUN") && isatty(STDERR_FILENO); + ATF_TP_ADD_TC(tp, tz_default); + ATF_TP_ADD_TC(tp, tz_invalid_file); ATF_TP_ADD_TC(tp, thin_jail); #ifdef DETECT_TZ_CHANGES ATF_TP_ADD_TC(tp, detect_tz_changes); #endif /* DETECT_TZ_CHANGES */ ATF_TP_ADD_TC(tp, tz_env); + ATF_TP_ADD_TC(tp, tz_invalid_env); ATF_TP_ADD_TC(tp, setugid); ATF_TP_ADD_TC(tp, tz_env_setugid); return (atf_no_error()); diff --git a/lib/libc/tests/string/memcmp_test.c b/lib/libc/tests/string/memcmp_test.c index 5286a0b994f3..fa2f498ccfaf 100644 --- a/lib/libc/tests/string/memcmp_test.c +++ b/lib/libc/tests/string/memcmp_test.c @@ -41,14 +41,14 @@ #endif /* - * On FreeBSD we demand that memcmp returns the difference between the - * characters at the first site of mismatch. However, ISO/IEC 9899:1990 - * only specifies that a number greater than, equal to, or less than - * zero shall be returned. If a unit test for this less strict - * behaviour is desired, define RES(x) to be (((x) > 0) - ((x) < 0)). + * On FreeBSD we previously demanded that memcmp returns the difference + * between the characters at the first site of mismatch. However, + * ISO/IEC 9899:1990 only specifies that a number greater than, equal + * to, or less than zero shall be returned. If a unit test for the + * more strict behaviour is desired, define RES(x) to be (x). */ #ifndef RES -#define RES(x) (x) +#define RES(x) (((x) > 0) - ((x) < 0)) #endif static int (*memcmp_fn)(const void *, const void *, size_t); 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= |