@@ -112,6 +112,7 @@ struct codegen_ctxt {
112112 size_t cache_size ;
113113 } locations ;
114114 size_t max_stack_ptr ;
115+ bool is_big_endian ;
115116};
116117
117118static struct codegen_ctxt * context_create (void ) {
@@ -275,10 +276,16 @@ static int add_jump_set(struct codegen_ctxt *ctxt, __u32 what, int tloc,
275276#define HIGH_WORD 0
276277#define LOW_WORD 1
277278
278- // TODO handle big-endian
279- #define ARG_LOW (arg ) offsetof(struct seccomp_data, args[(arg)])
279+ /*
280+ * On little-endian, the low 32 bits of a 64-bit arg are at the base offset
281+ * and the high 32 bits are at base + 4. On big-endian the order is reversed.
282+ */
283+ #define ARG_LOW (arg ) \
284+ (offsetof(struct seccomp_data, args[(arg)]) + \
285+ (ctxt->is_big_endian ? sizeof(uint32_t) : 0))
280286#define ARG_HIGH (arg ) \
281- offsetof(struct seccomp_data, args[(arg)]) + sizeof(uint32_t)
287+ (offsetof(struct seccomp_data, args[(arg)]) + \
288+ (ctxt->is_big_endian ? 0 : sizeof(uint32_t)))
282289#define NUM_LOW (num ) ((num)&UINT32_MAX)
283290#define NUM_HIGH (num ) (((num) >> 32) & UINT32_MAX)
284291
@@ -759,6 +766,11 @@ static int compile_policy_impl(struct codegen_ctxt *ctxt,
759766 int next = - ACTION_KILL ;
760767
761768 for (int i = 0 ; i < archs_len ; ++ i ) {
769+ /* __AUDIT_ARCH_LE (0x40000000) is set for little-endian architectures.
770+ * When absent, the target is big-endian and 64-bit argument word order
771+ * in seccomp_data must be swapped.
772+ */
773+ ctxt -> is_big_endian = (archs [i ].audit_arch & 0x40000000 ) == 0 ;
762774 int policy = compile_policy_for_archs (ctxt , kafel_ctxt , archs [i ].target_archs );
763775 if (policy != - ACTION_KILL ) {
764776 next = add_jump (ctxt , BPF_JEQ , archs [i ].audit_arch , policy , next );
0 commit comments