https://github.com/git/git
Revision e1e12e97ac73ded85f7d000da1063a774b3cc14f authored by Patrick Steinhardt on 01 December 2022, 14:45:36 UTC, committed by Junio C Hamano on 05 December 2022, 06:14:16 UTC
Attributes have a field that tracks the position in the `all_attrs`
array they're stored inside. This field gets set via `hashmap_get_size`
when adding the attribute to the global map of attributes. But while the
field is of type `int`, the value returned by `hashmap_get_size` is an
`unsigned int`. It can thus happen that the value overflows, where we
would now dereference teh `all_attrs` array at an out-of-bounds value.

We do have a sanity check for this overflow via an assert that verifies
the index matches the new hashmap's size. But asserts are not a proper
mechanism to detect against any such overflows as they may not in fact
be compiled into production code.

Fix this by using an `unsigned int` to track the index and convert the
assert to a call `die()`.

Reported-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent 447ac90
Raw File
Tip revision: e1e12e97ac73ded85f7d000da1063a774b3cc14f authored by Patrick Steinhardt on 01 December 2022, 14:45:36 UTC
attr: fix integer overflow with more than INT_MAX macros
Tip revision: e1e12e9
patch-ids.h
#ifndef PATCH_IDS_H
#define PATCH_IDS_H

#include "diff.h"
#include "hashmap.h"

struct commit;
struct object_id;
struct repository;

struct patch_id {
	struct hashmap_entry ent;
	struct object_id patch_id;
	struct commit *commit;
};

struct patch_ids {
	struct hashmap patches;
	struct diff_options diffopts;
};

int commit_patch_id(struct commit *commit, struct diff_options *options,
		    struct object_id *oid, int, int);
int init_patch_ids(struct repository *, struct patch_ids *);
int free_patch_ids(struct patch_ids *);

/* Add a patch_id for a single commit to the set. */
struct patch_id *add_commit_patch_id(struct commit *, struct patch_ids *);

/* Returns true if the patch-id of "commit" is present in the set. */
int has_commit_patch_id(struct commit *commit, struct patch_ids *);

/*
 * Iterate over all commits in the set whose patch id matches that of
 * "commit", like:
 *
 *   struct patch_id *cur;
 *   for (cur = patch_id_iter_first(commit, ids);
 *        cur;
 *        cur = patch_id_iter_next(cur, ids) {
 *           ... look at cur->commit
 *   }
 */
struct patch_id *patch_id_iter_first(struct commit *commit, struct patch_ids *);
struct patch_id *patch_id_iter_next(struct patch_id *cur, struct patch_ids *);

#endif /* PATCH_IDS_H */
back to top