ac_fireflak() dereferenced plp after ac_planedamage() freed it.
Broken in commit
16b16e34, v4.3.27. Diagnosed with valgrind.
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_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);
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);
ac_planedamage(struct plist *plp, natid from, int dam, int flak,
char *mesg)
{
ac_planedamage(struct plist *plp, natid from, int dam, int flak,
char *mesg)
{
- int disp = ac_damage_plane(&plp->plane, from, dam, flak, mesg);
- 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);
+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)
{
static void
ac_doflak(struct emp_qelem *list, struct sctstr *from)
{
ac_fireflak(struct emp_qelem *list, natid from, int guns)
{
struct plist *plp;
ac_fireflak(struct emp_qelem *list, natid from, int guns)
{
struct plist *plp;
struct emp_qelem *qp;
struct emp_qelem *next;
char msg[14];
struct emp_qelem *qp;
struct emp_qelem *next;
char msg[14];
next = qp->q_forw;
plp = (struct plist *)qp;
n = ac_flak_dam(guns, pln_def(&plp->plane), plp->pcp->pl_flags);
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);
mpr(plp->plane.pln_own, " %s takes %d%s%s.\n",
prplane(&plp->plane), n, *msg ? " --" : "", msg);
+ ac_putplane(plp, disp);