diff options
author | Paul Moore <pmoore@redhat.com> | 2015-08-24 18:05:05 -0400 |
---|---|---|
committer | Paul Moore <pmoore@redhat.com> | 2015-08-27 15:32:59 -0400 |
commit | 51c46f80c1edee863bbc4eb21b03decc44e69a45 (patch) | |
tree | f31f9fa56c7657f52055ab88c070f69b3c80667a /src/arch.c | |
parent | 1d63fad4a064b80e0b921b16ed419f3342337ed4 (diff) | |
download | libseccomp-51c46f80c1edee863bbc4eb21b03decc44e69a45.tar.gz |
all: block negative syscall numbers from the filter
We use negative syscalls numbers to indicate syscalls that aren't
supported by a certain arch/ABI and unfortunately there were cases
where these bogus syscall values were finding their way into the
filter. This patch corrects this and adds a new test to check for
this in the future.
Reported-by: Mike Frysinger <vapier@gentoo.org>
Signed-off-by: Paul Moore <pmoore@redhat.com>
Diffstat (limited to 'src/arch.c')
-rw-r--r-- | src/arch.c | 30 |
1 files changed, 14 insertions, 16 deletions
@@ -383,18 +383,15 @@ int arch_syscall_translate(const struct arch_def *arch, int *syscall) /** * Rewrite a syscall value to match the architecture * @param arch the architecture definition - * @param strict strict flag * @param syscall the syscall number * * Syscalls can vary across different architectures so this function rewrites - * the syscall into the correct value for the specified architecture. If - * @strict is true then the function will fail if the syscall can not be - * preservered, however, if @strict is false the function will do a "best - * effort" rewrite and not fail. Returns zero on success, negative values on - * failure. + * the syscall into the correct value for the specified architecture. Returns + * zero on success, -EDOM if the syscall is not defined for @arch, and negative + * values on failure. * */ -int arch_syscall_rewrite(const struct arch_def *arch, bool strict, int *syscall) +int arch_syscall_rewrite(const struct arch_def *arch, int *syscall) { int sys = *syscall; @@ -408,14 +405,12 @@ int arch_syscall_rewrite(const struct arch_def *arch, bool strict, int *syscall) /* rewritable syscalls */ switch (arch->token) { case SCMP_ARCH_X86: - return x86_syscall_rewrite(arch, strict, syscall); + x86_syscall_rewrite(arch, syscall); } - /* NOTE: we fall through to the default handling (strict?) if - * we don't support any rewriting for the architecture */ } /* syscalls not defined on this architecture */ - if (strict) + if ((*syscall) < 0) return -EDOM; return 0; } @@ -432,12 +427,14 @@ int arch_syscall_rewrite(const struct arch_def *arch, bool strict, int *syscall) * regardless of the rule or architecture. If @strict is true then the * function will fail if the entire filter can not be preservered, however, * if @strict is false the function will do a "best effort" rewrite and not - * fail. Returns zero on success, negative values on failure. + * fail. Returns zero on success, -EDOM if the syscall is not defined for + * @arch, and negative values on failure. * */ int arch_filter_rewrite(const struct arch_def *arch, bool strict, int *syscall, struct db_api_arg *chain) { + int rc; int sys = *syscall; if (sys >= 0) { @@ -450,14 +447,15 @@ int arch_filter_rewrite(const struct arch_def *arch, /* rewritable syscalls */ switch (arch->token) { case SCMP_ARCH_X86: - return x86_filter_rewrite(arch, strict, syscall, chain); + rc = x86_filter_rewrite(arch, strict, syscall, chain); + /* we still want to catch invalid rewrites */ + if (rc == -EINVAL) + return -EINVAL; } - /* NOTE: we fall through to the default handling (strict?) if - * we don't support any rewriting for the architecture */ } /* syscalls not defined on this architecture */ - if (strict) + if ((*syscall) < 0) return -EDOM; return 0; } |