From: Ashishkumar Parmar <[email protected]>

Pick the upstream backport [1] for CVE-2026-43620 as mentioned in [2],
where a malicious rsync server could trigger an out-of-bounds file-list
access in the receiver.

[1] 
https://github.com/RsyncProject/rsync/commit/0a5fa00fdcbacbebb89daca0ae68ae320f22dc74
[2] https://www.cve.org/CVERecord?id=CVE-2026-43620

Signed-off-by: Ashishkumar Parmar <[email protected]>
---
 .../rsync/files/CVE-2026-43620.patch          | 124 ++++++++++++++++++
 meta/recipes-devtools/rsync/rsync_3.2.7.bb    |   1 +
 2 files changed, 125 insertions(+)
 create mode 100644 meta/recipes-devtools/rsync/files/CVE-2026-43620.patch

diff --git a/meta/recipes-devtools/rsync/files/CVE-2026-43620.patch 
b/meta/recipes-devtools/rsync/files/CVE-2026-43620.patch
new file mode 100644
index 0000000000..dd50f1ebd6
--- /dev/null
+++ b/meta/recipes-devtools/rsync/files/CVE-2026-43620.patch
@@ -0,0 +1,124 @@
+From 6495fc027ad48678c98eab3de4224e29473ccb08 Mon Sep 17 00:00:00 2001
+From: Andrew Tridgell <[email protected]>
+Date: Tue, 5 May 2026 16:48:16 +1000
+Subject: [PATCH] receiver: add parent_ndx<0 guard, mirroring 797e17f
+
+Commit 797e17f ("fixed an invalid access to files array") added a
+parent_ndx < 0 guard to send_files() in sender.c, but the visually-
+identical block in recv_files() in receiver.c was not updated. A
+malicious rsync:// server can therefore drive any connecting client
+into the same out-of-bounds dir_flist->files[-1] read followed by a
+file_struct dereference in f_name() one line later.
+
+Reach: protocol-30+ default (inc_recurse) makes flist.c:2745 set
+parent_ndx = -1 on the first received flist when the sender omits a
+leading "." entry; rsync.c flist_for_ndx() does not reject ndx == 0
+in that state because the range check evaluates 0 < 0 = false; and
+read_ndx_and_attrs() only validates ndx with the ITEM_TRANSFER bit
+set, so iflags=ITEM_IS_NEW (or any other non-transfer iflag word)
+bypasses the check.
+
+Apply the same guard receiver-side. Confirmed: the same PoC (a
+minimal Python rsyncd that handshakes with CF_INC_RECURSE, sends a
+no-leading-"." flist, and emits ndx=0 with ITEM_IS_NEW) crashes
+unpatched 3.4.2 with SEGV_MAPERR si_addr=0x4101a-class in the
+receiver child; with this guard it exits cleanly with code 2
+(RERR_PROTOCOL).
+
+The attack surface delta over the sender variant is large:
+the original was malicious-client -> daemon, this is
+malicious-server -> any rsync client doing a normal rsync://
+or remote-shell pull.
+
+Reported by Pratham Gupta (alchemy1729).
+
+Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
+
+CVE: CVE-2026-43620
+Upstream-Status: Backport 
[https://github.com/RsyncProject/rsync/commit/0a5fa00fdcbacbebb89daca0ae68ae320f22dc74]
+
+(cherry picked from commit 0a5fa00fdcbacbebb89daca0ae68ae320f22dc74)
+Signed-off-by: Ashishkumar Parmar <[email protected]>
+---
+ generator.c | 4 ++++
+ io.c        | 3 +++
+ receiver.c  | 7 ++++++-
+ sender.c    | 2 ++
+ 4 files changed, 15 insertions(+), 1 deletion(-)
+
+diff --git a/generator.c b/generator.c
+index b80eb2e3..38f5ad33 100644
+--- a/generator.c
++++ b/generator.c
+@@ -2146,6 +2146,8 @@ void check_for_finished_files(int itemizing, enum 
logcode code, int check_redo)
+                       if (send_failed)
+                               ndx = get_hlink_num();
+                       flist = flist_for_ndx(ndx, 
"check_for_finished_files.1");
++                      if (ndx < flist->ndx_start)
++                              exit_cleanup(RERR_PROTOCOL);
+                       file = flist->files[ndx - flist->ndx_start];
+                       assert(file->flags & FLAG_HLINKED);
+                       if (send_failed)
+@@ -2174,6 +2176,8 @@ void check_for_finished_files(int itemizing, enum 
logcode code, int check_redo)
+ 
+                       flist = cur_flist;
+                       cur_flist = flist_for_ndx(ndx, 
"check_for_finished_files.2");
++                      if (ndx < cur_flist->ndx_start)
++                              exit_cleanup(RERR_PROTOCOL);
+ 
+                       file = cur_flist->files[ndx - cur_flist->ndx_start];
+                       if (solo_file)
+diff --git a/io.c b/io.c
+index bb60eeca..c654a7ba 100644
+--- a/io.c
++++ b/io.c
+@@ -1090,6 +1090,9 @@ static void got_flist_entry_status(enum festatus status, 
int ndx)
+ {
+       struct file_list *flist = flist_for_ndx(ndx, "got_flist_entry_status");
+ 
++      if (ndx < flist->ndx_start)
++              exit_cleanup(RERR_PROTOCOL);
++
+       if (remove_source_files) {
+               active_filecnt--;
+               active_bytecnt -= F_LENGTH(flist->files[ndx - 
flist->ndx_start]);
+diff --git a/receiver.c b/receiver.c
+index 63e5cedb..0a993e0f 100644
+--- a/receiver.c
++++ b/receiver.c
+@@ -467,7 +467,10 @@ static void handle_delayed_updates(char *local_name)
+ static void no_batched_update(int ndx, BOOL is_redo)
+ {
+       struct file_list *flist = flist_for_ndx(ndx, "no_batched_update");
+-      struct file_struct *file = flist->files[ndx - flist->ndx_start];
++      struct file_struct *file;
++      if (ndx < flist->ndx_start)
++              exit_cleanup(RERR_PROTOCOL);
++      file = flist->files[ndx - flist->ndx_start];
+ 
+       rprintf(FERROR_XFER, "(No batched update for%s \"%s\")\n",
+               is_redo ? " resend of" : "", f_name(file, NULL));
+@@ -604,6 +607,8 @@ int recv_files(int f_in, int f_out, char *local_name)
+ 
+               if (ndx - cur_flist->ndx_start >= 0)
+                       file = cur_flist->files[ndx - cur_flist->ndx_start];
++              else if (cur_flist->parent_ndx < 0)
++                      exit_cleanup(RERR_PROTOCOL);
+               else
+                       file = dir_flist->files[cur_flist->parent_ndx];
+               fname = local_name ? local_name : f_name(file, fbuf);
+diff --git a/sender.c b/sender.c
+index 99f431fe..033f87e5 100644
+--- a/sender.c
++++ b/sender.c
+@@ -140,6 +140,8 @@ void successful_send(int ndx)
+               return;
+ 
+       flist = flist_for_ndx(ndx, "successful_send");
++      if (ndx < flist->ndx_start)
++              exit_cleanup(RERR_PROTOCOL);
+       file = flist->files[ndx - flist->ndx_start];
+       if (!change_pathname(file, NULL, 0))
+               return;
+-- 
+2.35.6
diff --git a/meta/recipes-devtools/rsync/rsync_3.2.7.bb 
b/meta/recipes-devtools/rsync/rsync_3.2.7.bb
index e232abafc3..b1483fc6a6 100644
--- a/meta/recipes-devtools/rsync/rsync_3.2.7.bb
+++ b/meta/recipes-devtools/rsync/rsync_3.2.7.bb
@@ -39,6 +39,7 @@ SRC_URI = 
"https://download.samba.org/pub/${BPN}/src/${BP}.tar.gz \
            file://CVE-2026-43619_p3.patch \
            file://CVE-2026-43619_p4.patch \
            file://CVE-2026-43618.patch \
+           file://CVE-2026-43620.patch \
            "
 SRC_URI[sha256sum] = 
"4e7d9d3f6ed10878c58c5fb724a67dacf4b6aac7340b13e488fb2dc41346f2bb"
 
-- 
2.44.1

-=-=-=-=-=-=-=-=-=-=-=-
Links: You receive all messages sent to this group.
View/Reply Online (#238606): 
https://lists.openembedded.org/g/openembedded-core/message/238606
Mute This Topic: https://lists.openembedded.org/mt/119772226/21656
Group Owner: [email protected]
Unsubscribe: https://lists.openembedded.org/g/openembedded-core/unsub 
[[email protected]]
-=-=-=-=-=-=-=-=-=-=-=-

  • ... Ashishkumar Parmar X (asparmar - E INFOCHIPS PRIVATE LIMITED at Cisco) via lists.openembedded.org
    • ... Ashishkumar Parmar X (asparmar - E INFOCHIPS PRIVATE LIMITED at Cisco) via lists.openembedded.org
    • ... Ashishkumar Parmar X (asparmar - E INFOCHIPS PRIVATE LIMITED at Cisco) via lists.openembedded.org
    • ... Ashishkumar Parmar X (asparmar - E INFOCHIPS PRIVATE LIMITED at Cisco) via lists.openembedded.org
    • ... Ashishkumar Parmar X (asparmar - E INFOCHIPS PRIVATE LIMITED at Cisco) via lists.openembedded.org
    • ... Ashishkumar Parmar X (asparmar - E INFOCHIPS PRIVATE LIMITED at Cisco) via lists.openembedded.org

Reply via email to