diff options
author | Tom Hromatka <tom.hromatka@oracle.com> | 2019-04-16 20:07:33 -0400 |
---|---|---|
committer | Paul Moore <paul@paul-moore.com> | 2019-04-16 20:07:33 -0400 |
commit | 40758a140793733e8fdd416bff65a14f8c5d5836 (patch) | |
tree | a501c0123e674e15d4ece5c50bb75dc301a23f30 | |
parent | 4d64011741375bb1a4ba7d71905ca37b97885083 (diff) | |
download | libseccomp-40758a140793733e8fdd416bff65a14f8c5d5836.tar.gz |
bpf: add accumulator state to the instruction block hash
This addresses a problem where dissimilar instruction blocks were
improperly hashed to the same value because we were not taking into
account the accumulator state.
See the GitHub issue below for more information:
* https://github.com/seccomp/libseccomp/issues/148
Reported-by: Toralf Förster <toralf.foerster@gmx.de>
Signed-off-by: Paul Moore <paul@paul-moore.com>
Signed-off-by: Tom Hromatka <tom.hromatka@oracle.com>
-rw-r--r-- | src/gen_bpf.c | 13 |
1 files changed, 10 insertions, 3 deletions
diff --git a/src/gen_bpf.c b/src/gen_bpf.c index 9f8f5c3..1b559b0 100644 --- a/src/gen_bpf.c +++ b/src/gen_bpf.c @@ -556,7 +556,7 @@ static void _state_release(struct bpf_state *state) static int _hsh_add(struct bpf_state *state, struct bpf_blk **blk_p, unsigned int found) { - uint64_t h_val; + uint64_t h_val, h_val_tmp[3]; struct bpf_hash_bkt *h_new, *h_iter, *h_prev = NULL; struct bpf_blk *blk = *blk_p; struct bpf_blk *b_iter; @@ -569,7 +569,10 @@ static int _hsh_add(struct bpf_state *state, struct bpf_blk **blk_p, return -ENOMEM; /* generate the hash */ - h_val = hash(blk->blks, _BLK_MSZE(blk)); + h_val_tmp[0] = hash(blk->blks, _BLK_MSZE(blk)); + h_val_tmp[1] = hash(&blk->acc_start, sizeof(blk->acc_start)); + h_val_tmp[2] = hash(&blk->acc_end, sizeof(blk->acc_end)); + h_val = hash(h_val_tmp, sizeof(h_val_tmp)); blk->hash = h_val; blk->flag_hash = true; blk->node = NULL; @@ -584,7 +587,11 @@ hsh_add_restart: if ((h_iter->blk->hash == h_val) && (_BLK_MSZE(h_iter->blk) == _BLK_MSZE(blk)) && (memcmp(h_iter->blk->blks, blk->blks, - _BLK_MSZE(blk)) == 0)) { + _BLK_MSZE(blk)) == 0) && + _ACC_CMP_EQ(h_iter->blk->acc_start, + blk->acc_start) && + _ACC_CMP_EQ(h_iter->blk->acc_end, + blk->acc_end)) { /* duplicate block */ free(h_new); |