NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
kern/59608: compat_linux should ignore LINUX_CLONE_SYSVSEM and assume stack grows down
>Number: 59608
>Category: kern
>Synopsis: compat_linux should ignore LINUX_CLONE_SYSVSEM and assume stack grows down
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: kern-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Mon Aug 25 19:20:00 +0000 2025
>Originator: csaba mate
>Release: 11.0-beta
>Organization:
freertr.org
>Environment:
NetBSD 11.0_BETA NetBSD 11.0_BETA (GENERIC) #0: Mon Aug 25 20:56:36 CEST 2025 mc36@noti:/home/mc36/obj/sys/arch/amd64/compile/GENERIC amd64
>Description:
running a simple
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <pthread.h>
void doNativeLoop() {
printf("running\n");
}
void main() {
pthread_t threadUdp;
printf("start\n");
if (pthread_create(&threadUdp, NULL, (void*) & doNativeLoop, NULL)) printf("error\n");
printf("done\n");
sleep(1);
printf("exit\n");
}
results in a non-running thread on the latest netbsd-11-beta + latest glibc.
>How-To-Repeat:
compile the above c code and run it with glibc 2.42 and you'll get "error" and not "running"
in glibc source (clone-internal.c) i see this:
int
__clone_internal_fallback (struct clone_args *cl_args,
<------><------><------> int (*func) (void *arg), void *arg)
{
/* Map clone3 arguments to clone arguments. NB: No need to check
invalid clone3 specific bits in flags nor exit_signal since this
is an internal function. */
int flags = cl_args->flags | cl_args->exit_signal;
void *stack = cast_to_pointer (cl_args->stack);
int ret;
#if !_STACK_GROWS_DOWN && !_STACK_GROWS_UP
# error "Define either _STACK_GROWS_DOWN or _STACK_GROWS_UP"
#endif
#if _STACK_GROWS_DOWN
stack += cl_args->stack_size;
#endif
ret = __clone (func, stack, flags, arg,
<------><------> cast_to_pointer (cl_args->parent_tid),
<------><------> cast_to_pointer (cl_args->tls),
<------><------> cast_to_pointer (cl_args->child_tid));
return ret;
}
thats how i came up with the below stack arithmetic...
they set stack_grows_down everywhere except hppa, which is not a target of compat-linux at the time of writing...
>Fix:
--- src.bad/sys/compat/linux/common/linux_sched.h 2024-09-28 21:35:56.000000000 +0200
+++ src.ok/sys/compat/linux/common/linux_sched.h 2025-08-25 20:48:10.531115738 +0200
@@ -85,7 +85,7 @@
LINUX_CLONE_VM | LINUX_CLONE_FS | LINUX_CLONE_FILES | \
LINUX_CLONE_SIGHAND | LINUX_CLONE_THREAD | LINUX_CLONE_VFORK | \
LINUX_CLONE_PARENT_SETTID | LINUX_CLONE_CHILD_CLEARTID | \
- LINUX_CLONE_CHILD_SETTID | LINUX_CLONE_SETTLS)
+ LINUX_CLONE_CHILD_SETTID | LINUX_CLONE_SETTLS | LINUX_CLONE_SYSVSEM)
#define LINUX_CLONE_UNIMPLEMENTED_FLAGS ( \
LINUX_CLONE_NEWNS | LINUX_CLONE_NEWUTS | LINUX_CLONE_NEWIPC | \
--- src.bad/sys/compat/linux/common/linux_sched.c 2024-10-03 14:56:49.000000000 +0200
+++ src.ok/sys/compat/linux/common/linux_sched.c 2025-08-25 21:01:34.107972657 +0200
@@ -230,7 +230,7 @@
// XXX: clone3 has stacksize, instead implement clone as a clone3
// wrapper.
SCARG(&clone_args, flags) = flags;
- SCARG(&clone_args, stack) = (void *)(uintptr_t)cl_args.stack;
+ SCARG(&clone_args, stack) = (void *)((uintptr_t)cl_args.stack + (uintptr_t)cl_args.stack_size);
SCARG(&clone_args, parent_tidptr) =
(void *)(intptr_t)cl_args.parent_tid;
SCARG(&clone_args, tls) =
Home |
Main Index |
Thread Index |
Old Index