[PATCH 4/4] tests: check decoding of SIOC* ioctls

JingPiao Chen chenjingpiao at gmail.com
Tue Dec 27 03:43:31 UTC 2016


* tests/ioctl_sock.c: New file.
* tests/ioctl_sock.test: New test.
* tests/.gitignore: Add ioctl_sock.
* tests/Makefile.am (check_PROGRAMS): Likewise.
(DECODER_TESTS): Add ioctl_sock.test.
---
 tests/.gitignore      |   1 +
 tests/Makefile.am     |   2 +
 tests/ioctl_sock.c    | 290 ++++++++++++++++++++++++++++++++++++++++++++++++++
 tests/ioctl_sock.test |  12 +++
 4 files changed, 305 insertions(+)
 create mode 100644 tests/ioctl_sock.c
 create mode 100755 tests/ioctl_sock.test

diff --git a/tests/.gitignore b/tests/.gitignore
index 48a0e21..fdd9626 100644
--- a/tests/.gitignore
+++ b/tests/.gitignore
@@ -126,6 +126,7 @@ ioctl_loop-v
 ioctl_mtd
 ioctl_rtc
 ioctl_rtc-v
+ioctl_sock
 ioctl_uffdio
 ioctl_v4l2
 ioperm
diff --git a/tests/Makefile.am b/tests/Makefile.am
index cd98900..dd670e3 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -185,6 +185,7 @@ check_PROGRAMS = \
 	ioctl_mtd \
 	ioctl_rtc \
 	ioctl_rtc-v \
+	ioctl_sock \
 	ioctl_uffdio \
 	ioctl_v4l2 \
 	ioperm \
@@ -577,6 +578,7 @@ DECODER_TESTS = \
 	ioctl_mtd.test \
 	ioctl_rtc.test \
 	ioctl_rtc-v.test \
+	ioctl_sock.test \
 	ioctl_uffdio.test \
 	ioctl_v4l2.test \
 	ioperm.test \
diff --git a/tests/ioctl_sock.c b/tests/ioctl_sock.c
new file mode 100644
index 0000000..82a8385
--- /dev/null
+++ b/tests/ioctl_sock.c
@@ -0,0 +1,290 @@
+/*
+ * This file is part of ioctl_sock strace test.
+ *
+ * Copyright (c) 2016 JingPiao Chen <chenjingpiao at gmail.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "tests.h"
+#include <stdio.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <linux/sockios.h>
+#include <arpa/inet.h>
+#include <net/if.h>
+
+#define TEST_STRUCT_IFREQ_ARG_READ(cmd, addr) \
+	ioctl(-1, cmd, addr); \
+	printf("ioctl(-1, %s, {ifr_name=\"%.*s\"}) = -1 EBADF (%m)\n", \
+			#cmd, (int) sizeof(addr->ifr_name), \
+			addr->ifr_name)
+
+#define TEST_STRUCT_IFREQ_ARG_WRITE(cmd, addr) \
+	init_ifreq(cmd, addr); \
+	ioctl(-1, cmd, addr); \
+	printf("ioctl(-1, %s, {ifr_name=\"%.*s\", ", #cmd, \
+			(int) sizeof(addr->ifr_name), addr->ifr_name); \
+	print_ifreq(cmd, ifr); \
+	printf("}) = -1 EBADF (%m)\n")
+
+static const unsigned int magic = 0xdeadbeef;
+
+static void
+init_magic(void *addr, const unsigned int size)
+{
+	unsigned int *p = addr;
+	const unsigned int *end = addr + size - sizeof(int);
+
+	for (; p <= end; ++p)
+		*(unsigned int *) p = magic;
+}
+
+static void
+init_sockaddr(void *addr)
+{
+	struct sockaddr_in *sin;
+	sin = (struct sockaddr_in *) addr;
+
+	sin->sin_family = AF_INET;
+	sin->sin_addr.s_addr = inet_addr("0.0.0.0");
+}
+
+static void
+print_sockaddr(void *addr, const char *str)
+{
+	struct sockaddr_in *sin = (struct sockaddr_in *) addr;
+
+	printf("%s={sa_family=AF_INET, sin_port=htons(%u), "
+			"sin_addr=inet_addr(\"0.0.0.0\")}",
+			str, sin->sin_port);
+}
+
+static void
+init_ifreq(const unsigned int code, struct ifreq *ifr)
+{
+	switch (code) {
+	case SIOCSIFADDR:
+		init_sockaddr((void *) &ifr->ifr_addr);
+		break;
+
+	case SIOCSIFDSTADDR:
+		init_sockaddr((void *) &ifr->ifr_dstaddr);
+		break;
+
+	case SIOCSIFBRDADDR:
+		init_sockaddr((void *) &ifr->ifr_broadaddr);
+		break;
+
+	case SIOCSIFNETMASK:
+		init_sockaddr((void *) &ifr->ifr_netmask);
+		break;
+
+	case SIOCSIFFLAGS:
+		ifr->ifr_flags = IFF_UP;
+		break;
+
+	case SIOCSIFMETRIC:
+		ifr->ifr_metric = magic;
+		break;
+
+	case SIOCSIFMTU:
+		ifr->ifr_mtu = magic;
+		break;
+
+	case SIOCSIFSLAVE:
+		memset(ifr->ifr_slave, 'B', sizeof(ifr->ifr_slave));
+		break;
+
+	case SIOCSIFHWADDR:
+		init_magic(&ifr->ifr_hwaddr.sa_data,
+				sizeof(ifr->ifr_hwaddr.sa_data));
+		break;
+
+	case SIOCSIFTXQLEN:
+		ifr->ifr_qlen = magic;
+		break;
+
+	case SIOCSIFMAP:
+		init_magic(&ifr->ifr_map, sizeof(ifr->ifr_map));
+		break;
+	}
+}
+
+static void
+print_ifreq(const unsigned int code, const struct ifreq *ifr)
+{
+	switch (code) {
+	case SIOCSIFADDR:
+		print_sockaddr((void *) &ifr->ifr_addr, "ifr_addr");
+		break;
+
+	case SIOCSIFDSTADDR:
+		print_sockaddr((void *) &ifr->ifr_dstaddr, "ifr_dstaddr");
+		break;
+
+	case SIOCSIFBRDADDR:
+		print_sockaddr((void *) &ifr->ifr_broadaddr, "ifr_broadaddr");
+		break;
+
+	case SIOCSIFNETMASK:
+		print_sockaddr((void *) &ifr->ifr_netmask, "ifr_netmask");
+		break;
+
+	case SIOCSIFFLAGS:
+		printf("ifr_flags=IFF_UP");
+		break;
+
+	case SIOCSIFMETRIC:
+		printf("ifr_metric=%d", ifr->ifr_metric);
+		break;
+
+	case SIOCSIFMTU:
+		printf("ifr_mtu=%d", ifr->ifr_mtu);
+		break;
+
+	case SIOCSIFSLAVE:
+		printf("ifr_slave=\"%.*s\"", (int) sizeof(ifr->ifr_slave),
+				ifr->ifr_slave);
+		break;
+
+	case SIOCSIFHWADDR: {
+		const unsigned char *bytes =
+			(unsigned char *) &ifr->ifr_hwaddr.sa_data;
+		printf("ifr_hwaddr=%02x:%02x:%02x:%02x:%02x:%02x",
+			bytes[0], bytes[1], bytes[2],
+			bytes[3], bytes[4], bytes[5]);
+		break;
+	}
+
+	case SIOCSIFTXQLEN:
+		printf("ifr_qlen=%d", ifr->ifr_qlen);
+		break;
+
+	case SIOCSIFMAP:
+		printf("ifr_map={mem_start=%#lx, "
+			"mem_end=%#lx, base_addr=%#x, "
+			"irq=%u, dma=%u, port=%u}",
+			ifr->ifr_map.mem_start,
+			ifr->ifr_map.mem_end,
+			(unsigned) ifr->ifr_map.base_addr,
+			(unsigned) ifr->ifr_map.irq,
+			(unsigned) ifr->ifr_map.dma,
+			(unsigned) ifr->ifr_map.port);
+		break;
+	}
+}
+
+int
+main(void)
+{
+	char brname[] = "eth0";
+	struct ifconf *const ifc = tail_alloc(sizeof(*ifc));
+	struct ifreq *const ifr = tail_alloc(sizeof(*ifr));;
+	init_magic(ifr, sizeof(*ifr));
+	init_magic(ifc, sizeof(*ifc));
+	memset(ifr->ifr_name, 'A', sizeof(ifr->ifr_name));
+
+	ioctl(-1, SIOCGIFCONF, ifc);
+	printf("ioctl(-1, SIOCGIFCONF, {%d, %#llx}) = -1 EBADF (%m)\n",
+			ifc->ifc_len, (long long) ifc);
+
+#ifdef SIOCBRADDBR
+	ioctl(-1, SIOCBRADDBR, brname);
+	printf("ioctl(-1, SIOCBRADDBR, \"eth0\") = -1 EBADF (%m)\n");
+
+	ioctl(-1, SIOCBRDELBR, brname);
+	printf("ioctl(-1, SIOCBRDELBR, \"eth0\") = -1 EBADF (%m)\n");
+#endif
+
+#ifdef FIOSETOWN
+	ioctl(-1, FIOSETOWN, &magic);
+	printf("ioctl(-1, FIOSETOWN, [%d]) = -1 EBADF (%m)\n", magic);
+#endif
+#ifdef SIOCSPGRP
+	ioctl(-1, SIOCSPGRP, &magic);
+	printf("ioctl(-1, SIOCSPGRP, [%d]) = -1 EBADF (%m)\n", magic);
+#endif
+#ifdef FIOGETOWN
+	ioctl(-1, FIOGETOWN, &magic);
+	printf("ioctl(-1, FIOGETOWN, %#llx) = -1 EBADF (%m)\n",
+			(long long) &magic);
+#endif
+#ifdef SIOCGPGRP
+	ioctl(-1, SIOCGPGRP, &magic);
+	printf("ioctl(-1, SIOCGPGRP, %#llx) = -1 EBADF (%m)\n",
+			(long long) &magic);
+#endif
+#ifdef SIOCATMARK
+	ioctl(-1, SIOCATMARK, &magic);
+	printf("ioctl(-1, SIOCATMARK, %#llx) = -1 EBADF (%m)\n",
+			(long long) &magic);
+#endif
+#ifdef SIOCBRADDIF
+	ioctl(-1, SIOCBRADDIF, 0);
+	printf("ioctl(-1, SIOCBRADDIF) = -1 EBADF (%m)\n");
+#endif
+#ifdef SIOCBRDELIF
+	ioctl(-1, SIOCBRDELIF, 0);
+	printf("ioctl(-1, SIOCBRDELIF) = -1 EBADF (%m)\n");
+#endif
+
+	memset(ifr->ifr_newname, 'B', sizeof(ifr->ifr_newname));
+	ioctl(-1, SIOCSIFNAME, ifr);
+	printf("ioctl(-1, SIOCSIFNAME, {ifr_name=\"%.*s\", ifr_newname=\"%.*s\"})"
+	       " = -1 EBADF (%m)\n", (int) sizeof(ifr->ifr_name), ifr->ifr_name,
+	       (int) sizeof(ifr->ifr_newname), ifr->ifr_newname);
+
+	TEST_STRUCT_IFREQ_ARG_WRITE(SIOCSIFADDR, ifr);
+	TEST_STRUCT_IFREQ_ARG_WRITE(SIOCSIFDSTADDR, ifr);
+	TEST_STRUCT_IFREQ_ARG_WRITE(SIOCSIFBRDADDR, ifr);
+	TEST_STRUCT_IFREQ_ARG_WRITE(SIOCSIFNETMASK, ifr);
+	TEST_STRUCT_IFREQ_ARG_WRITE(SIOCSIFFLAGS, ifr);
+	TEST_STRUCT_IFREQ_ARG_WRITE(SIOCSIFMETRIC, ifr);
+	TEST_STRUCT_IFREQ_ARG_WRITE(SIOCSIFMTU, ifr);
+	TEST_STRUCT_IFREQ_ARG_WRITE(SIOCSIFSLAVE, ifr);
+	TEST_STRUCT_IFREQ_ARG_WRITE(SIOCSIFHWADDR, ifr);
+	TEST_STRUCT_IFREQ_ARG_WRITE(SIOCSIFTXQLEN, ifr);
+	TEST_STRUCT_IFREQ_ARG_WRITE(SIOCSIFMAP, ifr);
+
+	ioctl(-1, SIOCGIFNAME, ifr);
+	printf("ioctl(-1, SIOCGIFNAME, {ifr_index=%d}) = -1 EBADF (%m)\n",
+			ifr->ifr_ifindex);
+
+	TEST_STRUCT_IFREQ_ARG_READ(SIOCGIFINDEX, ifr);
+	TEST_STRUCT_IFREQ_ARG_READ(SIOCGIFADDR, ifr);
+	TEST_STRUCT_IFREQ_ARG_READ(SIOCGIFDSTADDR, ifr);
+	TEST_STRUCT_IFREQ_ARG_READ(SIOCGIFBRDADDR, ifr);
+	TEST_STRUCT_IFREQ_ARG_READ(SIOCGIFNETMASK, ifr);
+	TEST_STRUCT_IFREQ_ARG_READ(SIOCGIFFLAGS, ifr);
+	TEST_STRUCT_IFREQ_ARG_READ(SIOCGIFMETRIC, ifr);
+	TEST_STRUCT_IFREQ_ARG_READ(SIOCGIFMTU, ifr);
+	TEST_STRUCT_IFREQ_ARG_READ(SIOCGIFSLAVE, ifr);
+	TEST_STRUCT_IFREQ_ARG_READ(SIOCGIFHWADDR, ifr);
+	TEST_STRUCT_IFREQ_ARG_READ(SIOCGIFTXQLEN, ifr);
+	TEST_STRUCT_IFREQ_ARG_READ(SIOCGIFMAP, ifr);
+
+	puts("+++ exited with 0 +++");
+	return 0;
+}
diff --git a/tests/ioctl_sock.test b/tests/ioctl_sock.test
new file mode 100755
index 0000000..b915d1f
--- /dev/null
+++ b/tests/ioctl_sock.test
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+# Check decoding of SIOC* ioctls.
+
+. "${srcdir=.}/init.sh"
+
+run_prog > /dev/null
+run_strace -a22 -s9 -eioctl $args > "$EXP"
+check_prog grep
+grep -v '^ioctl([012],' < "$LOG" > "$OUT"
+match_diff "$OUT" "$EXP"
+rm -f "$EXP" "$OUT"
-- 
2.7.4





More information about the Strace-devel mailing list