tools/testing/selftests/powerpc/ptrace/core-pkey.c

Source file repositories/reference/linux-study-clean/tools/testing/selftests/powerpc/ptrace/core-pkey.c

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/powerpc/ptrace/core-pkey.c
Extension
.c
Size
9458 bytes
Lines
424
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

struct shared_info {
	struct child_sync child_sync;

	/* AMR value the parent expects to read in the core file. */
	unsigned long amr;

	/* IAMR value the parent expects to read in the core file. */
	unsigned long iamr;

	/* UAMOR value the parent expects to read in the core file. */
	unsigned long uamor;

	/* When the child crashed. */
	time_t core_time;
};

static int increase_core_file_limit(void)
{
	struct rlimit rlim;
	int ret;

	ret = getrlimit(RLIMIT_CORE, &rlim);
	FAIL_IF(ret);

	if (rlim.rlim_cur != RLIM_INFINITY && rlim.rlim_cur < CORE_FILE_LIMIT) {
		rlim.rlim_cur = CORE_FILE_LIMIT;

		if (rlim.rlim_max != RLIM_INFINITY &&
		    rlim.rlim_max < CORE_FILE_LIMIT)
			rlim.rlim_max = CORE_FILE_LIMIT;

		ret = setrlimit(RLIMIT_CORE, &rlim);
		FAIL_IF(ret);
	}

	ret = getrlimit(RLIMIT_FSIZE, &rlim);
	FAIL_IF(ret);

	if (rlim.rlim_cur != RLIM_INFINITY && rlim.rlim_cur < CORE_FILE_LIMIT) {
		rlim.rlim_cur = CORE_FILE_LIMIT;

		if (rlim.rlim_max != RLIM_INFINITY &&
		    rlim.rlim_max < CORE_FILE_LIMIT)
			rlim.rlim_max = CORE_FILE_LIMIT;

		ret = setrlimit(RLIMIT_FSIZE, &rlim);
		FAIL_IF(ret);
	}

	return TEST_PASS;
}

static int child(struct shared_info *info)
{
	bool disable_execute = true;
	int pkey1, pkey2, pkey3;
	int *ptr, ret;

	/* Wait until parent fills out the initial register values. */
	ret = wait_parent(&info->child_sync);
	if (ret)
		return ret;

	ret = increase_core_file_limit();
	FAIL_IF(ret);

	/* Get some pkeys so that we can change their bits in the AMR. */
	pkey1 = sys_pkey_alloc(0, PKEY_DISABLE_EXECUTE);
	if (pkey1 < 0) {
		pkey1 = sys_pkey_alloc(0, PKEY_UNRESTRICTED);
		FAIL_IF(pkey1 < 0);

		disable_execute = false;
	}

	pkey2 = sys_pkey_alloc(0, PKEY_UNRESTRICTED);
	FAIL_IF(pkey2 < 0);

	pkey3 = sys_pkey_alloc(0, PKEY_UNRESTRICTED);
	FAIL_IF(pkey3 < 0);

	info->amr |= 3ul << pkeyshift(pkey1) | 2ul << pkeyshift(pkey2);

	if (disable_execute)
		info->iamr |= 1ul << pkeyshift(pkey1);
	else
		info->iamr &= ~(1ul << pkeyshift(pkey1));

	info->iamr &= ~(1ul << pkeyshift(pkey2) | 1ul << pkeyshift(pkey3));

Annotation

Implementation Notes