Age | Commit message (Collapse) | Author | Lines |
---|
| the UTF-8 output code was written assuming an invariant that iconv's decoders only emit valid Unicode Scalar Values which wctomb can encode successfully, thereby always returning a value between 1 and 4. if this invariant is not satisfied, wctomb returns (size_t)-1, and the subsequent adjustments to the output buffer pointer and remaining output byte count overflow, moving the output position backwards, potentially past the beginning of the buffer, without storing any bytes. |
| the man page for this nonstandardized function has historically documented it as scanning for a substring; however, this is functionally incorrect (matches the substring "atime" in the "noatime" option, for example) and differs from other existing implementations. with the change made here, it should match glibc and other implementations, only matching whole options delimited by commas or separated from a value by an equals sign. |
| as a result of incorrect bounds checking on the lead byte being decoded, certain invalid inputs which should produce an encoding error, such as "\xc8\x41", instead produced out-of-bounds loads from the ksc table. in a worst case, the loaded value may not be a valid unicode scalar value, in which case, if the output encoding was UTF-8, wctomb would return (size_t)-1, causing an overflow in the output pointer and remaining buffer size which could clobber memory outside of the output buffer. bug report was submitted in private by Nick Wellnhofer on account of potential security implications. |
| out-of-range second bytes were not handled, leading to wrong character output rather than a reported encoding error. fix based on bug report by Nick Wellnhofer, submitted in private in case the issue turned out to have security implications. |
| Calling __tls_get_addr with brasl is not valid since it's a global symbol; doing so results in an R_390_PC32DBL relocation error from lld. We could fix this by marking __tls_get_addr hidden since it is not part of the s390x ABI, or by using a different instruction. However, given its simplicity, it makes more sense to just manually inline it into __tls_get_offset for performance. The patch has been tested by applying to Zig's bundled musl copy and running the full Zig test suite under qemu-s390x. |
| the kernel mq_attr structure has 8 64-bit longs instead of 8 32-bit longs. it's not clear that this is the nicest way to implement the fix, but the concept (translation) is right, and the details can be changed later if desired. |
| previously, we left any changes made by the application to the timer thread's signal mask active when resetting the thread state for reuse. not only did this violate the intended invariant that timer threads start with all signals blocked; it also allowed application code to execute in a thread that, formally, did not exist. and further, if the internal SIGTIMER signal became unblocked, it could also lead to missed timer expiration events. |
| commit 6ae2568bc2367b4d47e0ea1cb043fd56e697912f introduced a fatal signal condition if the internal timer signal used for SIGEV_THREAD timers is unblocked. this can happen whenever the application alters the signal mask with SIG_SETMASK, since sigset_t objects never include the bits used for implementation-internal signals. this patch effectively reverts the breakage by adding back a no-op signal handler. overruns will not be accounted if the timer signal becomes unblocked, but POSIX does not specify them except for SIGEV_SIGNAL timers anyway. |
| |
| When the pattern was changed from matching any whitespace to just matching spaces and tabs, a newline started being appended to the value of the matched field, if that field was a string. For example, in a 4-field line, the mnt_opts field would have a newline on the end. This happened because a newline is not a space or a tab, and so was matched as part of the value before the end of the string was reached. \n should therefore be added as a character that terminates a value. This shouldn't interfere with the intention of the change to space and tab only, as it was trying to make sure that other whitespace like carriage returns, that should have been part of parsed values, were. Fixes: f314e133 |
| |
| commit 8cca79a72cccbdb54726125d690d7d0095fc2409 added use of SYS_pause to exit() without accounting for newer archs omitting the syscall. use the newly-added __sys_pause abstraction instead, which uses SYS_ppoll when SYS_pause is missing. |
| newer archs lack the syscall. the pause() function accounted for this with its own #ifdef, but that didn't allow use of the syscall directly elsewhere, so move the logic to macros in src/internal/syscall.h where it can be shared. |
| commit b817541f1cfd38e4b81257b3215e276ea9d0fc61 introduced statx with a fallback using fstatat, but failed to fill in stx_rdev_major/minor and stx_attributes[_mask]. the rdev omission has been addressed separately. rather than explicitly zeroing the attributes and their mask, pre-fill the entire structure with zeros. this will also cover the padding adjacent to stx_mode, in case it's ever used in the future. explicit zeroing of stx_btime is removed since, with this change, it will already be pre-zeroed. as an aside, zeroing it was not strictly necessary, since STATX_BASIC_STATS does not include STATX_BTIME and thus does not indicate any validity for it. |
| The current implementation of the statx function fails to set the values of stx->stx_rdev_major and stx->stx_rdev_minor if the statx syscall fails with ENOSYS and thus the statx function has to fall back on fstatat-based emulation. |
| the value placed in the aux vector AT_MINSIGSTKSZ by the kernel is purely the signal frame size, and does not include any execution space for the signal handler. this is contrary to the POSIX definition of MINSIGSTKSZ to be a value that can actually execute at least some minimal signal handler, and contrary to the historical definitions of MINSIGSTKSZ which had at least 1k of headroom. |
| commit 996b6154b20184c3b08cce28eb01edb7f47e9413 added support for querying the dynamic limit but did not enforce it in sigaltstack. the kernel also does not seem to reliably enforce it, or at least does not necessarily enforce the same limit exposed to userspace, so it needs to be enforced here. |
| internally, printf always works with the maximal-size supported integer and floating point formats. however, the space needed to format a floating point number is proportional to the mantissa and exponent ranges. on archs where long double is larger than double, knowing that the actual value fit in double allows us to use a much smaller buffer, roughly 1/16 the size. as a bonus, making the working buffer a VLA whose dimension depends on the format specifier prevents the compiler from lifting the stack adjustment to the top of printf_core. this makes it so printf calls without floating point arguments do not waste even the smaller amount of stack space needed for double, making it much more practical to use printf in tightly stack-constrained environments. |
| linux puts hung-up ttys in a state where ioctls produce EIO, and may do the same for other types of devices in error or shutdown states. such an error clearly does not mean the device is not a tty, but it also can't reliably establish that the device is a tty, so the only safe thing to do seems to be reporting the error. programs that don't check errno will conclude that the device is not a tty, which is no different from what happens now, but at least they gain the option to differentiate between the cases. commit c84971995b3a6d5118f9357c040572f4c78bcd55 introduced the errno collapsing behavior, but prior to that, errno was not set at all by isatty. |
| this is purely a readability change, not a functional one. all of the integer format cases use a common tail for handling precision logic after the string representation of the number has been generated. the code as I originally wrote it was overly clever in the aim of making a point that the flow could be done without goto, and jumped over intervening cases by wrapping them in if (0) { }, with the case labels for each inside the conditional block scope. this has been a perpetual source of complaints about the readability and comprehensibility of the file, so I am now changing it to explicitly jump to the tail logic with goto statements. |
| this is the same as cp850, but with the euro symbol replacing the lowercase dotless i at 0xd5. it is significant because it's used by thermal receipt printers. |
| the output of atan2 is already in the correct range and does not need further reduction. the MAXNUM macros were both unused and incorrect. |
| the comment does not match the required or actual behavior when x<0 and y is not an integer. while it could be corrected, the role of comments here is to tell about characteristics unique to the implementation, not to restate the requirements of the standard, so just removing it seems best. |
| while not the only error codes presently omitted, these two are particularly likely to be encountered in the wild. EUCLEAN is used by linux filesystem and device drivers to report filesystem structure corruption or data corruption. ENAVAIL is used by some linux drivers to indicate non-availability of a resource. both names are new inventions to correspond to how they are actually used, as the original kernel strings ("Structure needs cleaning" and "No XENIX semaphores available") are not remotely meaningful or reasonable. |
| if sem_post is interrupted between clearing the waiters bit from the semaphore value and performing the futex wait operation, subsequent calls to sem_post will not perform a wake operation unless a new waiter has arrived. usually, this is at most a minor nuisance, since the original wake operation will eventually happen. however, it's possible that the wake is delayed indefinitely if interrupted by a signal handler, or that the address the wake needs to be performed on is no longer mapped if the semaphore was a process-shared one that has since been unmapped but has a waiter on a different mapping of the same semaphore. this can happen when another thread using the same mapping "steals the post" atomically before actually becoming a second waiter, deduces from success that it was the last user of the semaphore mapping, then re-posts and unmaps the semaphore mapping. this scenario was described in a report by Markus Wichmann. instead of checking only the waiters bit, also check the waiter count that was sampled before the atomic post operation, and perform the wake if it's nonzero. this will not produce any additional wakes under non-race conditions, since the waiters bit only becomes zero when targeting a single waiter for wake. checking both was already the behavior prior to commit 159d1f6c02569091c7a48bdb2e2e824b844a1902. |
| our pthread barrier implementation reportedly has bugs that are could lead to malfunction or crash in timer_create. while this has not been reviewed to confirm, there have been past reports of pthread barrier bugs, and it seems likely that something is actually wrong. pthread barriers are an obscure primitive, and timer_create is the only place we are using them internally at present. even if they were working correctly, this means we are imposing linking of otherwise likely-dead code whenever timer_create is used. a pair of semaphores functions identically to a 2-waiter barrier except for destruction order properties. since the parent is responsible for the argument structure (including semaphores) lifetimes, the last operation on them in the timer thread must be posting to the parent. |
| previously, global dtors, which are executed after all atexit handlers have been called rather than being implemented as an atexit handler themselves, would deadlock if they called atexit. it was intentional to disallow adding more atexit handlers past the last point where they would be executed, since a successful return from atexit imposes a contract that the handler will be executed, but this was only considered in the context of calls to atexit from other threads, not calls from the dtors. to fix this, release the lock after the exit handlers loop completes, but but set a flag first so that we can make all future calls to atexit return a failure code. |
| per the C and POSIX standards, calling exit "more than once", including via return from main, produces undefined behavior. this language predates threads, and at the time it was written, could only have applied to recursive calls to exit via atexit handlers. C++ likewise makes calls to exit from global dtors undefined. nonetheless, by the present specification as written, concurrent calls to exit by multiple threads also have undefined behavior. originally, our implementation of exit did have locking to handle concurrent calls safely, but that was changed in commit 2e55da911896a91e95b24ab5dc8a9d9b0718f4de based on it being undefined. from a standpoint of both hardening and quality of implementation, that change seems to have been a mistake. this change adds back locking, but with awareness of the lock owner so that recursive calls to exit can be trapped rather than deadlocking. this also opens up the possibility of allowing recursive calls to succeed, if future consensus ends up being in favor of that. prior to this change, exit already behaved partly as if protected by a lock as long as atexit was linked, but multiple threads calling exit could concurrently "pop off" atexit handlers and execute them in parallel with one another rather than serialized in the reverse order of registration. this was a likely unnoticed but potentially very dangerous manifestation of the undefined behavior. if on the other hand atexit was not linked, multiple threads calling exit concurrently could each run their own instance of global dtors, if any, likely producing double-free situations. now, if multiple threads call exit concurrently, all but the first will permanently block (in SYS_pause) until the process terminates, and all atexit handlers, global dtors, and stdio flushing/position consistency will be handled in the thread that arrived first. this is really the only reasonable way to define concurrent calls to exit. it is not recommended usage, but may become so in the future if there is consensus/standardization, as there is a push from the rust language community (and potentially other languages interoperating with the C runtime) to make concurrent calls to the language's exit interfaces safe even when multiple languages are involved in a program, and this is only possible by having the locking in the underlying C exit. |
| having it in __tz.c caused gmtime[_r] and timegm to pull in all of the time zone code despite having no need for it. |
| commit 895736d49bd2bb318c69de99a05ea70c035c2da9 made these changes along with fixing a real bug in LOG_MAKEPRI. based on further information, they do not seem to be well-motivated or in line with policy. the result of LOG_FAC is not a meaningful facility value if we shift it down like before, but apparently the way it is used by applications is as an index into an array of facility names. moreover, all historical systems which define it do so with the shift. as it is a nonstandard interface, there is no justification for providing a macro by the same name that is incompatible with historical practice. the value of LOG_FACMASK likewise is 0x3f8 on all historical systems checked. while only 5 bits are used for existing facility codes, the convention seems to be that all 7 bits belong to the facility field and theoretically could be used to expand to having more facilities. that seems unlikely to happen, but there is no reason to make a gratuitously incompatible change here. |
| |
| Per RFC 5952, ties for longest sequence of zero fields must be broken by choosing the earliest, but the implementation put the leading sequence of zeros at a disadvantage. That's because for example when compressing "0:0:0:10:0:0:0:10" the strspn(buf+i, ":0") call returns 6 for the first sequence and 7 for the second one – the second sequence has the benefit of a leading colon. Changing the condition to require beating the leading sequence by not one but two characters resolves the issue. |
| this interface does not have a lot of historical consensus on how it handles the contents of the /etc/shells file in regard to whitespace and comments, but the commonality between all checked is that they ignore lines that are blank or that begin with '#', so that is the behavior we adopt. |
| these are nonstandard and unnecessary for using the associated functionality, but resulted in applications that used them malfunctioning. patch based on proposed fix by erny hombre. |
| This syscall is available since Linux 3.15 and also implemented in glibc from version 2.28. It is commonly used in filesystem or security contexts. Constants RENAME_NOREPLACE, RENAME_EXCHANGE, RENAME_WHITEOUT are guarded by _GNU_SOURCE as with glibc. |
| commit 1b0d48517f816e98f19111df82f32bfc1608ecec wrongly copied the getdents return type of int rather than matching the ssize_t used by posix_getdents. this was overlooked in testing on 32-bit archs but obviously broke 64-bit archs. |
| this interface was added as the outcome of Austin Group tracker issue 697. no error is specified for unsupported flags, which is probably an oversight. for now, EOPNOTSUPP is used so as not to overload EINVAL. |
| the %s conversion is added as the outcome of Austin Group tracker issue 169 and its unspecified behavior is clarified as the outcome of issue 1727. the %F, %g, %G, %u, %V, %z, and %Z conversions are added as the outcome of Austin Group tracker issue 879 for alignment with strftime and the behaviors of %u, %z, and %Z are defined as the outcome of issue 1727. at this time, the conversions with unspecified effects on struct tm are all left as parse-only no-ops. this may be changed at a later time, particularly for %s, if there is reasonable cross-implementation consensus outside the standards process on what the behavior should be. |
| once the remaining value is less than 10, the modulo operation to produce the final digit and division to prepare for next loop iteration can be dropped. this may be a meaningful performance distinction when formatting low-magnitude numbers in bulk, and should never hurt. based on patch by Viktor Reznov. |
| historically linux limited the number of supplementary groups a process could be in to 32, but this limit was raised to 65536 in linux 2.6.4. proposals to support the new limit, change NGROUPS_MAX, or make it dynamic have been stalled due to the impact it would have on initgroups where the groups array exists in automatic storage. the changes here decouple initgroups from the value of NGROUPS_MAX and allow it to fall back to allocating a buffer in the case where getgrouplist indicates the user has more supplementary groups than could be reported in the buffer. getgrouplist already involves allocation, so this does not pull in any new link dependency. likewise, getgrouplist is already using the public malloc (vs internal libc one), so initgroups does the same. if this turns out not to be the best choice, both can be changed together later. the initial buffer size is left at 32, but now as the literal value, so that any potential future change to NGROUPS_MAX will not affect initgroups. |
| commit cfa0a54c082d41db6446638eed1d57f163434092 attempted to fix rounding on archs where long double is not 80-bit (where LDBL_MANT_DIG is not zero mod four), but failed to address the edge case where rounding was skipped because LDBL_MANT_DIG/4 rounded down in the comparison against the requested precision. the rounding logic based on hex digit count is difficult to understand and not well-motivated, so rather than try to fix it, replace it with an explicit calculation in terms of number of bits to be kept, without any truncating division operations. based on patch by Peter Ammon, but with scalbn to apply the rounding exponent since the value will not generally fit in any integer type. scalbn is used instead of scalbnl to avoid pulling in the latter unnecessarily, since the value is an exact power of two whose exponent range is bounded by LDBL_MANT_DIG, a small integer. |
| The principal expressions defining acosh and acos are such that acosh(z) = ±i acos(z) where the + is only true on the Im(z)>0 half of the complex plane (and partly on Im(z)==0 depending on number representation). fix the comment without expanding on the details. |
| if x!=0, y!=0, z==0 then fma(x,y,z) == x*y in all rounding modes, while adding z can ruin the sign of 0 if x*y rounds to -0. |
| POSIX requires pwrite to honor the explicit file offset where the write should take place even if the file was opened as O_APPEND. however, linux historically defined the pwrite syscall family as honoring O_APPEND. this cannot be changed on the kernel side due to stability policy, but the addition of the pwritev2 syscall with a flags argument opened the door to fixing it, and linux commit 73fa7547c70b32cc69685f79be31135797734eb6 adds the RWF_NOAPPEND flag that lets us request a write honoring the file offset argument. this patch changes the pwrite function to first attempt using the pwritev2 syscall with RWF_NOAPPEND, falling back to using the old pwrite syscall only after checking that O_APPEND is not set for the open file. if O_APPEND is set, the operation fails with EOPNOTSUPP, reflecting that the kernel does not support the correct behavior. this is an extended error case needed to avoid the wrong behavior that happened before (writing the data at the wrong location), and is aligned with the spirit of the POSIX requirement that "An attempt to perform a pwrite() on a file that is incapable of seeking shall result in an error." since the pwritev2 syscall interprets the offset of -1 as a request to write at the current file offset, it is mapped to a different negative value that will produce the expected error. pwritev, though not governed by POSIX at this time, is adjusted to match pwrite in honoring the offset. |
| the jis0208 table we use is only 84x94 in size, but the shift_jis encoding supports a 94x94 grid. attempts to convert sequences outside of the supported zone resulted in out-of-bounds table reads, misinterpreting adjacent rodata as part of the character table and thereby converting these sequences to unexpected characters. |
| this is not needed, but may act as a hint to the compiler, and also serves to suppress unused function warnings if enabled (on by default since commit 86ac0f794731f03dfff40ee843ff9e2752945d5e). |
| these are taken from the IANA registry, restricted to those that match the forms already used for other supported character encodings. |
| this is how it's defined in the cp936 document referenced by the IANA charset registry as defining GBK, and of the mappings defined there, was the only one missing. it is not accepted for GB18030, as GB18030 is a UTF and has its own unique mapping for the euro symbol. |
| |
| Identical to riscv64 except for stack offsets in clone. |