-
-
Notifications
You must be signed in to change notification settings - Fork 32.5k
Description
- Version: v14.15.4
- Platform: Linux 4.19.0-11-amd64 deps: update openssl to 1.0.1j #1 SMP Debian 4.19.146-1 (2020-09-17) x86_64 Linux
- Subsystem: fs
What steps will reproduce the bug?
if I have an external mount (in my case a cephfs cluster mounted using ceph-fuse
), then copying a file into it will fail with permission denied if the source file is read-only.
Simple code to reproduce the issue :
const fs = require("fs");
fs.copyFileSync("/tmp/foo", "/ceph-mount/tmp/bar");
Doing a touch /tmp/foo && chmod -w /tmp/foo
before running the script will allow you to reproduce the error. The above code will fail as long as the source file is read-only, even if the file can be copied in the shell.
(note, it might work with an NFS mount or some other type of mount, but have only tested with my cephfs mount. A local ext4fs mount does not seem to be affected by the problem).
Also note that this works with Node 12.18.4. I actually noticed this issue a little while ago when I reinstalled one of my systems, and ended up with node 12.19.0 and my app started failing to copy files from a read-only file system and I was forced to downgrade to 12.18.3 where it was known to be working as expected. Today, I confirmed the bug is still there in node 14.15.4.
Using this command docker run --rm -it -v /ceph-mount/:/ceph-mount node:12.19.0-alpine /bin/sh
to run node then pasting these commands in it will show the problem :
su - node
touch /tmp/foo
chmod -w /tmp/foo
cat <<EOF > test.js
const fs = require("fs");
fs.copyFileSync("/tmp/foo", "/ceph-mount/tmp/bar");
EOF
rm -f /ceph-mount/tmp/bar
node test.js
exit
exit
How often does it reproduce? Is there a required condition?
100% reproducible on node 12.19.0 up to 14.15.4, 0% reproducible on node 12.18.4
What is the expected behavior?
the fs.copyFile
should be able to succeed in copying the file as long as the destination folder is writable.
What do you see instead?
The output is :
internal/fs/utils.js:269
throw err;
^
Error: EACCES: permission denied, copyfile '/tmp/foo' -> '/ceph-mount/tmp/bar'
at Object.copyFileSync (fs.js:1904:3)
at Object.<anonymous> (/home/node/test.js:2:4)
at Module._compile (internal/modules/cjs/loader.js:1015:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1035:10)
at Module.load (internal/modules/cjs/loader.js:879:32)
at Function.Module._load (internal/modules/cjs/loader.js:724:14)
at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:60:12)
at internal/main/run_main_module.js:17:47 {
errno: -13,
syscall: 'copyfile',
code: 'EACCES',
path: '/tmp/foo',
dest: '/ceph-mount/tmp/bar'
}
Here are screenshots showing the above running on node 12.19.0 as well as 12.18.4 to prove that the bug was introduced in the 12.19.x branch :
And a screenshot showing it with node 14.15.4 proving that a cp
in the shell works as well (this is on another system, the /forge-vtt-dev/
folder is the cephfs mount):
This also shows a second bug where it's unable to overwrite the file if it already exists, and I'm about to file another issue for it.