execute: Fix seccomp support on x32
In the x32 ABI, syscall numbers start at 0x40000000. Mask that bit on x32 for lookups in the syscall_names array and syscall_filter and ensure that syscall.h is parsed correctly. [zj: added SYSCALL_TO_INDEX, INDEX_TO_SYSCALL macros.]
This commit is contained in:
parent
25da63b9da
commit
843fc7f7f2
|
@ -1099,7 +1099,7 @@ BUILT_SOURCES += \
|
|||
|
||||
src/core/syscall-list.txt: Makefile
|
||||
$(AM_V_at)$(MKDIR_P) $(dir $@)
|
||||
$(AM_V_GEN)$(CPP) $(CFLAGS) $(AM_CPPFLAGS) $(CPPFLAGS) -dM -include sys/syscall.h - < /dev/null | $(AWK) '/^#define[ \t]+__NR_[^ ]+[ \t]+\(?.*[0-9]+.*\)?/ { sub(/__NR_/, "", $$2); print $$2; }' > $@
|
||||
$(AM_V_GEN)$(CPP) $(CFLAGS) $(AM_CPPFLAGS) $(CPPFLAGS) -dM -include sys/syscall.h - < /dev/null | $(AWK) '/^#define[ \t]+__NR_[^ ]+[ \t]+[0-9(]/ { sub(/__NR_/, "", $$2); print $$2; }' > $@
|
||||
|
||||
src/core/syscall-from-name.gperf: src/core/syscall-list.txt Makefile
|
||||
$(AM_V_at)$(MKDIR_P) $(dir $@)
|
||||
|
@ -1111,7 +1111,7 @@ src/core/syscall-from-name.h: src/core/syscall-from-name.gperf Makefile
|
|||
|
||||
src/core/syscall-to-name.h: src/core/syscall-list.txt Makefile
|
||||
$(AM_V_at)$(MKDIR_P) $(dir $@)
|
||||
$(AM_V_GEN)$(AWK) 'BEGIN{ print "const char* const syscall_names[] = { "} { printf "[__NR_%s] = \"%s\",\n", $$1, $$1 } END{print "};"}' < $< > $@
|
||||
$(AM_V_GEN)$(AWK) 'BEGIN{ print "const char* const syscall_names[] = { "} { printf "[SYSCALL_TO_INDEX(__NR_%s)] = \"%s\",\n", $$1, $$1 } END{print "};"}' < $< > $@
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
systemd_SOURCES = \
|
||||
|
|
|
@ -957,7 +957,7 @@ static int apply_seccomp(uint32_t *syscall_filter) {
|
|||
for (i = 0, n = 0; i < syscall_max(); i++)
|
||||
if (syscall_filter[i >> 4] & (1 << (i & 31))) {
|
||||
struct sock_filter item[] = {
|
||||
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, i, 0, 1),
|
||||
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, INDEX_TO_SYSCALL(i), 0, 1),
|
||||
BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW)
|
||||
};
|
||||
|
||||
|
|
|
@ -2120,10 +2120,12 @@ int config_parse_documentation(
|
|||
}
|
||||
|
||||
static void syscall_set(uint32_t *p, int nr) {
|
||||
nr = SYSCALL_TO_INDEX(nr);
|
||||
p[nr >> 4] |= 1 << (nr & 31);
|
||||
}
|
||||
|
||||
static void syscall_unset(uint32_t *p, int nr) {
|
||||
nr = SYSCALL_TO_INDEX(nr);
|
||||
p[nr >> 4] &= ~(1 << (nr & 31));
|
||||
}
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@ const struct syscall_name *lookup_syscall(register const char *str, register uns
|
|||
#include "syscall-from-name.h"
|
||||
|
||||
const char *syscall_to_name(int id) {
|
||||
id = SYSCALL_TO_INDEX(id);
|
||||
if (id < 0 || id >= (int) ELEMENTSOF(syscall_names))
|
||||
return NULL;
|
||||
|
||||
|
|
|
@ -22,6 +22,20 @@
|
|||
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||||
***/
|
||||
|
||||
#if defined __x86_64__ && defined __ILP32__
|
||||
/* The x32 ABI defines all of its syscalls with bit 30 set, which causes
|
||||
issues when attempting to use syscalls as simple indicies into an array.
|
||||
Instead, use the syscall id & ~SYSCALL_MASK as the index, and | the
|
||||
internal id with the syscall mask as needed.
|
||||
*/
|
||||
#include <asm/unistd.h>
|
||||
#define SYSCALL_TO_INDEX(x) ((x) & ~__X32_SYSCALL_BIT)
|
||||
#define INDEX_TO_SYSCALL(x) ((x) | __X32_SYSCALL_BIT)
|
||||
#else
|
||||
#define SYSCALL_TO_INDEX(x) (x)
|
||||
#define INDEX_TO_SYSCALL(x) (x)
|
||||
#endif
|
||||
|
||||
const char *syscall_to_name(int id);
|
||||
int syscall_from_name(const char *name);
|
||||
|
||||
|
|
Loading…
Reference in a new issue