Skip to content

Commit

Permalink
Examine.c: Fix memory leaks in Examine()
Browse files Browse the repository at this point in the history
Fix memory leaks in Examine() reported by SAST analysis. Implement a
method to traverse and free all the nodes of the doubly linked list.
Replace for loop with while loop in order to improve redability of the
code and free allocated memory correctly.

Signed-off-by: Anna Sztukowska <[email protected]>
  • Loading branch information
asztukow authored and mtkaczyk committed Sep 10, 2024
1 parent dd0d193 commit da26064
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 5 deletions.
22 changes: 17 additions & 5 deletions Examine.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,10 @@ int Examine(struct mddev_dev *devlist,
close(fd);

if (err) {
if (st)
if (st) {
st->ss->free_super(st);
free(st);
}
continue;
}

Expand Down Expand Up @@ -152,19 +154,24 @@ int Examine(struct mddev_dev *devlist,
if (st->ss->export_examine_super)
st->ss->export_examine_super(st);
st->ss->free_super(st);
free(st);
} else {
printf("%s:\n",devlist->devname);
st->ss->examine_super(st, c->homehost);
st->ss->free_super(st);
free(st);
}
}
if (c->brief) {
struct array *ap;
for (ap = arrays; ap; ap = ap->next) {
struct array *ap = arrays, *next;

while (ap) {
char sep='=';
char *d;
int newline = 0;

next = ap->next;

ap->st->ss->brief_examine_super(ap->st, c->verbose > 0);
if (ap->spares && !ap->st->ss->external)
newline += printf(" spares=%d", ap->spares);
Expand All @@ -182,10 +189,15 @@ int Examine(struct mddev_dev *devlist,
printf("\n");
ap->st->ss->brief_examine_subarrays(ap->st, c->verbose);
}
ap->st->ss->free_super(ap->st);
/* FIXME free ap */
if (ap->spares || c->verbose > 0)
printf("\n");

ap->st->ss->free_super(ap->st);
free(ap->st);
dl_free_all(ap->devs);
free(ap);

ap = next;
}
}
return rv;
Expand Down
15 changes: 15 additions & 0 deletions dlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,21 @@ void dl_free(void *v)
free(vv-1);
}

void dl_free_all(void *head)
{
/* The list head is linked with the list tail so in order to free
* all the elements properly there is a need to keep starting point.
*/
void *d = dl_next(head), *next;

while (d != head) {
next = dl_next(d);
dl_free(d);
d = next;
}
dl_free(head);
}

void dl_init(void *v)
{
dl_next(v) = v;
Expand Down
1 change: 1 addition & 0 deletions dlink.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,4 @@ void dl_add(void*, void*);
void dl_del(void*);
void dl_free(void*);
void dl_init(void*);
void dl_free_all(void *head);

0 comments on commit da26064

Please sign in to comment.