summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorPaul Moore <paul@paul-moore.com>2019-01-14 22:33:44 -0500
committerPaul Moore <paul@paul-moore.com>2019-02-21 20:57:42 -0500
commit80a987d6f8d0152def07fa90ace6417d56eea741 (patch)
treefc823a59b36de7f48092cddac1b160cb3f989db9 /include
parentbd42d36c9b9f4e892a1d30c192dcbd11a5b7f1dd (diff)
downloadlibseccomp-80a987d6f8d0152def07fa90ace6417d56eea741.tar.gz
api: provide 32-bit friendly argument comparison macros
We have a longstanding issue with 32-bit to 64-bit sign extension inadvertently resulting in bogus syscall argument extensions. This patch introduces a new set of argument comparison macros which limit the argument values to 32-bit values so that we don't run into problems with sign extension. We use the macro overloading proposed by Roman at https://kecher.net/overloading-macros/ to retain the feature of these macros being usable as static initializers. Thanks to @jdstrand on GitHub for reporting the problem. Signed-off-by: Paul Moore <paul@paul-moore.com> Signed-off-by: Michael Weiser <michael.weiser@gmx.de>
Diffstat (limited to 'include')
-rw-r--r--include/seccomp.h.in87
1 files changed, 73 insertions, 14 deletions
diff --git a/include/seccomp.h.in b/include/seccomp.h.in
index 20ce45e..b28e76e 100644
--- a/include/seccomp.h.in
+++ b/include/seccomp.h.in
@@ -198,44 +198,103 @@ struct scmp_arg_cmp {
*/
#define SCMP_SYS(x) (__NR_##x)
+/* Helpers for the argument comparison macros, DO NOT USE directly */
+#define _SCMP_VA_NUM_ARGS(...) _SCMP_VA_NUM_ARGS_IMPL(__VA_ARGS__,2,1)
+#define _SCMP_VA_NUM_ARGS_IMPL(_1,_2,N,...) N
+#define _SCMP_MACRO_DISPATCHER(func, ...) \
+ _SCMP_MACRO_DISPATCHER_IMPL1(func, _SCMP_VA_NUM_ARGS(__VA_ARGS__))
+#define _SCMP_MACRO_DISPATCHER_IMPL1(func, nargs) \
+ _SCMP_MACRO_DISPATCHER_IMPL2(func, nargs)
+#define _SCMP_MACRO_DISPATCHER_IMPL2(func, nargs) \
+ func ## nargs
+#define _SCMP_CMP32_1(x, y, z) SCMP_CMP64(x, y, (uint32_t)(z))
+#define _SCMP_CMP32_2(x, y, z, q) SCMP_CMP64(x, y, (uint32_t)(z), (uint32_t)(q))
+
/**
- * Specify an argument comparison struct for use in declaring rules
+ * Specify a 64-bit argument comparison struct for use in declaring rules
* @param arg the argument number, starting at 0
* @param op the comparison operator, e.g. SCMP_CMP_*
* @param datum_a dependent on comparison
* @param datum_b dependent on comparison, optional
*/
-#define SCMP_CMP(...) ((struct scmp_arg_cmp){__VA_ARGS__})
+#define SCMP_CMP64(...) ((struct scmp_arg_cmp){__VA_ARGS__})
+#define SCMP_CMP SCMP_CMP64
+
+/**
+ * Specify a 32-bit argument comparison struct for use in declaring rules
+ * @param arg the argument number, starting at 0
+ * @param op the comparison operator, e.g. SCMP_CMP_*
+ * @param datum_a dependent on comparison (32-bits)
+ * @param datum_b dependent on comparison, optional (32-bits)
+ */
+#define SCMP_CMP32(x, y, ...) \
+ _SCMP_MACRO_DISPATCHER(_SCMP_CMP32_, __VA_ARGS__)(x, y, __VA_ARGS__)
+
+/**
+ * Specify a 64-bit argument comparison struct for argument 0
+ */
+#define SCMP_A0_64(...) SCMP_CMP64(0, __VA_ARGS__)
+#define SCMP_A0 SCMP_A0_64
+
+/**
+ * Specify a 32-bit argument comparison struct for argument 0
+ */
+#define SCMP_A0_32(x, ...) SCMP_CMP32(0, x, __VA_ARGS__)
+
+/**
+ * Specify a 64-bit argument comparison struct for argument 1
+ */
+#define SCMP_A1_64(...) SCMP_CMP64(1, __VA_ARGS__)
+#define SCMP_A1 SCMP_A1_64
+
+/**
+ * Specify a 32-bit argument comparison struct for argument 1
+ */
+#define SCMP_A1_32(x, ...) SCMP_CMP32(1, x, __VA_ARGS__)
+
+/**
+ * Specify a 64-bit argument comparison struct for argument 2
+ */
+#define SCMP_A2_64(...) SCMP_CMP64(2, __VA_ARGS__)
+#define SCMP_A2 SCMP_A2_64
+
+/**
+ * Specify a 32-bit argument comparison struct for argument 2
+ */
+#define SCMP_A2_32(x, ...) SCMP_CMP32(2, x, __VA_ARGS__)
/**
- * Specify an argument comparison struct for argument 0
+ * Specify a 64-bit argument comparison struct for argument 3
*/
-#define SCMP_A0(...) SCMP_CMP(0, __VA_ARGS__)
+#define SCMP_A3_64(...) SCMP_CMP64(3, __VA_ARGS__)
+#define SCMP_A3 SCMP_A3_64
/**
- * Specify an argument comparison struct for argument 1
+ * Specify a 32-bit argument comparison struct for argument 3
*/
-#define SCMP_A1(...) SCMP_CMP(1, __VA_ARGS__)
+#define SCMP_A3_32(x, ...) SCMP_CMP32(3, x, __VA_ARGS__)
/**
- * Specify an argument comparison struct for argument 2
+ * Specify a 64-bit argument comparison struct for argument 4
*/
-#define SCMP_A2(...) SCMP_CMP(2, __VA_ARGS__)
+#define SCMP_A4_64(...) SCMP_CMP64(4, __VA_ARGS__)
+#define SCMP_A4 SCMP_A4_64
/**
- * Specify an argument comparison struct for argument 3
+ * Specify a 32-bit argument comparison struct for argument 4
*/
-#define SCMP_A3(...) SCMP_CMP(3, __VA_ARGS__)
+#define SCMP_A4_32(x, ...) SCMP_CMP32(4, x, __VA_ARGS__)
/**
- * Specify an argument comparison struct for argument 4
+ * Specify a 64-bit argument comparison struct for argument 5
*/
-#define SCMP_A4(...) SCMP_CMP(4, __VA_ARGS__)
+#define SCMP_A5_64(...) SCMP_CMP64(5, __VA_ARGS__)
+#define SCMP_A5 SCMP_A5_64
/**
- * Specify an argument comparison struct for argument 5
+ * Specify a 32-bit argument comparison struct for argument 5
*/
-#define SCMP_A5(...) SCMP_CMP(5, __VA_ARGS__)
+#define SCMP_A5_32(x, ...) SCMP_CMP32(5, x, __VA_ARGS__)
/*
* seccomp actions