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;
>  

Reply via email to