diff --git a/NEWS b/NEWS index 8d1ccb2e3..fd6582dea 100644 --- a/NEWS +++ b/NEWS @@ -36,6 +36,10 @@ GNU coreutils NEWS -*- outline -*- 'head' and 'tail' now quote names in file headers when needed. [This bug was present in "the beginning".] + 'ls --color' no longer reads freed memory when LS_COLORS sets "ln=target" + and later becomes unparsable, e.g., LS_COLORS='ln=target:x'. + [This bug was present in "the beginning".] + 'mv' now warns when copying extended attributes fails with ENOTSUP, e.g., when moving files to a file system that does not support them. [bug introduced in coreutils-7.3] diff --git a/src/ls.c b/src/ls.c index 7f3b53541..9536209a5 100644 --- a/src/ls.c +++ b/src/ls.c @@ -2845,6 +2845,7 @@ parse_ls_color (void) free (e2); } print_with_color = false; + return; } else { diff --git a/tests/local.mk b/tests/local.mk index d91589355..e21c1116d 100644 --- a/tests/local.mk +++ b/tests/local.mk @@ -721,6 +721,7 @@ all_tests = \ tests/ls/color-norm.sh \ tests/ls/color-term.sh \ tests/ls/color-ext.sh \ + tests/ls/color-symlink-target.sh \ tests/ls/dangle.sh \ tests/ls/dired.sh \ tests/ls/file-type.sh \ diff --git a/tests/ls/color-symlink-target.sh b/tests/ls/color-symlink-target.sh new file mode 100755 index 000000000..fcbe2f1ef --- /dev/null +++ b/tests/ls/color-symlink-target.sh @@ -0,0 +1,33 @@ +#!/bin/sh +# An invalid LS_COLORS that appears after a valid "ln=target" entry +# used to make ls read the freed color buffer (heap-use-after-free). +# Copyright (C) 2026 Free Software Foundation, Inc. + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ ls + +# "ln=target" stores a pointer into the color buffer, +# Until v9.12 this buffer was free'd then accessed +# after a subsequent parsing failure. +LS_COLORS='ln=target:x' ls --color=always . >/dev/null 2>err || fail=1 + +cat <<\EOF > exp-err || framework_failure_ +ls: unparsable value for LS_COLORS environment variable +EOF + +compare exp-err err || fail=1 + +Exit $fail