Skip to content

Commit b06a504

Browse files
committed
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
2 parents f7cd3c0 + 8bcda98 commit b06a504

File tree

3 files changed

+17
-7
lines changed

3 files changed

+17
-7
lines changed

cbtree.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ struct cb_node {
2525
*/
2626
uint32_t byte;
2727
uint8_t otherbits;
28-
uint8_t k[FLEX_ARRAY]; /* arbitrary data */
28+
uint8_t k[FLEX_ARRAY]; /* arbitrary data, unaligned */
2929
};
3030

3131
struct cb_tree {

hash.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ static inline void git_SHA256_Clone(git_SHA256_CTX *dst, const git_SHA256_CTX *s
115115

116116
struct object_id {
117117
unsigned char hash[GIT_MAX_RAWSZ];
118-
int algo;
118+
int algo; /* XXX requires 4-byte alignment */
119119
};
120120

121121
/* A suitably aligned type for stack allocations of hash contexts. */

oidtree.c

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,19 @@ void oidtree_clear(struct oidtree *ot)
3131
void oidtree_insert(struct oidtree *ot, const struct object_id *oid)
3232
{
3333
struct cb_node *on;
34+
struct object_id k;
3435

3536
if (!oid->algo)
3637
BUG("oidtree_insert requires oid->algo");
3738

3839
on = mem_pool_alloc(&ot->mem_pool, sizeof(*on) + sizeof(*oid));
39-
oidcpy_with_padding((struct object_id *)on->k, oid);
40+
41+
/*
42+
* Clear the padding and copy the result in separate steps to
43+
* respect the 4-byte alignment needed by struct object_id.
44+
*/
45+
oidcpy_with_padding(&k, oid);
46+
memcpy(on->k, &k, sizeof(k));
4047

4148
/*
4249
* 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)
6875
static enum cb_next iter(struct cb_node *n, void *arg)
6976
{
7077
struct oidtree_iter_data *x = arg;
71-
const struct object_id *oid = (const struct object_id *)n->k;
78+
struct object_id k;
79+
80+
/* Copy to provide 4-byte alignment needed by struct object_id. */
81+
memcpy(&k, n->k, sizeof(k));
7282

73-
if (x->algo != GIT_HASH_UNKNOWN && x->algo != oid->algo)
83+
if (x->algo != GIT_HASH_UNKNOWN && x->algo != k.algo)
7484
return CB_CONTINUE;
7585

7686
if (x->last_nibble_at) {
77-
if ((oid->hash[*x->last_nibble_at] ^ x->last_byte) & 0xf0)
87+
if ((k.hash[*x->last_nibble_at] ^ x->last_byte) & 0xf0)
7888
return CB_CONTINUE;
7989
}
8090

81-
return x->fn(oid, x->arg);
91+
return x->fn(&k, x->arg);
8292
}
8393

8494
void oidtree_each(struct oidtree *ot, const struct object_id *oid,

0 commit comments

Comments
 (0)