1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * User Events FTrace Test Program
4  *
5  * Copyright (c) 2021 Beau Belgrave <beaub@linux.microsoft.com>
6  */
7 
8 #include <errno.h>
9 #include <linux/user_events.h>
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <fcntl.h>
13 #include <sys/ioctl.h>
14 #include <sys/stat.h>
15 #include <sys/uio.h>
16 #include <unistd.h>
17 
18 #include "../kselftest_harness.h"
19 
20 const char *data_file = "/sys/kernel/tracing/user_events_data";
21 const char *status_file = "/sys/kernel/tracing/user_events_status";
22 const char *enable_file = "/sys/kernel/tracing/events/user_events/__test_event/enable";
23 const char *trace_file = "/sys/kernel/tracing/trace";
24 const char *fmt_file = "/sys/kernel/tracing/events/user_events/__test_event/format";
25 
26 static int trace_bytes(void)
27 {
28 	int fd = open(trace_file, O_RDONLY);
29 	char buf[256];
30 	int bytes = 0, got;
31 
32 	if (fd == -1)
33 		return -1;
34 
35 	while (true) {
36 		got = read(fd, buf, sizeof(buf));
37 
38 		if (got == -1)
39 			return -1;
40 
41 		if (got == 0)
42 			break;
43 
44 		bytes += got;
45 	}
46 
47 	close(fd);
48 
49 	return bytes;
50 }
51 
52 static int skip_until_empty_line(FILE *fp)
53 {
54 	int c, last = 0;
55 
56 	while (true) {
57 		c = getc(fp);
58 
59 		if (c == EOF)
60 			break;
61 
62 		if (last == '\n' && c == '\n')
63 			return 0;
64 
65 		last = c;
66 	}
67 
68 	return -1;
69 }
70 
71 static int get_print_fmt(char *buffer, int len)
72 {
73 	FILE *fp = fopen(fmt_file, "r");
74 	char *newline;
75 
76 	if (!fp)
77 		return -1;
78 
79 	/* Read until empty line (Skip Common) */
80 	if (skip_until_empty_line(fp) < 0)
81 		goto err;
82 
83 	/* Read until empty line (Skip Properties) */
84 	if (skip_until_empty_line(fp) < 0)
85 		goto err;
86 
87 	/* Read in print_fmt: */
88 	if (fgets(buffer, len, fp) == NULL)
89 		goto err;
90 
91 	newline = strchr(buffer, '\n');
92 
93 	if (newline)
94 		*newline = '\0';
95 
96 	fclose(fp);
97 
98 	return 0;
99 err:
100 	fclose(fp);
101 
102 	return -1;
103 }
104 
105 static int clear(int *check)
106 {
107 	struct user_unreg unreg = {0};
108 
109 	unreg.size = sizeof(unreg);
110 	unreg.disable_bit = 31;
111 	unreg.disable_addr = (__u64)check;
112 
113 	int fd = open(data_file, O_RDWR);
114 
115 	if (fd == -1)
116 		return -1;
117 
118 	if (ioctl(fd, DIAG_IOCSUNREG, &unreg) == -1)
119 		if (errno != ENOENT)
120 			return -1;
121 
122 	if (ioctl(fd, DIAG_IOCSDEL, "__test_event") == -1)
123 		if (errno != ENOENT)
124 			return -1;
125 
126 	close(fd);
127 
128 	return 0;
129 }
130 
131 static int check_print_fmt(const char *event, const char *expected, int *check)
132 {
133 	struct user_reg reg = {0};
134 	char print_fmt[256];
135 	int ret;
136 	int fd;
137 
138 	/* Ensure cleared */
139 	ret = clear(check);
140 
141 	if (ret != 0)
142 		return ret;
143 
144 	fd = open(data_file, O_RDWR);
145 
146 	if (fd == -1)
147 		return fd;
148 
149 	reg.size = sizeof(reg);
150 	reg.name_args = (__u64)event;
151 	reg.enable_bit = 31;
152 	reg.enable_addr = (__u64)check;
153 	reg.enable_size = sizeof(*check);
154 
155 	/* Register should work */
156 	ret = ioctl(fd, DIAG_IOCSREG, &reg);
157 
158 	close(fd);
159 
160 	if (ret != 0) {
161 		printf("Reg failed in fmt\n");
162 		return ret;
163 	}
164 
165 	/* Ensure correct print_fmt */
166 	ret = get_print_fmt(print_fmt, sizeof(print_fmt));
167 
168 	if (ret != 0)
169 		return ret;
170 
171 	return strcmp(print_fmt, expected);
172 }
173 
174 FIXTURE(user) {
175 	int status_fd;
176 	int data_fd;
177 	int enable_fd;
178 	int check;
179 };
180 
181 FIXTURE_SETUP(user) {
182 	self->status_fd = open(status_file, O_RDONLY);
183 	ASSERT_NE(-1, self->status_fd);
184 
185 	self->data_fd = open(data_file, O_RDWR);
186 	ASSERT_NE(-1, self->data_fd);
187 
188 	self->enable_fd = -1;
189 }
190 
191 FIXTURE_TEARDOWN(user) {
192 	close(self->status_fd);
193 	close(self->data_fd);
194 
195 	if (self->enable_fd != -1) {
196 		write(self->enable_fd, "0", sizeof("0"));
197 		close(self->enable_fd);
198 	}
199 
200 	if (clear(&self->check) != 0)
201 		printf("WARNING: Clear didn't work!\n");
202 }
203 
204 TEST_F(user, register_events) {
205 	struct user_reg reg = {0};
206 	struct user_unreg unreg = {0};
207 
208 	reg.size = sizeof(reg);
209 	reg.name_args = (__u64)"__test_event u32 field1; u32 field2";
210 	reg.enable_bit = 31;
211 	reg.enable_addr = (__u64)&self->check;
212 	reg.enable_size = sizeof(self->check);
213 
214 	unreg.size = sizeof(unreg);
215 	unreg.disable_bit = 31;
216 	unreg.disable_addr = (__u64)&self->check;
217 
218 	/* Register should work */
219 	ASSERT_EQ(0, ioctl(self->data_fd, DIAG_IOCSREG, &reg));
220 	ASSERT_EQ(0, reg.write_index);
221 
222 	/* Multiple registers to the same addr + bit should fail */
223 	ASSERT_EQ(-1, ioctl(self->data_fd, DIAG_IOCSREG, &reg));
224 	ASSERT_EQ(EADDRINUSE, errno);
225 
226 	/* Multiple registers to same name should result in same index */
227 	reg.enable_bit = 30;
228 	ASSERT_EQ(0, ioctl(self->data_fd, DIAG_IOCSREG, &reg));
229 	ASSERT_EQ(0, reg.write_index);
230 
231 	/* Ensure disabled */
232 	self->enable_fd = open(enable_file, O_RDWR);
233 	ASSERT_NE(-1, self->enable_fd);
234 	ASSERT_NE(-1, write(self->enable_fd, "0", sizeof("0")))
235 
236 	/* Enable event and ensure bits updated in status */
237 	ASSERT_NE(-1, write(self->enable_fd, "1", sizeof("1")))
238 	ASSERT_EQ(1 << reg.enable_bit, self->check);
239 
240 	/* Disable event and ensure bits updated in status */
241 	ASSERT_NE(-1, write(self->enable_fd, "0", sizeof("0")))
242 	ASSERT_EQ(0, self->check);
243 
244 	/* File still open should return -EBUSY for delete */
245 	ASSERT_EQ(-1, ioctl(self->data_fd, DIAG_IOCSDEL, "__test_event"));
246 	ASSERT_EQ(EBUSY, errno);
247 
248 	/* Unregister */
249 	ASSERT_EQ(0, ioctl(self->data_fd, DIAG_IOCSUNREG, &unreg));
250 	unreg.disable_bit = 30;
251 	ASSERT_EQ(0, ioctl(self->data_fd, DIAG_IOCSUNREG, &unreg));
252 
253 	/* Delete should work only after close and unregister */
254 	close(self->data_fd);
255 	self->data_fd = open(data_file, O_RDWR);
256 	ASSERT_EQ(0, ioctl(self->data_fd, DIAG_IOCSDEL, "__test_event"));
257 }
258 
259 TEST_F(user, write_events) {
260 	struct user_reg reg = {0};
261 	struct iovec io[3];
262 	__u32 field1, field2;
263 	int before = 0, after = 0;
264 
265 	reg.size = sizeof(reg);
266 	reg.name_args = (__u64)"__test_event u32 field1; u32 field2";
267 	reg.enable_bit = 31;
268 	reg.enable_addr = (__u64)&self->check;
269 	reg.enable_size = sizeof(self->check);
270 
271 	field1 = 1;
272 	field2 = 2;
273 
274 	io[0].iov_base = &reg.write_index;
275 	io[0].iov_len = sizeof(reg.write_index);
276 	io[1].iov_base = &field1;
277 	io[1].iov_len = sizeof(field1);
278 	io[2].iov_base = &field2;
279 	io[2].iov_len = sizeof(field2);
280 
281 	/* Register should work */
282 	ASSERT_EQ(0, ioctl(self->data_fd, DIAG_IOCSREG, &reg));
283 	ASSERT_EQ(0, reg.write_index);
284 	ASSERT_EQ(0, self->check);
285 
286 	/* Write should fail on invalid slot with ENOENT */
287 	io[0].iov_base = &field2;
288 	io[0].iov_len = sizeof(field2);
289 	ASSERT_EQ(-1, writev(self->data_fd, (const struct iovec *)io, 3));
290 	ASSERT_EQ(ENOENT, errno);
291 	io[0].iov_base = &reg.write_index;
292 	io[0].iov_len = sizeof(reg.write_index);
293 
294 	/* Enable event */
295 	self->enable_fd = open(enable_file, O_RDWR);
296 	ASSERT_NE(-1, write(self->enable_fd, "1", sizeof("1")))
297 
298 	/* Event should now be enabled */
299 	ASSERT_NE(1 << reg.enable_bit, self->check);
300 
301 	/* Write should make it out to ftrace buffers */
302 	before = trace_bytes();
303 	ASSERT_NE(-1, writev(self->data_fd, (const struct iovec *)io, 3));
304 	after = trace_bytes();
305 	ASSERT_GT(after, before);
306 
307 	/* Negative index should fail with EINVAL */
308 	reg.write_index = -1;
309 	ASSERT_EQ(-1, writev(self->data_fd, (const struct iovec *)io, 3));
310 	ASSERT_EQ(EINVAL, errno);
311 }
312 
313 TEST_F(user, write_fault) {
314 	struct user_reg reg = {0};
315 	struct iovec io[2];
316 	int l = sizeof(__u64);
317 	void *anon;
318 
319 	reg.size = sizeof(reg);
320 	reg.name_args = (__u64)"__test_event u64 anon";
321 	reg.enable_bit = 31;
322 	reg.enable_addr = (__u64)&self->check;
323 	reg.enable_size = sizeof(self->check);
324 
325 	anon = mmap(NULL, l, PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
326 	ASSERT_NE(MAP_FAILED, anon);
327 
328 	io[0].iov_base = &reg.write_index;
329 	io[0].iov_len = sizeof(reg.write_index);
330 	io[1].iov_base = anon;
331 	io[1].iov_len = l;
332 
333 	/* Register should work */
334 	ASSERT_EQ(0, ioctl(self->data_fd, DIAG_IOCSREG, &reg));
335 	ASSERT_EQ(0, reg.write_index);
336 
337 	/* Write should work normally */
338 	ASSERT_NE(-1, writev(self->data_fd, (const struct iovec *)io, 2));
339 
340 	/* Faulted data should zero fill and work */
341 	ASSERT_EQ(0, madvise(anon, l, MADV_DONTNEED));
342 	ASSERT_NE(-1, writev(self->data_fd, (const struct iovec *)io, 2));
343 	ASSERT_EQ(0, munmap(anon, l));
344 }
345 
346 TEST_F(user, write_validator) {
347 	struct user_reg reg = {0};
348 	struct iovec io[3];
349 	int loc, bytes;
350 	char data[8];
351 	int before = 0, after = 0;
352 
353 	reg.size = sizeof(reg);
354 	reg.name_args = (__u64)"__test_event __rel_loc char[] data";
355 	reg.enable_bit = 31;
356 	reg.enable_addr = (__u64)&self->check;
357 	reg.enable_size = sizeof(self->check);
358 
359 	/* Register should work */
360 	ASSERT_EQ(0, ioctl(self->data_fd, DIAG_IOCSREG, &reg));
361 	ASSERT_EQ(0, reg.write_index);
362 	ASSERT_EQ(0, self->check);
363 
364 	io[0].iov_base = &reg.write_index;
365 	io[0].iov_len = sizeof(reg.write_index);
366 	io[1].iov_base = &loc;
367 	io[1].iov_len = sizeof(loc);
368 	io[2].iov_base = data;
369 	bytes = snprintf(data, sizeof(data), "Test") + 1;
370 	io[2].iov_len = bytes;
371 
372 	/* Undersized write should fail */
373 	ASSERT_EQ(-1, writev(self->data_fd, (const struct iovec *)io, 1));
374 	ASSERT_EQ(EINVAL, errno);
375 
376 	/* Enable event */
377 	self->enable_fd = open(enable_file, O_RDWR);
378 	ASSERT_NE(-1, write(self->enable_fd, "1", sizeof("1")))
379 
380 	/* Event should now be enabled */
381 	ASSERT_EQ(1 << reg.enable_bit, self->check);
382 
383 	/* Full in-bounds write should work */
384 	before = trace_bytes();
385 	loc = DYN_LOC(0, bytes);
386 	ASSERT_NE(-1, writev(self->data_fd, (const struct iovec *)io, 3));
387 	after = trace_bytes();
388 	ASSERT_GT(after, before);
389 
390 	/* Out of bounds write should fault (offset way out) */
391 	loc = DYN_LOC(1024, bytes);
392 	ASSERT_EQ(-1, writev(self->data_fd, (const struct iovec *)io, 3));
393 	ASSERT_EQ(EFAULT, errno);
394 
395 	/* Out of bounds write should fault (offset 1 byte out) */
396 	loc = DYN_LOC(1, bytes);
397 	ASSERT_EQ(-1, writev(self->data_fd, (const struct iovec *)io, 3));
398 	ASSERT_EQ(EFAULT, errno);
399 
400 	/* Out of bounds write should fault (size way out) */
401 	loc = DYN_LOC(0, bytes + 1024);
402 	ASSERT_EQ(-1, writev(self->data_fd, (const struct iovec *)io, 3));
403 	ASSERT_EQ(EFAULT, errno);
404 
405 	/* Out of bounds write should fault (size 1 byte out) */
406 	loc = DYN_LOC(0, bytes + 1);
407 	ASSERT_EQ(-1, writev(self->data_fd, (const struct iovec *)io, 3));
408 	ASSERT_EQ(EFAULT, errno);
409 
410 	/* Non-Null should fault */
411 	memset(data, 'A', sizeof(data));
412 	loc = DYN_LOC(0, bytes);
413 	ASSERT_EQ(-1, writev(self->data_fd, (const struct iovec *)io, 3));
414 	ASSERT_EQ(EFAULT, errno);
415 }
416 
417 TEST_F(user, print_fmt) {
418 	int ret;
419 
420 	ret = check_print_fmt("__test_event __rel_loc char[] data",
421 			      "print fmt: \"data=%s\", __get_rel_str(data)",
422 			      &self->check);
423 	ASSERT_EQ(0, ret);
424 
425 	ret = check_print_fmt("__test_event __data_loc char[] data",
426 			      "print fmt: \"data=%s\", __get_str(data)",
427 			      &self->check);
428 	ASSERT_EQ(0, ret);
429 
430 	ret = check_print_fmt("__test_event s64 data",
431 			      "print fmt: \"data=%lld\", REC->data",
432 			      &self->check);
433 	ASSERT_EQ(0, ret);
434 
435 	ret = check_print_fmt("__test_event u64 data",
436 			      "print fmt: \"data=%llu\", REC->data",
437 			      &self->check);
438 	ASSERT_EQ(0, ret);
439 
440 	ret = check_print_fmt("__test_event s32 data",
441 			      "print fmt: \"data=%d\", REC->data",
442 			      &self->check);
443 	ASSERT_EQ(0, ret);
444 
445 	ret = check_print_fmt("__test_event u32 data",
446 			      "print fmt: \"data=%u\", REC->data",
447 			      &self->check);
448 	ASSERT_EQ(0, ret);
449 
450 	ret = check_print_fmt("__test_event int data",
451 			      "print fmt: \"data=%d\", REC->data",
452 			      &self->check);
453 	ASSERT_EQ(0, ret);
454 
455 	ret = check_print_fmt("__test_event unsigned int data",
456 			      "print fmt: \"data=%u\", REC->data",
457 			      &self->check);
458 	ASSERT_EQ(0, ret);
459 
460 	ret = check_print_fmt("__test_event s16 data",
461 			      "print fmt: \"data=%d\", REC->data",
462 			      &self->check);
463 	ASSERT_EQ(0, ret);
464 
465 	ret = check_print_fmt("__test_event u16 data",
466 			      "print fmt: \"data=%u\", REC->data",
467 			      &self->check);
468 	ASSERT_EQ(0, ret);
469 
470 	ret = check_print_fmt("__test_event short data",
471 			      "print fmt: \"data=%d\", REC->data",
472 			      &self->check);
473 	ASSERT_EQ(0, ret);
474 
475 	ret = check_print_fmt("__test_event unsigned short data",
476 			      "print fmt: \"data=%u\", REC->data",
477 			      &self->check);
478 	ASSERT_EQ(0, ret);
479 
480 	ret = check_print_fmt("__test_event s8 data",
481 			      "print fmt: \"data=%d\", REC->data",
482 			      &self->check);
483 	ASSERT_EQ(0, ret);
484 
485 	ret = check_print_fmt("__test_event u8 data",
486 			      "print fmt: \"data=%u\", REC->data",
487 			      &self->check);
488 	ASSERT_EQ(0, ret);
489 
490 	ret = check_print_fmt("__test_event char data",
491 			      "print fmt: \"data=%d\", REC->data",
492 			      &self->check);
493 	ASSERT_EQ(0, ret);
494 
495 	ret = check_print_fmt("__test_event unsigned char data",
496 			      "print fmt: \"data=%u\", REC->data",
497 			      &self->check);
498 	ASSERT_EQ(0, ret);
499 
500 	ret = check_print_fmt("__test_event char[4] data",
501 			      "print fmt: \"data=%s\", REC->data",
502 			      &self->check);
503 	ASSERT_EQ(0, ret);
504 }
505 
506 int main(int argc, char **argv)
507 {
508 	return test_harness_run(argc, argv);
509 }
510