From 15182fd96845a03216d7ac5a2cf31c4e77e406e3 Mon Sep 17 00:00:00 2001
From: "djm@openbsd.org" <djm@openbsd.org>
Date: Fri, 16 Nov 2018 06:10:29 +0000
Subject: [PATCH 115/294] upstream: make grandparent-parent-child sshbuf chains
 robust to

use-after-free faults if the ancestors are freed before the descendents.
Nothing in OpenSSH uses this deallocation pattern. Reported by Jann Horn

OpenBSD-Commit-ID: d93501d1d2734245aac802a252b9bb2eccdba0f2
---
 sshbuf.c | 17 ++++++++++-------
 1 file changed, 10 insertions(+), 7 deletions(-)

diff --git a/sshbuf.c b/sshbuf.c
index 20ddf9e..adfddf7 100644
--- a/sshbuf.c
+++ b/sshbuf.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: sshbuf.c,v 1.12 2018/07/09 21:56:06 markus Exp $	*/
+/*	$OpenBSD: sshbuf.c,v 1.13 2018/11/16 06:10:29 djm Exp $	*/
 /*
  * Copyright (c) 2011 Damien Miller
  *
@@ -143,12 +143,7 @@ sshbuf_free(struct sshbuf *buf)
 	 */
 	if (sshbuf_check_sanity(buf) != 0)
 		return;
-	/*
-	 * If we are a child, the free our parent to decrement its reference
-	 * count and possibly free it.
-	 */
-	sshbuf_free(buf->parent);
-	buf->parent = NULL;
+
 	/*
 	 * If we are a parent with still-extant children, then don't free just
 	 * yet. The last child's call to sshbuf_free should decrement our
@@ -157,6 +152,14 @@ sshbuf_free(struct sshbuf *buf)
 	buf->refcount--;
 	if (buf->refcount > 0)
 		return;
+
+	/*
+	 * If we are a child, the free our parent to decrement its reference
+	 * count and possibly free it.
+	 */
+	sshbuf_free(buf->parent);
+	buf->parent = NULL;
+
 	if (!buf->readonly) {
 		explicit_bzero(buf->d, buf->alloc);
 		free(buf->d);
-- 
1.8.3.1

