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.
This commit is contained in:
Markus Armbruster 2011-06-06 19:15:05 +02:00
parent de9d7b011f
commit ed715061be

View file

@ -62,6 +62,7 @@ static void ac_combat_headers(natid, natid);
static void ac_airtoair(struct emp_qelem *, struct emp_qelem *); static void ac_airtoair(struct emp_qelem *, struct emp_qelem *);
static void ac_dog(struct plist *, struct plist *); static void ac_dog(struct plist *, struct plist *);
static void ac_planedamage(struct plist *, natid, int, int, char *); 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_doflak(struct emp_qelem *, struct sctstr *);
static void ac_landflak(struct emp_qelem *, coord, coord); static void ac_landflak(struct emp_qelem *, coord, coord);
static void ac_shipflak(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, ac_planedamage(struct plist *plp, natid from, int dam, int flak,
char *mesg) char *mesg)
{ {
int disp = ac_damage_plane(&plp->plane, from, dam, flak, mesg); int disp;
if (disp) { disp = ac_damage_plane(&plp->plane, from, dam, flak, mesg);
pln_put1(plp); ac_putplane(plp, disp);
} else
putplane(plp->plane.pln_uid, &plp->plane);
} }
int int
@ -571,6 +570,15 @@ ac_damage_plane(struct plnstr *pp, natid from, int dam, int flak,
return disp; 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 static void
ac_doflak(struct emp_qelem *list, struct sctstr *from) 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) ac_fireflak(struct emp_qelem *list, natid from, int guns)
{ {
struct plist *plp; struct plist *plp;
int n; int n, disp;
struct emp_qelem *qp; struct emp_qelem *qp;
struct emp_qelem *next; struct emp_qelem *next;
char msg[14]; char msg[14];
@ -704,9 +712,10 @@ ac_fireflak(struct emp_qelem *list, natid from, int guns)
next = qp->q_forw; next = qp->q_forw;
plp = (struct plist *)qp; plp = (struct plist *)qp;
n = ac_flak_dam(guns, pln_def(&plp->plane), plp->pcp->pl_flags); 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", mpr(plp->plane.pln_own, " %s takes %d%s%s.\n",
prplane(&plp->plane), n, *msg ? " --" : "", msg); prplane(&plp->plane), n, *msg ? " --" : "", msg);
ac_putplane(plp, disp);
} }
} }