From 7b40b6922a0c7a93ff62b69dd2b3c2a6076be851 Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Thu, 25 Feb 2016 22:33:33 +0100 Subject: [PATCH] Added patch to ensure no async operations can be queued for broken pipes. --- ...low-to-queue-async-operation-for-bro.patch | 92 +++++++++++++++++++ patches/patchinstall.sh | 2 + 2 files changed, 94 insertions(+) create mode 100644 patches/kernel32-Named_Pipe/0022-server-Do-not-allow-to-queue-async-operation-for-bro.patch diff --git a/patches/kernel32-Named_Pipe/0022-server-Do-not-allow-to-queue-async-operation-for-bro.patch b/patches/kernel32-Named_Pipe/0022-server-Do-not-allow-to-queue-async-operation-for-bro.patch new file mode 100644 index 00000000..174129c9 --- /dev/null +++ b/patches/kernel32-Named_Pipe/0022-server-Do-not-allow-to-queue-async-operation-for-bro.patch @@ -0,0 +1,92 @@ +From 32b32213893b9007898c35cd01246d852153d80c Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +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 + diff --git a/patches/patchinstall.sh b/patches/patchinstall.sh index 6128f4d5..53bf79aa 100755 --- a/patches/patchinstall.sh +++ b/patches/patchinstall.sh @@ -4073,6 +4073,7 @@ if test "$enable_kernel32_Named_Pipe" -eq 1; then patch_apply kernel32-Named_Pipe/0019-ntdll-Set-NamedPipeState-to-FILE_PIPE_CLOSING_STATE-.patch patch_apply kernel32-Named_Pipe/0020-server-Return-correct-error-codes-for-NtWriteFile-wh.patch patch_apply kernel32-Named_Pipe/0021-ntdll-Pre-cache-file-descriptors-after-opening-a-fil.patch + patch_apply kernel32-Named_Pipe/0022-server-Do-not-allow-to-queue-async-operation-for-bro.patch ( echo '+ { "Sebastian Lackner", "kernel32/tests: Only allow one test result.", 1 },'; echo '+ { "Dan Kegel", "kernel32: ConnectNamedPort should return FALSE and set ERROR_PIPE_CONNECTED on success in overlapped mode.", 1 },'; @@ -4095,6 +4096,7 @@ if test "$enable_kernel32_Named_Pipe" -eq 1; then echo '+ { "Sebastian Lackner", "ntdll: Set NamedPipeState to FILE_PIPE_CLOSING_STATE on broken pipe in NtQueryInformationFile.", 1 },'; echo '+ { "Sebastian Lackner", "server: Return correct error codes for NtWriteFile when pipes are closed without disconnecting.", 1 },'; echo '+ { "Sebastian Lackner", "ntdll: Pre-cache file descriptors after opening a file.", 1 },'; + echo '+ { "Sebastian Lackner", "server: Do not allow to queue async operation for broken pipes.", 1 },'; ) >> "$patchlist" fi