tools/testing/selftests/landlock/tsync_test.c
Source file repositories/reference/linux-study-clean/tools/testing/selftests/landlock/tsync_test.c
File Facts
- System
- Linux kernel
- Corpus path
tools/testing/selftests/landlock/tsync_test.c- Extension
.c- Size
- 8444 bytes
- Lines
- 328
- 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
linux/landlock.hpthread.hsignal.hsys/prctl.hcommon.h
Detected Declarations
struct thread_restrict_datastruct signaler_datafunction create_rulesetfunction ASSERT_LEfunction store_no_new_privsfunction signal_nop_handlerfunction wait_for_completion_interruptible
Annotated Snippet
struct thread_restrict_data {
pthread_t t;
int ruleset_fd;
int result;
};
static void *thread_restrict(void *data)
{
struct thread_restrict_data *d = data;
d->result = landlock_restrict_self(d->ruleset_fd,
LANDLOCK_RESTRICT_SELF_TSYNC);
return NULL;
}
TEST(competing_enablement)
{
const int ruleset_fd = create_ruleset(_metadata);
struct thread_restrict_data d[] = {
{ .ruleset_fd = ruleset_fd },
{ .ruleset_fd = ruleset_fd },
};
disable_caps(_metadata);
ASSERT_EQ(0, prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0));
ASSERT_EQ(0, pthread_create(&d[0].t, NULL, thread_restrict, &d[0]));
ASSERT_EQ(0, pthread_create(&d[1].t, NULL, thread_restrict, &d[1]));
/* Wait for threads to finish. */
ASSERT_EQ(0, pthread_join(d[0].t, NULL));
ASSERT_EQ(0, pthread_join(d[1].t, NULL));
/* Expect that both succeeded. */
EXPECT_EQ(0, d[0].result);
EXPECT_EQ(0, d[1].result);
EXPECT_EQ(0, close(ruleset_fd));
}
static void signal_nop_handler(int sig)
{
}
struct signaler_data {
pthread_t target;
volatile bool stop;
};
static void *signaler_thread(void *data)
{
struct signaler_data *sd = data;
while (!sd->stop)
pthread_kill(sd->target, SIGUSR1);
return NULL;
}
/*
* Number of idle sibling threads. This must be large enough that even on
* machines with many cores, the sibling threads cannot all complete their
* credential preparation in a single parallel wave, otherwise the signaler
* thread has no window to interrupt wait_for_completion_interruptible().
* 200 threads on a 64-core machine yields ~3 serialized waves, giving the
* tight signal loop enough time to land an interruption.
*/
#define NUM_IDLE_THREADS 200
/*
* Exercises the tsync interruption and cancellation paths in tsync.c.
*
* When a signal interrupts the calling thread while it waits for sibling
* threads to finish their credential preparation
* (wait_for_completion_interruptible in landlock_restrict_sibling_threads),
* the kernel sets ERESTARTNOINTR, cancels queued task works that have not
* started yet (cancel_tsync_works), then waits for the remaining works to
* finish. On the error return, syscalls.c aborts the prepared credentials.
* The kernel automatically restarts the syscall, so userspace sees success.
*/
TEST(tsync_interrupt)
{
size_t i;
pthread_t threads[NUM_IDLE_THREADS];
pthread_t signaler;
struct signaler_data sd;
struct sigaction sa = {};
const int ruleset_fd = create_ruleset(_metadata);
disable_caps(_metadata);
Annotation
- Immediate include surface: `linux/landlock.h`, `pthread.h`, `signal.h`, `sys/prctl.h`, `common.h`.
- Detected declarations: `struct thread_restrict_data`, `struct signaler_data`, `function create_ruleset`, `function ASSERT_LE`, `function store_no_new_privs`, `function signal_nop_handler`, `function wait_for_completion_interruptible`.
- 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.