On 14/09/2026 04:46, Collin Funk wrote:
Pádraig Brady <[email protected]> writes:

From: Ismail Ramzi <[email protected]>

parse_ls_color stores color_indicator[C_LINK].string as a pointer into
the color_buf buffer, then frees color_buf on the unparsable-value path.
The "ln=target" check after the parse loop still read that freed buffer,
e.g. with LS_COLORS='ln=target:x'.  Skip it on the failure path, where
color output is disabled anyway and the buffer is gone.
* src/ls.c (parse_ls_color): Return after freeing color_buf on failure,
so the color_indicator[C_LINK] check only runs when the buffer is live.
* tests/ls/color-symlink-target.sh: New test.
* tests/local.mk (all_tests): Add it.
* NEWS: Mention the fix.

Link: https://github.com/coreutils/coreutils/pull/352
---
  NEWS                             |  4 ++++
  src/ls.c                         |  1 +
  tests/local.mk                   |  1 +
  tests/ls/color-symlink-target.sh | 33 ++++++++++++++++++++++++++++++++
  4 files changed, 39 insertions(+)
  create mode 100755 tests/ls/color-symlink-target.sh

Thankfully, it seems pretty harmless. The bad read is the here:

     if (color_indicator[C_LINK].len == 6
         && !STRNCMP_LIT (color_indicator[C_LINK].string, "target"))
       color_symlink_as_referent = true;

Where STRNCMP_LIT expands to:

    strncmp (color_indicator[C_LINK].string, "target", 6)

and "color_indicator[C_LINK].string" is the just freed string that
previously contained a string constructed from the values parsed from
LS_COLORS.

But I agree it is worth applying before you make the release.

Right. The main potential issue is DOS I think,
where one might induce a failure in a set -e script,
by setting LS_COLORS.
On a semi-related note, I've been a bit tempted to mess with the
--enable-single-binary code a bit to allow building a library with
ls_main, etc. That would make it possible to use LibFuzzer to try to
catch stuff like this. I expiremented a bit with AFL++, which seems
fine, but I suspect it is less efficient since it needs to execute a
process for each case.
An interesting idea.
One potential issue is how for efficiency reasons we don't free all heap memory 
just before exit,
which might need consideration.

cheers,
Padraig

Reply via email to