diff options
author | Paul Moore <paul@paul-moore.com> | 2019-09-29 22:02:42 -0400 |
---|---|---|
committer | Paul Moore <paul@paul-moore.com> | 2019-10-31 05:34:07 -0400 |
commit | bf747eb21e428c2b3ead6ebcca27951b681963a0 (patch) | |
tree | 51c58cfca163b77f89849f5864cd4b7ed734c257 /src/arch-s390.c | |
parent | ae19647048b38ad6d2ab0f2ac0db4dc1e9be1f7d (diff) | |
download | libseccomp-bf747eb21e428c2b3ead6ebcca27951b681963a0.tar.gz |
arch: update the internal syscall tables to Linux v5.4-rc4
This is long overdue so quite a few changes, including tweaks to
support some newly direct wired syscalls which were previously
multiplexed.
We really need to make sure we update the syscall table more often.
Acked-by: Tom Hromatka <tom.hromatka@oracle.com>
Signed-off-by: Paul Moore <paul@paul-moore.com>
Diffstat (limited to 'src/arch-s390.c')
-rw-r--r-- | src/arch-s390.c | 160 |
1 files changed, 142 insertions, 18 deletions
diff --git a/src/arch-s390.c b/src/arch-s390.c index 2e49fb2..6c13368 100644 --- a/src/arch-s390.c +++ b/src/arch-s390.c @@ -27,16 +27,16 @@ const struct arch_def arch_def_s390 = { }; /** - * Convert a multiplexed pseudo socket syscall into a direct syscall - * @param socketcall the multiplexed pseudo syscall number + * Convert a multiplexed pseudo syscall into a direct syscall + * @param syscall the multiplexed pseudo syscall number * * Return the related direct syscall number, __NR_SCMP_UNDEF is there is * no related syscall, or __NR_SCMP_ERROR otherwise. * */ -static int _s390_sock_demux(int socketcall) +static int _s390_syscall_demux(int syscall) { - switch (socketcall) { + switch (syscall) { case -101: /* socket */ return 359; @@ -97,6 +97,43 @@ static int _s390_sock_demux(int socketcall) case -120: /* sendmmsg */ return 345; + case -201: + /* semop - not defined */ + return __NR_SCMP_UNDEF; + case -202: + /* semget */ + return 393; + case -203: + /* semctl */ + return 394; + case -204: + /* semtimedop - not defined */ + return __NR_SCMP_UNDEF; + case -211: + /* msgsnd */ + return 400; + case -212: + /* msgrcv */ + return 401; + case -213: + /* msgget */ + return 399; + case -214: + /* msgctl */ + return 402; + case -221: + /* shmat */ + return 397; + case -222: + /* shmdt */ + return 398; + case -223: + /* shmget */ + return 395; + case -224: + /* shmctl */ + return 396; + } return __NR_SCMP_ERROR; @@ -110,7 +147,7 @@ static int _s390_sock_demux(int socketcall) * there is no related pseudo syscall, or __NR_SCMP_ERROR otherwise. * */ -static int _s390_sock_mux(int syscall) +static int _s390_syscall_mux(int syscall) { switch (syscall) { case 337: @@ -164,6 +201,36 @@ static int _s390_sock_mux(int syscall) case 373: /* shutdown */ return -113; + case 393: + /* semget */ + return -202; + case 394: + /* semctl */ + return -203; + case 400: + /* msgsnd */ + return -211; + case 401: + /* msgrcv */ + return -212; + case 399: + /* msgget */ + return -213; + case 402: + /* msgctl */ + return -214; + case 397: + /* shmat */ + return -221; + case 398: + /* shmdt */ + return -222; + case 395: + /* shmget */ + return -223; + case 396: + /* shmctl */ + return -224; } return __NR_SCMP_ERROR; @@ -228,7 +295,7 @@ int s390_rule_add(struct db_filter *db, struct db_api_rule_list *rule) /* determine both the muxed and direct syscall numbers */ if (sys > 0) { - sys_a = _s390_sock_mux(sys); + sys_a = _s390_syscall_mux(sys); if (sys_a == __NR_SCMP_ERROR) { rc = __NR_SCMP_ERROR; goto add_return; @@ -236,7 +303,7 @@ int s390_rule_add(struct db_filter *db, struct db_api_rule_list *rule) sys_b = sys; } else { sys_a = sys; - sys_b = _s390_sock_demux(sys); + sys_b = _s390_syscall_demux(sys); if (sys_b == __NR_SCMP_ERROR) { rc = __NR_SCMP_ERROR; goto add_return; @@ -291,24 +358,81 @@ int s390_rule_add(struct db_filter *db, struct db_api_rule_list *rule) if (rc < 0) goto add_return; } - } else if (sys <= -200 && sys >= -224) { - /* multiplexed ipc syscalls */ + } else if ((sys <= -200 && sys >= -224) || (sys >= 393 && sys <= 402)) { + /* (-200 to -224) : multiplexed ipc syscalls + (393 to 402) : direct ipc syscalls */ + + /* strict check for the multiplexed socket syscalls */ for (iter = 0; iter < ARG_COUNT_MAX; iter++) { if ((rule->args[iter].valid != 0) && (rule->strict)) { rc = -EINVAL; goto add_return; } } - rule->args[0].arg = 0; - rule->args[0].op = SCMP_CMP_EQ; - rule->args[0].mask = DATUM_MAX; - rule->args[0].datum = abs(sys) % 200; - rule->args[0].valid = 1; - rule->syscall = __s390_NR_ipc; - rc = db_rule_add(db, rule); - if (rc < 0) - goto add_return; + /* determine both the muxed and direct syscall numbers */ + if (sys > 0) { + sys_a = _s390_syscall_mux(sys); + if (sys_a == __NR_SCMP_ERROR) { + rc = __NR_SCMP_ERROR; + goto add_return; + } + sys_b = sys; + } else { + sys_a = sys; + sys_b = _s390_syscall_demux(sys); + if (sys_b == __NR_SCMP_ERROR) { + rc = __NR_SCMP_ERROR; + goto add_return; + } + } + + /* use rule_a for the multiplexed syscall and use rule_b for + * the direct wired syscall */ + + if (sys_a == __NR_SCMP_UNDEF) { + rule_a = NULL; + rule_b = rule; + } else if (sys_b == __NR_SCMP_UNDEF) { + rule_a = rule; + rule_b = NULL; + } else { + /* need two rules, dup the first and link together */ + rule_a = rule; + rule_dup = db_rule_dup(rule_a); + rule_b = rule_dup; + if (rule_b == NULL) + goto add_return; + rule_b->prev = rule_a; + rule_b->next = NULL; + rule_a->next = rule_b; + } + + /* multiplexed socket syscalls */ + if (rule_a != NULL) { + rule_a->syscall = __s390_NR_ipc; + rule_a->args[0].arg = 0; + rule_a->args[0].op = SCMP_CMP_EQ; + rule_a->args[0].mask = DATUM_MAX; + rule_a->args[0].datum = (-sys_a) % 200; + rule_a->args[0].valid = 1; + } + + /* direct wired socket syscalls */ + if (rule_b != NULL) + rule_b->syscall = sys_b; + + /* we should be protected by a transaction checkpoint */ + if (rule_a != NULL) { + rc = db_rule_add(db, rule_a); + if (rc < 0) + goto add_return; + } + if (rule_b != NULL) { + rc = db_rule_add(db, rule_b); + if (rc < 0) + goto add_return; + } } else if (sys >= 0) { /* normal syscall processing */ rc = db_rule_add(db, rule); |