Your message dated Mon, 28 Sep 2026 16:14:28 +0200
with message-id <[email protected]>
and subject line Re: Bug#905647: tftpd-hpa: Logic flaw in macro expansion in 
remap for \x causes malfunction and memory corruption
has caused the Debian Bug report #905647,
regarding tftpd-hpa: Logic flaw in macro expansion in remap for \x causes 
malfunction and memory corruption
to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact [email protected]
immediately.)


-- 
905647: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=905647
Debian Bug Tracking System
Contact [email protected] with problems
--- Begin Message ---
Package: tftpd-hpa
Version: 5.2+20150808-1+b1
Severity: normal
Tags: upstream patch

Dear Maintainer,

   * What led up to the situation?

I wanted to use the remap function with macro \x (hex ip)

   * What exactly did you do (or not do) that was effective (or
     ineffective)?

Start with --map-file /somefile
In '/somefile', I have a rule:
r       /fai/efi/grub.cfg       /fai/efi/grub.cfg.d/\x

   * What was the outcome of this action?

Complaints from glibc about memory corruption, segfaults. Valgrind gave
54 errors. No working file.

   * What outcome did you expect instead?

Macro expansion and working file.


In tftpd/tftpd.c the function rewrite_macros is first called with
argument 'output' = NULL, asking for "how long will the string be".
A logic flaw makes the function return l=0 for macro 'x'. 0 bytes (+1
for string-ending NULL) is allocated, and then the actual macro
expansion is performed and stored there (8 bytes for ipv4, 32 for ipv6),
overwriting other memory.

Patch moves the 'if (output)' to only include the string copying, not
length calculation.

Same flaw exists in upstreams version 5.2 and Ubuntu version
5.2+20150808-1ubuntu3.

-- System Information:
Debian Release: 9.5
  APT prefers stable-updates
  APT policy: (500, 'stable-updates'), (500, 'stable')
Architecture: amd64 (x86_64)
Foreign Architectures: i386

Kernel: Linux 4.9.0-7-amd64 (SMP w/3 CPU cores)
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8), 
LANGUAGE=en_US.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/bash
Init: systemd (via /run/systemd/system)

Versions of packages tftpd-hpa depends on:
ii  adduser                3.115
ii  debconf [debconf-2.0]  1.5.61
ii  libc6                  2.24-11+deb9u3
ii  libwrap0               7.6.q-26

tftpd-hpa recommends no packages.

Versions of packages tftpd-hpa suggests:
pn  pxelinux  <none>

-- debconf information excluded
--- tftpd.c.orig        2015-08-08 06:24:45.000000000 +0200
+++ tftpd.c     2018-08-07 15:03:53.242504752 +0200
@@ -1365,24 +1365,26 @@
             return strlen(p);
 
     case 'x':
-        if (output) {
-            if (from.sa.sa_family == AF_INET) {
+        if (from.sa.sa_family == AF_INET) {
+            l = 8;
+            if (output) {
                 sprintf(output, "%08lX",
                     (unsigned long)ntohl(from.si.sin_addr.s_addr));
-                l = 8;
+            }
 #ifdef HAVE_IPV6
-            } else {
-                unsigned char *c = (unsigned char *)SOCKADDR_P(&from);
-                p = tb;
-                for (l = 0; l < 16; l++) {
-                    sprintf(p, "%02X", *c);
-                    c++;
-                    p += 2;
-                }
+        } else {
+            unsigned char *c = (unsigned char *)SOCKADDR_P(&from);
+            p = tb;
+            for (l = 0; l < 16; l++) {
+                sprintf(p, "%02X", *c);
+                c++;
+                p += 2;
+            }
+            l = strlen(tb);
+            if (output) {
                 strcpy(output, tb);
-                l = strlen(tb);
-#endif
             }
+#endif
         }
         return l;
 

--- End Message ---
--- Begin Message ---
Source: tftp-hpa
Source-Version: 7.1-1

Closing this per info from upstream.


On Sun, Sep 27, 2026 at 05:04:19PM -0700, H. Peter Anvin wrote:
> On September 27, 2026 6:11:16 AM PDT, Chris Hofstaedtler <[email protected]> 
> wrote:
> >Hello hpa,
> >
> >did you happen to see this issue? It was forwarded on to
> >https://bugzilla.syslinux.org/show_bug.cgi?id=76
> >
> >I can't reproduce it with 7.2 (on arm64), maybe it was solved, 
> >possibly by 04d7b0db0672ef5c7c36886e00f136672881a9ef?
> >
> >Thanks,
> >Chris
> >
> >On Tue, Aug 07, 2018 at 04:51:13PM +0200, Tomas Forsman wrote:
> >> Package: tftpd-hpa
> >> Version: 5.2+20150808-1+b1
> >[..]
> >> I wanted to use the remap function with macro \x (hex ip)
> >> 
> >>    * What exactly did you do (or not do) that was effective (or
> >>      ineffective)?
> >> 
> >> Start with --map-file /somefile
> >> In '/somefile', I have a rule:
> >> r       /fai/efi/grub.cfg       /fai/efi/grub.cfg.d/\x
> >> 
> >>    * What was the outcome of this action?
> >> 
> >> Complaints from glibc about memory corruption, segfaults. Valgrind gave
> >> 54 errors. No working file.
> >> 
> >>    * What outcome did you expect instead?
> >> 
> >> Macro expansion and working file.
> >> 
> >> 
> >> In tftpd/tftpd.c the function rewrite_macros is first called with
> >> argument 'output' = NULL, asking for "how long will the string be".
> >> A logic flaw makes the function return l=0 for macro 'x'. 0 bytes (+1
> >> for string-ending NULL) is allocated, and then the actual macro
> >> expansion is performed and stored there (8 bytes for ipv4, 32 for ipv6),
> >> overwriting other memory.
> >> 
> >> Patch moves the 'if (output)' to only include the string copying, not
> >> length calculation.
> >> 
> >> Same flaw exists in upstreams version 5.2 and Ubuntu version
> >> 5.2+20150808-1ubuntu3.
> >
> >> --- tftpd.c.orig   2015-08-08 06:24:45.000000000 +0200
> >> +++ tftpd.c        2018-08-07 15:03:53.242504752 +0200
> >> @@ -1365,24 +1365,26 @@
> >>              return strlen(p);
> >>  
> >>      case 'x':
> >> -        if (output) {
> >> -            if (from.sa.sa_family == AF_INET) {
> >> +        if (from.sa.sa_family == AF_INET) {
> >> +            l = 8;
> >> +            if (output) {
> >>                  sprintf(output, "%08lX",
> >>                      (unsigned long)ntohl(from.si.sin_addr.s_addr));
> >> -                l = 8;
> >> +            }
> >>  #ifdef HAVE_IPV6
> >> -            } else {
> >> -                unsigned char *c = (unsigned char *)SOCKADDR_P(&from);
> >> -                p = tb;
> >> -                for (l = 0; l < 16; l++) {
> >> -                    sprintf(p, "%02X", *c);
> >> -                    c++;
> >> -                    p += 2;
> >> -                }
> >> +        } else {
> >> +            unsigned char *c = (unsigned char *)SOCKADDR_P(&from);
> >> +            p = tb;
> >> +            for (l = 0; l < 16; l++) {
> >> +                sprintf(p, "%02X", *c);
> >> +                c++;
> >> +                p += 2;
> >> +            }
> >> +            l = strlen(tb);
> >> +            if (output) {
> >>                  strcpy(output, tb);
> >> -                l = strlen(tb);
> >> -#endif
> >>              }
> >> +#endif
> >>          }
> >>          return l;
> >>  
> >
> 
> Hi, 
> 
> This was fixed quite a while ago. I can't remember if it was intentional or 
> an accidental side effect of another change.

--- End Message ---

Reply via email to