Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

'hard_link = true' deletes special files like '/dev/null' and replaces them with regular files #564

Closed
trofi opened this issue Mar 16, 2020 · 1 comment
Labels
bug Does not work as intended/documented
Milestone

Comments

@trofi
Copy link
Contributor

trofi commented Mar 16, 2020

It's an upstream variant of bug https://bugs.gentoo.org/712080 observed and debugged by Dan Goodliffe on ccache-3.7.7

There user runs kernel build as root in a container (or on real machine) and observes /dev/null to be replaced by regular file.

Trigger command:

CCACHE_HARDLINK=1 /usr/lib/ccache/bin/cc -Werror -Wmaybe-uninitialized -S -x c /dev/null -o /dev/null

Kernel's build ssystem probably just probes flag support and redirects unused output to /dev/null.

On my system strace confirms rename attempt. It fails to damage my system only because /dev/null is a mountpoint for me:

# ls -l /dev/null; id; CCACHE_HARDLINK=1 strace -y -f /usr/lib/ccache/bin/cc  -Werror -Wmaybe-uninitialized -S -x c /dev/null -o /dev/null |& egrep 'rename.*null' ; ls -l /dev/null
crw-rw-rw- 1 root root 1, 3 Mar 16 22:17 /dev/null
uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel),11(floppy),20(dialout),26(tape),27(video)
rename("/root/.ccache/tmp/null.stdout.sf.17002.qbbtTO", "/root/.ccache/tmp/null.stdout.sf.17002.qbbtTO.i") = 0
rename("/dev/null", "/dev/null.rm.sf.17002.XXXXXX") = -1 EBUSY (Device or resource busy)
crw-rw-rw- 1 root root 1, 3 Mar 16 22:17 /dev/null

In upstream bug user observed successful rename():

rename("/dev/null", "/dev/null.rm.akira.261700.XXXXXX") = 0
unlink("/dev/null.rm.akira.261700.XXXXXX") = 0
...

Would it be reasonable for ccache not to try moving special files around even in CCACHE_HARDLINK=1 mode (or maybe handle /dev/null in a special way that does not require writes into target). Or should this behaviour be declared Intended Behaviour?

Thanks!

@trofi trofi added the bug Does not work as intended/documented label Mar 16, 2020
@jrosdahl jrosdahl added this to the 3.7.9 milestone Mar 22, 2020
jrosdahl added a commit to jrosdahl/ccache that referenced this issue Mar 22, 2020
When hard link mode is enabled, ccache ≥3.6 unlinks the output file
before writing to it as a workaround for a bug in Clang (ccache#331). This
unfortunately means that /dev/null will be removed when building as root
(don’t do that, BTW) with hard link mode enabled and /dev/null as the
the output file.

Fix this by disabling hard link mode if the output object file is
/dev/null and by not copying cached output to /dev/null at all, thus not
triggering unlink-before-write for other files (e.g. dependency file) as
well. (There is no need to handle other non-regular output files since
/dev/null is the only allowed non-regular output file.)

Fixes ccache#564.
jrosdahl added a commit to jrosdahl/ccache that referenced this issue Mar 22, 2020
When hard link mode is enabled, ccache ≥3.6 unlinks the output file
before writing to it as a workaround for a bug in Clang (ccache#331). This
unfortunately means that /dev/null will be removed when building as root
(don’t do that, BTW) with hard link mode enabled and /dev/null as the
the output file. A similar problem exists if the dependency file is
/dev/null, regardless of hard link mode.

Fix this by not unlinking the output file if it’s /dev/null and by not
copying files to /dev/null at all. (There is no need to handle other
non-regular output files since /dev/null is the only allowed non-regular
output file.)

Fixes ccache#564.
jrosdahl added a commit to jrosdahl/ccache that referenced this issue Mar 22, 2020
When hard link mode is enabled, ccache ≥3.6 unlinks the output file
before writing to it as a workaround for a bug in Clang (ccache#331). This
unfortunately means that /dev/null will be removed when building as root
(don’t do that, BTW) with hard link mode enabled and /dev/null as the
the output file. A similar problem exists if the dependency file is
/dev/null, regardless of hard link mode.

Fix this by not unlinking the output file if it’s /dev/null and by not
copying files to /dev/null at all. (There is no need to handle other
non-regular output files since /dev/null is the only allowed non-regular
output file.)

Fixes ccache#564.
@jrosdahl
Copy link
Member

Fixed by 9a79468 on 3.7-maint and 1905d63 on master.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Does not work as intended/documented
Projects
None yet
Development

No branches or pull requests

2 participants