From: Krzysztof Kowalczyk <kkowalczyk@xxxxxxxxx> Fixes memory corruption in interpret_target() due to overwriting a string and avoids such problems in the future. Makes alloc_ref() use xcalloc() for compactness. Signed-off-by: Krzysztof Kowalczyk <kkowalczyk@xxxxxxxxx> --- builtin-fetch.c | 6 ++---- http-push.c | 6 ++---- remote.c | 29 ++++++++++++----------------- remote.h | 2 ++ transport.c | 6 ++---- walker.c | 3 +-- 6 files changed, 21 insertions(+), 31 deletions(-) diff --git a/builtin-fetch.c b/builtin-fetch.c index e56617e..f6584ec 100644 --- a/builtin-fetch.c +++ b/builtin-fetch.c @@ -508,10 +508,8 @@ static void find_non_local_tags(struct transport *transport, will_fetch(head, ref->old_sha1))) { path_list_insert(ref_name, &new_refs); - rm = alloc_ref(strlen(ref_name) + 1); - strcpy(rm->name, ref_name); - rm->peer_ref = alloc_ref(strlen(ref_name) + 1); - strcpy(rm->peer_ref->name, ref_name); + rm = alloc_ref_from_str(ref_name); + rm->peer_ref = alloc_ref_from_str(ref_name); hashcpy(rm->old_sha1, ref_sha1); **tail = rm; diff --git a/http-push.c b/http-push.c index 939a764..42727c8 100644 --- a/http-push.c +++ b/http-push.c @@ -1761,8 +1761,7 @@ static void one_remote_ref(char *refname) struct ref *ref; struct object *obj; - ref = alloc_ref(strlen(refname) + 1); - strcpy(ref->name, refname); + ref = alloc_ref_from_str(refname); if (http_fetch_ref(remote->url, ref) != 0) { fprintf(stderr, @@ -1894,8 +1893,7 @@ static void add_remote_info_ref(struct remote_ls_ctx *ls) char *ref_info; struct ref *ref; - ref = alloc_ref(strlen(ls->dentry_name) + 1); - strcpy(ref->name, ls->dentry_name); + ref = alloc_ref_from_str(ls->dentry_name); if (http_fetch_ref(remote->url, ref) != 0) { fprintf(stderr, diff --git a/remote.c b/remote.c index 6b480cb..780d497 100644 --- a/remote.c +++ b/remote.c @@ -686,8 +686,14 @@ int remote_find_tracking(struct remote *remote, struct refspec *refspec) struct ref *alloc_ref(unsigned namelen) { - struct ref *ret = xmalloc(sizeof(struct ref) + namelen); - memset(ret, 0, sizeof(struct ref) + namelen); + return xcalloc(sizeof(struct ref) + namelen, 1); +} + +struct ref *alloc_ref_from_str(const char* str) +{ + unsigned len = strlen(str) + 1; + struct ref *ret = alloc_ref(len); + memcpy(ret->name, str, len); return ret; } @@ -797,31 +803,22 @@ static struct ref *try_explicit_object_name(const char *name) { unsigned char sha1[20]; struct ref *ref; - int len; if (!*name) { - ref = alloc_ref(20); - strcpy(ref->name, "(delete)"); + ref = alloc_ref_from_str("(delete)"); hashclr(ref->new_sha1); return ref; } if (get_sha1(name, sha1)) return NULL; - len = strlen(name) + 1; - ref = alloc_ref(len); - memcpy(ref->name, name, len); + ref = alloc_ref_from_str(name); hashcpy(ref->new_sha1, sha1); return ref; } static struct ref *make_linked_ref(const char *name, struct ref ***tail) { - struct ref *ret; - size_t len; - - len = strlen(name) + 1; - ret = alloc_ref(len); - memcpy(ret->name, name, len); + struct ref *ret = alloc_ref_from_str(name); tail_link_ref(ret, tail); return ret; } @@ -1125,9 +1122,7 @@ static struct ref *get_local_ref(const char *name) return NULL; if (!prefixcmp(name, "refs/")) { - ret = alloc_ref(strlen(name) + 1); - strcpy(ret->name, name); - return ret; + return alloc_ref_from_str(name); } if (!prefixcmp(name, "heads/") || diff --git a/remote.h b/remote.h index 75d006b..2ee83a3 100644 --- a/remote.h +++ b/remote.h @@ -54,6 +54,8 @@ struct refspec { struct ref *alloc_ref(unsigned namelen); +struct ref *alloc_ref_from_str(const char* str); + struct ref *copy_ref_list(const struct ref *ref); int check_ref_type(const struct ref *ref, int flags); diff --git a/transport.c b/transport.c index b012a28..1bc16f2 100644 --- a/transport.c +++ b/transport.c @@ -504,8 +504,7 @@ static struct ref *get_refs_via_curl(struct transport *transport) strbuf_release(&buffer); - ref = alloc_ref(strlen("HEAD") + 1); - strcpy(ref->name, "HEAD"); + ref = alloc_ref_from_str("HEAD"); if (!walker->fetch_ref(walker, ref) && !resolve_remote_symref(ref, refs)) { ref->next = refs; @@ -546,9 +545,8 @@ static struct ref *get_refs_from_bundle(struct transport *transport) die ("Could not read bundle '%s'.", transport->url); for (i = 0; i < data->header.references.nr; i++) { struct ref_list_entry *e = data->header.references.list + i; - struct ref *ref = alloc_ref(strlen(e->name) + 1); + struct ref *ref = alloc_ref_from_str(e->name); hashcpy(ref->old_sha1, e->sha1); - strcpy(ref->name, e->name); ref->next = result; result = ref; } diff --git a/walker.c b/walker.c index fa96a7c..31de6c1 100644 --- a/walker.c +++ b/walker.c @@ -190,8 +190,7 @@ static int interpret_target(struct walker *walker, char *target, unsigned char * if (!get_sha1_hex(target, sha1)) return 0; if (!check_ref_format(target)) { - struct ref *ref = alloc_ref(strlen(target)); - strcpy(ref->name, target); + struct ref *ref = alloc_ref_from_str(target); if (!walker->fetch_ref(walker, ref)) { hashcpy(sha1, ref->old_sha1); free(ref); -- 1.5.4.5 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html