summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Moore <pmoore@redhat.com>2016-01-02 22:24:29 -0500
committerPaul Moore <paul@paul-moore.com>2016-02-09 08:32:15 -0500
commit5b42b8cfa25506fa260c8f46b4a063b5cfd09d1c (patch)
tree9c7d95b3b2499edca5437357b3861d932e318e38
parent996e445a74823c735757413fda809e1ed0afc7d4 (diff)
downloadlibseccomp-5b42b8cfa25506fa260c8f46b4a063b5cfd09d1c.tar.gz
arch: enable more involved arch/ABI specific rule creation
Create the infrastructure for arch/ABI specific rule creation that allows us much more involved arch/ABI customization. Signed-off-by: Paul Moore <pmoore@redhat.com>
-rw-r--r--src/arch-aarch64.c1
-rw-r--r--src/arch-arm.c1
-rw-r--r--src/arch-mips.c2
-rw-r--r--src/arch-mips64.c2
-rw-r--r--src/arch-mips64n32.c2
-rw-r--r--src/arch-ppc.c1
-rw-r--r--src/arch-ppc64.c2
-rw-r--r--src/arch-s390.c1
-rw-r--r--src/arch-s390x.c1
-rw-r--r--src/arch-x32.c1
-rw-r--r--src/arch-x86.c50
-rw-r--r--src/arch-x86.h3
-rw-r--r--src/arch-x86_64.c1
-rw-r--r--src/arch.c69
-rw-r--r--src/arch.h3
15 files changed, 41 insertions, 99 deletions
diff --git a/src/arch-aarch64.c b/src/arch-aarch64.c
index 7b596db..188bc6f 100644
--- a/src/arch-aarch64.c
+++ b/src/arch-aarch64.c
@@ -34,6 +34,5 @@ const struct arch_def arch_def_aarch64 = {
.syscall_resolve_name = aarch64_syscall_resolve_name,
.syscall_resolve_num = aarch64_syscall_resolve_num,
.syscall_rewrite = NULL,
- .filter_rewrite = NULL,
.rule_add = NULL,
};
diff --git a/src/arch-arm.c b/src/arch-arm.c
index 713f393..b403d98 100644
--- a/src/arch-arm.c
+++ b/src/arch-arm.c
@@ -34,6 +34,5 @@ const struct arch_def arch_def_arm = {
.syscall_resolve_name = arm_syscall_resolve_name,
.syscall_resolve_num = arm_syscall_resolve_num,
.syscall_rewrite = NULL,
- .filter_rewrite = NULL,
.rule_add = NULL,
};
diff --git a/src/arch-mips.c b/src/arch-mips.c
index 3c3dd8d..1d1f4e2 100644
--- a/src/arch-mips.c
+++ b/src/arch-mips.c
@@ -35,7 +35,6 @@ const struct arch_def arch_def_mips = {
.syscall_resolve_name = mips_syscall_resolve_name,
.syscall_resolve_num = mips_syscall_resolve_num,
.syscall_rewrite = NULL,
- .filter_rewrite = NULL,
.rule_add = NULL,
};
@@ -47,6 +46,5 @@ const struct arch_def arch_def_mipsel = {
.syscall_resolve_name = mips_syscall_resolve_name,
.syscall_resolve_num = mips_syscall_resolve_num,
.syscall_rewrite = NULL,
- .filter_rewrite = NULL,
.rule_add = NULL,
};
diff --git a/src/arch-mips64.c b/src/arch-mips64.c
index 9327bb6..9cb34e2 100644
--- a/src/arch-mips64.c
+++ b/src/arch-mips64.c
@@ -33,7 +33,6 @@ const struct arch_def arch_def_mips64 = {
.syscall_resolve_name = mips64_syscall_resolve_name,
.syscall_resolve_num = mips64_syscall_resolve_num,
.syscall_rewrite = NULL,
- .filter_rewrite = NULL,
.rule_add = NULL,
};
@@ -45,6 +44,5 @@ const struct arch_def arch_def_mipsel64 = {
.syscall_resolve_name = mips64_syscall_resolve_name,
.syscall_resolve_num = mips64_syscall_resolve_num,
.syscall_rewrite = NULL,
- .filter_rewrite = NULL,
.rule_add = NULL,
};
diff --git a/src/arch-mips64n32.c b/src/arch-mips64n32.c
index 6831592..c798c89 100644
--- a/src/arch-mips64n32.c
+++ b/src/arch-mips64n32.c
@@ -35,7 +35,6 @@ const struct arch_def arch_def_mips64n32 = {
.syscall_resolve_name = mips64n32_syscall_resolve_name,
.syscall_resolve_num = mips64n32_syscall_resolve_num,
.syscall_rewrite = NULL,
- .filter_rewrite = NULL,
.rule_add = NULL,
};
@@ -47,6 +46,5 @@ const struct arch_def arch_def_mipsel64n32 = {
.syscall_resolve_name = mips64n32_syscall_resolve_name,
.syscall_resolve_num = mips64n32_syscall_resolve_num,
.syscall_rewrite = NULL,
- .filter_rewrite = NULL,
.rule_add = NULL,
};
diff --git a/src/arch-ppc.c b/src/arch-ppc.c
index 3586422..cb430a9 100644
--- a/src/arch-ppc.c
+++ b/src/arch-ppc.c
@@ -33,6 +33,5 @@ const struct arch_def arch_def_ppc = {
.syscall_resolve_name = ppc_syscall_resolve_name,
.syscall_resolve_num = ppc_syscall_resolve_num,
.syscall_rewrite = NULL,
- .filter_rewrite = NULL,
.rule_add = NULL,
};
diff --git a/src/arch-ppc64.c b/src/arch-ppc64.c
index 2da9970..b8de8e7 100644
--- a/src/arch-ppc64.c
+++ b/src/arch-ppc64.c
@@ -33,7 +33,6 @@ const struct arch_def arch_def_ppc64 = {
.syscall_resolve_name = ppc64_syscall_resolve_name,
.syscall_resolve_num = ppc64_syscall_resolve_num,
.syscall_rewrite = NULL,
- .filter_rewrite = NULL,
.rule_add = NULL,
};
@@ -45,6 +44,5 @@ const struct arch_def arch_def_ppc64le = {
.syscall_resolve_name = ppc64_syscall_resolve_name,
.syscall_resolve_num = ppc64_syscall_resolve_num,
.syscall_rewrite = NULL,
- .filter_rewrite = NULL,
.rule_add = NULL,
};
diff --git a/src/arch-s390.c b/src/arch-s390.c
index 494c0de..f509809 100644
--- a/src/arch-s390.c
+++ b/src/arch-s390.c
@@ -18,6 +18,5 @@ const struct arch_def arch_def_s390 = {
.syscall_resolve_name = s390_syscall_resolve_name,
.syscall_resolve_num = s390_syscall_resolve_num,
.syscall_rewrite = NULL,
- .filter_rewrite = NULL,
.rule_add = NULL,
};
diff --git a/src/arch-s390x.c b/src/arch-s390x.c
index 038622a..5471738 100644
--- a/src/arch-s390x.c
+++ b/src/arch-s390x.c
@@ -18,6 +18,5 @@ const struct arch_def arch_def_s390x = {
.syscall_resolve_name = s390x_syscall_resolve_name,
.syscall_resolve_num = s390x_syscall_resolve_num,
.syscall_rewrite = NULL,
- .filter_rewrite = NULL,
.rule_add = NULL,
};
diff --git a/src/arch-x32.c b/src/arch-x32.c
index 15ddb1d..a496d18 100644
--- a/src/arch-x32.c
+++ b/src/arch-x32.c
@@ -35,6 +35,5 @@ const struct arch_def arch_def_x32 = {
.syscall_resolve_name = x32_syscall_resolve_name,
.syscall_resolve_num = x32_syscall_resolve_num,
.syscall_rewrite = NULL,
- .filter_rewrite = NULL,
.rule_add = NULL,
};
diff --git a/src/arch-x86.c b/src/arch-x86.c
index 00c3a97..b5fbbab 100644
--- a/src/arch-x86.c
+++ b/src/arch-x86.c
@@ -38,8 +38,7 @@ const struct arch_def arch_def_x86 = {
.syscall_resolve_name = x86_syscall_resolve_name,
.syscall_resolve_num = x86_syscall_resolve_num,
.syscall_rewrite = x86_syscall_rewrite,
- .filter_rewrite = x86_filter_rewrite,
- .rule_add = NULL,
+ .rule_add = x86_rule_add,
};
/**
@@ -66,31 +65,31 @@ int x86_syscall_rewrite(int *syscall)
}
/**
- * Rewrite a filter rule to match the architecture specifics
- * @param arch the architecture definition
- * @param strict strict flag
+ * add a new rule to the x86 seccomp filter
+ * @param db the seccomp filter db
+ * @param strict the strict flag
* @param rule the filter rule
*
- * Syscalls can vary across different architectures so this function handles
- * the necessary seccomp rule rewrites to ensure the right thing is done
- * 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.
+ * This function adds a new syscall filter to the seccomp filter db, making any
+ * necessary adjustments for the x86 ABI. Returns zero on success, negative
+ * values on failure.
*
*/
-int x86_filter_rewrite(bool strict, struct db_api_rule_list *rule)
+int x86_rule_add(struct db_filter *db, bool strict,
+ struct db_api_rule_list *rule)
{
- int arg_max;
+ int rc;
unsigned int iter;
int sys = rule->syscall;
- arg_max = ARG_COUNT_MAX;
- if (arg_max < 0)
- return arg_max;
-
- if (sys <= -100 && sys >= -117) {
- for (iter = 0; iter < arg_max; iter++) {
+ if (sys >= 0) {
+ /* normal syscall processing */
+ rc = db_rule_add(db, rule);
+ if (rc < 0)
+ return rc;
+ } else if (sys <= -100 && sys >= -117) {
+ /* multiplexed socket syscalls */
+ for (iter = 0; iter < ARG_COUNT_MAX; iter++) {
if ((rule->args[iter].valid != 0) && (strict))
return -EINVAL;
}
@@ -100,8 +99,13 @@ int x86_filter_rewrite(bool strict, struct db_api_rule_list *rule)
rule->args[0].datum = abs(sys) % 100;
rule->args[0].valid = 1;
rule->syscall = __x86_NR_socketcall;
+
+ rc = db_rule_add(db, rule);
+ if (rc < 0)
+ return rc;
} else if (sys <= -200 && sys >= -211) {
- for (iter = 0; iter < arg_max; iter++) {
+ /* multiplexed ipc syscalls */
+ for (iter = 0; iter < ARG_COUNT_MAX; iter++) {
if ((rule->args[iter].valid != 0) && (strict))
return -EINVAL;
}
@@ -111,7 +115,11 @@ int x86_filter_rewrite(bool strict, struct db_api_rule_list *rule)
rule->args[0].datum = abs(sys) % 200;
rule->args[0].valid = 1;
rule->syscall = __x86_NR_ipc;
- } else if (sys < 0)
+
+ rc = db_rule_add(db, rule);
+ if (rc < 0)
+ return rc;
+ } else if (strict)
return -EDOM;
return 0;
diff --git a/src/arch-x86.h b/src/arch-x86.h
index 4f895e0..793c480 100644
--- a/src/arch-x86.h
+++ b/src/arch-x86.h
@@ -37,6 +37,7 @@ const char *x86_syscall_iterate_name(unsigned int spot);
int x86_syscall_rewrite(int *syscall);
-int x86_filter_rewrite(bool strict, struct db_api_rule_list *rule);
+int x86_rule_add(struct db_filter *db, bool strict,
+ struct db_api_rule_list *rule);
#endif
diff --git a/src/arch-x86_64.c b/src/arch-x86_64.c
index 17beaea..ccbf1b1 100644
--- a/src/arch-x86_64.c
+++ b/src/arch-x86_64.c
@@ -34,6 +34,5 @@ const struct arch_def arch_def_x86_64 = {
.syscall_resolve_name = x86_64_syscall_resolve_name,
.syscall_resolve_num = x86_64_syscall_resolve_num,
.syscall_rewrite = NULL,
- .filter_rewrite = NULL,
.rule_add = NULL,
};
diff --git a/src/arch.c b/src/arch.c
index 0fc0062..afe7ae9 100644
--- a/src/arch.c
+++ b/src/arch.c
@@ -381,49 +381,6 @@ int arch_syscall_rewrite(const struct arch_def *arch, int *syscall)
}
/**
- * Rewrite a filter rule to match the architecture specifics
- * @param arch the architecture definition
- * @param strict strict flag
- * @param rule the filter rule
- *
- * Syscalls can vary across different architectures so this function handles
- * the necessary seccomp rule rewrites to ensure the right thing is done
- * 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, -EDOM if the syscall is not defined for
- * @arch, and negative values on failure.
- *
- */
-static int arch_filter_rewrite(const struct arch_def *arch, bool strict,
- struct db_api_rule_list *rule)
-{
- int rc;
- int sys = rule->syscall;
-
- if (sys >= 0) {
- /* we shouldn't be here - no rewrite needed */
- return 0;
- } else if (sys < 0 && sys > -100) {
- /* reserved values */
- return -EINVAL;
- } else if (sys <= -100 && sys > -10000) {
- /* rewritable syscalls */
- if (arch->filter_rewrite) {
- rc = (*arch->filter_rewrite)(strict, rule);
- /* we still want to catch invalid rewrites */
- if (rc == -EINVAL)
- return -EINVAL;
- }
- }
-
- /* syscalls not defined on this architecture */
- if (rule->syscall < 0)
- return -EDOM;
- return 0;
-}
-
-/**
* Add a new rule to the specified filter
* @param db the seccomp filter db
* @param strict the strict flag
@@ -453,6 +410,11 @@ int arch_filter_rule_add(struct db_filter *db, bool strict,
if (syscall < 0 && syscall > -100)
return -EINVAL;
+ /* translate the syscall */
+ rc = arch_syscall_translate(db->arch, &syscall);
+ if (rc < 0)
+ return rc;
+
/* copy of the chain for each filter in the collection */
rule = malloc(sizeof(*rule));
if (rule == NULL)
@@ -471,27 +433,14 @@ int arch_filter_rule_add(struct db_filter *db, bool strict,
/* add the new rule to the existing filter */
if (db->arch->rule_add == NULL) {
- rc = arch_syscall_translate(db->arch, &rule->syscall);
- if (rc < 0)
+ /* negative syscalls require a db->arch->rule_add() function */
+ if (syscall < 0 && strict) {
+ rc = -EDOM;
goto rule_add_failure;
-
- /* if this is a pseudo syscall (syscall < 0) then we need to
- * rewrite the rule for some arch specific reason */
- if (rule->syscall < 0) {
- /* mangle the private chain copy */
- rc = arch_filter_rewrite(db->arch, strict, rule);
- if ((rc == -EDOM) && (!strict)) {
- /* don't consider this a failure */
- rc = 0;
- goto rule_add_failure;
- }
- if (rc < 0)
- goto rule_add_failure;
}
-
rc = db_rule_add(db, rule);
} else
- rc = (db->arch->rule_add)(db, rule);
+ rc = (db->arch->rule_add)(db, strict, rule);
if (rc == 0) {
/* insert the chain to the end of the filter's rule list */
rule_tail = rule;
diff --git a/src/arch.h b/src/arch.h
index 54380f7..580e521 100644
--- a/src/arch.h
+++ b/src/arch.h
@@ -53,8 +53,7 @@ struct arch_def {
int (*syscall_resolve_name)(const char *name);
const char *(*syscall_resolve_num)(int num);
int (*syscall_rewrite)(int *syscall);
- int (*filter_rewrite)(bool strict, struct db_api_rule_list *rule);
- int (*rule_add)(struct db_filter *filter,
+ int (*rule_add)(struct db_filter *filter, bool strict,
struct db_api_rule_list *rule);
};