tools/testing/selftests/filesystems/openat2/openat2_test.c

Source file repositories/reference/linux-study-clean/tools/testing/selftests/filesystems/openat2/openat2_test.c

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/filesystems/openat2/openat2_test.c
Extension
.c
Size
10750 bytes
Lines
363
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 open_how_ext {
	struct open_how inner;
	uint32_t extra1;
	char pad1[128];
	uint32_t extra2;
	char pad2[128];
	uint32_t extra3;
};

struct struct_test {
	const char *name;
	struct open_how_ext arg;
	size_t size;
	int err;
};

struct flag_test {
	const char *name;
	struct open_how how;
	int err;
};

FIXTURE(openat2) {};

FIXTURE_SETUP(openat2)
{
	if (!openat2_supported)
		SKIP(return, "openat2(2) not supported");
}

FIXTURE_TEARDOWN(openat2) {}

/*
 * Verify that the struct size and misalignment handling for openat2(2) is
 * correct, including that is_zeroed_user() works.
 */
TEST_F(openat2, struct_argument_sizes)
{
	int misalignments[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 17, 87 };
	struct struct_test tests[] = {
		/* Normal struct. */
		{ .name = "normal struct",
		  .arg.inner.flags = O_RDONLY,
		  .size = sizeof(struct open_how) },
		/* Bigger struct, with zeroed out end. */
		{ .name = "bigger struct (zeroed out)",
		  .arg.inner.flags = O_RDONLY,
		  .size = sizeof(struct open_how_ext) },

		/* TODO: Once expanded, check zero-padding. */

		/* Smaller than version-0 struct. */
		{ .name = "zero-sized 'struct'",
		  .arg.inner.flags = O_RDONLY, .size = 0, .err = -EINVAL },
		{ .name = "smaller-than-v0 struct",
		  .arg.inner.flags = O_RDONLY,
		  .size = OPEN_HOW_SIZE_VER0 - 1, .err = -EINVAL },

		/* Bigger struct, with non-zero trailing bytes. */
		{ .name = "bigger struct (non-zero data in first 'future field')",
		  .arg.inner.flags = O_RDONLY, .arg.extra1 = 0xdeadbeef,
		  .size = sizeof(struct open_how_ext), .err = -E2BIG },
		{ .name = "bigger struct (non-zero data in middle of 'future fields')",
		  .arg.inner.flags = O_RDONLY, .arg.extra2 = 0xfeedcafe,
		  .size = sizeof(struct open_how_ext), .err = -E2BIG },
		{ .name = "bigger struct (non-zero data at end of 'future fields')",
		  .arg.inner.flags = O_RDONLY, .arg.extra3 = 0xabad1dea,
		  .size = sizeof(struct open_how_ext), .err = -E2BIG },
	};

	for (int i = 0; i < ARRAY_SIZE(tests); i++) {
		struct struct_test *test = &tests[i];
		struct open_how_ext how_ext = test->arg;

		for (int j = 0; j < ARRAY_SIZE(misalignments); j++) {
			int fd, misalign = misalignments[j];
			void *copy = NULL, *how_copy = &how_ext;
			char *fdpath = NULL;

			if (misalign) {
				/*
				 * Explicitly misalign the structure copying it with the given
				 * (mis)alignment offset. The other data is set to be non-zero to
				 * make sure that non-zero bytes outside the struct aren't checked
				 *
				 * This is effectively to check that is_zeroed_user() works.
				 */
				copy = malloc(misalign + sizeof(how_ext));
				how_copy = copy + misalign;
				memset(copy, 0xff, misalign);

Annotation

Implementation Notes