[RFC PATCH] Test for syscall templates

Yury Norov ynorov@caviumnetworks.com
Sat Feb 11 14:47:00 GMT 2017


On Fri, Feb 10, 2017 at 09:10:03AM -0500, Zack Weinberg wrote:
> On Fri, Feb 10, 2017 at 8:27 AM, Yury Norov <ynorov@caviumnetworks.com> wrote:
> > On Fri, Feb 10, 2017 at 07:51:07AM -0500, Zack Weinberg wrote:
> >> On Fri, Feb 10, 2017 at 5:10 AM, Yury Norov <ynorov@caviumnetworks.com> wrote:
> >> >
> >> > This is RFC because I'm not sure this is right way to check the macro
> >>
> >> The way to make this a better test, and ensure you're not just testing
> >> one of several possible implementations of the
> >> trap-to-kernel-then-set-errno sequence, is to apply the same test to
> >> _as many syscalls as practical_.
> >
> > So I only tried to test error path of syscall template. If you think
> > that the correct way to do it is to call each syscall that may fail
> > in each possible scenario - then I think glibc don't need the test
> > like that, and we'd run LTP to find bugs of that sort - like I did in
> > this case.
> 
> You asked how to make the test better.  I told you how I think you
> could make the test better.
> 
> I realize I'm asking for some extra work, but it should not take more
> than a half hour and it really will be a better test this way.
> 
> (I _do_ think glibc should have a test like this.  It does not require
> elaborate setup, and the more bugs we can catch _during development_,
> rather than months after the fact when someone thinks to run LTP, the
> better.)
> 
> zw

OK. Below is what I have. This is not the glibc test but standalone
application. If I do what you mean, I will finish the syscall list
(I take it from sysdeps/unix/syscalls.list), and send it as glibc test
for POSIX syscalls. IIUC we need similar test for linux syscalls in 
sysdeps/unix/sysv/linux/syscalls.list

Surprisingly, some syscalls cause segfaults on aarch64/lp64, which is
presumably wrong.

I didn't analyze it yet, and didn't finish the test. Just asking if I
understand you right.

Yury

--

#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/vfs.h>
#include <sys/mman.h>
#include <unistd.h>

#define test_wrp(err, test_syscall, params...) do {			\
	errno = 0xdead;							\
	int ret = test_syscall(params);					\
	if (ret != -1)							\
		printf("Syscall '" #test_syscall			\
			"' didn't fail as expected\n");			\
	else if (errno == 0xdead)					\
		printf("Syscall'" #test_syscall				\
			"' didn't update errno\n");			\
	else if (errno != err) {					\
		printf("Syscall'" #test_syscall	"':\n");		\
		printf("errno is: %d (%s)\nexpected: %d (%s)\n",	\
			errno, strerror (errno), err, strerror (err));	\
	}								\
	else								\
		break;							\
	return -1;							\
} while (0)

int main(int argc, char *argv[])
{
	test_wrp(EBADF, write, -1, "Hello", sizeof("Hello") );
	test_wrp(EFAULT, access, (void *) -1, 0);
	test_wrp(EFAULT, acct, (void *) -1);
	test_wrp(EBADF, bind, -1, (void *) -1, 0);
	test_wrp(EFAULT, chdir, (void *) -1);
	test_wrp(EFAULT, chmod, (void *) -1, 0);
	test_wrp(EBADF, close, -1);
	test_wrp(EBADF, connect, -1, (void *) -1, -1);
	test_wrp(EBADF, dup, -1);
	test_wrp(EBADF, fcntl, -1, 0);
	test_wrp(EBADF, fstatfs, -1, (void *) -1);
	test_wrp(EBADF, fsync, -1);
	test_wrp(EBADF, ftruncate, -1, 0);
	//test_wrp(EFAULT, getdomainname, (void *) -1, 1); //segfault
	test_wrp(EINVAL, getgroups, -1, (void *) -1);
	//test_wrp(EFAULT, gethostname, -1, (void *) -1); //segfault
	//test_wrp(EFAULT, gettimeofday, (void *) -1, (void *) -1); //segfault
	test_wrp(EBADF, ioctl, -1, 0);
	test_wrp(EFAULT, link, (void *) -1, (void *) -1);
	test_wrp(EBADF, listen, -1, -1);
	test_wrp(EBADF, lseek, -1, 0, 0);
	test_wrp(EINVAL, madvise, (void *) -1, 0, 0);
	test_wrp(EFAULT, mkdir, (void *) -1, 0);
	//test_wrp(EBADF, mmap, (void *) -1, 0, 0, 0, -1, 0); //compiler warning
	test_wrp(EINVAL, mprotect, (void *) -1, 0, 0);
	test_wrp(EINVAL, msync, (void *) -1, 0, 0);
	test_wrp(EINVAL, munmap, (void *) -1, 0);
	test_wrp(EFAULT, open, (void *) -1, 0);
	test_wrp(EBADF, read, -1, (void *) -1, 0);
	test_wrp(EINVAL, readlink, (void *) -1, (void *) -1, 0);
	test_wrp(EBADF, readv, -1, (void *) -1, 1);
	//test_wrp(EFAULT, recv, -1, (void *) -1, 1, 0); lp64 and ilp32 //different errors
	test_wrp(EBADF, recvmsg, -1, (void *) -1, 0);
	test_wrp(EFAULT, rename, (void *) -1, (void *) -1);
	test_wrp(EFAULT, rmdir, (void *) -1);
	//test_wrp(EINVAL, select, -1, (void *) -1, (void *) -1, (void *) -1, (void *) -1); //segfault

	return 0;
}



More information about the Libc-alpha mailing list