-
Notifications
You must be signed in to change notification settings - Fork 332
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Re-work nxt_process_check_pid_status() slightly (resolves a clang-analyzer (non-)issue) #1442
Conversation
Is there a guarantee that Within the function there's no nullcheck, and there's also no check to see whether what's at that address is what we expect there to be 🤔 . Could it be that coverity says "well this could be null, so the return of If I understand it correctly, local non-static uninitialised variable is indeterminate: https://stackoverflow.com/questions/1597405/what-happens-to-a-declared-uninitialized-variable-in-c-does-it-have-a-value |
Well let's see...
nxt_fd_t pid_pipe[2], gc_pipe[2]; At this point the two members of gc_pipe have undefined values. It is then passed into ret = nxt_process_init_pidns(task, process, pid_pipe, gc_pipe, &use_pidns); From there it is passed into ret = nxt_pipe_create(task, gc_pipe, 0, 0);
if (nxt_slow_path(ret == NXT_ERROR)) {
return NXT_ERROR;
} After returning, either the two members of So long story short, no, |
Hm, does that not mean that in order for In isolation there's nothing preventing any code addition in the future to pass a null pointer to |
I don't actually see this issue in coverity only clang-analyzer. But anyway the only possible return values of |
The only way
Right, this is an internal unit API, use it correctly! (In this if you did pass in It won't take you more than two seconds looking around the Unit code base to find more like this... We do not need to check every single pointer passed into functions... |
Passing |
This is completely outwith the scope of this PR but something we could consider, though I would need convincing it's a worthwhile exercise, would be to use the nonnull function attribute to enable compile time checks e.g. #include <stddef.h>
static void f(void *p)
{
}
int main(void)
{
f(NULL);
return 0;
} $ CFLAGS=-Wall make nn
cc -Wall nn.c -o nn #include <stddef.h>
__attribute__((nonnull))
static void f(void *p)
{
}
int main(void)
{
f(NULL);
return 0;
} $ CFLAGS=-Wall make nn
cc -Wall nn.c -o nn
nn.c: In function ‘main’:
nn.c:10:9: warning: argument 1 null where non-null expected [-Wnonnull]
10 | f(NULL);
| ^
nn.c:4:13: note: in a call to function ‘f’ declared ‘nonnull’
4 | static void f(void *p)
| ^ (the attribute can also take a list of arguments position for nonnull pointers) |
There has been a long standing clang-analyzer issue in nxt_process_check_pid_status(), well ever since I introduced this function in commit b0e2d9d ("Isolation: Switch to fork(2) & unshare(2) on Linux."), It is complaining that there are cases where 'status' could be returned with an undefined or garbage value. Now I'm convinced this can't happen If nxt_process_pipe_timer() returns NXT_OK read(2) the status value If the read(2) failed or if we got NXT_ERROR from nxt_process_pipe_timer(), NXT_OK (0) and NXT_ERROR (-1) are the only possible return values here, then we set status to -1 I don't see a scenario where status is either not set by the read(2) or not set to -1. Now I'm not a fan of initialising variables willy-nilly, however, in this case if we initialise status to -1, then we can simply remove the if (ret <= 0) { check. So it closes this (non-)issue but also provides a little code simplification. NOTE: There is no need to check the return from the read(2) here. We are reading a single byte, we either get it or don't. Signed-off-by: Andrew Clayton <[email protected]>
Rebased with master
|
There has been a long standing clang-analyzer issue in nxt_process_check_pid_status(), well ever since I introduced this function in commit b0e2d9d ("Isolation: Switch to fork(2) & unshare(2) on Linux."),
It is complaining that there are cases where 'status' could be returned with an undefined or garbage value.
Now I'm convinced this can't happen
I don't see a scenario where status is either not set by the read(2) or not set to -1.
Now I'm not a fan of initialising variables willy-nilly, however, in this case if we initialise status to -1, then we can simply remove the
check. So it closes this (non-)issue but also provides a little code simplification.
NOTE: There is no need to check the return from the read(2) here. We are reading a single byte, we either get it or don't.