lib/tests/fortify_kunit.c

Source file repositories/reference/linux-study-clean/lib/tests/fortify_kunit.c

File Facts

System
Linux kernel
Corpus path
lib/tests/fortify_kunit.c
Extension
.c
Size
38496 bytes
Lines
1070
Domain
Kernel Services
Bucket
lib
Inferred role
Kernel Services: implementation source
Status
source implementation candidate

Why This File Exists

Shared kernel service surface used by multiple subsystems, including helpers, cryptography, virtualization support, and async I/O infrastructure.

Dependency Surface

Detected Declarations

Annotated Snippet

struct fortify_padding {
	unsigned long bytes_before;
	char buf[32];
	unsigned long bytes_after;
};

static void fortify_test_strlen(struct kunit *test)
{
	struct fortify_padding pad = { };
	int i, end = sizeof(pad.buf) - 1;

	/* Fill 31 bytes with valid characters. */
	for (i = 0; i < sizeof(pad.buf) - 1; i++)
		pad.buf[i] = i + '0';
	/* Trailing bytes are still %NUL. */
	KUNIT_EXPECT_EQ(test, pad.buf[end], '\0');
	KUNIT_EXPECT_EQ(test, pad.bytes_after, 0);

	/* String is terminated, so strlen() is valid. */
	KUNIT_EXPECT_EQ(test, strlen(pad.buf), end);
	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0);

	/* Make string unterminated, and recount. */
	pad.buf[end] = 'A';
	end = sizeof(pad.buf);
	KUNIT_EXPECT_EQ(test, strlen(pad.buf), end);
	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 1);
}

static void fortify_test_strnlen(struct kunit *test)
{
	struct fortify_padding pad = { };
	int i, end = sizeof(pad.buf) - 1;

	/* Fill 31 bytes with valid characters. */
	for (i = 0; i < sizeof(pad.buf) - 1; i++)
		pad.buf[i] = i + '0';
	/* Trailing bytes are still %NUL. */
	KUNIT_EXPECT_EQ(test, pad.buf[end], '\0');
	KUNIT_EXPECT_EQ(test, pad.bytes_after, 0);

	/* String is terminated, so strnlen() is valid. */
	KUNIT_EXPECT_EQ(test, strnlen(pad.buf, sizeof(pad.buf)), end);
	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0);
	/* A truncated strnlen() will be safe, too. */
	KUNIT_EXPECT_EQ(test, strnlen(pad.buf, sizeof(pad.buf) / 2),
					sizeof(pad.buf) / 2);
	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0);

	/* Make string unterminated, and recount. */
	pad.buf[end] = 'A';
	end = sizeof(pad.buf);
	/* Reading beyond will fail. */
	KUNIT_EXPECT_EQ(test, strnlen(pad.buf, end + 1), end);
	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 1);
	KUNIT_EXPECT_EQ(test, strnlen(pad.buf, end + 2), end);
	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 2);

	/* Early-truncated is safe still, though. */
	KUNIT_EXPECT_EQ(test, strnlen(pad.buf, end), end);
	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 2);

	end = sizeof(pad.buf) / 2;
	KUNIT_EXPECT_EQ(test, strnlen(pad.buf, end), end);
	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 2);
}

static void fortify_test_strcpy(struct kunit *test)
{
	struct fortify_padding pad = { };
	char src[sizeof(pad.buf) + 1] = { };
	int i;

	/* Fill 31 bytes with valid characters. */
	for (i = 0; i < sizeof(src) - 2; i++)
		src[i] = i + '0';

	/* Destination is %NUL-filled to start with. */
	KUNIT_EXPECT_EQ(test, pad.bytes_before, 0);
	KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 1], '\0');
	KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 2], '\0');
	KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 3], '\0');
	KUNIT_EXPECT_EQ(test, pad.bytes_after, 0);

	/* Legitimate strcpy() 1 less than of max size. */
	KUNIT_ASSERT_TRUE(test, strcpy(pad.buf, src)
				== pad.buf);
	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0);
	KUNIT_EXPECT_EQ(test, fortify_write_overflows, 0);
	/* Only last byte should be %NUL */

Annotation

Implementation Notes