]> granicus.if.org Git - strace/blob - tests/netlink_kobject_uevent.c
strace: terminate itself if interrupted by a signal
[strace] / tests / netlink_kobject_uevent.c
1 /*
2  * Copyright (c) 2017 JingPiao Chen <chenjingpiao@gmail.com>
3  * Copyright (c) 2017-2018 The strace developers.
4  * All rights reserved.
5  *
6  * SPDX-License-Identifier: GPL-2.0-or-later
7  */
8
9 #include "tests.h"
10 #include <string.h>
11 #include <stdio.h>
12 #include <sys/socket.h>
13 #include <arpa/inet.h>
14 #include "netlink.h"
15 #include "netlink_kobject_uevent.h"
16
17 static const char *errstr;
18
19 static ssize_t
20 sys_send(const int fd, const void *const buf, const size_t len)
21 {
22         const ssize_t rc = sendto(fd, buf, len, MSG_DONTWAIT, NULL, 0);
23         errstr = sprintrc(rc);
24         return rc;
25 }
26
27 static void
28 test_nlmsg_type_udev(const int fd)
29 {
30         static const char extra[] = "12345678";
31         struct udev_monitor_netlink_header uh = {
32                 .prefix = "libudev",
33                 .magic = htonl(0xfeedcafe),
34                 .header_size = sizeof(uh),
35                 .properties_off = 40,
36                 .properties_len = 299,
37                 .filter_subsystem_hash = htonl(0xc370b302),
38                 .filter_devtype_hash = htonl(0x10800000),
39                 .filter_tag_bloom_hi = htonl(0x2000400),
40                 .filter_tag_bloom_lo = htonl(0x10800000),
41         };
42         const unsigned int extra_len = LENGTH_OF(extra);
43         const unsigned int uh_len = sizeof(uh);
44
45         char *const buf = tail_alloc(uh_len + extra_len);
46         memcpy(buf + extra_len, &uh, uh_len);
47
48         sys_send(fd, buf + extra_len, uh_len);
49         printf("sendto(%d, {{prefix=\"%s\", magic=htonl(%#x)"
50                ", header_size=%u, properties_off=%u, properties_len=%u"
51                ", filter_subsystem_hash=htonl(%#x)"
52                ", filter_devtype_hash=htonl(%#x)"
53                ", filter_tag_bloom_hi=htonl(%#x)"
54                ", filter_tag_bloom_lo=htonl(%#x)}}, %u, MSG_DONTWAIT, NULL, "
55                "0) = %s\n"
56                , fd, uh.prefix,
57                ntohl(uh.magic), uh.header_size, uh.properties_off,
58                uh.properties_len, ntohl(uh.filter_subsystem_hash),
59                ntohl(uh.filter_devtype_hash), ntohl(uh.filter_tag_bloom_hi),
60                ntohl(uh.filter_tag_bloom_lo), uh_len, errstr);
61
62         memcpy(buf, &uh, uh_len);
63         memcpy(buf + uh_len, extra, extra_len);
64         sys_send(fd, buf, uh_len + extra_len);
65         printf("sendto(%d, {{prefix=\"%s\", magic=htonl(%#x)"
66                ", header_size=%u, properties_off=%u, properties_len=%u"
67                ", filter_subsystem_hash=htonl(%#x)"
68                ", filter_devtype_hash=htonl(%#x)"
69                ", filter_tag_bloom_hi=htonl(%#x)"
70                ", filter_tag_bloom_lo=htonl(%#x)}, "
71                , fd, uh.prefix,
72                ntohl(uh.magic), uh.header_size, uh.properties_off,
73                uh.properties_len, ntohl(uh.filter_subsystem_hash),
74                ntohl(uh.filter_devtype_hash), ntohl(uh.filter_tag_bloom_hi),
75                ntohl(uh.filter_tag_bloom_lo));
76         print_quoted_memory(buf + uh_len, extra_len);
77         printf("}, %u, MSG_DONTWAIT, NULL, 0) = %s\n",
78                uh_len + extra_len, errstr);
79
80         memcpy(buf + extra_len + 1, &uh, uh_len - 1);
81         sys_send(fd, buf + extra_len + 1, uh_len);
82         printf("sendto(%d, ", fd);
83         print_quoted_memory(&uh, MIN(uh_len - 1, DEFAULT_STRLEN));
84         printf("%s, %u, MSG_DONTWAIT, NULL, 0) = %s\n",
85                (uh_len - 1 > DEFAULT_STRLEN ? "..." : ""),
86                uh_len, errstr);
87 }
88
89 static void
90 test_nlmsg_type_kernel(const int fd)
91 {
92         struct udev_monitor_netlink_header uh = {
93                 .prefix = "change@",
94                 .magic = htonl(0xfeedcafe),
95                 .header_size = sizeof(uh),
96                 .properties_off = 10,
97                 .properties_len = 299,
98                 .filter_subsystem_hash = htonl(0xfffffff),
99                 .filter_devtype_hash = htonl(0x10000000),
100                 .filter_tag_bloom_hi = htonl(0x2000400),
101         };
102         const unsigned int uh_len = sizeof(uh);
103
104         TAIL_ALLOC_OBJECT_CONST_PTR(struct udev_monitor_netlink_header, p);
105         memcpy(p, &uh, uh_len);
106
107         sys_send(fd, p, uh_len);
108         printf("sendto(%d, ", fd);
109         print_quoted_memory(&uh, MIN(uh_len, DEFAULT_STRLEN));
110         printf("%s, %u, MSG_DONTWAIT, NULL, 0) = %s\n",
111                (uh_len > DEFAULT_STRLEN ? "..." : ""),
112                uh_len, errstr);
113 }
114
115 int
116 main(void)
117 {
118         skip_if_unavailable("/proc/self/fd/");
119
120         int fd = create_nl_socket(NETLINK_KOBJECT_UEVENT);
121
122         test_nlmsg_type_udev(fd);
123         test_nlmsg_type_kernel(fd);
124         /* test using data that looks like a zero-length C string */
125         char *const buf = tail_alloc(DEFAULT_STRLEN + 1);
126         buf[0] = '=';
127         fill_memory_ex(buf + 1, DEFAULT_STRLEN, 0, DEFAULT_STRLEN);
128
129         sys_send(fd, buf + 1, DEFAULT_STRLEN);
130         printf("sendto(%d, ", fd);
131         print_quoted_memory(buf + 1, DEFAULT_STRLEN);
132         printf(", %u, MSG_DONTWAIT, NULL, 0) = %s\n",
133                DEFAULT_STRLEN, errstr);
134
135         sys_send(fd, buf, DEFAULT_STRLEN + 1);
136         printf("sendto(%d, ", fd);
137         print_quoted_memory(buf, DEFAULT_STRLEN);
138         printf("..., %u, MSG_DONTWAIT, NULL, 0) = %s\n",
139                DEFAULT_STRLEN + 1, errstr);
140
141         puts("+++ exited with 0 +++");
142         return 0;
143 }