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