From f4657489b52e52f113028e2154a8d31b8d15e3b4 Mon Sep 17 00:00:00 2001
From: Stefan Eissing <icing@apache.org>
Date: Wed, 23 Sep 2015 09:42:03 +0000
Subject: [PATCH] avoiding race where h2_stream is closed/reset by client while
 being unprocessed in ready_ios set

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1704797 13f79535-47bb-0310-9956-ffa450edef68
---
 modules/http2/h2_io.c   | 1 -
 modules/http2/h2_mplx.c | 6 +++++-
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/modules/http2/h2_io.c b/modules/http2/h2_io.c
index 24d2a9feec..42734430fa 100644
--- a/modules/http2/h2_io.c
+++ b/modules/http2/h2_io.c
@@ -33,7 +33,6 @@ h2_io *h2_io_create(int id, apr_pool_t *pool, apr_bucket_alloc_t *bucket_alloc)
         io->pool = pool;
         io->bbin = NULL;
         io->bbout = apr_brigade_create(pool, bucket_alloc);
-        io->response = apr_pcalloc(pool, sizeof(h2_response));
     }
     return io;
 }
diff --git a/modules/http2/h2_mplx.c b/modules/http2/h2_mplx.c
index c04b05e772..2d07b1eb6c 100644
--- a/modules/http2/h2_mplx.c
+++ b/modules/http2/h2_mplx.c
@@ -281,6 +281,7 @@ static void stream_destroy(h2_mplx *m, h2_stream *stream, h2_io *io)
          * file handle pool. */
         m->file_handles_allowed += io->files_handles_owned;
         h2_io_set_remove(m->stream_ios, io);
+        h2_io_set_remove(m->ready_ios, io);
         h2_io_destroy(io);
     }
 }
@@ -492,6 +493,8 @@ h2_stream *h2_mplx_next_submit(h2_mplx *m, h2_stream_set *streams)
         h2_io *io = h2_io_set_get_highest_prio(m->ready_ios);
         if (io) {
             h2_response *response = io->response;
+            
+            AP_DEBUG_ASSERT(response);
             h2_io_set_remove(m->ready_ios, io);
             
             stream = h2_stream_set_get(streams, response->stream_id);
@@ -564,6 +567,7 @@ static apr_status_t out_open(h2_mplx *m, int stream_id, h2_response *response,
         }
         
         io->response = h2_response_copy(io->pool, response);
+        AP_DEBUG_ASSERT(io->response);
         h2_io_set_add(m->ready_ios, io);
         if (bb) {
             status = out_write(m, io, f, bb, iowait);
@@ -641,7 +645,7 @@ apr_status_t h2_mplx_out_close(h2_mplx *m, int stream_id)
         if (!m->aborted) {
             h2_io *io = h2_io_set_get(m->stream_ios, stream_id);
             if (io) {
-                if (!io->response->ngheader) {
+                if (!io->response || !io->response->ngheader) {
                     /* In case a close comes before a response was created,
                      * insert an error one so that our streams can properly
                      * reset.
-- 
2.40.0