Merge branch 'rs/oidtree-alignment-fix'

Codepath to access recently added oidtree data structure had
to make unaligned accesses to oids, which has been corrected.

* rs/oidtree-alignment-fix:
  oidtree: avoid unaligned access to crit-bit tree
This commit is contained in:
Junio C Hamano 2021-08-16 12:14:35 -07:00
commit b06a5047ee
3 changed files with 17 additions and 7 deletions

View file

@ -25,7 +25,7 @@ struct cb_node {
*/
uint32_t byte;
uint8_t otherbits;
uint8_t k[FLEX_ARRAY]; /* arbitrary data */
uint8_t k[FLEX_ARRAY]; /* arbitrary data, unaligned */
};
struct cb_tree {

2
hash.h
View file

@ -115,7 +115,7 @@ static inline void git_SHA256_Clone(git_SHA256_CTX *dst, const git_SHA256_CTX *s
struct object_id {
unsigned char hash[GIT_MAX_RAWSZ];
int algo;
int algo; /* XXX requires 4-byte alignment */
};
/* A suitably aligned type for stack allocations of hash contexts. */

View file

@ -31,12 +31,19 @@ void oidtree_clear(struct oidtree *ot)
void oidtree_insert(struct oidtree *ot, const struct object_id *oid)
{
struct cb_node *on;
struct object_id k;
if (!oid->algo)
BUG("oidtree_insert requires oid->algo");
on = mem_pool_alloc(&ot->mem_pool, sizeof(*on) + sizeof(*oid));
oidcpy_with_padding((struct object_id *)on->k, oid);
/*
* Clear the padding and copy the result in separate steps to
* respect the 4-byte alignment needed by struct object_id.
*/
oidcpy_with_padding(&k, oid);
memcpy(on->k, &k, sizeof(k));
/*
* n.b. Current callers won't get us duplicates, here. If a
@ -68,17 +75,20 @@ int oidtree_contains(struct oidtree *ot, const struct object_id *oid)
static enum cb_next iter(struct cb_node *n, void *arg)
{
struct oidtree_iter_data *x = arg;
const struct object_id *oid = (const struct object_id *)n->k;
struct object_id k;
if (x->algo != GIT_HASH_UNKNOWN && x->algo != oid->algo)
/* Copy to provide 4-byte alignment needed by struct object_id. */
memcpy(&k, n->k, sizeof(k));
if (x->algo != GIT_HASH_UNKNOWN && x->algo != k.algo)
return CB_CONTINUE;
if (x->last_nibble_at) {
if ((oid->hash[*x->last_nibble_at] ^ x->last_byte) & 0xf0)
if ((k.hash[*x->last_nibble_at] ^ x->last_byte) & 0xf0)
return CB_CONTINUE;
}
return x->fn(oid, x->arg);
return x->fn(&k, x->arg);
}
void oidtree_each(struct oidtree *ot, const struct object_id *oid,