diff options
author | Paul Moore <paul@paul-moore.com> | 2019-01-14 22:33:44 -0500 |
---|---|---|
committer | Paul Moore <paul@paul-moore.com> | 2019-02-21 20:57:42 -0500 |
commit | 80a987d6f8d0152def07fa90ace6417d56eea741 (patch) | |
tree | fc823a59b36de7f48092cddac1b160cb3f989db9 /include | |
parent | bd42d36c9b9f4e892a1d30c192dcbd11a5b7f1dd (diff) | |
download | libseccomp-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.in | 87 |
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 |