Skip to content

Commit 7640e77

Browse files
beaubelgraverostedt
authored andcommitted
user_events: Add self-test for validator boundaries
Tests to ensure validator boundary cases are working correctly within close and far bounds. Ensures __data_loc and __rel_loc strings are null terminated and within range. Ensures min size checks work as expected. Link: https://lkml.kernel.org/r/20220118204326.2169-11-beaub@linux.microsoft.com Acked-by: Masami Hiramatsu <mhiramat@kernel.org> Signed-off-by: Beau Belgrave <beaub@linux.microsoft.com> Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
1 parent 3a61638 commit 7640e77

1 file changed

Lines changed: 65 additions & 0 deletions

File tree

tools/testing/selftests/user_events/ftrace_test.c

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,71 @@ TEST_F(user, write_fault) {
309309
ASSERT_EQ(0, munmap(anon, l));
310310
}
311311

312+
TEST_F(user, write_validator) {
313+
struct user_reg reg = {0};
314+
struct iovec io[3];
315+
int loc, bytes;
316+
char data[8];
317+
int before = 0, after = 0;
318+
319+
reg.size = sizeof(reg);
320+
reg.name_args = (__u64)"__test_event __rel_loc char[] data";
321+
322+
/* Register should work */
323+
ASSERT_EQ(0, ioctl(self->data_fd, DIAG_IOCSREG, &reg));
324+
ASSERT_EQ(0, reg.write_index);
325+
ASSERT_NE(0, reg.status_index);
326+
327+
io[0].iov_base = &reg.write_index;
328+
io[0].iov_len = sizeof(reg.write_index);
329+
io[1].iov_base = &loc;
330+
io[1].iov_len = sizeof(loc);
331+
io[2].iov_base = data;
332+
bytes = snprintf(data, sizeof(data), "Test") + 1;
333+
io[2].iov_len = bytes;
334+
335+
/* Undersized write should fail */
336+
ASSERT_EQ(-1, writev(self->data_fd, (const struct iovec *)io, 1));
337+
ASSERT_EQ(EINVAL, errno);
338+
339+
/* Enable event */
340+
self->enable_fd = open(enable_file, O_RDWR);
341+
ASSERT_NE(-1, write(self->enable_fd, "1", sizeof("1")))
342+
343+
/* Full in-bounds write should work */
344+
before = trace_bytes();
345+
loc = DYN_LOC(0, bytes);
346+
ASSERT_NE(-1, writev(self->data_fd, (const struct iovec *)io, 3));
347+
after = trace_bytes();
348+
ASSERT_GT(after, before);
349+
350+
/* Out of bounds write should fault (offset way out) */
351+
loc = DYN_LOC(1024, bytes);
352+
ASSERT_EQ(-1, writev(self->data_fd, (const struct iovec *)io, 3));
353+
ASSERT_EQ(EFAULT, errno);
354+
355+
/* Out of bounds write should fault (offset 1 byte out) */
356+
loc = DYN_LOC(1, bytes);
357+
ASSERT_EQ(-1, writev(self->data_fd, (const struct iovec *)io, 3));
358+
ASSERT_EQ(EFAULT, errno);
359+
360+
/* Out of bounds write should fault (size way out) */
361+
loc = DYN_LOC(0, bytes + 1024);
362+
ASSERT_EQ(-1, writev(self->data_fd, (const struct iovec *)io, 3));
363+
ASSERT_EQ(EFAULT, errno);
364+
365+
/* Out of bounds write should fault (size 1 byte out) */
366+
loc = DYN_LOC(0, bytes + 1);
367+
ASSERT_EQ(-1, writev(self->data_fd, (const struct iovec *)io, 3));
368+
ASSERT_EQ(EFAULT, errno);
369+
370+
/* Non-Null should fault */
371+
memset(data, 'A', sizeof(data));
372+
loc = DYN_LOC(0, bytes);
373+
ASSERT_EQ(-1, writev(self->data_fd, (const struct iovec *)io, 3));
374+
ASSERT_EQ(EFAULT, errno);
375+
}
376+
312377
TEST_F(user, print_fmt) {
313378
int ret;
314379

0 commit comments

Comments
 (0)