diff --git a/patches/004-config-h-struct-layout.patch b/patches/003-null-guard-and-config-h.patch similarity index 77% rename from patches/004-config-h-struct-layout.patch rename to patches/003-null-guard-and-config-h.patch index 800c7c9..07964db 100644 --- a/patches/004-config-h-struct-layout.patch +++ b/patches/003-null-guard-and-config-h.patch @@ -11,7 +11,7 @@ index 774316f4..d4e70243 100644 #include "plugins/channels.h" #include "rdp.h" diff --git a/src/protocols/rdp/channels/disp.c b/src/protocols/rdp/channels/disp.c -index da1ca800..616b77d7 100644 +index 0293843c..616b77d7 100644 --- a/src/protocols/rdp/channels/disp.c +++ b/src/protocols/rdp/channels/disp.c @@ -17,6 +17,7 @@ @@ -22,29 +22,7 @@ index da1ca800..616b77d7 100644 #include "channels/disp.h" #include "plugins/channels.h" #include "fs.h" -@@ -85,6 +86,10 @@ static void guac_rdp_disp_channel_connected(rdpContext* context, - if (strcmp(args->name, DISP_DVC_CHANNEL_NAME) != 0) - return; - -+ /* Abort if display update module is not yet initialized */ -+ if (guac_disp == NULL) -+ return; -+ - /* Init module with current display size */ - guac_rdp_disp_set_size(guac_disp, rdp_client->settings, - context->instance, guac_rdp_get_width(context->instance), -@@ -127,6 +132,10 @@ static void guac_rdp_disp_channel_disconnected(rdpContext* context, - if (strcmp(args->name, DISP_DVC_CHANNEL_NAME) != 0) - return; - -+ /* Abort if display update module is not yet initialized */ -+ if (guac_disp == NULL) -+ return; -+ - /* Channel is no longer connected */ - guac_disp->disp = NULL; - -@@ -153,6 +162,10 @@ void guac_rdp_disp_load_plugin(rdpContext* context) { +@@ -161,6 +162,10 @@ void guac_rdp_disp_load_plugin(rdpContext* context) { void guac_rdp_disp_set_size(guac_rdp_disp* disp, guac_rdp_settings* settings, freerdp* rdp_inst, int width, int height) { diff --git a/patches/003-null-guard-disp-size.patch b/patches/003-null-guard-disp-size.patch deleted file mode 100644 index 430e65a..0000000 --- a/patches/003-null-guard-disp-size.patch +++ /dev/null @@ -1,31 +0,0 @@ -diff --git a/src/protocols/rdp/channels/disp.c b/src/protocols/rdp/channels/disp.c -index 0293843c..a1b2c3d4 100644 ---- a/src/protocols/rdp/channels/disp.c -+++ b/src/protocols/rdp/channels/disp.c -@@ -161,6 +161,10 @@ void guac_rdp_disp_load_plugin(rdpContext* context) { - void guac_rdp_disp_set_size(guac_rdp_disp* disp, guac_rdp_settings* settings, - freerdp* rdp_inst, int width, int height) { - -+ /* Abort if display module or settings are not yet initialized */ -+ if (disp == NULL || settings == NULL) -+ return; -+ - guac_rect resize = { - .left = 0, - .top = 0, -diff --git a/src/protocols/rdp/input.c b/src/protocols/rdp/input.c -index 06bfac13..c8e1d2f7 100644 ---- a/src/protocols/rdp/input.c -+++ b/src/protocols/rdp/input.c -@@ -105,6 +105,11 @@ int guac_rdp_user_size_handler(guac_user* user, int width, int height) { - guac_rdp_settings* settings = rdp_client->settings; - freerdp* rdp_inst = rdp_client->rdp_inst; - -+ /* Abort if not yet fully initialized (browser may send size instruction -+ * before the RDP connection is fully established) */ -+ if (settings == NULL || rdp_client->disp == NULL) -+ return 0; -+ - /* Convert client pixels to remote pixels */ - width = width * settings->resolution / user->info.optimal_resolution; - height = height * settings->resolution / user->info.optimal_resolution; diff --git a/patches/README.md b/patches/README.md index d1fdd33..a647593 100644 --- a/patches/README.md +++ b/patches/README.md @@ -49,31 +49,24 @@ Three new connection parameters: **Requires:** FreeRDP 3.x built with Kerberos support (`-DWITH_KRB5=ON`). Debian 13's `freerdp3-dev` includes this by default. -## 003-null-guard-disp-size.patch +## 003-null-guard-and-config-h.patch -**Problem:** Browser may send `size` instructions before the RDP connection is fully established, or FreeRDP 3.x may fire PubSub events before `guac_rdp_disp` is fully initialized. This causes NULL pointer dereferences. +**Problem:** Two related issues causing RDP display resize to silently fail: + +1. **Missing `config.h` include** — Several RDP channel source files and `input.c` do not include `config.h`, so `ENABLE_COMMON_SSH` is undefined in those compilation units. This causes the `guac_rdp_client` struct to have a different layout (missing 3 SSH pointer fields = 24 bytes), making all field accesses after the `#ifdef ENABLE_COMMON_SSH` block read/write wrong memory offsets. Specifically, `rdp_client->disp` reads NULL (actually the `recording` field), so RDP display resizing silently fails. + +2. **Early size instructions** — Browser may send `size` instructions before the RDP connection is fully established, causing NULL pointer dereferences in the resize handler. **Files patched:** | File | Fix | |------|-----| -| `src/protocols/rdp/channels/disp.c` | Add NULL guard for `guac_disp` in `guac_rdp_disp_channel_connected()`, `guac_rdp_disp_channel_disconnected()`, and `guac_rdp_disp_set_size()` | -| `src/protocols/rdp/input.c` | Add NULL guard for `settings` and `rdp_client->disp` in `guac_rdp_user_size_handler()` | - -## 004-config-h-struct-layout.patch - -**Problem:** Several RDP channel source files and `input.c` do not include `config.h`, so `ENABLE_COMMON_SSH` is undefined in those compilation units. This causes the `guac_rdp_client` struct to have a different layout (missing 3 SSH pointer fields = 24 bytes), making all field accesses after the `#ifdef ENABLE_COMMON_SSH` block read/write wrong memory offsets. Specifically, `rdp_client->disp` reads NULL (actually the `recording` field), so **RDP display resizing silently fails**. - -**Files patched:** - -| File | Fix | -|------|-----| -| `src/protocols/rdp/channels/disp.c` | Add `#include "config.h"` | | `src/protocols/rdp/channels/common-svc.c` | Add `#include "config.h"` | +| `src/protocols/rdp/channels/disp.c` | Add `#include "config.h"`, add NULL guard in `guac_rdp_disp_set_size()` | | `src/protocols/rdp/channels/pipe-svc.c` | Add `#include "config.h"` | | `src/protocols/rdp/channels/rdpei.c` | Add `#include "config.h"` | | `src/protocols/rdp/channels/rdpgfx.c` | Add `#include "config.h"` | -| `src/protocols/rdp/input.c` | Add `#include "config.h"` | +| `src/protocols/rdp/input.c` | Add `#include "config.h"`, add NULL guard in `guac_rdp_user_size_handler()` | ## Applying patches