tools/testing/selftests/arm64/gcs/libc-gcs.c
Source file repositories/reference/linux-study-clean/tools/testing/selftests/arm64/gcs/libc-gcs.c
File Facts
- System
- Linux kernel
- Corpus path
tools/testing/selftests/arm64/gcs/libc-gcs.c- Extension
.c- Size
- 17480 bytes
- Lines
- 730
- Domain
- Support Tooling And Documentation
- Bucket
- tools
- Inferred role
- Support Tooling And Documentation: implementation source
- Status
- source implementation candidate
Why This File Exists
Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.
- Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
pthread.hstdbool.hsys/auxv.hsys/mman.hsys/prctl.hsys/ptrace.hsys/uio.hasm/hwcap.hasm/mman.hasm/ptrace.hlinux/compiler.hkselftest_harness.hgcs-util.h
Detected Declarations
function gcs_recursefunction forkfunction main
Annotated Snippet
if (pid == -1) {
ksft_print_msg("wait() failed: %s",
strerror(errno));
goto error;
}
/*
* This should never happen but it's hard to flag in
* the framework.
*/
if (pid != child)
continue;
if (WIFEXITED(status) || WIFSIGNALED(status))
ksft_exit_fail_msg("Child died unexpectedly\n");
if (!WIFSTOPPED(status))
goto error;
sig = WSTOPSIG(status);
if (ptrace(PTRACE_GETSIGINFO, pid, NULL, &si)) {
if (errno == ESRCH) {
ASSERT_NE(errno, ESRCH);
return;
}
if (errno == EINVAL) {
sig = 0; /* bust group-stop */
goto cont;
}
ksft_print_msg("PTRACE_GETSIGINFO: %s\n",
strerror(errno));
goto error;
}
if (sig == SIGSTOP && si.si_code == SI_TKILL &&
si.si_pid == pid)
break;
cont:
if (ptrace(PTRACE_CONT, pid, NULL, sig)) {
if (errno == ESRCH) {
ASSERT_NE(errno, ESRCH);
return;
}
ksft_print_msg("PTRACE_CONT: %s\n", strerror(errno));
goto error;
}
}
/* Where is the child GCS? */
iov.iov_base = &child_gcs;
iov.iov_len = sizeof(child_gcs);
ret = ptrace(PTRACE_GETREGSET, child, NT_ARM_GCS, &iov);
if (ret != 0) {
ksft_print_msg("Failed to read child GCS state: %s (%d)\n",
strerror(errno), errno);
goto error;
}
/* We should have inherited GCS over fork(), confirm */
if (!(child_gcs.features_enabled & PR_SHADOW_STACK_ENABLE)) {
ASSERT_TRUE(child_gcs.features_enabled &
PR_SHADOW_STACK_ENABLE);
goto error;
}
gcspr = child_gcs.gcspr_el0;
ksft_print_msg("Child GCSPR 0x%lx, flags %llx, locked %llx\n",
gcspr, child_gcs.features_enabled,
child_gcs.features_locked);
/* Ideally we'd cross check with the child memory map */
errno = 0;
val = ptrace(PTRACE_PEEKDATA, child, (void *)gcspr, NULL);
ret = errno;
if (ret != 0)
ksft_print_msg("PTRACE_PEEKDATA failed: %s (%d)\n",
strerror(ret), ret);
EXPECT_EQ(ret, 0);
/* The child should be in a function, the GCSPR shouldn't be 0 */
EXPECT_NE(val, 0);
/* Same thing via process_vm_readv() */
local_iov.iov_base = &rval;
Annotation
- Immediate include surface: `pthread.h`, `stdbool.h`, `sys/auxv.h`, `sys/mman.h`, `sys/prctl.h`, `sys/ptrace.h`, `sys/uio.h`, `asm/hwcap.h`.
- Detected declarations: `function gcs_recurse`, `function fork`, `function main`.
- Atlas domain: Support Tooling And Documentation / tools.
- Implementation status: source implementation candidate.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.