Open FrankHB opened 1 year ago
Thanks for your review, but I think almost all your reviews should be submitted to musl upstream.
This function is copied from musl. https://elixir.bootlin.com/musl/latest/source/src/string/strchrnul.c#L10
Yeah, this function can be replaced by strchrnul
because strchrnul
is introduced since Android 7.
(Minor) Misleading comment
Handling of reference count before creation
These comments and codes are copied from musl libc without any change. So you'd better report this issue to musl upstream.
Upstream also use write
without any protection. https://elixir.bootlin.com/musl/latest/source/src/thread/sem_open.c#L124
All of the functions of pthread cancellation is not supported by Bionic libc (see https://android.googlesource.com/platform/bionic/+/master/docs/status.md).
Thanks for your review, but I think almost all your reviews should be submitted to musl upstream.
- (Minor) Bloated __strchrnul
This function is copied from musl. https://elixir.bootlin.com/musl/latest/source/src/string/strchrnul.c#L10
Yeah, this function can be replaced by
strchrnul
becausestrchrnul
is introduced since Android 7.I see. However, manually inlining this into the call site can be even clearer. (Or probably also better report it to musl?)
- (Minor) Misleading comment
- Handling of reference count before creation
These comments and codes are copied from musl libc without any change. So you'd better report this issue to musl upstream.
- Missing handling of EINTR for write
Upstream also use
write
without any protection. https://elixir.bootlin.com/musl/latest/source/src/thread/sem_open.c#L124
Thanks for confirmation. I'll report them to upstream.
- Missing handling of pthread calcellation
All of the functions of pthread cancellation is not supported by Bionic libc (see https://android.googlesource.com/platform/bionic/+/master/docs/status.md).
Glad to see this. (esp. "Unlikely to ever be implemented"... as a few things actually ease the life with Android.)
@richfelker For probably better contextual information, would you mind to continue the discussion here, or I should transfer the questions to musl mailing list?
Problem description
There are multiple issues found in the source code of the named semaphore implementation.
Since the source of the package is directly maintained in this repository without some upstream, issues are reported here. (Although I see most of the code vendored here has the upstream: musl.)
List of issues
(Minor) Bloated
__strchrnul
https://github.com/termux/termux-packages/blob/0cb89e24e5d872af1d4cd84f452100a45d3696a0/packages/libandroid-posix-semaphore/semaphore.c#L49
__strchrnul
is bloated. Looks like better inlined into the call site, since it is used only once. Extraction of the function into file scope does not make it more readable. The cast away ofconst
is also a source of suspicous mess.(Minor) Misleading comment
https://github.com/termux/termux-packages/blob/0cb89e24e5d872af1d4cd84f452100a45d3696a0/packages/libandroid-posix-semaphore/semaphore.c#L110-L112
The comment is misleading, because it is not that "necessary". Some other implementations (notably glibc) use different approach: cleanup later instead of preallocating the slot eagerly. Nevertheless, the current code is OK. This is at least simpler compared to glibc's approach which needs to set and recover
errno
aroundmunmap
on further failure path.Handling of reference count before creation
https://github.com/termux/termux-packages/blob/0cb89e24e5d872af1d4cd84f452100a45d3696a0/packages/libandroid-posix-semaphore/semaphore.c#L114-L123
cnt += semtab[i].refcnt;
likely leads to undefined behavior if it overflows. The comment later ("Avoid possibility of overflow later") is then nonsense in this case, because it has already overflow.+=
is just the WTF stuff, because it serves nothing to do with limitations from the spec. Should this actually be=
?Missing handling of
EINTR
forwrite
https://github.com/termux/termux-packages/blob/0cb89e24e5d872af1d4cd84f452100a45d3696a0/packages/libandroid-posix-semaphore/semaphore.c#L171-L175
The call to
write
may be interrupted. The upstream codedoes not usealso does not handle it properly (although it is in a loop). OTOH, glibc has the logic by usingwrite
TEMP_FAILURE_RETRY
:https://github.com/bminor/glibc/blob/4290aed05135ae4c0272006442d147f2155e70d7/sysdeps/pthread/sem_open.c#L163-L168
Missing handling of pthread calcellation
Both musl and glibc has logic to temporarily disable pthread cancellation. Nothing is here.
Is this just unsupported?
Missing translation of
errno
forsem_unlink
unlink
may returnEPERM
, which is not allowed forsem_unlink
.Musl is also buggy here. OTOH, glibc will set
errno
appropriately.Remarks
Many but not all of the issues are also in musl.
What steps will reproduce the bug?
Since the bugs are found by source code auditing, it just takes some time to direct to the source code. Then, read carefully.
What is the expected behavior?
See the discussions in the list of issues in problem description.
Test cases are not provided due to non-triviality.
System information
termux-info:
(I don't see it relavant here because the analysis is totally off the runtime, but OK...)