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
This commit is contained in:
Ed Maste 2011-08-04 14:18:09 +00:00
parent 9f0f0b4d4c
commit cf933f5bf9
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=224650

View File

@ -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,
@ -209,6 +210,22 @@ create_obj_from_file(struct bsdar *bsdar, const char *name, time_t mtime)
return (NULL);
}
/*
* 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.
*/
@ -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);