From 32b32213893b9007898c35cd01246d852153d80c Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Wed, 24 Feb 2016 15:45:09 +0100
Subject: server: Do not allow to queue async operation for broken pipes.

---
 server/named_pipe.c | 34 ++++++++++++++++++++++++++++++++--
 1 file changed, 32 insertions(+), 2 deletions(-)

diff --git a/server/named_pipe.c b/server/named_pipe.c
index 546984ddf..9f560c9 100644
--- a/server/named_pipe.c
+++ b/server/named_pipe.c
@@ -154,6 +154,7 @@ static obj_handle_t pipe_server_flush( struct fd *fd, const async_data_t *async,
 static enum server_fd_type pipe_server_get_fd_type( struct fd *fd );
 static obj_handle_t pipe_server_ioctl( struct fd *fd, ioctl_code_t code, const async_data_t *async,
                                        int blocking );
+static void pipe_server_queue_async( struct fd *fd, const async_data_t *data, int type, int count );
 
 static const struct object_ops pipe_server_ops =
 {
@@ -187,7 +188,7 @@ static const struct fd_ops pipe_server_fd_ops =
     no_fd_write,                  /* write */
     pipe_server_flush,            /* flush */
     pipe_server_ioctl,            /* ioctl */
-    default_fd_queue_async,       /* queue_async */
+    pipe_server_queue_async,      /* queue_async */
     default_fd_reselect_async,    /* reselect_async */
     default_fd_cancel_async,      /* cancel_async */
 };
@@ -200,6 +201,7 @@ static int pipe_client_close_handle( struct object *obj, struct process *process
 static void pipe_client_destroy( struct object *obj );
 static obj_handle_t pipe_client_flush( struct fd *fd, const async_data_t *async, int blocking );
 static enum server_fd_type pipe_client_get_fd_type( struct fd *fd );
+static void pipe_client_queue_async( struct fd *fd, const async_data_t *data, int type, int count );
 
 static const struct object_ops pipe_client_ops =
 {
@@ -233,7 +235,7 @@ static const struct fd_ops pipe_client_fd_ops =
     no_fd_write,                  /* write */
     pipe_client_flush,            /* flush */
     default_fd_ioctl,             /* ioctl */
-    default_fd_queue_async,       /* queue_async */
+    pipe_client_queue_async,      /* queue_async */
     default_fd_reselect_async,    /* reselect_async */
     default_fd_cancel_async       /* cancel_async */
 };
@@ -629,6 +631,20 @@ static obj_handle_t pipe_client_flush( struct fd *fd, const async_data_t *async,
     return 0;
 }
 
+static void pipe_client_queue_async( struct fd *fd, const async_data_t *data, int type, int count )
+{
+    struct pipe_client *client = get_fd_user( fd );
+    struct pipe_server *server = client->server;
+
+    if (!server || !server->fd)
+    {
+        set_error( STATUS_PIPE_BROKEN );
+        return;
+    }
+
+    default_fd_queue_async( fd, data, type, count );
+}
+
 static inline int is_overlapped( unsigned int options )
 {
     return !(options & (FILE_SYNCHRONOUS_IO_ALERT | FILE_SYNCHRONOUS_IO_NONALERT));
@@ -718,6 +734,20 @@ static obj_handle_t pipe_server_ioctl( struct fd *fd, ioctl_code_t code, const a
     }
 }
 
+static void pipe_server_queue_async( struct fd *fd, const async_data_t *data, int type, int count )
+{
+    struct pipe_server *server = get_fd_user( fd );
+    struct pipe_client *client = server->client;
+
+    if (!client || !client->fd)
+    {
+        set_error( STATUS_PIPE_BROKEN );
+        return;
+    }
+
+    default_fd_queue_async( fd, data, type, count );
+}
+
 static struct pipe_server *get_pipe_server_obj( struct process *process,
                                 obj_handle_t handle, unsigned int access )
 {
-- 
2.7.1

