[PATCH] nptl: fix block problem caused by setxid called from clone
Gao feng
gaofeng@cn.fujitsu.com
Wed Nov 13 09:37:00 GMT 2013
On 11/08/2013 09:41 AM, Gao feng wrote:
> The process created by clone will have a copy of memory of
> parent process, if parent creates some thread before call
> clone, the stacked_used, __stack_user list is invalid for
> the child process created by clone. and if this child process
> runs before the threads, the setxid_futex of these threads
> will never be changed to 0 for this child process. since
> it only has a copied memory. so the setxid will be blocked
> by futex forever.
>
> This patch skips operation of the threads in different thread
> group.
>
Any comment?
> Signed-off-by: Gao feng <gaofeng@cn.fujitsu.com>
> ---
> nptl/allocatestack.c | 21 ++++++++++++++-------
> 1 file changed, 14 insertions(+), 7 deletions(-)
>
> diff --git a/nptl/allocatestack.c b/nptl/allocatestack.c
> index 1e0fe1f..8fc2591 100644
> --- a/nptl/allocatestack.c
> +++ b/nptl/allocatestack.c
> @@ -1075,12 +1075,19 @@ __nptl_setxid (struct xid_command *cmdp)
>
> struct pthread *self = THREAD_SELF;
>
> + INTERNAL_SYSCALL_DECL (err);
> + pid_t pid = INTERNAL_SYSCALL(getpid, err, 0);
> +
> /* Iterate over the list with system-allocated threads first. */
> list_t *runp;
> list_for_each (runp, &stack_used)
> {
> struct pthread *t = list_entry (runp, struct pthread, list);
> - if (t == self)
> + /* setxid may be called by the process created by clone,
> + * this process has a copy of parent's memory but it is
> + * running in different thread group, skip the threads
> + * in different thread group. */
> + if (t == self || t->pid != pid)
> continue;
>
> setxid_mark_thread (cmdp, t);
> @@ -1090,7 +1097,7 @@ __nptl_setxid (struct xid_command *cmdp)
> list_for_each (runp, &__stack_user)
> {
> struct pthread *t = list_entry (runp, struct pthread, list);
> - if (t == self)
> + if (t == self || t->pid != pid)
> continue;
>
> setxid_mark_thread (cmdp, t);
> @@ -1106,7 +1113,7 @@ __nptl_setxid (struct xid_command *cmdp)
> list_for_each (runp, &stack_used)
> {
> struct pthread *t = list_entry (runp, struct pthread, list);
> - if (t == self)
> + if (t == self || t->pid != pid)
> continue;
>
> signalled += setxid_signal_thread (cmdp, t);
> @@ -1115,7 +1122,7 @@ __nptl_setxid (struct xid_command *cmdp)
> list_for_each (runp, &__stack_user)
> {
> struct pthread *t = list_entry (runp, struct pthread, list);
> - if (t == self)
> + if (t == self || t->pid != pid)
> continue;
>
> signalled += setxid_signal_thread (cmdp, t);
> @@ -1135,7 +1142,7 @@ __nptl_setxid (struct xid_command *cmdp)
> list_for_each (runp, &stack_used)
> {
> struct pthread *t = list_entry (runp, struct pthread, list);
> - if (t == self)
> + if (t == self || t->pid != pid)
> continue;
>
> setxid_unmark_thread (cmdp, t);
> @@ -1144,7 +1151,7 @@ __nptl_setxid (struct xid_command *cmdp)
> list_for_each (runp, &__stack_user)
> {
> struct pthread *t = list_entry (runp, struct pthread, list);
> - if (t == self)
> + if (t == self || t->pid != pid)
> continue;
>
> setxid_unmark_thread (cmdp, t);
> @@ -1152,7 +1159,7 @@ __nptl_setxid (struct xid_command *cmdp)
>
> /* This must be last, otherwise the current thread might not have
> permissions to send SIGSETXID syscall to the other threads. */
> - INTERNAL_SYSCALL_DECL (err);
> +
> result = INTERNAL_SYSCALL_NCS (cmdp->syscall_no, err, 3,
> cmdp->id[0], cmdp->id[1], cmdp->id[2]);
> if (INTERNAL_SYSCALL_ERROR_P (result, err))
>
More information about the Libc-alpha
mailing list