#1059474 sed fails when used with --follow-links and -i options, when used on long paths with multiple symbolic links

Package:
sed
Source:
sed
Description:
GNU stream editor for filtering/transforming text
Submitter:
Vladimir Podobaev
Date:
2024-07-26 16:09:05 UTC
Severity:
normal
Tags:
#1059474#5
Date:
2023-12-26 16:02:12 UTC
From:
To:
Dear Maintainer,

Attaching the script, which reproduces the bug on sed 4.9-1 (and 4.9 downloaded
from upstream also).

#!/bin/bash

# NOTE. Directory and file names do not matter. But their name lengths matter.

USERDIR=/home/user1234

DIR1="$USERDIR/1234/b12345678901234/c12345/d12345678/e1234/f12345678901/g1234567/h12345"

DIR2="i12"
DIR3="j1/k12345"
DIR4="l1234567"
FILE="m12345"

mkdir -p $DIR1/$DIR2/$DIR4
mkdir -p $DIR1/$DIR3

touch $DIR1/$DIR2/$DIR4/$FILE
ln -sf ../../$DIR2/$DIR4/$FILE $DIR1/$DIR3/$FILE
ln -sf ../$DIR3/$FILE $DIR1/$DIR2/$FILE


sed -i --follow-symlinks -e 's/^a/b/' $DIR1/$DIR2/$FILE

# Here sed 4.9 gives an error:
# sed: couldn't readlink
/home/podobaev/1234/b12345678901234/c12345/d12345678/e1234/f12345678901/g1234567/h12345/i12/../j1/k12345/../../i12/l12345:
No such file or directory
#
# I guess, some internal buffer lengths are calculated incorrectly.

# END OF SCRIPT

Thank you.

Best regards, Vladimir

#1059474#10
Date:
2024-07-26 16:01:48 UTC
From:
To:
The last sed release had a "minor" problem which was fixed after the
release:
https://git.savannah.gnu.org/gitweb/?p=sed.git;a=commit;h=8f600f2df293d539e9e9137f6f82faa1633b97c1
- mishandling of symlinks.

There was unfortunately no new release, and this is a major issue,
because the packaged version of sed breaks buildroot (specfically the
mkusers script) with targets that contain a second level of indirection,
shortened reproducer:



```
export
TARGET=/work2/work/abc/br2_target/basesystem/abcdef_ghij/build/buildroot-fs/squashfs/target
mkdir -p $TARGET/etc/
mkdir -p  $TARGET/tmp/etc/
touch $TARGET/etc/group.default
ln -sf -T ../tmp/etc/group $TARGET/etc/group
ln -sf -T ../../etc/group.default $TARGET/tmp/etc/group

sed -i --follow-symlinks -e '/^service:.*/d;' $TARGET/etc/group
unset TARGET
```
This breaks:
```
sed -i --follow-symlinks -e '/^service:.*/d;' $TARGET/etc/group
sed: couldn't readlink
/work2/work/abc/br2_target/basesystem/abcdef_ghij/build/buildroot-fs/squashfs/target/etc/../tmp/etc/../../etc/group.defaul:
No such file or directory
```

Mind the path - the "t" at the end is missing. Sed line borrowed from
buildroot.