On Fri, Feb 28, 2025 at 07:47:08AM +0100, Helge Deller via Dnsmasq-discuss 
wrote:
> 
> Here is an updated patch.
> Please verify, and Simon, please install if you think it's Ok.
> 
> Helge
> 
> --------------------
> 
> [PATCH] Fix TFTP loading from real-world HP workstation
> 
> This patch reverts commit 368ceff6e099 ("TFTP off-by-2 bugfix") which
> wrongly assumed there was an off-by-two issue in the packet length.
> 
> Instead it turns out, that the internal funtion next(), which extracts a
> NUL-terminated string starting from the current packet position is
> buggy.  This function checks the very last byte of the packet if it is
> zero in order to prevent strings reaching outside beyond the packet.
> 
> On my machine (HP C8000 workstation), the initial packet is 516 bytes
> long and there is no requirement that the last byte is zero, as long as
> all strings are properly NUL-terminated and all are stored fully inside
> the packet (way earlier than reaching the last byte of the packet).
> 
> This patch fixes the next() function, so that it searches for the
> terminating NUL-byte starting from the current position and avoids
> accessing any memory outside of the packet. For that it avoids using
> strlen() and instead uses a simple loop.
> 
> Tested with my HP C8000 workstation, and via trivial get command.
> 
> Signed-off-by: Helge Deller <del...@gmx.de>
> Reported-by: Dominik Derigs <dl...@dl6er.de>
> 
> 
> diff --git a/src/tftp.c b/src/tftp.c
> index 637a566..8420652 100644
> --- a/src/tftp.c
> +++ b/src/tftp.c
> @@ -360,7 +360,7 @@ void tftp_request(struct listener *listen, time_t now)
>      }
> 
>    p = packet + 2;
> -  end = packet + 2 + len;
> +  end = packet + len;
> 
>    if (ntohs(*((unsigned short *)packet)) != OP_RRQ ||
>        !(filename = next(&p, end)) ||
> @@ -743,15 +743,21 @@ static void free_transfer(struct tftp_transfer 
> *transfer)
>  static char *next(char **p, char *end)
>  {
>    char *ret = *p;
> -  size_t len;
> -
> -  if (*(end-1) != 0 ||
> -      *p == end ||
> -      (len = strlen(ret)) == 0)
> -    return NULL;
> -
> -  *p += len + 1;
> -  return ret;
> +  char *n = *p;
> +
> +  /* as long as end of packet not reached: */
> +  while (n < end) {
> +     if (*n) {
> +             /* contiue while terminating NUL char not found yet */
> +             ++n;
> +             continue;
> +     }
> +     /* NUL char found. Update start pointer and return start of string. */
> +     *p = n + 1;
> +     return ret;
> +  }
> +  /* end of packet reached, but NUL-terminated string not found: */
> +  return NULL;
>  }
> 
>  static void sanitise(char *buf)
> 

|stappers@alpaca:~/src/dnsmasq
|$ patch -p1 < /tmp/helge
|patching file src/tftp.c
|Hunk #1 FAILED at 360.
|Hunk #2 FAILED at 743.
|2 out of 2 hunks FAILED -- saving rejects to file src/tftp.c.rej
|stappers@alpaca:~/src/dnsmasq
|$



Groeten
Geert Stappers
-- 
Silence is hard to parse

_______________________________________________
Dnsmasq-discuss mailing list
Dnsmasq-discuss@lists.thekelleys.org.uk
https://lists.thekelleys.org.uk/cgi-bin/mailman/listinfo/dnsmasq-discuss

Reply via email to