diff --git a/0001-arch-fix-a-number-of-32-bit-x86-failures-related-to-.patch b/0001-arch-fix-a-number-of-32-bit-x86-failures-related-to-.patch new file mode 100644 index 0000000..c9f80eb --- /dev/null +++ b/0001-arch-fix-a-number-of-32-bit-x86-failures-related-to-.patch @@ -0,0 +1,204 @@ +From 73d83e45efbe8c31067c97155162f17ca51b7435 Mon Sep 17 00:00:00 2001 +From: Paul Moore +Date: Fri, 8 Apr 2016 17:10:03 -0400 +Subject: [PATCH] arch: fix a number of 32-bit x86 failures related to socket + syscalls + +It turns out there was still a few bugs with the 32-bit x86 socket +syscalls, especially on systems with older kernel headers installed. +This patch corrects these problems and perhaps more importantly, +returns the resolver API functions to returning the negative pseudo +syscall numbers in the case of 32-bit x86, this helps ensure things +continue to work as they did before as the API does not change. + +It it important to note that libseccomp still generates filter code +for both multiplexed and direct socket syscalls regardless. + +Signed-off-by: Paul Moore +--- + src/arch-x86-syscalls.c | 84 ++++++++++++++++++++++++++++++++++++++ + src/arch-x86.c | 23 +++++++++-- + tests/30-sim-socket_syscalls.tests | 3 +- + 3 files changed, 105 insertions(+), 5 deletions(-) + +diff --git a/src/arch-x86-syscalls.c b/src/arch-x86-syscalls.c +index e51dd83..58e0597 100644 +--- a/src/arch-x86-syscalls.c ++++ b/src/arch-x86-syscalls.c +@@ -469,6 +469,48 @@ int x86_syscall_resolve_name(const char *name) + const struct arch_syscall_def *table = x86_syscall_table; + + /* XXX - plenty of room for future improvement here */ ++ ++ if (strcmp(name, "accept") == 0) ++ return __PNR_accept; ++ if (strcmp(name, "accept4") == 0) ++ return __PNR_accept4; ++ else if (strcmp(name, "bind") == 0) ++ return __PNR_bind; ++ else if (strcmp(name, "connect") == 0) ++ return __PNR_connect; ++ else if (strcmp(name, "getpeername") == 0) ++ return __PNR_getpeername; ++ else if (strcmp(name, "getsockname") == 0) ++ return __PNR_getsockname; ++ else if (strcmp(name, "getsockopt") == 0) ++ return __PNR_getsockopt; ++ else if (strcmp(name, "listen") == 0) ++ return __PNR_listen; ++ else if (strcmp(name, "recv") == 0) ++ return __PNR_recv; ++ else if (strcmp(name, "recvfrom") == 0) ++ return __PNR_recvfrom; ++ else if (strcmp(name, "recvmsg") == 0) ++ return __PNR_recvmsg; ++ else if (strcmp(name, "recvmmsg") == 0) ++ return __PNR_recvmmsg; ++ else if (strcmp(name, "send") == 0) ++ return __PNR_send; ++ else if (strcmp(name, "sendmsg") == 0) ++ return __PNR_sendmsg; ++ else if (strcmp(name, "sendmmsg") == 0) ++ return __PNR_sendmmsg; ++ else if (strcmp(name, "sendto") == 0) ++ return __PNR_sendto; ++ else if (strcmp(name, "setsockopt") == 0) ++ return __PNR_setsockopt; ++ else if (strcmp(name, "shutdown") == 0) ++ return __PNR_shutdown; ++ else if (strcmp(name, "socket") == 0) ++ return __PNR_socket; ++ else if (strcmp(name, "socketpair") == 0) ++ return __PNR_socketpair; ++ + for (iter = 0; table[iter].name != NULL; iter++) { + if (strcmp(name, table[iter].name) == 0) + return table[iter].num; +@@ -492,6 +534,48 @@ const char *x86_syscall_resolve_num(int num) + const struct arch_syscall_def *table = x86_syscall_table; + + /* XXX - plenty of room for future improvement here */ ++ ++ if (num == __PNR_accept) ++ return "accept"; ++ else if (num == __PNR_accept4) ++ return "accept4"; ++ else if (num == __PNR_bind) ++ return "bind"; ++ else if (num == __PNR_connect) ++ return "connect"; ++ else if (num == __PNR_getpeername) ++ return "getpeername"; ++ else if (num == __PNR_getsockname) ++ return "getsockname"; ++ else if (num == __PNR_getsockopt) ++ return "getsockopt"; ++ else if (num == __PNR_listen) ++ return "listen"; ++ else if (num == __PNR_recv) ++ return "recv"; ++ else if (num == __PNR_recvfrom) ++ return "recvfrom"; ++ else if (num == __PNR_recvmsg) ++ return "recvmsg"; ++ else if (num == __PNR_recvmmsg) ++ return "recvmmsg"; ++ else if (num == __PNR_send) ++ return "send"; ++ else if (num == __PNR_sendmsg) ++ return "sendmsg"; ++ else if (num == __PNR_sendmmsg) ++ return "sendmmsg"; ++ else if (num == __PNR_sendto) ++ return "sendto"; ++ else if (num == __PNR_setsockopt) ++ return "setsockopt"; ++ else if (num == __PNR_shutdown) ++ return "shutdown"; ++ else if (num == __PNR_socket) ++ return "socket"; ++ else if (num == __PNR_socketpair) ++ return "socketpair"; ++ + for (iter = 0; table[iter].num != __NR_SCMP_ERROR; iter++) { + if (num == table[iter].num) + return table[iter].name; +diff --git a/src/arch-x86.c b/src/arch-x86.c +index 76a1e7e..1bab53f 100644 +--- a/src/arch-x86.c ++++ b/src/arch-x86.c +@@ -104,6 +104,15 @@ int _x86_sock_demux(int socketcall) + case -117: + /* recvmsg */ + return 372; ++ case -118: ++ /* accept4 */ ++ return 364; ++ case -119: ++ /* recvmmsg */ ++ return 337; ++ case -120: ++ /* sendmmsg */ ++ return 345; + } + + return __NR_SCMP_ERROR; +@@ -120,6 +129,12 @@ int _x86_sock_demux(int socketcall) + int _x86_sock_mux(int syscall) + { + switch (syscall) { ++ case 337: ++ /* recvmmsg */ ++ return -119; ++ case 345: ++ /* sendmmsg */ ++ return -120; + case 359: + /* socket */ + return -101; +@@ -137,7 +152,7 @@ int _x86_sock_mux(int syscall) + return -104; + case 364: + /* accept4 */ +- return __NR_SCMP_UNDEF; ++ return -118; + case 365: + /* getsockopt */ + return -115; +@@ -183,7 +198,7 @@ int x86_syscall_rewrite(int *syscall) + { + int sys = *syscall; + +- if (sys <= -100 && sys >= -117) ++ if (sys <= -100 && sys >= -120) + *syscall = __x86_NR_socketcall; + else if (sys <= -200 && sys >= -211) + *syscall = __x86_NR_ipc; +@@ -215,8 +230,8 @@ int x86_rule_add(struct db_filter_col *col, struct db_filter *db, bool strict, + int sys_a, sys_b; + struct db_api_rule_list *rule_a, *rule_b; + +- if ((sys <= -100 && sys >= -117) || (sys >= 359 && sys <= 373)) { +- /* (-100 to -117) : multiplexed socket syscalls ++ if ((sys <= -100 && sys >= -120) || (sys >= 359 && sys <= 373)) { ++ /* (-100 to -120) : multiplexed socket syscalls + (359 to 373) : direct socket syscalls, Linux 4.4+ */ + + /* strict check for the multiplexed socket syscalls */ +diff --git a/tests/30-sim-socket_syscalls.tests b/tests/30-sim-socket_syscalls.tests +index 413629f..9d54b0e 100644 +--- a/tests/30-sim-socket_syscalls.tests ++++ b/tests/30-sim-socket_syscalls.tests +@@ -18,7 +18,8 @@ test type: bpf-sim + 30-sim-socket_syscalls +x86 373 0 1 2 N N N ALLOW + 30-sim-socket_syscalls +x86 accept 5 N N N N N ALLOW + 30-sim-socket_syscalls +x86 accept 0 1 2 N N N KILL +-30-sim-socket_syscalls +x86 accept4 0 1 2 N N N ALLOW ++30-sim-socket_syscalls +x86 accept4 18 1 2 N N N ALLOW ++30-sim-socket_syscalls +x86 accept4 0 1 2 N N N KILL + 30-sim-socket_syscalls +x86_64 socket 0 1 2 N N N ALLOW + 30-sim-socket_syscalls +x86_64 connect 0 1 2 N N N ALLOW + 30-sim-socket_syscalls +x86_64 accept4 0 1 2 N N N ALLOW +-- +2.6.6 + diff --git a/0001-tests-replace-socket-syscall-references-in-15-basic-.patch b/0001-tests-replace-socket-syscall-references-in-15-basic-.patch new file mode 100644 index 0000000..12151ac --- /dev/null +++ b/0001-tests-replace-socket-syscall-references-in-15-basic-.patch @@ -0,0 +1,76 @@ +From 13e0bae9571c195ee979a66b329aa538b87ee65d Mon Sep 17 00:00:00 2001 +From: Paul Moore +Date: Tue, 19 Apr 2016 10:58:34 -0400 +Subject: [PATCH] tests: replace socket syscall references in 15-basic-resolver + +On 32-bit x86 the resolved socket syscall() doesn't always resolve to +the __NR_socket value due to the direct wired socket syscall so +replace it with the read() syscall to ensure the test doesn't fail. + +Signed-off-by: Paul Moore +--- + tests/15-basic-resolver.c | 8 ++++---- + tests/15-basic-resolver.py | 6 +++--- + 2 files changed, 7 insertions(+), 7 deletions(-) + +diff --git a/tests/15-basic-resolver.c b/tests/15-basic-resolver.c +index eff54fe..b3c9497 100644 +--- a/tests/15-basic-resolver.c ++++ b/tests/15-basic-resolver.c +@@ -31,7 +31,7 @@ int main(int argc, char *argv[]) + + if (seccomp_syscall_resolve_name("open") != __NR_open) + goto fail; +- if (seccomp_syscall_resolve_name("socket") != __NR_socket) ++ if (seccomp_syscall_resolve_name("read") != __NR_read) + goto fail; + if (seccomp_syscall_resolve_name("INVALID") != __NR_SCMP_ERROR) + goto fail; +@@ -40,7 +40,7 @@ int main(int argc, char *argv[]) + "open") != __NR_open) + goto fail; + if (seccomp_syscall_resolve_name_arch(SCMP_ARCH_NATIVE, +- "socket") != __NR_socket) ++ "read") != __NR_read) + goto fail; + if (seccomp_syscall_resolve_name_arch(SCMP_ARCH_NATIVE, + "INVALID") != __NR_SCMP_ERROR) +@@ -51,8 +51,8 @@ int main(int argc, char *argv[]) + goto fail; + free(name); + +- name = seccomp_syscall_resolve_num_arch(SCMP_ARCH_NATIVE, __NR_socket); +- if (name == NULL || strcmp(name, "socket") != 0) ++ name = seccomp_syscall_resolve_num_arch(SCMP_ARCH_NATIVE, __NR_read); ++ if (name == NULL || strcmp(name, "read") != 0) + goto fail; + free(name); + +diff --git a/tests/15-basic-resolver.py b/tests/15-basic-resolver.py +index 329754e..12c4d7d 100755 +--- a/tests/15-basic-resolver.py ++++ b/tests/15-basic-resolver.py +@@ -33,7 +33,7 @@ def test(): + # this differs from the native test as we don't support the syscall + # resolution functions by themselves + f.add_rule(ALLOW, "open") +- f.add_rule(ALLOW, "socket") ++ f.add_rule(ALLOW, "read") + try: + f.add_rule(ALLOW, "INVALID") + except RuntimeError: +@@ -43,9 +43,9 @@ def test(): + sys_name = resolve_syscall(Arch(), sys_num) + if (sys_name != "open"): + raise RuntimeError("Test failure") +- sys_num = resolve_syscall(Arch(), "socket") ++ sys_num = resolve_syscall(Arch(), "read") + sys_name = resolve_syscall(Arch(), sys_num) +- if (sys_name != "socket"): ++ if (sys_name != "read"): + raise RuntimeError("Test failure") + + test() +-- +2.6.6 + diff --git a/libseccomp.changes b/libseccomp.changes index 0503c2d..6e1648c 100644 --- a/libseccomp.changes +++ b/libseccomp.changes @@ -1,3 +1,13 @@ +------------------------------------------------------------------- +Tue Apr 19 16:00:29 UTC 2016 - jengelh@inai.de + +- Add 0001-tests-replace-socket-syscall-references-in-15-basic-.patch + +------------------------------------------------------------------- +Sun Apr 10 22:31:15 UTC 2016 - jengelh@inai.de + +- Add 0001-arch-fix-a-number-of-32-bit-x86-failures-related-to-.patch + ------------------------------------------------------------------- Wed Mar 23 16:06:20 UTC 2016 - meissner@suse.com diff --git a/libseccomp.spec b/libseccomp.spec index c15c3aa..276ac18 100644 --- a/libseccomp.spec +++ b/libseccomp.spec @@ -30,6 +30,8 @@ Source: https://github.com/seccomp/libseccomp/releases/download/v%versio Source2: https://github.com/seccomp/libseccomp/releases/download/v%version/%name-%version.tar.gz.SHA256SUM.asc Source99: baselibs.conf Patch1: no-static.diff +Patch2: 0001-arch-fix-a-number-of-32-bit-x86-failures-related-to-.patch +Patch3: 0001-tests-replace-socket-syscall-references-in-15-basic-.patch BuildRoot: %{_tmppath}/%{name}-%{version}-build BuildRequires: autoconf BuildRequires: automake >= 1.11 @@ -97,10 +99,12 @@ This subpackage contains debug utilities for the seccomp interface. %prep %setup -q -%patch -P 1 -p1 +%patch -P 1 -P 2 -P 3 -p1 %build -perl -i -pe 's{AC_INIT\(\[libseccomp\], \[0\.0\.0\]\)}{AC_INIT([libseccomp], [2.3.0])}' configure.ac +if [ ! -e configure ]; then + perl -i -pe 's{AC_INIT\(\[libseccomp\], \[0\.0\.0\]\)}{AC_INIT([libseccomp], [2.3.0])}' configure.ac +fi autoreconf -fi %configure --includedir="%_includedir/%name" --disable-static make %{?_smp_mflags};