[packages/tnef] updated to 1.4.18
arekm
arekm at pld-linux.org
Sun Oct 18 20:57:13 CEST 2026
commit 521e52ea3a2fec26d9c283df2dd22deb34b9a65e
Author: Arkadiusz Miśkiewicz <arekm at maven.pl>
Date: Sun Oct 18 20:56:01 2026 +0200
updated to 1.4.18
Fixes CVE-2026-103678, CVE-2026-103679, CVE-2026-103680.
tnef-CVE-2026-103678.patch | 48 +++++++++++++++++++++++++++++
tnef-CVE-2026-103679.patch | 43 ++++++++++++++++++++++++++
tnef-CVE-2026-103680.patch | 69 ++++++++++++++++++++++++++++++++++++++++++
tnef-attr_read-prototype.patch | 16 ++++++++++
tnef.spec | 30 +++++++++++++++---
5 files changed, 201 insertions(+), 5 deletions(-)
---
diff --git a/tnef.spec b/tnef.spec
index 1bb79f8..5216bc0 100644
--- a/tnef.spec
+++ b/tnef.spec
@@ -1,17 +1,28 @@
+#
+# Conditional build:
+%bcond_without tests # build with tests
+
Summary: Decodes MS-TNEF attachments
Summary(pl.UTF-8): Dekoder załączników w formacie MS-TNEF
Summary(ru.UTF-8): Программа для распаковки аттачментов MIME типа "application/ms-tnef"
Summary(uk.UTF-8): Програма для розпаковки атачментів MIME типу "application/ms-tnef"
Name: tnef
-Version: 1.4.12
+Version: 1.4.18
Release: 1
License: GPL v2+
Group: Applications/Mail
-Source0: http://downloads.sourceforge.net/tnef/%{name}-%{version}.tar.gz
-# Source0-md5: 92b27d6ff4374fea28b04e38032c7710
-URL: http://sourceforge.net/projects/tnef/
+Source0: https://github.com/verdammelt/%{name}/archive/refs/tags/%{version}/%{name}-%{version}.tar.gz
+# Source0-md5: c18c0166aaf5d19355394515978480e6
+Patch0: %{name}-attr_read-prototype.patch
+Patch1: %{name}-CVE-2026-103678.patch
+Patch2: %{name}-CVE-2026-103679.patch
+Patch3: %{name}-CVE-2026-103680.patch
+URL: https://github.com/verdammelt/%{name}
BuildRequires: autoconf >= 2.59
BuildRequires: automake
+%if %{with tests}
+BuildRequires: diffutils
+%endif
BuildRoot: %{tmpdir}/%{name}-%{version}-root-%(id -u -n)
%description
@@ -48,6 +59,10 @@ TNEF - це програма для розпаковки атачментів MI
%prep
%setup -q
+%patch -P0 -p1
+%patch -P1 -p1
+%patch -P2 -p1
+%patch -P3 -p1
%build
%{__aclocal}
@@ -57,6 +72,11 @@ TNEF - це програма для розпаковки атачментів MI
%configure
%{__make}
+%if %{with tests}
+# tests share one working directory, so they cannot run in parallel
+%{__make} -j1 check
+%endif
+
%install
rm -rf $RPM_BUILD_ROOT
@@ -68,6 +88,6 @@ rm -rf $RPM_BUILD_ROOT
%files
%defattr(644,root,root,755)
-%doc AUTHORS BUGS ChangeLog NEWS README.md THANKS doc/{FAQ,file-format.tex}
+%doc AUTHORS BUGS ChangeLog NEWS README.md THANKS doc/{FAQ,file-format.txt}
%attr(755,root,root) %{_bindir}/tnef
%{_mandir}/man1/tnef.1*
diff --git a/tnef-CVE-2026-103678.patch b/tnef-CVE-2026-103678.patch
new file mode 100644
index 0000000..18f80f6
--- /dev/null
+++ b/tnef-CVE-2026-103678.patch
@@ -0,0 +1,48 @@
+get_rtf_data_from_buf() trusts the uncompressed size in the RTF value
+header and memmove()s that many bytes out of a buffer that only holds the
+declared compressed size. An uncompressed ("MELA") RTF value with an
+oversized uncompressed size therefore reads past the end of the heap
+buffer; with --save-body the over-read bytes end up in the extracted file.
+
+CVE-2026-103678
+Reported via https://bugzilla.redhat.com/show_bug.cgi?id=2544476
+Upstream proposal: https://github.com/verdammelt/tnef/pull/54
+From that pull request only the assert placement is used: it does not hold
+for uncompressed values, so it now sits in the compressed branch. The
+pull request itself just turns the over-read into an abort under assert(),
+which disappears in NDEBUG builds, so an explicit size check is done here.
+--- a/src/rtf.c
++++ b/src/rtf.c
+@@ -316,18 +316,29 @@
+ magic = GETINT32(data + idx); idx += 4;
+ checksum = GETINT32 (data + idx); idx += 4;
+
+- /* sanity check */
+- assert (compr_size + 4 == len);
+-
+ (*out_len) = uncompr_size;
+
+ if (magic == rtf_uncompressed_magic) /* uncompressed rtf stream */
+ {
++ /* the uncompressed stream is copied straight out of the value
++ buffer, so its declared size cannot exceed what is left of
++ that buffer */
++ if (uncompr_size > len - 4)
++ {
++ (*out_data) = CHECKED_XCALLOC(unsigned char, 4);
++ (*out_len) = 0;
++ fprintf( stderr, "RTF size larger than buffer, input file may be corrupted\n" );
++ return;
++ }
++
+ (*out_data) = CHECKED_XCALLOC(unsigned char, (*out_len));
+ memmove ((*out_data), data+4, uncompr_size);
+ }
+ else if (magic == rtf_compressed_magic) /* compressed rtf stream */
+ {
++ /* sanity check */
++ assert (compr_size + 4 == len);
++
+ if ( checksum == generate_crc( data+idx, len-idx ) )
+ {
+ (*out_data) = decompress_rtf_data (data+idx, len-idx, uncompr_size);
diff --git a/tnef-CVE-2026-103679.patch b/tnef-CVE-2026-103679.patch
new file mode 100644
index 0000000..a5f68d6
--- /dev/null
+++ b/tnef-CVE-2026-103679.patch
@@ -0,0 +1,43 @@
+get_body_files() allocates the output file name and the MIME type once and
+points every generated file at the same buffers. When a TNEF stream
+carries more than one body value, each File is freed separately, so the
+second and later files free memory that was already freed: use after free
+followed by double free.
+
+CVE-2026-103679
+Reported via https://bugzilla.redhat.com/show_bug.cgi?id=2544477
+No upstream fix at the time of writing: still present in upstream git
+master and unpatched in Debian and Fedora, and no pull request either.
+This fix is PLD's.
+--- a/src/tnef.c
++++ b/src/tnef.c
+@@ -126,9 +126,6 @@
+ strcpy (tmp, filename);
+ strcat (tmp, ext);
+
+- char *mime = CHECKED_XCALLOC(char, strlen(type) + 1);
+- strcpy (mime, type);
+-
+ /* first get a count */
+ while (data[count++]);
+
+@@ -136,13 +133,17 @@
+ for (i = 0; data[i]; i++)
+ {
+ files[i] = (File*)XCALLOC(File, 1);
+- files[i]->name = tmp;
+- files[i]->mime_type = mime;
++ /* every file owns its own name and mime type, so that each
++ of them can be freed independently */
++ files[i]->name = xstrdup (tmp);
++ files[i]->mime_type = xstrdup (type);
+ files[i]->len = data[i]->len;
+ files[i]->data
+ = CHECKED_XMALLOC(unsigned char, data[i]->len);
+ memmove (files[i]->data, data[i]->data, data[i]->len);
+ }
++
++ XFREE (tmp);
+ }
+ return files;
+ }
diff --git a/tnef-CVE-2026-103680.patch b/tnef-CVE-2026-103680.patch
new file mode 100644
index 0000000..c070e79
--- /dev/null
+++ b/tnef-CVE-2026-103680.patch
@@ -0,0 +1,69 @@
+find_free_number() sizes its buffer for a five digit numeric suffix but
+formats the counter with sprintf() without any bound. With
+--number-backups and without --overwrite, a stream with enough colliding
+attachment names pushes the counter past 99999 and sprintf() writes past
+the end of the heap buffer.
+
+CVE-2026-103680
+Reported via https://bugzilla.redhat.com/show_bug.cgi?id=2544478
+Taken from upstream pull request https://github.com/verdammelt/tnef/pull/53
+by suve <veg at svgames.pl>: the buffer is sized for a full width unsigned
+counter, the counter becomes unsigned and gives up (returning NULL) when
+exhausted; the caller reports the failure instead of writing the file.
+--- a/src/path.c
++++ b/src/path.c
+@@ -25,6 +25,7 @@
+
+ #include "common.h"
+ #include <ctype.h>
++#include <limits.h>
+
+ #if HAVE_SYS_STAT_H
+ # include <sys/stat.h>
+@@ -102,16 +103,19 @@
+ {
+ size_t len = (strlen(fname)
+ + 1 /* '.' */
+- + 5 /* big enough for our purposes (i hope) */
++ + 20 /* if unsigned int is 64 bits, 2**64-1 is 20 decimal digits */
+ + 1); /* NULL */
+ char *tmp = CHECKED_XMALLOC (char, len);
+- int counter = 1;
++ unsigned int counter = 0;
+ do
+ {
+- sprintf (tmp, "%s.%d", fname, counter++);
++ sprintf (tmp, "%s.%u", fname, ++counter);
++ if (!file_exists(tmp)) return tmp;
+ }
+- while (file_exists(tmp));
+- return tmp;
++ while (counter < UINT_MAX);
++
++ XFREE(tmp);
++ return NULL;
+ }
+
+ /* windows pathname manipulation routines */
+--- a/src/file.c
++++ b/src/file.c
+@@ -112,9 +112,16 @@
+ else
+ {
+ char *tmp = find_free_number (path);
+- debug_print ("Renaming %s to %s\n", path, tmp);
+- XFREE (path);
+- path = tmp;
++ if (tmp != NULL) {
++ debug_print ("Renaming %s to %s\n", path, tmp);
++ XFREE (path);
++ path = tmp;
++ } else {
++ fprintf (stderr,
++ "tnef: %s: Could not create file: File exists, all alternative names tried\n",
++ path);
++ return;
++ }
+ }
+ }
+ }
diff --git a/tnef-attr_read-prototype.patch b/tnef-attr_read-prototype.patch
new file mode 100644
index 0000000..0d2126f
--- /dev/null
+++ b/tnef-attr_read-prototype.patch
@@ -0,0 +1,16 @@
+attr_read() is called with a FILE* argument, but declared as taking none.
+GCC 14 rejects the mismatch in attr.c as an error.
+
+Upstream commit 86bfa75cfacbe71c8d5282fa0065981b4544c5ad
+https://github.com/verdammelt/tnef/commit/86bfa75cfacbe71c8d5282fa0065981b4544c5ad
+
+--- a/src/attr.h
++++ b/src/attr.h
+@@ -69,6 +69,6 @@
+ extern void attr_dump (Attr* attr);
+ extern void attr_free (Attr* attr);
+ extern void copy_date_from_attr (Attr* attr, struct date* dt);
+-extern Attr* attr_read ();
++extern Attr* attr_read (FILE* in);
+
+ #endif /* ATTR_H */
================================================================
---- gitweb:
http://git.pld-linux.org/gitweb.cgi/packages/tnef.git/commitdiff/521e52ea3a2fec26d9c283df2dd22deb34b9a65e
More information about the pld-cvs-commit
mailing list