summaryrefslogtreecommitdiff
AgeCommit message (Collapse)AuthorLines
2026-10-14regex: avoid int overflow in regcompHEADmasterSzabolcs Nagy-6/+35
regcomp has many int arith ops that may overflow. before tre_expand_ast int values are limited by 2x the input length n, e.g.: input ERE int field max value aaaaaaaaaaaa... position n ()()()()()()... submatch_id n/2+1 ()||||||||||... num_tags 2n-3 so overflow before expand requires large n (and a lot of memory). later some values can become big due to repetitions: input ERE int field that overflows (((a{255}){255}){255}){255} position ((a|b*){255,}){255,} num_transitions num_transitions and memory use can be big without {k,} repetitions too: input ERE what max value (a|a|a|a...|a)* num_transitions n^2/4 (()|a|a|...|a)* sum tnfa tags > n^3/16 - n^2 so memory can run out quickly as n grows (with 31bit va space 1700 long input is enough even without {k,}) about half is tnfa and half is ast firstpos/lastpos data. but overflow can happen before allocations fail. fix early overflow by limiting n. the stack usage is in [n,11n] without repetitions, usually 7n, so the stack limit got adjusted too. the limit is such that almost all inputs that worked before still work. overflows during and after expand are fixed by explicit checks via a check_add helper and xcalloc instead of xmalloc.
2026-10-12SIGEV_THREAD timers: fix deadlock when timer_create syscall failsColin Cross-9/+26
sem_wait is a cancellation point. If the parent thread in timer_create sets td->cancel = 1 before the child thread reaches sem_wait then the thread will exit and sem_post will never be called, causing the parent thread to deadlock in sem_wait. 3ad3fa962efee12067d68c3405a537dce156a7ac set td->cancel = 1 to fix a thread leak when the syscall failed. The switch to two-way semaphores cde213f9c3ac1aa168581222edee6a6642113323 allows checking if self->timer_id is -1 instead of self->cancel because timer_delete can't have been called before the sem_post allows the parent thread to return from timer_create. The deadlock was observed in a test that called timer_create(CLOCK_BOOTTIME_ALARM, SIGEV_THREAD, ...) without CAP_WAKE_ALARM, causing the kernel to return EPERM. Also disable cancellation around the parent semaphores to avoid the parent being cancelled while the child is still accessing the args on the parent stack, and save the result of the timer_create syscall to return as errno on error.
2026-10-12strtod: fix incorrect logic detecting underflowRich Felker-2/+1
underflow should be reported (via ERANGE) on any inexact denormal result, which is expressed in the logic as (denormal && frac). the denormal boolean is set above based on the magnitude of the exponent relative to the target type's exponent range after normalizing the working mantissa to occupy LDBL_MANT_DIG bits directly above the radix point. but, since rounding up can raise the exponent out of the denormal range, there is additional logic to clear the denormal flag when that happens, and it was wrong. the logic clearing denormal triggered when: bits==LDBL_MANT_DIG+e2-emin here e2+LDBL_MANT_DIG is the actual place of the highest bit, and initially, bits+emin was equal to -emax+3. however, at the point the condition is evaluated, bits no longer represents the full mantissa width of the target type. it has already been replaced with a reduced width corresponding to the precision of the denormal. as a consequence of the replacement, the condition was basically always true (except when bits gets clamped non-negative), and so the denormal flag got cleared when rounding up with carry. the logic is fixed by using the value -emax+3 which is constant for the duration of the function, and by moving evaluation from before the exponent adjust to after, since the denormal flag should be cleared based on the new exponent, not the old exponent. with this change, behavior has been confirmed to be correct for rounding both up and down around the minimum normal and maximum denormal double, expressed both as 21 decimal digits and the full exact value. this patch does not address missing underflow logic when parsing hex floats, which is a separate issue.
2026-10-12fcntl.h: add new fallocate operation flagsRich Felker-0/+5
these are complete as of linux 7.2
2026-10-06swprintf: properly set errno when output is truncatedRich Felker-1/+5
unlike snprintf, swprintf is required to discard the computed length and return -1 if the output does not fit. this was done correctly, but POSIX also requires errno be set to EOVERFLOW for this condition.
2026-10-06fnmatch: fix false matches from invalid bytes behaving as end-of-stringRich Felker-2/+2
when an invalid byte appeared next in the string immediately following a character that matched the last character of the pattern, it was mistakenly treated the same as end-of-string, causing fnmatch to report the string as matching.
2026-10-05fnmatch: do not match reversed ranges in bracket expressionsRich Felker-1/+2
POSIX allows a reversed-order range to be treated as invalid (forcing the bracket to be interpreted as a literal) or as valid but not matching any characters. because we matched the starting character of the range before identifying it as a range, however, [z-a] would match 'z'. explicitly check for a subsequent non-terminal '-', and don't match if one is present. the match, if any, will be caught by the range logic in the next iteration.
2026-10-05fnmatch: fix processing bracket range with multibyte endpointRich Felker-1/+1
the advancement logic was off-by-one, accounting for the p++ in the for clause but not the '-' character. this resulted in attempting to process the last byte of the range endpoint on the next iteration of the loop. for a single-byte endpoint this was harmless, but for a multi-byte character, mbtowc would fail on the next iteration, preventing matching of any subsequent part of the bracket.
2026-10-02newlocale: fix values for categories not in mask with (locale_t)0 baseRich Felker-2/+2
the category values from the old locale were only being used for a non-null base; for null ((locale_t)0) base, a lookup for "" was wrongly being performed rather than using the C locale values. this caused, for example, newlocale(LC_CTYPE_MASK,"",0) to produce a locale_t matching newlocale(LC_ALL_MASK,"",0) rather than one that only reflects LC_CTYPE.
2026-09-29fix off-by-one in wcwidth special cases for tags, variation selectorsRich Felker-1/+1
these ranges are special-cased because they lie near the top of the encoding space far above where the bit tables currently end, and they are unlikely to change often. the last character in each of these ranges failed to get reported as having width 0.
2026-09-22floatscan: fix oob store at -1 index in mantissa buffer at wrapRich Felker-1/+1
the code to implement a modular postincrement was too clever, and essentially did it as a reducing version of (z+=1)-1, but only applied the redution after the addition not the subtraction. as a result, it evaluated to -1 when wrapping, causing a fixed value of zero to be stored out of bounds below the buffer. whether this condition is triggered depends on where the mantissa bits end up in the circular buffer after processing. for archs with 80-bit extended long double or IEEE quad long double, the input "710542735760100185871124267578125e-33" was reported to and has been confirmed to trigger it.
2026-09-21fnmatch: fix FNM_PERIOD failure of escaped '.' to match leading '.'Rich Felker-1/+1
the new condition also allows forward progress into ordinary matching if the pattern begins with a backslash. this is fine independent of FNM_NOESCAPE and independent of what follows the backslash; if FNM_NOESCAPE is active, the backslash is literal and will not match. if FNM_NOESCAPE is not active, the pattern beginning with a backslash ensures that the first character is literal.
2026-09-17asprintf: always clear the result pointer on failureRich Felker-0/+1
previously, the malloc-failure error path cleared it, but other failures from vsnprintf such as EILSEQ or EOVERFLOW left the original contents of the result object in place. leaving any old value in place is allowed, and would be required if the specification did not explicitly permit clobbering it on failure, but it does. by overwriting any old value there with a null pointer, we harden callers that might have failed to check the return value for errors against accessing and possibly exposing unrelated data; instead they will fault on dereference.
2026-09-16fix printf handling of indirect (asterisk) field width of INT_MINRich Felker-0/+2
in this case, negation produces integer overflow. since a field width of the faithfully negated value would necessarily overflow INT_MAX, just detect this case and immediately treat it as an output overflow error.
2026-09-10vfwscanf: consistently use MB_LEN_MAX instead of magic number 4Rich Felker-1/+1
this magic number 4 is what ensures the next wctomb won't overflow the allocated buffer, but its purpose wasn't clear.
2026-09-10stdio: reserve multibyte space in allocated vfwscanf %c conversionsMatthias Goergens-0/+1
Allocated narrow %c conversions initially reserve only width+1 bytes. For the default width this is two bytes, but in a UTF-8 locale wctomb can write up to MB_LEN_MAX bytes into the buffer before the post-conversion growth check, overflowing the two-byte allocation for a three- or four-byte input character. Ensure every allocated narrow buffer starts at no less than MB_LEN_MAX bytes. The existing geometric growth then keeps at least MB_LEN_MAX spare bytes available after each conversion.
2026-09-10vf[w]scanf: fix integer overflow in %mlc allocation with large widthRich Felker-0/+4
on archs with 32-bit size_t, multiplying the caller-provided signed int field width by sizeof(wchar_t) can overflow. we could explicitly error out, but just replacing the requested size to let malloc fail avoids the need to poke at errno, and the rest of the function here is already using guaranteed-fail in the geometric buffer growth path to avoid explicit size checks.
2026-09-09wordexp: clear positional parametersSzabolcs Nagy-1/+1
added 'set --' so $@, $*, $#, $1, $2 are cleared (does not seem to be in the spec, but cleaner) wordexp("$*", p, 0) was "$*","2>/dev/stderr", now empty list.
2026-09-09wordexp: fix stderr redirectionSzabolcs Nagy-3/+11
stderr redirection to /dev/null didn't work, can be done in the command, but would not redirect errors printed during sh startup. wordexp(")", p, 0) clobbered stderr, now silent.
2026-09-09fix undefined pointer arithmetic in wcsrchrMatthias Goergens-2/+6
On an unsuccessful search, the backwards loop decrements the pointer past the beginning of the string and then compares that invalid pointer with the string pointer. Check for the beginning of the string before decrementing instead. This preserves the existing results without forming a pointer outside the array.
2026-09-09mntent: avoid undefined behavior on long linesMatthias Goergens-2/+2
The continue for lines longer than INT_MAX reaches the do-while condition without initializing n. On the first such line, the condition reads indeterminate values. After an earlier line, it reuses stale offsets from that line. Jump directly to the start of the loop instead. This is the minimal form requested in the previous review and preserves the intended behavior of skipping an overlong line.
2026-09-09math: fmaf rewriteSzabolcs Nagy-94/+22
the new code uses that for all real |x| in [0x1p-999,0x1p999] y = (float)x is the same as r = (double)x t = x - r if (t!=0 && r.bits%2==0) r.bits += (r<0)==(t<0) ? 1 : -1 y = (float)r in all rounding modes, with the same fenv effects. this can be interpreted as a round to odd adjustment[1]. in fmaf t is computed with a fast2sum variant. - optimized common case. - implicit uflow handling instead of fenv calls. - no fegetround check. - no api calls on hf targets. - fixed missed uflow on targets that signal it before rounding: fmaf(-0x1p-100f, 0x1p-100f, 0x1p-126f) - removed freebsd code references and comments. - fmaf.o code size vs before the halfway subnormal fix: x86_64: 514 -> 210 armhf: 304 -> 156 (v7 thumb, no vfma op) arm: 400 -> 348 (soft float, no fenv) round to odd paper (suggested by Sergey Davidoff): [1] S. Boldo et al., Emulation of a FMA and correctly-rounded sums: proved algorithms using rounding to odd, 2008
2026-09-09math: fix fmaf subnormal double roundingSzabolcs Nagy-2/+12
inexact halfway cases were not handled correctly for subnormals fmaf(0x20201p-92f, 0x1fe01p-92f, 0x1p-130f) = (float)(0x1p-130 + 0x1.000000004p-150) was rounded to 0x1.00001p-130 first in double precision, then to 0x1p-130 in the float subnormal range instead of 0x1.00002p-130. this is a minimal fix of the halfway check. Reported-by: Sergey Davidoff <shnatsel@gmail.com>
2026-09-09time: fix TZif version parsingMatthias Goergens-1/+1
TZif v1 encodes its version as NUL, but do_tzset treats only the byte '1' as v1. It consequently reads a valid v1 file as if it contained a second header. Use zero and nonzero version bytes to distinguish v1 from later files.
2026-09-08scandir: remove unused headerLuca Kellermann-1/+0
stddef.h is unused, commit da88b16a221c9d327e1bfa61dd6f4f08dacce57a removed the use of offsetof().
2026-09-08scandir: fix qsort usageLuca Kellermann-1/+9
calling qsort() with a pointer to a function whose type is not compatible with int(const void *, const void *) results in UB because qsort() would call this function with an incompatible type. avoid this by using qsort_r(). this is similar to how qsort() is implemented on top of qsort_r(). the types of the pointers passed to wrapper_cmp() are struct dirent *const * but the caller's comparison function expects const struct dirent **. copy the pointer values into local variables and pass their addresses to the caller's comparison function to get the right type and avoid aliasing violations. this is only necessary because the pointer to the comparison function for scandir() was (incorrectly) specified as int (*)(const struct dirent **, const struct dirent **) rather than int (*)(struct dirent *const *, struct dirent *const *).
2026-09-08scandir: report ENOMEM and EOVERFLOWLuca Kellermann-1/+9
if the loop is exited because len * sizeof *names does not fit into size_t, errno should be explicitly set to ENOMEM. previously, the behavior differed depending on which value errno happened to have at this point. if cnt reached a value > INT_MAX, scandir() returned an incorrect value. EOVERFLOW should be reported instead. it's unlikely that these errors can actually occur. it may not even be possible to have directories with that many entries, and even then malloc() or realloc() will probably fail long before len or cnt reach those large values.
2026-09-08scandir: disable cancellation around cancellation pointsLuca Kellermann-0/+13
opendir() or closedir() might act upon a cancellation request. because scandir() did not disable cancellation or install a cancellation cleanup handler, this could lead to memory and file descriptor leaks.
2026-09-08scandir: don't examine errno after closedir()Luca Kellermann-1/+7
when closedir() set errno, scandir() misinterpreted this as a failure. this was wrong for two reasons: * if closedir() succeeds, errno could still have been set, e.g. by __aio_close(). * even if closedir() "fails", it always closes the file descriptor and frees memory, so there is no reason to free all directory entries and return from scandir() with a failure.
2026-09-08scandir: hide that errno is set to 0Luca Kellermann-1/+6
POSIX.1-2024 requires that standard functions don't set errno to 0. commit dae17a1aaf25d8333e729173d86659066607d87d ensured that cmp() and the caller of scandir() cannot observe that errno is set to 0 internally. however, this was not yet the case for the sel() callback.
2026-09-08catgets: accept (nl_catd)-1 catalog descriptorIsmael Luceno-0/+4
the standard allows but does not require detecting bad catalog descriptors and reporting the as EBADF. detection is only possible in the general case if nl_catd is its own resource identifier namespace not shaed with address space or file descriptors or anything else; however, (nl_catd)-1 is always detectable since it's reserved as an error value, and reportedly all other implementations detect this condition and just return the untranslated string. users of catgets, including tcsh, rely on this.
2026-09-08sprintf: fix one byte truncation when producing string of length INT_MAXLuca Kellermann-1/+1
(v)sprint() is supposed to return the number of bytes written to s, excluding the terminating null byte. however, when these functions return INT_MAX, only INT_MAX - 1 bytes (excluding the terminating null byte) are written. this is caused by the way vsprintf() is implemented: calling vsnprintf() with n = INT_MAX. vsnprintf() returns the number of bytes that would be written to s had n been sufficiently large excluding the terminating null byte. output bytes beyond the n-1st are discarded. to accommodate the largest strings (v)sprintf() can produce (length INT_MAX, the return value is of type int), vsnprintf() has to be called with n >= INT_MAX + 1. calling vsnprintf() with n > INT_MAX is possible since commit 11fb383275d20f5f94c00425bd888a02ecbd218e.
2026-09-08math: fix expl on x86Szabolcs Nagy-15/+15
expl asm special cased |x|>=16384 and used 2^trunc(x) then, but this was wrong for x<=-16384 when 2^trunc(x) doesn't underflow to 0. fixed by bumping the threshold up to 32768. Reported-by: Paul Zimmermann <Paul.Zimmermann@inria.fr>
2026-09-07math: fix powl(x<0,oddint) for some over/underflow casesSzabolcs Nagy-2/+2
when x<0 and y is an odd int then powl is computed for -x first then negated at the end. some overflow cases missed the negation: powl(-1.5, 50001) powl(-0.5, 50001) powl(-0x1p-16444L, -1) returned inf, 0 and inf instead of the negated values. Reported-by: Paul Zimmermann <Paul.Zimmermann@inria.fr>
2026-09-07wordexp: free word on vector allocation failureMatthias Goergens-1/+4
getword allocates the next expanded word before the result vector is grown. If realloc fails, that word has not been stored in the vector and cannot be reached by wordfree, so returning WRDE_NOSPACE leaks it. Free the exclusively owned word before leaving the loop. Existing partial results and the returned error are unchanged.
2026-09-07powerpc: set up a proper stack frame in the parent thread in clone()Alex Rønne Petersen-4/+5
The ABI requires a stack frame to, at minimum, consist of the backchain slot and the LR save slot at sp+0 and sp+4 respectively. The old code spilled r30/r31 into those slots, meaning that a backchain-based unwinder would see a nonsense value as the backchain pointer and go on a wild goose chase. It's admittedly a very small window where this is possible -- a thread that's stopped in the middle of the clone() parent body -- but fixing it just requires shifting the r30/r31 spill slots down by 8 bytes and storing the old sp in the backchain slot, so seems reasonable to do.
2026-09-07riscv: clear fp and ra in _start like on other portsAlex Rønne Petersen-0/+4
As usual, clearing fp helps simple/generic frame-pointer-based unwinders. Clearing ra unbreaks DWARF unwinders because ra would otherwise contain garbage from _start all the way through to libc_start_main_stage2. The CFI for libc_start_main_stage2 would then incorrectly claim that ra contains a perfectly valid return address that the unwinder should proceed through. If that return address just so happened to land inside a real function somewhere, the unwinder would then happily proceed to run that function's CFI on a completely unrelated register context, unsurprisingly leading to weird crashes. As an aside: Some ports don't clear their ra equivalent in _start, but they do use a linked branch to _start_c. That works out too because the unwinder then actually reaches _start which intentionally has no CFI, so it stops there. Between these approaches, clearing ra and using an unlinked branch tends to lead to slightly nicer stack traces for users because there won't be an unwind error printed for the _start frame (due to missing CFI).
2026-09-07x32: clone: fix read of stack slot containing ctidAlex Rønne Petersen-1/+1
It's a 32-bit pointer and passed on the stack; the upper 32 bits of the stack slot are garbage. This works out fine if we're lucky and those bits happen to be zeroed, but if they're not, we ask the kernel to write to some random 64-bit location, which it will just silently fail to do (the process is in x32 mode; nothing can be mapped up there), and consequently, we never learn the new thread's tid.
2026-09-07or1k: fix local-exec tls with large alignmentSzabolcs Nagy-2/+3
or1k uses an unusual variant of the TLS_ABOVE_TP layout: powerpc, mips, m68k: pthread | tls +----------+-----------------+-- | |< tpoff >| self a = e = m tp arm, aarch64, sh: pthread < gap >| tls +----------+-------------+------ | | | self a = e = tp m or1k: pthread < gap >| tls +----------+-------------+------ | |< tpoff >| self a = e m = tp tp: thread pointer a: address aligned to tls_align e: end of the libc internal pthread self struct m: min user tls address the layout variant only matters for local-exec tls access, but then ld and libc have to match how tp-relative tls addresses are computed. or1k is tpoff=gap=16 in bfd ld, but it was gap=tpoff=0 in musl. this works if tls_align <= 16, but an exe with larger tls_align fails. TP_OFFSET (tpoff) and GAP_ABOVE_TP (gap) are now defined as tpoff: tp - a gap: m - a (so it is not really "gap above tp") TPOFF_K = -tpoff is needed for relocs as the tls_module->offset is internally computed relative to a, not tp. this changes tp - e on or1k which in general may affect internal abi (e.g. tlsdesc asm uses self->dtv) or toolchain abi (the layout below m is not visible to the elf abi, but e.g. ssp uses self->canary on some targets with fixed tp offset), but or1k seems unaffected. it is possible to place the pthread struct such that tp = m = e on or1k, to aviod this abi change, but that looks uglier (e.g. a != e then). found and tested on user qemu-or1k.
2026-09-07fix integer overflow in gai_strerror, hstrerror and regerrorLuca Kellermann-3/+6
at least gai_strerror() and regerror() are specified to accept any int value. if the value was close to INT_MAX (for gai_strerror()) or INT_MIN (for hstrerror() and regerror()) a signed integer overflow would occur. fix this by converting the int argument to unsigned before doing arithmetic.
2026-09-07riscv32, riscv64: make alignment padding in ucontext_t explicitMichael Forney-0/+2
Add explicit padding between struct fields with alignment attributes. This ensures that the struct layout is the same with and without the attribute.
2026-09-07dns: Avoid division-by-zero when zero attempts is specified in resolv.confYao Zi-2/+4
DNS query retry interval is calculated through timeout / attempts in __res_msend_rc(), both are loaded from resolv.conf in __get_resolv_conf(), while value of attempts isn't checked. This would trigger an undefined behavior if attempts is set to zero in configuration, causing misfunction or termination with SIGFPE. Gracefully handle it by returning early.
2026-09-07sys/types.h: add reclen_tLuca Kellermann-2/+3
POSIX.1-2024 requires both dirent.h and sys/types.h to define this type.
2026-09-07fix return type of CPU_ISSET[_S] macrosRich Felker-1/+1
the documented type is int. on 64-bit archs, callers which truncate the result from the raw bitmask to int will not see any bits above 31 as being set.
2026-09-07mipsn32: pass syscall arguments as long long instead of longAlex Rønne Petersen-32/+35
This matches what is done for the x32 port. As far as I can tell based on kernel and glibc sources, this is the expected kABI for mipsn32 since the syscall path uses the n32 calling convention, i.e. full 64-bit registers. Before this patch, you would get compiler warnings about truncation of off_t values in various syscall wrappers. As for x32, I left the return type (and r2 register variable type) as long since lseek() remains the only syscall with a 64-bit return type on ILP32 targets. This change has been tested by running Zig's module tests for mips64-linux-muslabin32 and mips64el-linux-muslabin32 with no regressions.
2026-09-06fix build regression in clock_nanosleep on 64-bit archsRich Felker-1/+1
commit cb0cdc2e88c652af225d2fc31c1dec99b9880d39 broke this as part of future proofing.
2026-08-17clock_nanosleep: don't assume nanosleep syscall existsRich Felker-2/+11
this fixes a build regression for riscv32 introduced in commit b306b16af15c89a04d8e0c55cac2dadbeb39c083. prior to that, the riscv32 bits/syscall.h.in defined a macro for the nanosleep syscall, despite the kernel on time64-native archs having no such syscall. our clock_nanosleep uses the old nanosleep syscall when possible as part of minimal compatibility with pre-2.6 kernels. using a non-functional syscall number didn't have any ill effect on riscv32 or future time64-native archs, since the affected code is unreachable in that case, but removing the wrongly defined macro broke the build. this change fixes it. in order not to need to fix this again if future 64-bit archs also drop the old nanosleep syscall factor out the conditional use of SYS_nanosleep and use the same approach in the preprocessor else block for them.
2026-08-14ftello: report overflow in buffered stream positionMatthias Goergens-1/+6
ftello adds pending buffered output to the position reported by the underlying seek operation. Near LLONG_MAX, the addition can overflow signed off_t and return an apparently successful negative position. Check that the buffered-byte count fits before adding it. Fail with EOVERFLOW when the logical position cannot be represented.
2026-08-14fseeko: avoid overflow adjusting relative seek offsetMatthias Goergens-1/+8
For SEEK_CUR, fseeko subtracts the unread input-buffer length from the caller's offset before invoking the underlying seek operation. A valid LLONG_MIN offset therefore overflows before the seek can reject the unrepresentable logical result. Detect the underflow and fail with EOVERFLOW without flushing or discarding the stream's buffers.
2026-08-05time: avoid overflow normalizing extreme tm_mdayMatthias Goergens-1/+1
mktime is required to accept and normalize out-of-range members of struct tm. When tm_mday is INT_MIN, subtracting one from it overflows before the existing long long multiplication takes effect. Perform the subtraction in long long so the complete int range can be normalized as intended.