From ed715061be0bdb0c1444b985027bee852a86ef0d Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Mon, 6 Jun 2011 19:15:05 +0200 Subject: [PATCH] Fix use-after-free when plane gets shot down or aborted by flak ac_fireflak() dereferenced plp after ac_planedamage() freed it. Broken in commit 16b16e34, v4.3.27. Diagnosed with valgrind. --- src/lib/subs/aircombat.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/src/lib/subs/aircombat.c b/src/lib/subs/aircombat.c index 4ae807c6e..3330af740 100644 --- a/src/lib/subs/aircombat.c +++ b/src/lib/subs/aircombat.c @@ -62,6 +62,7 @@ static void ac_combat_headers(natid, natid); static void ac_airtoair(struct emp_qelem *, struct emp_qelem *); static void ac_dog(struct plist *, struct plist *); static void ac_planedamage(struct plist *, natid, int, int, char *); +static void ac_putplane(struct plist *, int); static void ac_doflak(struct emp_qelem *, struct sctstr *); static void ac_landflak(struct emp_qelem *, coord, coord); static void ac_shipflak(struct emp_qelem *, coord, coord); @@ -528,12 +529,10 @@ static void ac_planedamage(struct plist *plp, natid from, int dam, int flak, char *mesg) { - int disp = ac_damage_plane(&plp->plane, from, dam, flak, mesg); + int disp; - if (disp) { - pln_put1(plp); - } else - putplane(plp->plane.pln_uid, &plp->plane); + disp = ac_damage_plane(&plp->plane, from, dam, flak, mesg); + ac_putplane(plp, disp); } int @@ -571,6 +570,15 @@ ac_damage_plane(struct plnstr *pp, natid from, int dam, int flak, return disp; } +static void +ac_putplane(struct plist *plp, int disp) +{ + if (disp) + pln_put1(plp); + else + putplane(plp->plane.pln_uid, &plp->plane); +} + static void ac_doflak(struct emp_qelem *list, struct sctstr *from) { @@ -695,7 +703,7 @@ static void ac_fireflak(struct emp_qelem *list, natid from, int guns) { struct plist *plp; - int n; + int n, disp; struct emp_qelem *qp; struct emp_qelem *next; char msg[14]; @@ -704,9 +712,10 @@ ac_fireflak(struct emp_qelem *list, natid from, int guns) next = qp->q_forw; plp = (struct plist *)qp; n = ac_flak_dam(guns, pln_def(&plp->plane), plp->pcp->pl_flags); - ac_planedamage(plp, from, n, 1, msg); + disp = ac_damage_plane(&plp->plane, from, n, 1, msg); mpr(plp->plane.pln_own, " %s takes %d%s%s.\n", prplane(&plp->plane), n, *msg ? " --" : "", msg); + ac_putplane(plp, disp); } } -- 2.43.0