[PATCH v4 3/6] tests: check decoding of GPIO ioctls

Dmitry V. Levin ldv at altlinux.org
Sun Jan 24 15:15:07 UTC 2021


On Sat, Jan 23, 2021 at 09:56:42AM +0800, Kent Gibson wrote:
> * tests/.gitignore: Add ioctl_gpio, ioctl_gpio-success,
>     ioctl_gpio-success-Xabbrev, ioctl_gpio-success-Xraw,
>     ioctl_gpio-success-Xverbose, ioctl_gpio-success-v,
>     ioctl_gpio-success-v-Xabbrev, ioctl_gpio-success-v-Xraw,
>     ioctl_gpio-success-v-Xverbose, ioctl_gpio-Xabbrev,
>     ioctl_gpio-Xraw, ioctl_gpio-Xverbose, ioctl_gpio-v,
>     ioctl_gpio-v-Xabbrev, ioctl_gpio-v-Xraw, and ioctl_gpio-v-Xverbose.
> * tests/Makefile.am (check_PROGRAMS): Add ioctl_gpio-success,
>     ioctl_gpio-success-Xabbrev, ioctl_gpio-success-Xraw,
>     ioctl_gpio-success-Xverbose, ioctl_gpio-success-v,
>     ioctl_gpio-success-v-Xabbrev, ioctl_gpio-success-v-Xraw,
>     and ioctl_gpio-success-v-Xverbose.
> * tests/gen_tests.in (ioctl_gpio, ioctl_gpio-Xabbrev, ioctl_gpio-Xraw,
>     ioctl_gpio-Xverbose, ioctl_gpio-v, ioctl_gpio-v-Xabbrev,
>     ioctl_gpio-v-Xraw, ioctl_gpio-v-Xverbose, ioctl_gpio-success,
>     ioctl_gpio-success-Xabbrev, ioctl_gpio-success-Xraw,
>     ioctl_gpio-success-Xverbose, ioctl_gpio-success-v,
>     ioctl_gpio-success-v-Xabbrev, ioctl_gpio-success-v-Xraw,
>     ioctl_gpio-success-v-Xverbose): New tests.
> * tests/ioctl_gpio.c: New file.
> * tests/ioctl_gpio-Xabbrev.c: Likewise.
> * tests/ioctl_gpio-Xraw.c: Likewise.
> * tests/ioctl_gpio-Xverbose.c: Likewise.
> * tests/ioctl_gpio-success.c: Likewise.
> * tests/ioctl_gpio-success-Xabbrev.c: Likewise.
> * tests/ioctl_gpio-success-Xraw.c: Likewise.
> * tests/ioctl_gpio-success-Xverbose.c: Likewise.
> * tests/ioctl_gpio-success-v.c: Likewise.
> * tests/ioctl_gpio-success-v-Xabbrev.c: Likewise.
> * tests/ioctl_gpio-success-v-Xraw.c: Likewise.
> * tests/ioctl_gpio-success-v-Xverbose.c: Likewise.
> * tests/ioctl_gpio-v.c: Likewise.
> * tests/ioctl_gpio-v-Xabbrev.c: Likewise.
> * tests/ioctl_gpio-v-Xraw.c: Likewise.
> * tests/ioctl_gpio-v-Xverbose.c: Likewise.
> * tests/pure_executables.list: Add ioctl_gpio, ioctl_gpio-Xabbrev,
>     ioctl_gpio-Xraw, ioctl_gpio-Xverbose, ioctl_gpio-v,
>     ioctl_gpio-v-Xabbrev, ioctl_gpio-v-Xraw, and ioctl_gpio-v-Xverbose.
> 
> Signed-off-by: Kent Gibson <warthog618 at gmail.com>

I've given this a wider testing and found some portability issues.

[...]
> +	kernel_ulong_t unknown_gpio_cmd = (kernel_ulong_t) 0xbadc0dedfeedb45eULL;

Apparently, this results to different ioctl commands depending on the
architecture because of the difference in _IOC_* constants, just compare
definitions in include/uapi/asm-generic/ioctl.h and e.g.
arch/powerpc/include/uapi/asm/ioctl.h files.

I suggest using a properly defined _IOC(...) constant, see below.

> +	kernel_ulong_t cmd_arg = (kernel_ulong_t) 0xdeadbeefbadc0dedULL;

Unfortunately, the ioctl() function from libc fails to forward
kernel_ulong_t when it's larger than unsigned long, this results to test
failing on x32.  I suggest using an unsigned long constant.

Also, I suggest giving preference in the test to the definitions provided
by Linux kernel headers.

Here is a patch on top of yours I suggest to consider:

diff --git a/tests/ioctl_gpio.c b/tests/ioctl_gpio.c
index 6d526c1b6..0454bfe19 100644
--- a/tests/ioctl_gpio.c
+++ b/tests/ioctl_gpio.c
@@ -8,15 +8,42 @@
  */
 
 #include "tests.h"
-
-#if HAVE_LINUX_GPIO_H
-
 #include <errno.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <sys/ioctl.h>
 #include "types/gpio.h"
+#define XLAT_MACROS_ONLY
+# include "xlat/gpio_event_flags.h"
+# include "xlat/gpio_handle_flags.h"
+# include "xlat/gpio_ioctl_cmds.h"
+# include "xlat/gpio_line_flags.h"
+#undef XLAT_MACROS_ONLY
+
+#ifdef HAVE_STRUCT_GPIOCHIP_INFO
+# define struct_gpiochip_info struct gpiochip_info
+#endif
+
+#ifdef HAVE_STRUCT_GPIOLINE_INFO
+# define struct_gpioline_info struct gpioline_info
+#endif
+
+#ifdef HAVE_STRUCT_GPIOHANDLE_REQUEST
+# define struct_gpiohandle_request struct gpiohandle_request
+#endif
+
+#ifdef HAVE_STRUCT_GPIOEVENT_REQUEST
+# define struct_gpioevent_request struct gpioevent_request
+#endif
+
+#ifdef HAVE_STRUCT_GPIOHANDLE_DATA
+# define struct_gpiohandle_data struct gpiohandle_data
+#endif
+
+#ifdef HAVE_STRUCT_GPIOHANDLE_CONFIG
+# define struct_gpiohandle_config struct gpiohandle_config
+#endif
 
 # define str_event_flags	XLAT_KNOWN(0x3, "GPIOEVENT_REQUEST_BOTH_EDGES")
 # define str_handle_flags	XLAT_KNOWN(0x14, \
@@ -85,7 +112,7 @@ test_print_gpiochip_info(void)
 	printf("ioctl(-1, %s, NULL) = %s\n",
 	       XLAT_STR(GPIO_GET_CHIPINFO_IOCTL), errstr);
 
-	TAIL_ALLOC_OBJECT_CONST_PTR(struct gpiochip_info, p_chipinfo);
+	TAIL_ALLOC_OBJECT_CONST_PTR(struct_gpiochip_info, p_chipinfo);
 
 	p_chipinfo->lines = 0xca;
 	strcpy(p_chipinfo->name, "chip name");
@@ -113,7 +140,7 @@ test_print_gpioline_info(void)
 	printf("ioctl(-1, %s, NULL) = %s\n",
 	       XLAT_STR(GPIO_GET_LINEINFO_IOCTL), errstr);
 
-	TAIL_ALLOC_OBJECT_CONST_PTR(struct gpioline_info, p_lineinfo);
+	TAIL_ALLOC_OBJECT_CONST_PTR(struct_gpioline_info, p_lineinfo);
 
 	p_lineinfo->line_offset = 0x32;
 	p_lineinfo->flags = GPIOLINE_FLAG_ACTIVE_LOW|GPIOLINE_FLAG_OPEN_DRAIN;
@@ -182,7 +209,7 @@ test_print_gpiohandle_request(void)
 	printf("ioctl(-1, %s, NULL) = %s\n",
 	       XLAT_STR(GPIO_GET_LINEHANDLE_IOCTL), errstr);
 
-	TAIL_ALLOC_OBJECT_CONST_PTR(struct gpiohandle_request, p_handle_request);
+	TAIL_ALLOC_OBJECT_CONST_PTR(struct_gpiohandle_request, p_handle_request);
 
 	p_handle_request->lines = 4;
 	p_handle_request->lineoffsets[0] = 0x12;
@@ -234,7 +261,7 @@ test_print_gpioevent_request(void)
 	printf("ioctl(-1, %s, NULL) = %s\n",
 	       XLAT_STR(GPIO_GET_LINEEVENT_IOCTL), errstr);
 
-	TAIL_ALLOC_OBJECT_CONST_PTR(struct gpioevent_request, p_event_request);
+	TAIL_ALLOC_OBJECT_CONST_PTR(struct_gpioevent_request, p_event_request);
 
 	p_event_request->lineoffset = 4;
 	p_event_request->handleflags = GPIOHANDLE_REQUEST_ACTIVE_LOW|GPIOHANDLE_REQUEST_OPEN_SOURCE;
@@ -264,7 +291,7 @@ test_print_gpiohandle_get_values(void)
 	printf("ioctl(-1, %s, NULL) = %s\n",
 	       XLAT_STR(GPIOHANDLE_GET_LINE_VALUES_IOCTL), errstr);
 
-	TAIL_ALLOC_OBJECT_CONST_PTR(struct gpiohandle_data, p_handle_data);
+	TAIL_ALLOC_OBJECT_CONST_PTR(struct_gpiohandle_data, p_handle_data);
 
 	for (int i = 0; i < GPIOHANDLES_MAX; i++)
 		p_handle_data->values[i] = i + 1;
@@ -289,7 +316,7 @@ test_print_gpiohandle_set_values(void)
 	printf("ioctl(-1, %s, NULL) = %s\n",
 	       XLAT_STR(GPIOHANDLE_SET_LINE_VALUES_IOCTL), errstr);
 
-	TAIL_ALLOC_OBJECT_CONST_PTR(struct gpiohandle_data, p_handle_data);
+	TAIL_ALLOC_OBJECT_CONST_PTR(struct_gpiohandle_data, p_handle_data);
 
 	for (int i = 0; i < GPIOHANDLES_MAX; i++)
 		p_handle_data->values[i] = i + 1;
@@ -337,8 +364,10 @@ test_print_gpiohandle_set_config(void)
 int
 main(int argc, char *argv[])
 {
-	kernel_ulong_t unknown_gpio_cmd = (kernel_ulong_t) 0xbadc0dedfeedb45eULL;
-	kernel_ulong_t cmd_arg = (kernel_ulong_t) 0xdeadbeefbadc0dedULL;
+	unsigned long unknown_gpio_cmd =
+		_IOC(_IOC_READ|_IOC_WRITE, 0xb4, 0x5e, 0xfed) |
+		(unsigned long) 0xfacefeed00000000ULL;
+	unsigned long cmd_arg = (unsigned long) 0xdeadbeefbadc0dedULL;
 #ifdef INJECT_RETVAL
 	unsigned long num_skip;
 	bool locked = false;
@@ -370,8 +399,8 @@ main(int argc, char *argv[])
 	/* unknown GPIO command */
 	do_ioctl(unknown_gpio_cmd, cmd_arg);
 	printf("ioctl(-1, " XLAT_FMT ", %#lx) = %s\n",
-		XLAT_SEL((unsigned int)unknown_gpio_cmd,
-		"_IOC(_IOC_READ|_IOC_WRITE, 0xb4, 0x5e, 0x3eed)"),
+		XLAT_SEL((unsigned int) unknown_gpio_cmd,
+		"_IOC(_IOC_READ|_IOC_WRITE, 0xb4, 0x5e, 0xfed)"),
 		cmd_arg, errstr);
 
 	/* GPIO v1 ioctls */
@@ -387,9 +416,3 @@ main(int argc, char *argv[])
 	puts("+++ exited with 0 +++");
 	return 0;
 }
-
-#else
-
-SKIP_MAIN_UNDEFINED("HAVE_LINUX_GPIO_H")
-
-#endif

-- 
ldv


More information about the Strace-devel mailing list