Package: release.debian.org
Severity: normal
Tags: trixie
X-Debbugs-Cc: [email protected]
Control: affects -1 + src:freerdp3
User: [email protected]
Usertags: pu

[ Reason ]
There's one more security fix from upstream, back-ported
to the debian version of freerdp3 - CVE-2026-40254 - it is
possible to escape specified path when sharing files through
freerdp client.

[ Tests ]
The resulting binaries works, including transferring files
the normal way.  I haven't tried exploiting the bug to see
if it's fixed, though.

[ Risks ]
This change, unlike the previous ones, is a low-risk change,
because it's small and confined in the code which didn't change
much in subsequent (after debian) upstream releases, and the
fix is small too.

[ Checklist ]
  [x] *all* changes are documented in the d/changelog
  [x] I reviewed all changes and I approve them
  [x] attach debdiff against the package in (old)stable
  [x] the issue is verified as fixed in unstable

[ Other info ]
In order for the actual patch to apply cleanly, I picked
up another change in this area too, which is a warning
fix.

Thanks,

/mjt

diff -Nru freerdp3-3.15.0+dfsg/debian/changelog 
freerdp3-3.15.0+dfsg/debian/changelog
--- freerdp3-3.15.0+dfsg/debian/changelog       2026-04-03 18:45:10.000000000 
+0300
+++ freerdp3-3.15.0+dfsg/debian/changelog       2026-05-06 11:13:18.000000000 
+0300
@@ -1,3 +1,15 @@
+freerdp3 (3.15.0+dfsg-2.1+deb13u3) trixie; urgency=medium
+
+  * security fix from 3.25.0:
+
+    CVE-2026-40254 off-by-one in the path traversal filter in
+      channels/drive/client/drive_file.c:contains_dotdot()
+      
https://github.com/FreeRDP/FreeRDP/security/advisories/GHSA-3xpj-m4hx-8vmx
+      clang-warnings-fix-Wjump-misses-init.patch
+      channels-drive-refine-bounds-checks-CVE-2026-40254.patch
+
+ -- Michael Tokarev <[email protected]>  Wed, 06 May 2026 11:13:18 +0300
+
 freerdp3 (3.15.0+dfsg-2.1+deb13u2) trixie; urgency=medium
 
   * security fixes for client from 3.24.0 (medium):
diff -Nru 
freerdp3-3.15.0+dfsg/debian/patches/channels-drive-refine-bounds-checks-CVE-2026-40254.patch
 
freerdp3-3.15.0+dfsg/debian/patches/channels-drive-refine-bounds-checks-CVE-2026-40254.patch
--- 
freerdp3-3.15.0+dfsg/debian/patches/channels-drive-refine-bounds-checks-CVE-2026-40254.patch
        1970-01-01 03:00:00.000000000 +0300
+++ 
freerdp3-3.15.0+dfsg/debian/patches/channels-drive-refine-bounds-checks-CVE-2026-40254.patch
        2026-05-06 11:04:05.000000000 +0300
@@ -0,0 +1,39 @@
+From: Armin Novak <[email protected]>
+Date: Fri, 10 Apr 2026 08:45:55 +0200
+Subject: [channels,drive] refine bounds checks
+Origin: upstream, 
https://github.com/FreeRDP/FreeRDP/commit/f502dbb8462597fbe5b97f890359dfdecb525bf7
+Forwarded: not-needed
+Bug: https://github.com/FreeRDP/FreeRDP/security/advisories/GHSA-3xpj-m4hx-8vmx
+Bug: https://security-tracker.debian.org/tracker/CVE-2026-40254
+Comment: context & nullptr fixups for 3.15 by mjt
+
+* better logging, fix wrong path component printed
+* ensure path does not end with path/..
+
+diff --git a/channels/drive/client/drive_file.c 
b/channels/drive/client/drive_file.c
+--- a/channels/drive/client/drive_file.c
++++ b/channels/drive/client/drive_file.c
+@@ -113,6 +113,8 @@ static BOOL contains_dotdot(const WCHAR* path, size_t 
base_length, size_t path_l
+                               if ((tst[2] == '/') || (tst[2] == '\\'))
+                                       return TRUE;
+                       }
++                      else
++                              return TRUE;
+               }
+               tst += 2;
+       } while (TRUE);
+@@ -147,11 +149,10 @@ static WCHAR* drive_file_combine_fullpath(const WCHAR* 
base_path, const WCHAR* p
+               /* Ensure the path does not contain sequences like '..' */
+               if (contains_dotdot(&fullpath[base_path_length], 
base_path_length, PathWCharLength))
+               {
+-                      char abuffer[MAX_PATH] = { 0 };
+-                      (void)ConvertWCharToUtf8(&fullpath[base_path_length], 
abuffer, ARRAYSIZE(abuffer));
+-
++                      char* abuffer = 
ConvertWCharToUtf8Alloc(&fullpath[base_path_length], NULL);
+                       WLog_WARN(TAG, "[rdpdr] received invalid file path '%s' 
from server, aborting!",
+-                                &abuffer[base_path_length]);
++                                abuffer);
++                      free(abuffer);
+                       goto fail;
+               }
+       }
diff -Nru 
freerdp3-3.15.0+dfsg/debian/patches/clang-warnings-fix-Wjump-misses-init.patch 
freerdp3-3.15.0+dfsg/debian/patches/clang-warnings-fix-Wjump-misses-init.patch
--- 
freerdp3-3.15.0+dfsg/debian/patches/clang-warnings-fix-Wjump-misses-init.patch  
    1970-01-01 03:00:00.000000000 +0300
+++ 
freerdp3-3.15.0+dfsg/debian/patches/clang-warnings-fix-Wjump-misses-init.patch  
    2026-05-06 11:04:05.000000000 +0300
@@ -0,0 +1,87 @@
+From: Armin Novak <[email protected]>
+Date: Thu, 8 Jan 2026 10:32:29 +0100
+Subject: [clang,warnings] fix Wjump-misses-init
+Origin: upstream, 
https://github.com/FreeRDP/FreeRDP/commit/15b0085ddfbb0e98ad189311fe9d652ea502adcc
+Forwarded: not-needed
+Comment: preparation for CVE-2026-40254 fix
+
+---
+ channels/drive/client/drive_file.c | 50 ++++++++++++++++--------------
+ 1 file changed, 27 insertions(+), 23 deletions(-)
+
+diff --git a/channels/drive/client/drive_file.c 
b/channels/drive/client/drive_file.c
+--- a/channels/drive/client/drive_file.c
++++ b/channels/drive/client/drive_file.c
+@@ -129,29 +129,31 @@ static WCHAR* drive_file_combine_fullpath(const WCHAR* 
base_path, const WCHAR* p
+       if (!base_path || (!path && (PathWCharLength > 0)))
+               goto fail;
+ 
+-      const size_t base_path_length = _wcsnlen(base_path, MAX_PATH);
+-      const size_t length = base_path_length + PathWCharLength + 1;
+-      fullpath = (WCHAR*)calloc(length, sizeof(WCHAR));
++      {
++              const size_t base_path_length = _wcsnlen(base_path, MAX_PATH);
++              const size_t length = base_path_length + PathWCharLength + 1;
++              fullpath = (WCHAR*)calloc(length, sizeof(WCHAR));
+ 
+-      if (!fullpath)
+-              goto fail;
++              if (!fullpath)
++                      goto fail;
+ 
+-      CopyMemory(fullpath, base_path, base_path_length * sizeof(WCHAR));
+-      if (path)
+-              CopyMemory(&fullpath[base_path_length], path, PathWCharLength * 
sizeof(WCHAR));
++              CopyMemory(fullpath, base_path, base_path_length * 
sizeof(WCHAR));
++              if (path)
++                      CopyMemory(&fullpath[base_path_length], path, 
PathWCharLength * sizeof(WCHAR));
+ 
+-      if (!drive_file_fix_path(fullpath, length))
+-              goto fail;
++              if (!drive_file_fix_path(fullpath, length))
++                      goto fail;
+ 
+-      /* Ensure the path does not contain sequences like '..' */
+-      if (contains_dotdot(&fullpath[base_path_length], base_path_length, 
PathWCharLength))
+-      {
+-              char abuffer[MAX_PATH] = { 0 };
+-              (void)ConvertWCharToUtf8(&fullpath[base_path_length], abuffer, 
ARRAYSIZE(abuffer));
++              /* Ensure the path does not contain sequences like '..' */
++              if (contains_dotdot(&fullpath[base_path_length], 
base_path_length, PathWCharLength))
++              {
++                      char abuffer[MAX_PATH] = { 0 };
++                      (void)ConvertWCharToUtf8(&fullpath[base_path_length], 
abuffer, ARRAYSIZE(abuffer));
+ 
+-              WLog_WARN(TAG, "[rdpdr] received invalid file path '%s' from 
server, aborting!",
+-                        &abuffer[base_path_length]);
+-              goto fail;
++                      WLog_WARN(TAG, "[rdpdr] received invalid file path '%s' 
from server, aborting!",
++                                &abuffer[base_path_length]);
++                      goto fail;
++              }
+       }
+ 
+       ok = TRUE;
+@@ -617,12 +619,14 @@ BOOL drive_file_query_information(DRIVE_FILE* file, 
UINT32 FsInformationClass, w
+ 
+       /* If we failed before (i.e. if information for a drive is queried) 
fall back to
+        * GetFileAttributesExW */
+-      WIN32_FILE_ATTRIBUTE_DATA fileAttributes = { 0 };
+-      if (!GetFileAttributesExW(file->fullpath, GetFileExInfoStandard, 
&fileAttributes))
+-              goto out_fail;
++      {
++              WIN32_FILE_ATTRIBUTE_DATA fileAttributes = { 0 };
++              if (!GetFileAttributesExW(file->fullpath, 
GetFileExInfoStandard, &fileAttributes))
++                      goto out_fail;
+ 
+-      if (!drive_file_query_from_attributes(file, &fileAttributes, 
FsInformationClass, output))
+-              goto out_fail;
++              if (!drive_file_query_from_attributes(file, &fileAttributes, 
FsInformationClass, output))
++                      goto out_fail;
++      }
+ 
+       return TRUE;
+ out_fail:
+-- 
+2.47.3
+
diff -Nru freerdp3-3.15.0+dfsg/debian/patches/series 
freerdp3-3.15.0+dfsg/debian/patches/series
--- freerdp3-3.15.0+dfsg/debian/patches/series  2026-04-03 18:45:10.000000000 
+0300
+++ freerdp3-3.15.0+dfsg/debian/patches/series  2026-05-06 11:04:05.000000000 
+0300
@@ -100,3 +100,6 @@
 codec-h264-update-H264_CONTEXT-width-height-after-al-CVE-2026-33986.patch
 cache-persistent-update-PERSISTENT_CACHE_ENTRY-size--CVE-2026-33987.patch
 cache-persist-use-winpr_aligned_calloc-CVE-2026-33982.patch
+# 3.25.0:
+clang-warnings-fix-Wjump-misses-init.patch
+channels-drive-refine-bounds-checks-CVE-2026-40254.patch

Reply via email to