tools/testing/selftests/arm64/gcs/gcs-locking.c

Source file repositories/reference/linux-study-clean/tools/testing/selftests/arm64/gcs/gcs-locking.c

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/arm64/gcs/gcs-locking.c
Extension
.c
Size
4936 bytes
Lines
200
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.

Dependency Surface

Detected Declarations

Annotated Snippet

// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (C) 2023 ARM Limited.
 *
 * Tests for GCS mode locking.  These tests rely on both having GCS
 * unconfigured on entry and on the kselftest harness running each
 * test in a fork()ed process which will have it's own mode.
 */

#include <limits.h>

#include <sys/auxv.h>
#include <sys/prctl.h>

#include <asm/hwcap.h>

#include "kselftest_harness.h"

#include "gcs-util.h"

#define my_syscall2(num, arg1, arg2)                                          \
({                                                                            \
	register long _num  __asm__ ("x8") = (num);                           \
	register long _arg1 __asm__ ("x0") = (long)(arg1);                    \
	register long _arg2 __asm__ ("x1") = (long)(arg2);                    \
	register long _arg3 __asm__ ("x2") = 0;                               \
	register long _arg4 __asm__ ("x3") = 0;                               \
	register long _arg5 __asm__ ("x4") = 0;                               \
	                                                                      \
	__asm__  volatile (                                                   \
		"svc #0\n"                                                    \
		: "=r"(_arg1)                                                 \
		: "r"(_arg1), "r"(_arg2),                                     \
		  "r"(_arg3), "r"(_arg4),                                     \
		  "r"(_arg5), "r"(_num)					      \
		: "memory", "cc"                                              \
	);                                                                    \
	_arg1;                                                                \
})

/* No mode bits are rejected for locking */
TEST(lock_all_modes)
{
	int ret;

	ret = prctl(PR_LOCK_SHADOW_STACK_STATUS, ULONG_MAX, 0, 0, 0);
	ASSERT_EQ(ret, 0);
}

FIXTURE(valid_modes)
{
};

FIXTURE_VARIANT(valid_modes)
{
	unsigned long mode;
};

FIXTURE_VARIANT_ADD(valid_modes, enable)
{
	.mode = PR_SHADOW_STACK_ENABLE,
};

FIXTURE_VARIANT_ADD(valid_modes, enable_write)
{
	.mode = PR_SHADOW_STACK_ENABLE | PR_SHADOW_STACK_WRITE,
};

FIXTURE_VARIANT_ADD(valid_modes, enable_push)
{
	.mode = PR_SHADOW_STACK_ENABLE | PR_SHADOW_STACK_PUSH,
};

FIXTURE_VARIANT_ADD(valid_modes, enable_write_push)
{
	.mode = PR_SHADOW_STACK_ENABLE | PR_SHADOW_STACK_WRITE |
		PR_SHADOW_STACK_PUSH,
};

FIXTURE_SETUP(valid_modes)
{
}

FIXTURE_TEARDOWN(valid_modes)
{
}

/* We can set the mode at all */
TEST_F(valid_modes, set)
{

Annotation

Implementation Notes