tools/testing/selftests/gpio/gpio-cdev-uaf.c

Source file repositories/reference/linux-study-clean/tools/testing/selftests/gpio/gpio-cdev-uaf.c

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/gpio/gpio-cdev-uaf.c
Extension
.c
Size
5896 bytes
Lines
293
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

strcmp(argv[1], "req") == 0) {
		if (strcmp(argv[2], "poll") &&
		    strcmp(argv[2], "read") &&
		    strcmp(argv[2], "ioctl")) {
			fprintf(stderr, "unknown command: %s\n", argv[2]);
			return EXIT_FAILURE;
		}
	} else if (strcmp(argv[1], "handle") == 0) {
		if (strcmp(argv[2], "ioctl")) {
			fprintf(stderr, "unknown command: %s\n", argv[2]);
			return EXIT_FAILURE;
		}
	} else {
		fprintf(stderr, "unknown command: %s\n", argv[1]);
		return EXIT_FAILURE;
	}

	if (strcmp(argv[2], "poll") == 0)
		test_func = test_poll;
	else if (strcmp(argv[2], "read") == 0)
		test_func = test_read;
	else	/* strcmp(argv[2], "ioctl") == 0 */
		test_func = test_ioctl;

	cfd = open_chip("chip", "bank");
	if (cfd == -1) {
		fprintf(stderr, "failed to open chip\n");
		return EXIT_FAILURE;
	}

	/* Step 1: Hold a FD to the test target. */
	if (strcmp(argv[1], "chip") == 0) {
		fd = cfd;
	} else if (strcmp(argv[1], "handle") == 0) {
		struct gpiohandle_request req = {0};

		req.lines = 1;
		if (ioctl(cfd, GPIO_GET_LINEHANDLE_IOCTL, &req) == -1) {
			fprintf(stderr, "failed to get handle FD\n");
			goto err_close_chip;
		}

		close(cfd);
		fd = req.fd;
	} else if (strcmp(argv[1], "event") == 0) {
		struct gpioevent_request req = {0};

		if (ioctl(cfd, GPIO_GET_LINEEVENT_IOCTL, &req) == -1) {
			fprintf(stderr, "failed to get event FD\n");
			goto err_close_chip;
		}

		close(cfd);
		fd = req.fd;
	} else {	/* strcmp(argv[1], "req") == 0 */
		struct gpio_v2_line_request req = {0};

		req.num_lines = 1;
		if (ioctl(cfd, GPIO_V2_GET_LINE_IOCTL, &req) == -1) {
			fprintf(stderr, "failed to get req FD\n");
			goto err_close_chip;
		}

		close(cfd);
		fd = req.fd;
	}

	/* Step 2: Free the chip. */
	close_chip("chip", "bank");

	/* Step 3: Access the dangling FD to trigger UAF. */
	ret = test_func(fd);
	close(fd);
	return ret ? EXIT_FAILURE : EXIT_SUCCESS;
err_close_chip:
	close(cfd);
	close_chip("chip", "bank");
	return EXIT_FAILURE;
}

Annotation

Implementation Notes