new file mode 100644
@@ -0,0 +1,267 @@
+From 9eef71ce20fda2b345ef8431359aec96121215bd Mon Sep 17 00:00:00 2001
+From: Uwe Ohse at akiar <uwe@ohse.de>
+Date: Mon, 10 Aug 2026 17:55:28 +0200
+Subject: [PATCH] remove topipe 'feature'
+
+CVE: CVE-2026-105841
+Upstream-Status: Backport [https://github.com/UweOhse/lrzsz/commit/9eef71ce20fda2b345ef8431359aec96121215bd]
+
+Backport Changes:
+- Retained sys2() and exec2() and their declarations because 0.12.20
+ still calls them in its separate, opt-in ZCOMMAND handling. Removing
+ them as upstream does causes undefined references when linking lrz.
+- Omitted NEWS because its 0.13.0 release-note hunk conflicts with the
+ 0.12.20 release history and is not needed for the security fix.
+
+(cherry picked from commit 9eef71ce20fda2b345ef8431359aec96121215bd)
+Signed-off-by: Hetvi Thakar <hthakar@cisco.com>
+---
+ src/lrz.c | 193 ++++++++++++++++++++++--------------------------------
+ 1 file changed, 79 insertions(+), 114 deletions(-)
+
+diff --git a/src/lrz.c b/src/lrz.c
+index ae3c62d..9c08a3d 100644
+--- a/src/lrz.c
++++ b/src/lrz.c
+@@ -76,7 +76,6 @@ int skip_if_not_found;
+ char *Pathname;
+ const char *program_name; /* the name by which we were called */
+
+-int Topipe=0;
+ int MakeLCPathname=TRUE; /* make received pathname lower case */
+ int Verbose=0;
+ int Quiet=0; /* overrides logic that would otherwise set verbose */
+@@ -803,9 +802,6 @@ fubar:
+ shortname ? shortname : "no.name", protname());
+ #endif
+ canit(STDOUT_FILENO);
+- if (Topipe && fout) {
+- pclose(fout); return ERROR;
+- }
+ if (fout)
+ fclose(fout);
+
+@@ -1286,111 +1282,89 @@ procheader(char *name, struct zm_fileinfo *zi)
+ if (!zmodem_requested && MakeLCPathname && !IsAnyLower(name_static)
+ && !(zi->mode&UNIXFILE))
+ uncaps(name_static);
+- if (Topipe > 0) {
+- if (Pathname)
+- free(Pathname);
+- Pathname=malloc((PATH_MAX)*2);
+- if (!Pathname)
+- error(1,0,_("out of memory"));
+- sprintf(Pathname, "%s %s", program_name+2, name_static);
+- if (Verbose) {
+- vstringf("%s: %s %s\n",
+- _("Topipe"),
+- Pathname, Thisbinary?"BIN":"ASCII");
+- }
+- if ((fout=popen(Pathname, "w")) == NULL)
+- return ERROR;
+- } else {
+- if (protocol==ZM_XMODEM)
+- /* we don't have the filename yet */
+- return OK; /* dummy */
+- if (Pathname)
+- free(Pathname);
+- Pathname=malloc((PATH_MAX)*2);
+- if (!Pathname)
+- error(1,0,_("out of memory"));
+- strcpy(Pathname, name_static);
+- if (Verbose) {
+- /* overwrite the "waiting to receive" line */
+- vstring("\r \r");
+- vstringf(_("Receiving: %s\n"), name_static);
+- }
+- checkpath(name_static);
+- if (Nflag)
+- {
+- /* cast because we might not have a prototyp for strdup :-/ */
+- free(name_static);
+- name_static=(char *) strdup("/dev/null");
+- if (!name_static)
+- {
+- fprintf(stderr,"%s: %s\n", program_name, _("out of memory"));
+- exit(1);
+- }
+- }
+-#ifdef OMEN
+- /* looks like a security hole -- uwe */
+- if (name_static[0] == '!' || name_static[0] == '|') {
+- if ( !(fout = popen(name_static+1, "w"))) {
+- return ERROR;
+- }
+- Topipe = -1; return(OK);
+- }
+-#endif
+- if (Thisbinary && zconv==ZCRESUM) {
+- struct stat st;
+- fout = fopen(name_static, "r+");
+- if (fout && 0==fstat(fileno(fout),&st))
+- {
+- int can_resume=TRUE;
+- if (zmanag==ZF1_ZMCRC) {
+- int r=do_crc_check(fout,zi->bytes_total,st.st_size);
+- if (r==ERROR) {
+- fclose(fout);
+- return ZFERR;
+- }
+- if (r==ZCRC_DIFFERS) {
+- can_resume=FALSE;
+- }
+- }
+- if ((unsigned long)st.st_size > zi->bytes_total) {
+- can_resume=FALSE;
+- }
+- /* retransfer whole blocks */
+- zi->bytes_skipped = st.st_size & ~(1023);
+- if (can_resume) {
+- if (fseek(fout, (long) zi->bytes_skipped, SEEK_SET)) {
+- fclose(fout);
+- return ZFERR;
+- }
+- }
+- else
+- zi->bytes_skipped=0; /* resume impossible, file has changed */
+- goto buffer_it;
+- }
+- zi->bytes_skipped=0;
+- if (fout)
+- fclose(fout);
+- }
+- fout = fopen(name_static, openmode);
++
++ if (protocol==ZM_XMODEM)
++ /* we don't have the filename yet */
++ return OK; /* dummy */
++ if (Pathname)
++ free(Pathname);
++ Pathname=malloc((PATH_MAX)*2);
++ if (!Pathname)
++ error(1,0,_("out of memory"));
++ strcpy(Pathname, name_static);
++ if (Verbose) {
++ /* overwrite the "waiting to receive" line */
++ vstring("\r \r");
++ vstringf(_("Receiving: %s\n"), name_static);
++ }
++ checkpath(name_static);
++ if (Nflag)
++ {
++ /* cast because we might not have a prototyp for strdup :-/ */
++ free(name_static);
++ name_static=(char *) strdup("/dev/null");
++ if (!name_static)
++ {
++ fprintf(stderr,"%s: %s\n", program_name, _("out of memory"));
++ exit(1);
++ }
++ }
++
++ if (Thisbinary && zconv==ZCRESUM) {
++ struct stat st;
++ fout = fopen(name_static, "r+");
++ if (fout && 0==fstat(fileno(fout),&st))
++ {
++ int can_resume=TRUE;
++ if (zmanag==ZF1_ZMCRC) {
++ int r=do_crc_check(fout,zi->bytes_total,st.st_size);
++ if (r==ERROR) {
++ fclose(fout);
++ return ZFERR;
++ }
++ if (r==ZCRC_DIFFERS) {
++ can_resume=FALSE;
++ }
++ }
++ if ((unsigned long)st.st_size > zi->bytes_total) {
++ can_resume=FALSE;
++ }
++ /* retransfer whole blocks */
++ zi->bytes_skipped = st.st_size & ~(1023);
++ if (can_resume) {
++ if (fseek(fout, (long) zi->bytes_skipped, SEEK_SET)) {
++ fclose(fout);
++ return ZFERR;
++ }
++ }
++ else
++ zi->bytes_skipped=0; /* resume impossible, file has changed */
++ goto buffer_it;
++ }
++ zi->bytes_skipped=0;
++ if (fout)
++ fclose(fout);
++ }
++ fout = fopen(name_static, openmode);
+ #ifdef ENABLE_MKDIR
+- if ( !fout && Restricted < 2) {
+- if (make_dirs(name_static))
+- fout = fopen(name_static, openmode);
+- }
++ if ( !fout && Restricted < 2) {
++ if (make_dirs(name_static))
++ fout = fopen(name_static, openmode);
++ }
+ #endif
+- if ( !fout)
+- {
++ if ( !fout)
++ {
+ #ifdef ENABLE_SYSLOG
+- int e=errno;
++ int e=errno;
+ #endif
+- zpfatal(_("cannot open %s"), name_static);
+- DO_SYSLOG((LOG_ERR,"%s: cannot open: %s",
+- protname(),strerror(e)));
+- return ERROR;
+- }
+- }
++ zpfatal(_("cannot open %s"), name_static);
++ DO_SYSLOG((LOG_ERR,"%s: cannot open: %s",
++ protname(),strerror(e)));
++ return ERROR;
++ }
++
+ buffer_it:
+- if (Topipe == 0) {
++ {
+ static char *s=NULL;
+ static size_t last_length=0;
+ #if defined(F_GETFD) && defined(F_SETFD) && defined(O_SYNC)
+@@ -1550,8 +1524,7 @@ report(int sct)
+ }
+
+ /*
+- * If called as [-][dir/../]vrzCOMMAND set Verbose to 1
+- * If called as [-][dir/../]rzCOMMAND set the pipe flag
++ * If called as [-][dir/../]vrz set Verbose to 1
+ * If called as rb use YMODEM protocol
+ */
+ static void
+@@ -1576,8 +1549,6 @@ chkinvok(const char *s)
+ protocol=ZM_XMODEM;
+ if (s[0]=='r' && (s[1]=='b' || s[1]=='y'))
+ protocol=ZM_YMODEM;
+- if (s[2] && protocol!=ZM_XMODEM)
+- Topipe = 1;
+ }
+
+ /*
+@@ -2207,12 +2178,6 @@ static int
+ closeit(struct zm_fileinfo *zi)
+ {
+ int ret;
+- if (Topipe) {
+- if (pclose(fout)) {
+- return ERROR;
+- }
+- return OK;
+- }
+ if (in_tcpsync) {
+ rewind(fout);
+ if (!fgets(tcp_buf,sizeof(tcp_buf),fout)) {
+--
+2.35.6
@@ -21,6 +21,7 @@ SRC_URI = "https://www.ohse.de/uwe/releases/lrzsz-${PV}.tar.gz \
file://0001-Fix-cross-compilation-using-autoconf-detected-AR.patch \
file://0001-Fix-build-with-GCC-15.patch \
file://0001-lrzsz-convert-K-R-function-definitions-to-ANSI-C-pro.patch \
+ file://CVE-2026-105841.patch \
"
SRC_URI[sha256sum] = "c28b36b14bddb014d9e9c97c52459852f97bd405f89113f30bee45ed92728ff1"