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
shallow.h
#ifndef SHALLOW_H
#define SHALLOW_H

#include "lockfile.h"
#include "object.h"
#include "repository.h"
#include "strbuf.h"

void set_alternate_shallow_file(struct repository *r, const char *path, int override);
int register_shallow(struct repository *r, const struct object_id *oid);
int unregister_shallow(const struct object_id *oid);
int is_repository_shallow(struct repository *r);

/*
 * Lock for updating the $GIT_DIR/shallow file.
 *
 * Use `commit_shallow_file()` to commit an update, or
 * `rollback_shallow_file()` to roll it back. In either case, any
 * in-memory cached information about which commits are shallow will be
 * appropriately invalidated so that future operations reflect the new
 * state.
 */
struct shallow_lock {
	struct lock_file lock;
};
#define SHALLOW_LOCK_INIT { LOCK_INIT }

/* commit $GIT_DIR/shallow and reset stat-validity checks */
int commit_shallow_file(struct repository *r, struct shallow_lock *lk);
/* rollback $GIT_DIR/shallow and reset stat-validity checks */
void rollback_shallow_file(struct repository *r, struct shallow_lock *lk);

struct commit_list *get_shallow_commits(struct object_array *heads,
					int depth, int shallow_flag, int not_shallow_flag);
struct commit_list *get_shallow_commits_by_rev_list(
		int ac, const char **av, int shallow_flag, int not_shallow_flag);
int write_shallow_commits(struct strbuf *out, int use_pack_protocol,
			  const struct oid_array *extra);

void setup_alternate_shallow(struct shallow_lock *shallow_lock,
			     const char **alternate_shallow_file,
			     const struct oid_array *extra);

const char *setup_temporary_shallow(const struct oid_array *extra);

void advertise_shallow_grafts(int);

#define PRUNE_SHOW_ONLY 1
#define PRUNE_QUICK 2
void prune_shallow(unsigned options);

/*
 * Initialize with prepare_shallow_info() or zero-initialize (equivalent to
 * prepare_shallow_info with a NULL oid_array).
 */
struct shallow_info {
	struct oid_array *shallow;
	int *ours, nr_ours;
	int *theirs, nr_theirs;
	struct oid_array *ref;

	/* for receive-pack */
	uint32_t **used_shallow;
	int *need_reachability_test;
	int *reachable;
	int *shallow_ref;
	struct commit **commits;
	int nr_commits;
};

void prepare_shallow_info(struct shallow_info *, struct oid_array *);
void clear_shallow_info(struct shallow_info *);
void remove_nonexistent_theirs_shallow(struct shallow_info *);
void assign_shallow_commits_to_refs(struct shallow_info *info,
				    uint32_t **used,
				    int *ref_status);
int delayed_reachability_test(struct shallow_info *si, int c);

extern struct trace_key trace_shallow;

#endif /* SHALLOW_H */
back to top