On Mon, May 19, 2025, at 16:06, Yury Khrustalev wrote: > > This seems fragile and may call for writing cumbersome code. In essence, > we will have to have clone30(), clone31(), clone32()... wrappers which > probably defeats the point of why clone3 was added: > > > if (clone32_supported && clone32(...) == -1 && errno == E2BIG) > { > clone32_supported = false; > /* ... */ > } > else if (clone31_supported && clone31(...) == -1 && errno == E2BIG) > { > clone12_supported = false; > /* ... */ > } > ... > > Is there a neat way to work around this? What was the idea for extending > clone_args in practice? > > I suppose we can't rely on kernel version because support for extended > clone_args can be backported. In any case, we'd have to do a syscall > for this (it would probably be great to have kernel version in auxv). I don't think there is a generic way to handle extended syscalls from libc, it really depends on the specific feature it's trying to use that requires the additional fields to be nonzero: some features may have a reasonable fallback implementation in libc, other features still require an error to be passed back to the caller. As I understand the shadow stack feature, we want this to be enabled whenever the kernel and hardware supports it, completely transparent to an application, right? I think ideally we'd check for HWCAP_GCS on arm64 or the equivalent feature on other architectures and expect clone3 to support the longer argument whenever that is set, but it looks like that would break on current kernels that already support HWCAP_GCS but not the clone3 argument. Adding one more hwcap flag would be ugly, but that seems to be the easiest way. That way, glibc can just test for the new hwcap flag only use the extra clone3 word if all prerequisites (hardware support, kernel gcs support, clone3 argument support) are there. Arnd