Hi Paul Eggert,
Thank you for your response. I want to clarify the scenario and my concern more 
precisely.
The situation does not depend on creating /tmp/nmap during mv. The behavior 
occurs earlier during the cp operation when the destination file already exists 
and is controlled by an unprivileged user.Instead of the race condition, I will 
put forth below another scenario that I have experimented with.
Consider the following sequence:

  1.
An unprivileged user can also pre-create /tmp/nmap.
  2.
Because /tmp has the sticky bit set, other users cannot unlink or rename the 
file, but the attacker still owns it.
  3.
A privileged process later executes:

cp -a /usr/bin/nmap /tmp/nmap

Since the destination file already exists, cp opens the existing file and 
truncates it rather than creating a new file. The file contents are copied 
first, and the metadata (ownership, permissions, timestamps, etc.) is applied 
afterwards.
During the interval between truncating the file and applying the final 
metadata, the file remains owned by the attacker. Because the attacker still 
owns the file, another process controlled by the attacker can open the file 
concurrently and write to it while cp is copying the contents.
In testing, by racing concurrent writes against the copy operation, I observed 
different intermediate permission and ownership states depending on timing, 
allowing modification of the destination file contents before the final 
metadata is applied.
My concern is the following: when a privileged process copies a file with cp -a 
into a destination that already exists and is owned by another user, the 
operation writes to that existing file rather than failing or protecting the 
destination from concurrent modification. In other words, the destination file 
continues to follow its existing permissions and ownership during the copy 
phase, instead of being protected based on the source file’s metadata from the 
beginning of the operation.
I am trying to understand whether this behaviour is considered intentional 
design for cp, or if there are reasons why the operation should not fail or 
otherwise protect the destination file when it already exists and is owned by a 
different user.


[undefined]

Warm Regards,

Ajay SK

Firmware Security Researcher

Payatu Security Consulting Pvt Ltd.

Reach me on: 7397338492

This email and any files transmitted with it are confidential and intended 
solely for the use of the individual or entity to whom they are addressed. If 
you have received this email in error, please notify the system manager. Please 
note that any views or opinions presented in this email are solely those of the 
author and do not necessarily represent those of the company. Finally, the 
recipient should check this email and any attachments for the presence of 
Malwares. The company accepts no liability for any damage caused by any Malware 
transmitted by this email.

________________________________
From: Paul Eggert <[email protected]>
Sent: 09 March 2026 11:10
To: Ajay S.K <[email protected]>; Collin Funk <[email protected]>
Cc: [email protected] <[email protected]>
Subject: Re: bug#80572: [BUG] Privilege escalation via cp trying to replace 
file contents using root privileges

[You don't often get email from [email protected]. Learn why this is important 
at https://aka.ms/LearnAboutSenderIdentification ]

CAUTION: This email originated from outside of the organization. Do not click 
links or open attachments unless you recognize the sender and know the content 
is safe.

On 2026-03-08 20:32, Ajay S.K wrote:
> What happens during the race is the following. At a certain point while mv -f 
> /tmp/nmap /usr/bin/nmap is executing, my program manages to create /tmp/nmap.

That does not necessarily mean there's a problem.

As I mentioned earlier, the relevant syscalls executed by that mv
command should look like the following:

>   renameat2(AT_FDCWD, "/tmp/nmap", AT_FDCWD, "/usr/bin/nmap", 
> RENAME_NOREPLACE) = -1 EEXIST (File exists)
>   openat(AT_FDCWD, "/usr/bin/nmap", O_RDONLY|O_PATH|O_DIRECTORY) = -1 ENOTDIR 
> (Not a directory)
>   newfstatat(AT_FDCWD, "/tmp/nmap", {st_mode=S_IFREG|0755, st_size=138120, 
> ...}, AT_SYMLINK_NOFOLLOW) = 0
>   newfstatat(AT_FDCWD, "/usr/bin/nmap", {st_mode=S_IFREG|0755, 
> st_size=138120, ...}, AT_SYMLINK_NOFOLLOW) = 0
>   renameat(AT_FDCWD, "/tmp/nmap", AT_FDCWD, "/usr/bin/nmap") = 0

If your attacking program "manages to create" /tmp/nmap while the mv is
executing, that must occur after the last syscall (the renameat) quoted
above. This is because the file /tmp/nmap exists until then, and the
attacker cannot create a file that already exists.

And if your attacking program creates /tmp/nmap after the renameat, the
attacking program can't affect what's in /usr/bin/nmap. All it can do is
create a file /tmp/nmap that nobody else cares about. So privilege
escalation does not occur.

The rest of your email is also incoherent.

We can't debug this from a distance: you'll need to find out what
happened yourself. I suggest starting by using strace on the 'cp'
command, the 'mv' command, and your attacking program, and looking at
the strace output.

Reply via email to