Remove calls to the userspace API exit() from the kernel. The problem
with doing such calls is that the exit functions are called with kernel
mode privileges which is a big security no-no.
Do not allow a deferred cancellation if the group is exiting, it is too
dangerous to allow the threads to execute any user space code after the
exit has started.
If the cancelled thread is not inside a cancellation point, just kill it
immediately via asynchronous cancellation. This will create far less
problems than allowing it to continue running user code.
There is an issue where the wrong process exit code is given to the parent
when a process exits. This happens when the process has pthreads running
user code i.e. not within a cancel point / system call.
Why does this happen ?
When exit() is called, the following steps are done:
- group_kill_children(), which tells the children to die via pthread_cancel()
Then, one of two things can happen:
1. if the child is in a cancel point, it gets scheduled to allow it to leave
the cancel point and gets destroyed immediately
2. if the child is not in a cancel point, a "cancel pending" flag is set and
the child will die when the next cancel point is encountered
So what is the problem here?
The last thread alive dispatches SIGCHLD to the parent, which carries the
process's exit code. The group head has the only meaningful exit code and
this is what should be passed. However, in the second case, the group head
exits before the child, taking the process exit code to its grave. The child
that was alive will exit next and will pass its "status" to the parent process,
but this status is not the correct value to pass.
This commit fixes the issue by passing the group head's exit code ALWAYS to
the parent process.
Detach the address environment handling from the group structure to the
tcb. This is preparation to fix rare cases where the system (MMU) is left
without a valid page directory, e.g. when a process exits.
NuttX kernel should not use the syscall functions, especially after
enabling CONFIG_SCHED_INSTRUMENTATION_SYSCALL, all system functions
will be traced to backend, which will impact system performance.
Signed-off-by: chao an <anchao@xiaomi.com>
A testcase as following:
child_task()
{
sleep(3);
}
main_task()
{
while (1)
{
ret = task_create("child_task", child_task, );
sleep(1);
task_delete(ret);
}
}
Root casuse:
task_delete hasn's cover the condition that the deleted-task
is justing running on the other CPU.
Fix:
Let the nxsched_remove_readytorun() do the real work
Signed-off-by: ligd <liguiding1@xiaomi.com>
1. When pthread exit, set the default cancellability state to NONCANCELABLE state.
2. Make sure modify tcb->flags is atomic operations.
Signed-off-by: zhangyuan21 <zhangyuan21@xiaomi.com>
It takes about 10 cycles to obtain the task list according to the task
status. In most cases, we know the task status, so we can directly
add the task from the specified task list to reduce time consuming.
It takes about 10 cycles to obtain the task list according to the task
status. In most cases, we know the task status, so we can directly
delete the task from the specified task list to reduce time consuming.
strlcpy ensure the destination is NUL-terminated, and also fix warning:
```c
task/task_prctl.c:138:15: warning: 'strncpy' output may be truncated copying 30 bytes from a string of length 31 [-Wstringop-truncation]
138 | strncpy(name, tcb->name, CONFIG_TASK_NAME_SIZE - 1);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
```
Signed-off-by: Huang Qi <huangqi3@xiaomi.com>
For CONFIG_BUILD_KERNEL using the sched/task/task_exithook implementation
will just not work. It calls user code with kernel privileges which is
a bit of a security issue.
Deleting a task from another task's context will not do, so shut
this gate down for BUILD_KERNEL. In this case if a task wants another
task to terminate, it must ask the other task to politely kill itself.
Note: kthreads still need this, also, the kernel can delete a task
without asking.