summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Hromatka <tom.hromatka@oracle.com>2019-04-16 20:07:33 -0400
committerPaul Moore <paul@paul-moore.com>2019-04-16 20:07:33 -0400
commit40758a140793733e8fdd416bff65a14f8c5d5836 (patch)
treea501c0123e674e15d4ece5c50bb75dc301a23f30
parent4d64011741375bb1a4ba7d71905ca37b97885083 (diff)
downloadlibseccomp-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.c13
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);