Subject: bug#79433: 9.7: cp(1): lchownat(2/3) fallback bogus?

From: Steffen Nurpmeso <[email-masked]>
Date: Tue, 16 Sep 2025 16:36:58 +0200

Steffen Nurpmeso wrote in
 <20250916122011.vqDfAgh0@steffen%sdaoden.eu>:
 |Paul Eggert wrote in
 | <[email-masked]>:
 ||On 2025-09-15 17:40, Steffen Nurpmeso wrote:
 ||> How likely is a miscompilation of gcc 4.2.0?
 ||
 ||I would think not likely, but possible.
 ...
 |i'll attach it plzip(1)ped; i now install gdb, from objdump(1)
 |alone i cannot figure it out, the codepaths are too mangled for me
 |having no history with neither coreutils nor glibc.
 |
 |  $ ldd /bin/cp
 |  linux-vdso.so.1 (0x00007fffe1e13000)
 |  libacl.so.1 => /lib/libacl.so.1 (0x00007fcf92d3a000)
 |  libattr.so.1 => /lib/libattr.so.1 (0x00007fcf92d32000)
 |  libc.so.6 => /lib/libc.so.6 (0x00007fcf92b42000)
 |  /lib/ld-linux-x86-64.so.2 => /lib64/ld-linux-x86-64.so.2 (0x00007fcf92d6\
 |  6000)
 |
 |I could also place the actual libs on the server, just in case
 ..
 | --End of <[email-masked]>
 --End of <20250916122011.vqDfAgh0@steffen%sdaoden.eu>

So for

	gdb/gdb --args /bin/cp --debug -a xb xc

we enter

	else if (S_ISLNK (src_mode))

at copy.c:3106 since i see

	unlinkat
	readlink@plt
	symlinkat@plt
	free
	lstat@plt [hmm where; lchownat fallback?]
		lstat64
		fstatat64
	lchown@plt
		lchown

Thereafter only 10 "??" stepi in between resolved lchown and

	lchmod@plt
		fchmodat

which seems to be lchmodat() at line 3312, which makes me wonder
given that -a implies x->preserve_timestamps and thus the
utimensat() path at line 3220+ should have been taken, and,
furthermore, there is line 3256+ saying

  /* The operations beyond this point may dereference a symlink. */
  if (dest_is_symlink)
    return delayed_ok;

and then there was "dest_is_symlink = true;" at line 3109 in the
S_ISLNK() block.  Now my gdb knowledge is exceeded, i hate
debuggers.  And they hate me

 $ curl -O https://ftp.gnu.org/gnu/gdb/gdb-16.3.tar.xz
 % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
 			 Dload  Upload   Total   Spent    Left  Speed
 100 23.3M  100 23.3M    0     0  18748      0  0:21:43  0:21:43 --:--:-- 210080

but that aside.  It would need a debug guru to look at the data,
the file is stripped.  And it is optimized, so if i
"break symlinkat" and then "x/10i $pc"<>"stepi" (sorry, never
debuggers) we see early returns

	(gdb) next
	Single stepping until exit from function symlinkat,
...
	(gdb) x/10i $pc
	=> 0x555555560a15:      mov    %eax,%ebx
	   0x555555560a17:      test   %eax,%eax
	   0x555555560a19:      je     0x5555555609e3
...
	(gdb) x/10i $pc
	=> 0x5555555609e3:      mov    0x118(%rsp),%rax
	   0x5555555609eb:      sub    %fs:0x28,%rax
	   0x5555555609f4:      jne    0x555555560a77
	   0x5555555609fa:      add    $0x128,%rsp
	   0x555555560a01:      mov    %ebx,%eax
	   0x555555560a03:      pop    %rbx
	   0x555555560a04:      pop    %rbp
	   0x555555560a05:      pop    %r12
	   0x555555560a07:      pop    %r13
	   0x555555560a09:      pop    %r14
	[..]
	   0x555555560a0b:      pop    %r15
	   0x555555560a0d:      ret

So we actually left that, which we did not from the C source file
me thinks, so likely gcc spilled code around, anyway it would
require very deep inspection; and for me this is manual, since i
never ever cared for debugger and their support, it could be there
is a smart analyzer tools / extension somewhere which does exactly
that, but this i really do not know.  It seems to me coreutils do
not embed actual compiler and linker flags used somewhere, so the
binary is all i can give, i would think, shall reproduction from
scratch be of interest for some gcc developers maybe.

I have it here, if anyone gives debugger knowledge we can go
deeper, i could maybe even create a ssh guest account if it is
really important, and i have posted the compressed binary which
surely is where the error can be found.

My enthusiasm is hereby extinct, even though i would like to see
the content of the "const struct cp_options *x" as well as
"dest_is_symlink" local variable.
I would think it is a miscompilation of gcc 14.2.

Sorry for the noise, shall nothing further happen.  I, you know,
had that build error and it produced circles, i thought a quick
note is a thing.  You know, is there any just plain "cp -a symlink
symlink" test in coreutils, for example, as i look.

Ciao,

--steffen
|
|Der Kragenbaer,                The moon bear,
|der holt sich munter           he cheerfully and one by one
|einen nach dem anderen runter  wa.ks himself off
|(By Robert Gernhardt)