about summary refs log tree commit diff
Commit message (Collapse)AuthorAgeFilesLines
* release 1.2.4 v1.2.4Rich Felker2023-05-012-1/+70
|
* fix return value of wmemcmp for extreme wchar_t valuesRich Felker2023-04-241-1/+1
| | | | | analogous to the bug in wcscmp and wcsncmp that was fixed in commit 07616721f1fa6cb215ffbef23441cae80412484f.
* fix wide printf numbered argument buffer overflowGabriel Ravier2023-04-141-2/+2
| | | | | | | The nl_type and nl_arg arrays defined in vfwprintf may be accessed with an index up to and including NL_ARGMAX, but they are only of size NL_ARGMAX, meaning they may be written to or read from 1 element too far.
* wait4: fix missing rusage on x32 due to wrong success conditionAlexey Izbyshev2023-04-111-1/+1
| | | | | | | | Resource usage data is filled by the kernel only when wait4 returns a pid, i.e. a positive value. Commit 5850546e9669f793aab61dfc7c4f2c1ff35c4b29 introduced this bug, possibly because of copy-pasting from getrusage.
* semtimedop: fix timespec kernel ABI mismatch for 32-bit timeouts on x32Alexey Izbyshev2023-04-111-1/+2
| | | | | | | | | | | | | | | | | | | | | | | For time64 support, musl normally defines SYS_foo to the time32 variant of that syscall on arches that have it, and to the time64 variant otherwise, so that "SYS_foo == SYS_foo_time64" implies that the arch is time64-only. However, SYS_semtimedop is an odd case: some arches define only SYS_semtimedop_time64, yet they are not time64-only, because the time32 variant is provided via SYS_ipc instead. For such arches, defining SYS_semtimedop to SYS_semtimedop_time64 would break the implication above, so commit 4bbd7baea7c8538b3fb8e30f7b022a1eee071450 doesn't do this. Commit eb2e298cdc814493a6ced8c05cf0d0f5cccc8b63 attempts to detect time64-only arches by checking that both SYS_semtimedop and SYS_ipc are undefined, but this doesn't work for x32, because it's a time64-only arch that does define SYS_semtimedop. As a result, 32-bit timeouts trigger the fallback path that passes a 32-bit timespec to the kernel while it expects a 64-bit one, so the effective tv_sec is formed by interpreting 32-bit tv_sec and tv_nsec as a single long long, and the effective tv_nsec is whatever is located in the next 64 bits of the stack. Fix this by expanding the time64-only check to include arches where SYS_semtimedop is the time64 variant of the syscall.
* getopt: fix null pointer arithmetic ubAlexey Izbyshev2023-04-111-1/+2
| | | | | | | When an option that requires an argument is the last character of argv[argc-1], getopt computes argv[argc] + optpos. While optpos is always zero in this case, adding it to null pointer is still undefined.
* nftw: fix use of uninitialized struct statAlexey Izbyshev2023-04-111-1/+3
| | | | | | | | | | | | | | | | | If lstat/stat fails with EACCES, st is left uninitialized, but its st_dev/st_ino fields are then used in several places: * for FTW_MOUNT check (in practice typically results in a false positive and an early return) * for copying to the new struct history (though the struct is not used afterwards since we don't recurse in this case) * for cycle detection check (could theoretically result in a false positive and an early return) To avoid adding FTW_NS checks to all these places, fix this by zero-initializing st_dev/st_ino (which can never match an existing dentry due to zero inode being reserved in Linux), and check for FTW_NS only when handling FTW_MOUNT since we need two valid dentries there.
* fix inadvertently static local var in dynlink get_lfs64Rich Felker2023-04-111-1/+2
| | | | | | | | commit 246f1c811448f37a44b41cd8df8d0ef9736d95f4 inadvertently introduced the local variable p as static by declaring it together with lfs64_list. the function is only reachable under lock, and is not called reentrantly, so this is not a functional bug, but it is confusing and inefficient. fix by separating the declarations.
* dns: check length field in tcp response messageAlexey Kodanev2023-04-071-0/+1
| | | | | | | | | The received length field in the message may be greater than the size of the 'answer' buffer in which the message resides. Currently, ABUF_SIZE is 768. And if we get a larger 'alens[i]', it will result in an out-of-bounds reading in __dns_parse(). To fix this, limit the length to the size of the received buffer.
* fix swprintf handling of nul character in outputRich Felker2023-03-221-0/+1
| | | | | | | the buffer-flush function did not account for mbtowc returning 0 rather than 1 when converting the nul character. this prevented advancing past it, instead repeatedly converting it into the output wide character string until the max output length was exhausted.
* in printf, use ferror macro rather than directly inspecting flags bitRich Felker2023-03-211-2/+2
| | | | | this is purely aesthetic and should not affect code generation or functionality.
* remove wide printf dependency on ugly hack in vfprintfRich Felker2023-03-212-9/+15
| | | | | | | | | | | | | | | | | | | | | | | | | commit d42269d7c85308abdbf8cee38b1a1097249eb38b appropriated the stream error flag temporarily to let the printf family of functions suppress further output attempts after encountering a write error. since the wide printf code relies on (narrow) vfprintf to print padding and numeric conversions, a hack was put in vfprintf not to clear the initial error status unless the stream is narrow oriented. this was okay, because calling vfprintf on a wide-oriented stream (outside of internal use by the implementation) produces undefined behavior. however, it was highly non-obvious to anyone reading the wide printf code, where the calls to fprintf without first checking for error status appeared erroneous. this patch removes all direct use of fprintf from the wide printf core, except in the numeric conversions case where it was already checked before starting processing of the directive that the error status is not set. the other calls, which were performing padding, are replaced by a new pad() helper function, which performs the check and abstracts out the mechanism of writing the padding. direct use of the error flag is also replaced by ferror, which is defined as a macro in stdio_impl.h, expanding directly to the flag check with no call or locking overhead.
* fix (normal, narrow) printf erroneously processing %n after output errorsRich Felker2023-03-211-0/+3
| | | | | | | | | | | | | | | unlike with wide printf variants, encoding errors are not a vector by which this bug is reachable, and the out() helper function already ensured that no further output could be written after an output error, transient or otherwise. however, the %n specifier could still be processed after an error, yielding a side effect that wrongly implied output had succeeded. due to buffering effects, it's still possible for %n to show output as having "succeeded", but for it never to appear on the underlying file due to an error at flush time. this change, however, ensures that processing of %n does not conflict with any error which has already been seen.
* fix wide printf continuation after output or encoding errorsRich Felker2023-03-211-2/+6
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | this fixes a broader bug for which a special case was reported by Bruno Haible, in the form of %n getting processed (and reporting the number of wide characters which would have been written, but weren't) after an encoding error (EILSEQ). in addition to the %n case, some but not all of the format specifiers continued to attempt output after an error. in particular, %c, %lc, and %s all used fputwc directly without any check for error status. as long as the error condition was permanent rather than transient, these write attempts had no visible side effects, but in theory it could be visible, for example with EAGAIN/EWOULDBLOCK or ENOSPC, if the condition precluding output came to an end. this could produce output with missing non-final data, rather than just truncated output, albeit with the function still returning -1 as expected to report an error. to fix this, a check is added to stop processing of any new directive (including %n) if the stream is already in error state, and direct use of fputwc is replaced with calls to the out() helper function, which checks for error status. note that fprintf is also used directly without checking error status, but due to how commit d42269d7c85308abdbf8cee38b1a1097249eb38b previously attempted to solve the issue of output after error, the call to fprintf does not attempt to write anything when the wide-oriented stream is already in error state. this is non-obvious, and is quite a hack, so it should be changed, but I've left it alone for now to make the bug fix commit itself as non-invasive as possible.
* fix wide printf forms ignoring width for %lc format specifierRich Felker2023-03-201-5/+2
| | | | | since the code path for %c was already doing it right, and the logic is identical, condense them into a single case.
* poll: fix misuse of timespec type on 32-bit archs without poll syscallRich Felker2023-03-031-2/+7
| | | | | | | | | | | | | | | | | | | | | | | | | | this function was overlooked during the time64 transition, probably as a result of not having any time-related types in its application-side interface. however, for archs that lack the traditional poll syscall and have only ppoll, it used timespec as part of its interface with the kernel: the millisecond timeout was converted to a timespec to pass to SYS_ppoll. this is a type/ABI mismatch on 32-bit archs with legacy time32 syscalls. only one supported arch, or1k, is affected. all of the others either have SYS_poll, or are 64-bit. rather than using timespec, define a type locally to match what the kernel expects. the condition (SYS_ppoll_time64 == SYS_ppoll), comparable to conditions used elsewhere in timespec-handling code, evaluates true for "natively time64" 32-bit archs including x32, future riscv32, and all future 32-bit archs (via definitions in internal syscall.h). otherwise, the arch is either 64-bit or has syscalls that take the legacy type, and in either case "long" is correct. this fix is based on bug report and proposal by Alexey Izbyshev but with a different approach to the changes to minimize the contextual knowledge needed for a reader to understand the source file.
* select: fix 64-bit timeout truncation on pre-time64 kernelsAlexey Izbyshev2023-03-021-0/+1
| | | | | | | | | | | If the (normalized) timeout passed to select exceeds INT_MAX seconds on an arch with SYS_pselect6_time64 and the kernel is too old to support time64 syscalls, the timeout is implicitly converted to (32-bit) long on the fallback path, losing its upper 32 bits and potentially becoming a small positive value, violating the intended semantics, or even a negative value, causing the fallback syscall failure. Fix this by saturating the timeout at INT_MAX as done in other time64 fallback cases.
* dup3: don't set FD_CLOEXEC on failure on kernels without dup3 syscallRich Felker2023-02-281-1/+2
| | | | | | | | this is the best-effort fallback path for kernels that can't actually support the dup3 functionality. it was setting FD_CLOEXEC flag on the target fd (new) even if the dup2 operation failed. normally that shouldn't happen under correct usage, but it's possible if the source fd is not open or intentionally invalid (e.g. -1).
* fix dup3 ignoring all flags but O_CLOEXEC on archs with SYS_dup2 syscallRich Felker2023-02-281-1/+2
| | | | | | | | | | | | | our dup3 code wrongly skipped directly to making the SYS_dup2 syscall whenever the O_CLOEXEC bit of flags was not set. this is incorrect if any new flags are ever added, as it would silently ignore them rather than failing with an error. archs which lack SYS_dup2 were unaffected. adjust the logic so that SYS_dup3 is attempted whenever flags is nonzero, and explicitly fail with EINVAL if SYS_dup3 is unavailable and there are any unknown flags.
* fix pipe2 silently ignoring unknown flags on old kernelsRich Felker2023-02-281-0/+1
| | | | | | | kernels using the fallback have an inherent close-on-exec race condition and as such support for them is only best-effort anyway. however, ignoring potential new flags is still very bad behavior. instead, fail with EINVAL.
* getservbyport_r: fix wrong result if getnameinfo fails with EAI_OVERFLOWAlexey Izbyshev2023-02-281-0/+2
| | | | | EAI_OVERFLOW should be propagated as ERANGE to inform the caller about the need to expand the buffer.
* getservbyport_r: fix out-of-bounds buffer readAlexey Izbyshev2023-02-281-1/+1
| | | | | | | | | | | | If the buffer passed to getservbyport_r is just enough to store two pointers after aligning it, getnameinfo is called with buflen == 0 (which means that service name is not needed) and trivially succeeds. Then, strtol is called on the address just past the buffer end, and if it doesn't happen to find the port number there, getservbyport_r spuriously succeeds and returns the same bad address to the caller. Fix this by ensuring that buflen is at least 1 when passed to getnameinfo.
* getifaddrs: fix UB via taking address of null pointer union dereferenceAlexey Izbyshev2023-02-281-7/+7
| | | | | | | | getifaddrs computes &ctx->first->ifa even if ctx->first is NULL. While this shouldn't be possible on the success path because the loopback interface is hardcoded into the kernel, this is still possible on the error path (for example, if __rtnetlink_enumerate couldn't create a socket due to exceeding the fd limit).
* accept4: don't fall back to accept if we got unknown flagsAlexey Izbyshev2023-02-281-0/+4
| | | | | | | | | | | | accept4 emulation via accept ignores unknown flags, so it can spuriously succeed instead of failing (or succeed without doing the action implied by an unknown flag if it's added in a future kernel). Worse, unknown flags trigger the fallback code even on modern kernels if the real accept4 syscall returns EINVAL, because this is indistinguishable from socketcall returning EINVAL due to lack of accept4 support. Fix this by always failing with EINVAL if unknown flags are present and the syscall is missing or failed with EINVAL.
* fix potential read past end of buffer in getnameinfo host name lookupAlexey Izbyshev2023-02-271-0/+1
| | | | | | | This is completely analoguous to commit 633183b5d1c2. Similar code called from __lookup_name is not affected because it checks that the line contains the host name surrounded by blanks.
* dns: fix workaround for systems defaulting to ipv6-only socketsAlexey Izbyshev2023-02-271-15/+16
| | | | | | | | When IPv6 nameservers are present, __res_msend_rc attempts to disable IPV6_V6ONLY socket option to ensure that it can communicate with IPv4 nameservers (if they are present too) via IPv4-mapped IPv6 addresses. However, this option can't be disabled on bound sockets, so setsockopt always fails.
* dns: handle early eof in tcp fallbackAlexey Izbyshev2023-02-271-1/+1
| | | | | | | | A zero returned from recvmsg is currently treated as if some data were received, so if a DNS server closes its TCP socket before sending the full answer, __res_msend_rc will spin until the timeout elapses because POLLIN event will be reported on each poll. Fix this by treating an early EOF as an error.
* prevent CNAME/PTR parsing from reading data past the response endAlexey Izbyshev2023-02-274-7/+7
| | | | | | | | DNS parsing callbacks pass the response buffer end instead of the actual response end to dn_expand, so a malformed DNS response can use message compression to make dn_expand jump past the response end and attempt to parse uninitialized parts of that buffer, which might succeed and return garbage.
* fix out-of-bounds reads in __dns_parseAlexey Izbyshev2023-02-271-3/+3
| | | | | | | | | | | | | | | | | | | | | | | There are several issues with range checks in this function: * The question section parsing loop can read up to two out-of-bounds bytes before doing the range check and bailing out. * The answer section parsing loop, in addition to the same issue as above, uses the wrong length in the range check that doesn't prevent OOB reads when computing len later. * The len range check before calling the callback is off by 10. Also, p+len can overflow in a (probably theoretical) case when p is within 2^16 from UINTPTR_MAX. Because __dns_parse is used only with stack-allocated buffers, such small overreads can't result in a segfault. The first two also don't affect the function result, but the last one may result in getaddrinfo incorrectly succeeding and returning up to 10 bytes past the response buffer as a part of the IP address, and in (canon) name returned by getaddrinfo/getnameinfo being affected by memory past the response buffer (because dn_expand might interpret it as a pointer).
* fix incorrect unit for CPU_SETSIZE macroRich Felker2023-02-231-1/+1
| | | | | this macro is supposed to reflect the number of members (bits) in cpu_set_t, not the storage size (bytes).
* dns: prefer monotonic clock for timeoutsA. Wilcox2023-02-121-1/+2
| | | | | | | | | Before this commit, DNS timeouts always used CLOCK_REALTIME, which could produce spurious timeouts or delays if wall time changed for whatever reason. Now we try CLOCK_MONOTONIC and only fall back to CLOCK_REALTIME when it is unavailable.
* fix return value of wcs{,n}cmp for extreme wchar_t valuesGabriel Ravier2023-02-122-2/+2
| | | | | | | | | | | | | | As a result of using simple subtraction to implement the return values for wcscmp and wcsncmp, integer overflow can occur (producing undefined behavior, and in practice, a wrong comparison result). This does not occur for meaningful character values (21-bit range) but the functions are specified to work on arbitrary wchar_t arrays. This patch replaces the subtraction with a little bit of code that orders the characters correctly, returning -1 if the character from the first string is smaller than the one from the second, 0 if they are equal and 1 if the character from the first string is larger than the one from the second.
* math: fix undefined shift in logfSzabolcs Nagy2023-02-121-1/+1
| | | | | | | | A signed int shift overflowed when computing a constant mask, use hex literal instead. This is unlikely to cause actual issues unless the code was compiled with ubsan or similar instrumentation specifically to catch this. The stripped libc.so is unchanged on x86_64. Reported by q66 on irc.
* inet_pton: fix uninitialized memory use for IPv4-mapped IPv6 addressesAlexey Izbyshev2023-02-121-0/+1
| | | | | | | | | | | | | | When a dot is encountered, the loop counter is incremented before exiting the loop, but the corresponding ip array element is left uninitialized, so the subsequent memmove (if "::" was seen) and the loop copying ip to the output buffer will operate on an uninitialized uint16_t. The uninitialized data never directly influences the control flow and is overwritten on successful return by the second half of the parsed IPv4 address. But it's better to fix this to avoid unexpected transformations by a sufficiently smart compiler and reports from UB-detection tools.
* hsearch: fix null pointer arithmetic UBSzabolcs Nagy2023-02-121-2/+2
| | | | | htab->__tab->entries pointer may be 0 so delay using it in arithmetics. this did not cause any known issue other than with ubsan instrumentation.
* increase sendmsg internal buffer to support SCM_MAX_FDColin Cross2023-02-121-2/+5
| | | | | | | | | | | The kernel defines a limit on the number of fds that can be passed through an SCM_RIGHTS ancillary message as SCM_MAX_FD. The value was 255 before kernel 2.6.38 (after that it is 253), and an SCM_RIGHTS ancillary message with 255 fds requires 1040 bytes, slightly more than the current 1024 byte internal buffer in sendmsg. 1024 is an arbitrary size, so increase it to match the the arbitrary size limit in the kernel. This fixes tests that are verifying they support up to SCM_MAX_FD fds.
* mq_notify: block all (application) signals in the worker threadRich Felker2023-02-121-0/+5
| | | | | | | | | | | | | | | until the mq notification event arrives, it is mandatory that signals be blocked. otherwise, a signal can be received, and its handler executed, in a thread which does not yet exist on the abstract machine. after the point of the event arriving, having signals blocked is not a conformance requirement but a QoI requirement. while the application can unblock any signals it wants unblocked in the event handler thread, if they did not start out blocked, it could not block them without a race window where they are momentarily unblocked, and this would preclude controlled delivery or other forms of acceptance (sigwait, etc.) anywhere in the application.
* mq_notify: join worker thread before returning in error pathRich Felker2023-02-121-2/+5
| | | | | this avoids leaving behind transient resource consumption whose cleanup is subject to scheduling behavior.
* mq_notify: rework to fix use-after-close/double-close bugsRich Felker2023-02-121-8/+15
| | | | | | | | | | | | | in the error path where the mq_notify syscall fails, the initiating thread may have closed the socket before the worker thread calls recv on it. even in the absence of such a race, if the recv call failed, e.g. due to seccomp policy blocking it, the worker thread could proceed to close, producing a double-close condition. this can all be simplified by moving the mq_notify syscall into the new thread, so that the error case does not require pthread_cancel. now, the initiating thread only needs to read back the error status after waiting for the worker thread to consume its arguments.
* mq_notify: use semaphore instead of barrier to sync args consumptionRich Felker2023-02-111-5/+9
| | | | | semaphores are a much lighter primitive, and more idiomatic with current usage in the code base.
* fix pthread_detach inadvertently acting as cancellation point in race caseRich Felker2023-02-111-2/+6
| | | | | | | | disabling cancellation around the pthread_join call seems to be the safest and logically simplest fix. i believe it would also be possible to just perform the unmap directly here after __tl_sync, removing the dependency on pthread_join, but such an approach duplicately encodes a lot more implementation assumptions.
* powerpc-sf longjmp clobbering of val argumentRich Felker2023-02-111-4/+4
| | | | | | the logic to check hwcap for SPE register file inadvertently clobbered the val argument before use. switch to a different work register so this doesn't happen.
* riscv64: add vforkPedro Falcato2023-02-091-0/+12
| | | | Implement vfork() using clone(CLONE_VM | CLONE_VFORK | ...).
* fix wrong sigaction syscall ABI on mips*, or1k, microblaze, riscv64Rich Felker2023-02-0914-50/+12
| | | | | | | | | | | | | | | | | | | | | we wrongly defined a dummy SA_RESTORER flag on these archs, despite the kernel interface not actually having such a feature. on archs which lack SA_RESTORER, the kernel sigaction structure also lacks the restorer function pointer member, which means the signal mask appears at a different offset. the kernel was thereby interpreting the bits of the code address as part of the signal set to be masked while handling the signal. this patch removes the erroneous SA_RESTORER definitions from archs which do not have it, makes access to the member conditional on whether SA_RESTORER is defined for the arch, and removes the now-unused asm for the affected archs. because there are reportedly versions of qemu-user which also use the wrong ABI here, the old ksigaction struct size is preserved with an unused member at the end. this is harmless and mitigates the risk of such a bug turning into a buffer overflow onto the sigaction function's stack.
* fix integer overflow in WIFSTOPPED macroRich Felker2023-02-082-2/+2
| | | | | | | | | the result of the 0xffff mask with the exit status could have bit 15 set, in which case multiplying by 0x10001 overflows 32-bit signed int. making the multiply unsigned avoids the overflow. it also changes the sign extension behavior of the subsequent >> operation, but the affected bits are all unwanted anyway and all discarded by the cast to short.
* fix debugger tracking of shared libraries on mips with PIE main programRich Felker2023-01-185-0/+11
| | | | | | | | mips has its own mechanisms for DT_DEBUG because it makes _DYNAMIC read-only, and the original mechanism, DT_MIPS_RLD_MAP, was PIE-incompatible. DT_MIPS_RLD_MAP_REL was added to remedy this, but we never implemented support for it. add it now using the same idioms for mips-specific ldso logic.
* expose memmem under baseline POSIX feature profileRich Felker2023-01-061-1/+1
| | | | | | | memmem has been adopted for the next issue of POSIX (outcome of tracker item 1061). since mem* is in the reserved namespace for string.h it's already fully conforming to expose it by default, so just do so.
* use libc-internal malloc for pthread_atforkRich Felker2022-12-171-0/+5
| | | | | | | | | while no lock is held here making it a lock-order issue, replacement malloc is likely to want to use pthread_atfork, possibly making the call to malloc infinitely recursive. even if not, there is no reason to prefer an application-provided malloc here.
* prevent invalid reads of nl_arg in printf_coreMarkus Wichmann2022-12-141-6/+8
| | | | | | | | | | | | | | printf_core() runs twice, and during its first run, nl_arg is uninitialized and must not be read. It gets initialized at the end of the first run. Conversely, nl_type does not need to be set during the second run, as its useful life has ended at that point, since the only time it is read is during that exact same initialization. Therefore we can simply alternate the assignments. p and w do still need to get values assigned to them, since at least one line in the same if-statement depends on that, but they can be dummy values. arg does not need to be assigned, since in the first run, we encounter a continue statement before using the argument.
* elf.h: add ELFCOMPRESS_ZSTDFangrui Song2022-12-141-0/+1
|