diff options
author | emaste <emaste@FreeBSD.org> | 2011-08-04 14:18:09 +0000 |
---|---|---|
committer | emaste <emaste@FreeBSD.org> | 2011-08-04 14:18:09 +0000 |
commit | 5e22817e9284fa38450dd357c917e99fab99a497 (patch) | |
tree | 502879dd5ea3e4539d347937f6e891ab5fb17fcb /usr.bin/ar | |
parent | bb915740868d56df842f8200652a693fd86adac5 (diff) | |
download | FreeBSD-src-5e22817e9284fa38450dd357c917e99fab99a497.zip FreeBSD-src-5e22817e9284fa38450dd357c917e99fab99a497.tar.gz |
Don't try to free() an address returned by mmap(). This appears to be
triggered by the same .o being included twice on the command line.
Found by: Nima Misaghian at Sandvine
Reviewed by: kientzle, kaiw
Approved by: re
MFC after: 1 week
Diffstat (limited to 'usr.bin/ar')
-rw-r--r-- | usr.bin/ar/write.c | 33 |
1 files changed, 20 insertions, 13 deletions
diff --git a/usr.bin/ar/write.c b/usr.bin/ar/write.c index 5b6d369..ca348c2 100644 --- a/usr.bin/ar/write.c +++ b/usr.bin/ar/write.c @@ -58,6 +58,7 @@ static struct ar_obj *create_obj_from_file(struct bsdar *bsdar, const char *name, time_t mtime); static void create_symtab_entry(struct bsdar *bsdar, void *maddr, size_t size); +static void free_obj(struct bsdar *bsdar, struct ar_obj *obj); static void insert_obj(struct bsdar *bsdar, struct ar_obj *obj, struct ar_obj *pos); static void read_objs(struct bsdar *bsdar, const char *archive, @@ -210,6 +211,22 @@ giveup: } /* + * Free object itself and its associated allocations. + */ +static void +free_obj(struct bsdar *bsdar, struct ar_obj *obj) +{ + if (obj->fd == -1) + free(obj->maddr); + else + if (obj->maddr != NULL && munmap(obj->maddr, obj->size)) + bsdar_warnc(bsdar, errno, + "can't munmap file: %s", obj->name); + free(obj->name); + free(obj); +} + +/* * Insert obj to the tail, or before/after the pos obj. */ static void @@ -474,11 +491,8 @@ write_archive(struct bsdar *bsdar, char mode) *av); TAILQ_REMOVE(&bsdar->v_obj, obj, objs); - if (mode == 'd' || mode == 'r') { - free(obj->maddr); - free(obj->name); - free(obj); - } + if (mode == 'd' || mode == 'r') + free_obj(bsdar, obj); if (mode == 'm') insert_obj(bsdar, obj, pos); @@ -525,15 +539,8 @@ write_cleanup(struct bsdar *bsdar) struct ar_obj *obj, *obj_temp; TAILQ_FOREACH_SAFE(obj, &bsdar->v_obj, objs, obj_temp) { - if (obj->fd == -1) - free(obj->maddr); - else - if (obj->maddr != NULL && munmap(obj->maddr, obj->size)) - bsdar_warnc(bsdar, errno, - "can't munmap file: %s", obj->name); TAILQ_REMOVE(&bsdar->v_obj, obj, objs); - free(obj->name); - free(obj); + free_obj(bsdar, obj); } free(bsdar->as); |