diff options
Diffstat (limited to 'tools/testing/selftests/media_tests')
-rw-r--r-- | tools/testing/selftests/media_tests/Makefile | 2 | ||||
-rw-r--r-- | tools/testing/selftests/media_tests/regression_test.txt | 8 | ||||
-rw-r--r-- | tools/testing/selftests/media_tests/video_device_test.c | 111 |
3 files changed, 88 insertions, 33 deletions
diff --git a/tools/testing/selftests/media_tests/Makefile b/tools/testing/selftests/media_tests/Makefile index 60826d7d37d4..471d83e61d95 100644 --- a/tools/testing/selftests/media_tests/Makefile +++ b/tools/testing/selftests/media_tests/Makefile @@ -1,6 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 # -CFLAGS += -I../ -I../../../../usr/include/ +CFLAGS += -I../ $(KHDR_INCLUDES) TEST_GEN_PROGS := media_device_test media_device_open video_device_test include ../lib.mk diff --git a/tools/testing/selftests/media_tests/regression_test.txt b/tools/testing/selftests/media_tests/regression_test.txt index 2627367681f7..9d0fcd98c085 100644 --- a/tools/testing/selftests/media_tests/regression_test.txt +++ b/tools/testing/selftests/media_tests/regression_test.txt @@ -1,5 +1,5 @@ Testing for regressions in Media Controller API register, ioctl, syscall, -and unregister paths. There have a few problems that result in user-after +and unregister paths. There have a few problems that result in use-after free on media_device, media_devnode, and cdev pointers when the driver is unbound while ioctl is in progress. @@ -15,11 +15,11 @@ Build media_device_test cd tools/testing/selftests/media_tests make -Regressions test for cdev user-after free error on /dev/mediaX when driver +Regressions test for cdev use-after-free error on /dev/mediaX when driver is unbound: Start media_device_test to regression test media devnode dynamic alloc -and cdev user-after-free fixes. This opens media dev files and sits in +and cdev use-after-free fixes. This opens media dev files and sits in a loop running media ioctl MEDIA_IOC_DEVICE_INFO command once every 10 seconds. The idea is when device file goes away, media devnode and cdev should stick around until this test exits. @@ -40,4 +40,4 @@ keep ioctls going while bind/unbind runs. Copy bind_unbind_sample.txt and make changes to specify the driver name and number to run bind and unbind. Start the bind_unbind.sh -Run dmesg looking for any user-after free errors or mutex lock errors. +Run dmesg looking for any use-after-free errors or mutex lock errors. diff --git a/tools/testing/selftests/media_tests/video_device_test.c b/tools/testing/selftests/media_tests/video_device_test.c index 0f6aef2e2593..2c44e115f2f0 100644 --- a/tools/testing/selftests/media_tests/video_device_test.c +++ b/tools/testing/selftests/media_tests/video_device_test.c @@ -37,45 +37,58 @@ #include <time.h> #include <linux/videodev2.h> -int main(int argc, char **argv) +#define PRIORITY_MAX 4 + +int priority_test(int fd) { - int opt; - char video_dev[256]; - int count; - struct v4l2_tuner vtuner; - struct v4l2_capability vcap; + /* This test will try to update the priority associated with a file descriptor */ + + enum v4l2_priority old_priority, new_priority, priority_to_compare; int ret; - int fd; + int result = 0; - if (argc < 2) { - printf("Usage: %s [-d </dev/videoX>]\n", argv[0]); - exit(-1); + ret = ioctl(fd, VIDIOC_G_PRIORITY, &old_priority); + if (ret < 0) { + printf("Failed to get priority: %s\n", strerror(errno)); + return -1; + } + new_priority = (old_priority + 1) % PRIORITY_MAX; + ret = ioctl(fd, VIDIOC_S_PRIORITY, &new_priority); + if (ret < 0) { + printf("Failed to set priority: %s\n", strerror(errno)); + return -1; + } + ret = ioctl(fd, VIDIOC_G_PRIORITY, &priority_to_compare); + if (ret < 0) { + printf("Failed to get new priority: %s\n", strerror(errno)); + result = -1; + goto cleanup; + } + if (priority_to_compare != new_priority) { + printf("Priority wasn't set - test failed\n"); + result = -1; } - /* Process arguments */ - while ((opt = getopt(argc, argv, "d:")) != -1) { - switch (opt) { - case 'd': - strncpy(video_dev, optarg, sizeof(video_dev) - 1); - video_dev[sizeof(video_dev)-1] = '\0'; - break; - default: - printf("Usage: %s [-d </dev/videoX>]\n", argv[0]); - exit(-1); - } +cleanup: + ret = ioctl(fd, VIDIOC_S_PRIORITY, &old_priority); + if (ret < 0) { + printf("Failed to restore priority: %s\n", strerror(errno)); + return -1; } + return result; +} + +int loop_test(int fd) +{ + int count; + struct v4l2_tuner vtuner; + struct v4l2_capability vcap; + int ret; /* Generate random number of interations */ srand((unsigned int) time(NULL)); count = rand(); - /* Open Video device and keep it open */ - fd = open(video_dev, O_RDWR); - if (fd == -1) { - printf("Video Device open errno %s\n", strerror(errno)); - exit(-1); - } - printf("\nNote:\n" "While test is running, remove the device or unbind\n" "driver and ensure there are no use after free errors\n" @@ -98,4 +111,46 @@ int main(int argc, char **argv) sleep(10); count--; } + return 0; +} + +int main(int argc, char **argv) +{ + int opt; + char video_dev[256]; + int fd; + int test_result; + + if (argc < 2) { + printf("Usage: %s [-d </dev/videoX>]\n", argv[0]); + exit(-1); + } + + /* Process arguments */ + while ((opt = getopt(argc, argv, "d:")) != -1) { + switch (opt) { + case 'd': + strncpy(video_dev, optarg, sizeof(video_dev) - 1); + video_dev[sizeof(video_dev)-1] = '\0'; + break; + default: + printf("Usage: %s [-d </dev/videoX>]\n", argv[0]); + exit(-1); + } + } + + /* Open Video device and keep it open */ + fd = open(video_dev, O_RDWR); + if (fd == -1) { + printf("Video Device open errno %s\n", strerror(errno)); + exit(-1); + } + + test_result = priority_test(fd); + if (!test_result) + printf("Priority test - PASSED\n"); + else + printf("Priority test - FAILED\n"); + + loop_test(fd); } |