Repository: opencontainers/runc
File: tests/integration/testdata/seccomp_syscall_test1.c (C)

Code before:
	syscall_assert(write(-1, NULL, 0), -EBADF);

	// Basic syscall with masked rules.
	syscall_assert(raw(socket, AF_UNIX, SOCK_STREAM, 0x000), 3);
	syscall_assert(raw(socket, AF_UNIX, SOCK_STREAM, 0x0FF), -EPROTONOSUPPORT);
	syscall_assert(raw(socket, AF_UNIX, SOCK_STREAM, 0x001), 4);
	syscall_assert(raw(socket, AF_UNIX, SOCK_STREAM, 0x100), -EPERM);
	syscall_assert(raw(socket, AF_UNIX, SOCK_STREAM, 0xC00), -EPERM);

	// Multiple arguments with OR rules.
	syscall_assert(raw(process_vm_readv, 100, NULL, 0, NULL, 0, ~0), -EINVAL);
	syscall_assert(raw(process_vm_readv, 9001, NULL, 0, NULL, 0, ~0), -EINVAL);
	syscall_assert(raw(process_vm_readv, 0, NULL, 0, NULL, 0, ~0), -EPERM);
	syscall_assert(raw(process_vm_readv, 0, NULL, 0, NULL, 0, ~0), -EPERM);

	// Multiple arguments with OR rules -- rule is ERRNO(-ENOANO).
	syscall_assert(raw(process_vm_writev, 1337, NULL, 0, NULL, 0, ~0), -ENOANO);
	syscall_assert(raw(process_vm_writev, 2020, NULL, 0, NULL, 0, ~0), -ENOANO);
	syscall_assert(raw(process_vm_writev, 0, NULL, 0, NULL, 0, ~0), -EPERM);
	syscall_assert(raw(process_vm_writev, 0, NULL, 0, NULL, 0, ~0), -EPERM);

	// Multiple arguments with AND rules.
	syscall_assert(raw(ftruncate, 123456789, 1337), -EBADF);
	syscall_assert(raw(ftruncate, 0, 0), -EPERM);
	syscall_assert(raw(ftruncate, 500, 1337), -EPERM);
	syscall_assert(raw(ftruncate, 500, 500), -EPERM);

	// Multiple rules for the same syscall.
	syscall_assert(raw(dup3, 0, -100, 0xFFFF), -EPERM);
	syscall_assert(raw(dup3, 1, -100, 0xFFFF), -EINVAL);
	syscall_assert(raw(dup3, 2, -100, 0xFFFF), -EPERM);
	syscall_assert(raw(dup3, 3, -100, 0xFFFF), -EINVAL);

	// Explicitly denied syscalls (those in Linux 3.0) get -EPERM.
	syscall_assert(raw(unshare, 0), -EPERM);
	syscall_assert(raw(setns, 0, 0), -EPERM);

	// Out-of-bounds fake syscall.
	syscall_assert(syscall(1000, 0xDEADBEEF, 0xCAFEFEED, 0x1337), -ENOSYS);

	return exit_code;
}


Review comment (suggestion):
I think the original idea here was to check that AND rules work. Meaning, (1) if arg0 is 0 and arg1 is 1337, the syscall is allowed (and we get a different error), while (2) if either arg0 is not 0 or arg1 is not 1337, we should get EPERM, and (3) if both arg0 and arg1 are not as expected, we also get EPERM.

This change removed the check for (2) for the case when arg0 is as expected and arg1 is not.

In other words, the second check for ftruncate should look like this:
```C
syscall_assert(raw(ftruncate, 123456789, 0), -EPERM);
```

(cc @cyphar)

Code after:
	syscall_assert(write(-1, NULL, 0), -EBADF);

	// Basic syscall with masked rules.
	syscall_assert(raw(socket, AF_UNIX, SOCK_STREAM, 0x000), 3);
	syscall_assert(raw(socket, AF_UNIX, SOCK_STREAM, 0x0FF), -EPROTONOSUPPORT);
	syscall_assert(raw(socket, AF_UNIX, SOCK_STREAM, 0x001), 4);
	syscall_assert(raw(socket, AF_UNIX, SOCK_STREAM, 0x100), -EPERM);
	syscall_assert(raw(socket, AF_UNIX, SOCK_STREAM, 0xC00), -EPERM);

	// Multiple arguments with OR rules.
	syscall_assert(raw(process_vm_readv, 100, NULL, 0, NULL, 0, ~0), -EINVAL);
	syscall_assert(raw(process_vm_readv, 9001, NULL, 0, NULL, 0, ~0), -EINVAL);
	syscall_assert(raw(process_vm_readv, 0, NULL, 0, NULL, 0, ~0), -EPERM);
	syscall_assert(raw(process_vm_readv, 0, NULL, 0, NULL, 0, ~0), -EPERM);

	// Multiple arguments with OR rules -- rule is ERRNO(-ENOANO).
	syscall_assert(raw(process_vm_writev, 1337, NULL, 0, NULL, 0, ~0), -ENOANO);
	syscall_assert(raw(process_vm_writev, 2020, NULL, 0, NULL, 0, ~0), -ENOANO);
	syscall_assert(raw(process_vm_writev, 0, NULL, 0, NULL, 0, ~0), -EPERM);
	syscall_assert(raw(process_vm_writev, 0, NULL, 0, NULL, 0, ~0), -EPERM);

	// Multiple arguments with AND rules.
	syscall_assert(raw(ftruncate, 123456789, 1337), -EBADF);
	syscall_assert(raw(ftruncate, 123456789, 0), -EPERM);
	syscall_assert(raw(ftruncate, 500, 1337), -EPERM);
	syscall_assert(raw(ftruncate, 500, 500), -EPERM);

	// Multiple rules for the same syscall.
	syscall_assert(raw(dup3, 0, -100, 0xFFFF), -EPERM);
	syscall_assert(raw(dup3, 1, -100, 0xFFFF), -EINVAL);
	syscall_assert(raw(dup3, 2, -100, 0xFFFF), -EPERM);
	syscall_assert(raw(dup3, 3, -100, 0xFFFF), -EINVAL);

	// Explicitly denied syscalls (those in Linux 3.0) get -EPERM.
	syscall_assert(raw(unshare, 0), -EPERM);
	syscall_assert(raw(setns, 0, 0), -EPERM);

	// Out-of-bounds fake syscall.
	syscall_assert(syscall(1000, 0xDEADBEEF, 0xCAFEFEED, 0x1337), -ENOSYS);

	return exit_code;
}