forked from pool/libseccomp
205 lines
6.5 KiB
Diff
205 lines
6.5 KiB
Diff
|
From 73d83e45efbe8c31067c97155162f17ca51b7435 Mon Sep 17 00:00:00 2001
|
||
|
From: Paul Moore <paul@paul-moore.com>
|
||
|
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 <paul@paul-moore.com>
|
||
|
---
|
||
|
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
|
||
|
|