summaryrefslogtreecommitdiff
path: root/src/arch.c
diff options
context:
space:
mode:
authorPaul Moore <pmoore@redhat.com>2015-08-24 18:05:05 -0400
committerPaul Moore <pmoore@redhat.com>2015-08-27 15:32:59 -0400
commit51c46f80c1edee863bbc4eb21b03decc44e69a45 (patch)
treef31f9fa56c7657f52055ab88c070f69b3c80667a /src/arch.c
parent1d63fad4a064b80e0b921b16ed419f3342337ed4 (diff)
downloadlibseccomp-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.c30
1 files changed, 14 insertions, 16 deletions
diff --git a/src/arch.c b/src/arch.c
index 25d1ff6..5bb7f69 100644
--- a/src/arch.c
+++ b/src/arch.c
@@ -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;
}