diff --git a/meta/recipes-bsp/lrzsz/lrzsz-0.12.20/CVE-2026-105841.patch b/meta/recipes-bsp/lrzsz/lrzsz-0.12.20/CVE-2026-105841.patch
new file mode 100644
index 00000000000..268218fb8a6
--- /dev/null
+++ b/meta/recipes-bsp/lrzsz/lrzsz-0.12.20/CVE-2026-105841.patch
@@ -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
diff --git a/meta/recipes-bsp/lrzsz/lrzsz_0.12.20.bb b/meta/recipes-bsp/lrzsz/lrzsz_0.12.20.bb
index 042cf7fbaca..403266743e0 100644
--- a/meta/recipes-bsp/lrzsz/lrzsz_0.12.20.bb
+++ b/meta/recipes-bsp/lrzsz/lrzsz_0.12.20.bb
@@ -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"
 
