]> git.ipfire.org Git - thirdparty/coreutils.git/commitdiff
pwd: fix heap buffer overflow in file_name_prepend master
authorChris Down <chris@chrisdown.name>
Mon, 16 Feb 2026 05:06:31 +0000 (13:06 +0800)
committerPádraig Brady <P@draigBrady.com>
Mon, 16 Feb 2026 10:45:45 +0000 (10:45 +0000)
file_name_prepend works by right-aligning path data in a growing buffer.
When the buffer is too small, it then allocates a new buffer via
xpalloc() and copies existing data to the end of the new buffer.

Unfortunately, the memcpy destination is computed as buf + p->n_alloc -
n_free, but xpalloc has already updated p->n_alloc to the new (larger)
allocation size while n_free still reflects the old state. This places
the data at too high an offset, writing past the end of the buffer.

Update to properly calculate the destination offset.

Fixes: v9.5-171-g61ab25c35 ("pwd: prefer xpalloc to xnrealloc")
src/pwd.c

index 4f30d076535a41951fe637b837f2de2f6ef6df29..486e8e670f52538235381b017732e8653c7d5603 100644 (file)
--- a/src/pwd.c
+++ b/src/pwd.c
@@ -112,7 +112,7 @@ file_name_prepend (struct file_name *p, char const *s, size_t s_len)
          copy it only once.  */
       idx_t n_used = p->n_alloc - n_free;
       char *buf = xpalloc (NULL, &p->n_alloc, 1 + s_len - n_free, -1, 1);
          copy it only once.  */
       idx_t n_used = p->n_alloc - n_free;
       char *buf = xpalloc (NULL, &p->n_alloc, 1 + s_len - n_free, -1, 1);
-      p->start = memcpy (buf + p->n_alloc - n_free, p->start, n_used);
+      p->start = memcpy (buf + p->n_alloc - n_used, p->start, n_used);
       free (p->buf);
       p->buf = buf;
     }
       free (p->buf);
       p->buf = buf;
     }