-
Notifications
You must be signed in to change notification settings - Fork 5.7k
Description
Version: Deno 2.5.3
As the title suggests, the --allow-all
permission seems to be required for reading from /dev/shm
. This seems to be a bug for two reasons:
- There doesn't seem to be a good reason why simple
read
permissions shouldn't work (if there is, I couldn't find existing issues about it or documentation) - The condition is unrecoverable and deno incorrectly prompts for the
read
permission when it apparently needsall
.
Furthermore, this seems unrelated to /dev/shm
being a tmpfs
mount. Using a different tmpfs
mountpoint works normally.
Note that node --permission --allow-fs-read='*' minimal.ts
works as expected, even on /dev/shm
.
Minimal example:
import { readFile } from 'node:fs/promises';
await readFile('./test.txt');
Running this with deno run ./minimal.ts
from /dev/shm
will result in the following:
% deno run ./minimal.ts
✅ Granted read access to "./test.txt".
error: Uncaught (in promise) NotCapable: Requires all access to "/dev/shm/reproduc/test.txt", run again with the --allow-all flag
await readFile('./test.txt');
^
at Object.readFile (ext:deno_fs/30_fs.js:755:24)
at readFile (ext:deno_node/_fs/_fs_readFile.ts:34:14)
at ext:deno_node/_fs/_fs_readFile.ts:50:5
at new Promise (<anonymous>)
at readFilePromise (ext:deno_node/_fs/_fs_readFile.ts:49:10)
at file:///dev/shm/reproduc/minimal.ts:3:7
Note that in that case (no special permission flags given), Deno will prompt for 'read' permission, as shown below, and then fail, as shown above:
┏ ⚠️ Deno requests read access to "./test.txt".
┠─ Requested by `Deno.readFile()` API.
┠─ To see a stack trace for this prompt, set the DENO_TRACE_PERMISSIONS environmental variable.
┠─ Learn more at: https://docs.deno.com/go/--allow-read
┠─ Run again with --allow-read to bypass this prompt.
┗ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all read permissions) >
With -R
(--allow-read
), it won't prompt and will immediately fail:
% deno run -R ./minimal.ts
error: Uncaught (in promise) NotCapable: Requires all access to "/dev/shm/reproduc/test.txt", run again with the --allow-all flag
await readFile('./test.txt');
^
at Object.readFile (ext:deno_fs/30_fs.js:755:24)
at readFile (ext:deno_node/_fs/_fs_readFile.ts:34:14)
at ext:deno_node/_fs/_fs_readFile.ts:50:5
at new Promise (<anonymous>)
at readFilePromise (ext:deno_node/_fs/_fs_readFile.ts:49:10)
at file:///dev/shm/reproduc/minimal.ts:3:7
Instead, providing (-A
), --allow-all
does work:
% deno run -A ./minimal.ts
error: Uncaught (in promise) Error: ENOENT: no such file or directory, open './test.txt'
at __node_internal_captureLargerStackTrace (ext:deno_node/internal/errors.ts:90:3)
at __node_internal_uvException (ext:deno_node/internal/errors.ts:183:10)
at denoErrorToNodeError (ext:deno_node/internal/errors.ts:1913:14)
at ext:deno_node/_fs/_fs_readFile.ts:42:24
% touch test.txt
% deno run -A ./minimal.ts; echo exit: $?
exit: 0
Inspecting strace
in case there was anything useful there, it seems like there isn't, and that Deno fails due to some runtime check that rejects the read. This is the relevant part of an strace
diff, running with --read-all
from /dev/shm
(log1) and from a different location (log2)
strace diff
--- log1.d 2025-10-12 20:06:39.528716281 +0000
+++ log2.d 2025-10-12 20:07:21.928716281 +0000
@@ -1,55 +1,158 @@
- write(4, 0x7ffd004219e0, 8) = 8
- fcntl(15, F_SETLK, 0x7ffd00421750) = 0
- fcntl(15, F_SETLK, 0x7ffd00421860) = 0
- pread64(12, 0x55a920393b18, 4096, 193696) = 4096
- pread64(12, 0x55a920394c38, 4096, 111296) = 4096
- pread64(12, 0x55a9203ca478, 4096, 156616) = 4096
- pwrite64(12, 0x7ffd004216f0, 24, 197792) = 24
- pwrite64(12, 0x7f7224010e38, 4096, 197816) = 4096
- pwrite64(12, 0x7ffd004216f0, 24, 201912) = 24
- pwrite64(12, 0x55a92038d988, 4096, 201936) = 4096
- pwrite64(12, 0x7ffd004216f0, 24, 206032) = 24
- pwrite64(12, 0x55a9203ca478, 4096, 206056) = 4096
- pwrite64(12, 0x7ffd004216f0, 24, 210152) = 24
- pwrite64(12, 0x55a92041b398, 4096, 210176) = 4096
- pwrite64(12, 0x7ffd004216f0, 24, 214272) = 24
- pwrite64(12, 0x55a920394c38, 4096, 214296) = 4096
- pwrite64(12, 0x7ffd004216f0, 24, 218392) = 24
- pwrite64(12, 0x55a9203cb598, 4096, 218416) = 4096
- pwrite64(12, 0x7ffd004216f0, 24, 222512) = 24
- pwrite64(12, 0x55a920393b18, 4096, 222536) = 4096
- pwrite64(12, 0x7ffd004216f0, 24, 226632) = 24
- pwrite64(12, 0x55a920369e38, 4096, 226656) = 4096
- fcntl(15, F_SETLK, 0x7ffd004217c0) = 0
- fcntl(15, F_SETLK, 0x7ffd004217e0) = 0
- write(4, 0x7ffd00425840, 8) = 8
- epoll_wait(3, 0x55a920245ac0, 1024, 986) = 1
- epoll_wait(3, [], 1024, 986) = 0
- epoll_wait(3, [], 1024, 9) = 0
- getcwd(0x55a92037e610, 512) = 18
- sigaltstack(0x7ffd00421768, NULL) = 0
- munmap(0x7f7259ec5000, 12288) = 0
- exit_group(-1) = ?
+ write(4, 0x7ffc124330e0, 8) = 8
+ write(4, 0x7ffc12436f40, 8) = 8
+ epoll_wait(3, 0x55c370363ac0, 1024, 939) = 1
+ epoll_wait(3, [], 1024, 939) = 0
+ epoll_wait(3, [], 1024, 60) = 0
+ getcwd(0x55c3703b3e90, 512) = 29
+ readlink(0x7ffc12431eb0, 0x7ffc12431a50, 1023) = -1 EINVAL (Invalid argument)
+ readlink(0x7ffc12431eb0, 0x7ffc12431a50, 1023) = -1 EINVAL (Invalid argument)
+ readlink(0x7ffc12431eb0, 0x7ffc12431a50, 1023) = -1 EINVAL (Invalid argument)
+ readlink(0x7ffc12431eb0, 0x7ffc12431a50, 1023) = -1 EINVAL (Invalid argument)
+ readlink(0x7ffc12431eb0, 0x7ffc12431a50, 1023) = -1 EINVAL (Invalid argument)
+ openat(AT_FDCWD, 0x7ffc12432230, O_RDONLY|O_NOFOLLOW|O_CLOEXEC) = 21
+ futex(0x7ffa706614c0, FUTEX_WAKE_PRIVATE, 1) = 1
+ <... futex resumed>) = 0
+ statx(21, 0x55c333a9ac38, AT_STATX_SYNC_AS_STAT|AT_EMPTY_PATH, STATX_ALL, 0x7ffa7065f9b0) = 0
+ epoll_wait(3, <unfinished ...>
+ lseek(21, 0, SEEK_CUR) = 0
+ read(21, "", 32) = 0
+ close(21) = 0
+ write(4, 0x7ffa7065fc70, 8 <unfinished ...>
+ <... epoll_wait resumed>0x55c370363ac0, 1024, 7105) = 1
+ <... write resumed>) = 8
+ futex(0x7ffa706614c0, FUTEX_WAIT_PRIVATE, 1, 0x7ffa7065fd20 <unfinished ...>
+ close(18) = 0
+ close(19) = 0
+ close(20) = 0
+ munmap(0x7ffa70018000, 278528) = 0
+ munmap(0x7ffa637ad000, 225280) = 0
+ gettid() = 3186654
+ gettid() = 3186654
+ gettid() = 3186654
+ mmap(0x21fc00120000, 131072, PROT_NONE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x21fc00120000
+ mmap(0x21fc00100000, 131072, PROT_NONE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x21fc00100000
+ munmap(0xe3c77b40000, 262144) = 0
+ munmap(0xd2d5d240000, 262144) = 0
+ munmap(0x81da1cc0000, 262144) = 0
+ munmap(0x35c437100000, 262144) = 0
+ munmap(0x2c0b8e340000, 262144) = 0
+ munmap(0x20348de80000, 262144) = 0
+ munmap(0x2f07c31c0000, 262144) = 0
+ munmap(0x716f9ac0000, 262144) = 0
+ munmap(0x2436684c0000, 262144) = 0
+ munmap(0x1cfcef600000, 262144) = 0
+ munmap(0x32c20f440000, 262144) = 0
+ munmap(0x894ee6c0000, 262144) = 0
+ munmap(0x3d3d60540000, 262144) = 0
+ munmap(0x2973696c0000, 262144) = 0
+ munmap(0x305e38740000, 262144) = 0
+ munmap(0x160c0bac0000, 262144) = 0
+ munmap(0x2d5b44340000, 262144) = 0
+ munmap(0x88d4be00000, 262144) = 0
+ munmap(0x31ad92e00000, 262144) = 0
+ munmap(0xfa24a840000, 262144) = 0
+ munmap(0x2b04af9c0000, 262144) = 0
+ munmap(0x37549c000000, 262144) = 0
+ munmap(0x37dc2df40000, 262144) = 0
+ munmap(0x675c8540000, 262144) = 0
+ munmap(0x1c2513c80000, 262144) = 0
+ munmap(0x114f4ecc0000, 262144) = 0
+ munmap(0x20b1c5140000, 126976) = 0
+ munmap(0x18d4a2800000, 262144) = 0
+ munmap(0x304927380000, 217088) = 0
+ mmap(0x7ffa4c020000, 16384, PROT_NONE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7ffa4c020000
+ mmap(0x7ffa4c024000, 16384, PROT_NONE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7ffa4c024000
+ mmap(0x7ffa4c028000, 16384, PROT_NONE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7ffa4c028000
+ mmap(0x7ffa4c02c000, 16384, PROT_NONE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7ffa4c02c000
+ munmap(0x7ffa635f4000, 266240) = 0
+ munmap(0x7ffa18000000, 536870912) = 0
+ futex(0x7ffa7025f4c0, FUTEX_WAKE_PRIVATE, 1) = 1
+ <... futex resumed>) = 0
+ futex(0x7ffa704604c0, FUTEX_WAKE_PRIVATE, 1 <unfinished ...>
+ stat(0x7ffa3c001b14, <unfinished ...>
+ <... futex resumed>) = 1
+ <... futex resumed>) = 0
+ futex(0x7ffa706614c0, FUTEX_WAKE_PRIVATE, 1 <unfinished ...>
+ <... stat resumed>0x7ffa7025d688) = 0
+ stat(0x7ffa40001b34, <unfinished ...>
+ <... futex resumed>) = 1
+ fcntl(9, F_SETLK, 0x7ffa7025d778 <unfinished ...>
+ <... futex resumed>) = 0
+ <... stat resumed>0x7ffa7045e688) = 0
+ write(4, 0x7ffc12433530, 8 <unfinished ...>
+ <... fcntl resumed>) = 0
+ <... write resumed>) = 8
+ fcntl(10, F_SETLK, 0x7ffa7045e778 <unfinished ...>
+ stat(0x7ffa38001ab4, <unfinished ...>
+ epoll_wait(3, <unfinished ...>
+ fsync(13 <unfinished ...>
+ <... fcntl resumed>) = 0
+ <... epoll_wait resumed>0x55c370363ac0, 1024, 7094) = 1
+ <... stat resumed>0x7ffa7065f688) = 0
+ <... fsync resumed>) = 0
+ fsync(16 <unfinished ...>
+ close(3 <unfinished ...>
+ fcntl(12, F_SETLK, 0x7ffa7065f778 <unfinished ...>
+ openat(AT_FDCWD, 0x7ffa7025d3a0, O_RDONLY|O_CLOEXEC <unfinished ...>
+ <... fsync resumed>) = 0
+ <... close resumed>) = 0
+ <... fcntl resumed>) = 0
+ <... openat resumed>) = 3
+ openat(AT_FDCWD, 0x7ffa7045e3a0, O_RDONLY|O_CLOEXEC <unfinished ...>
+ close(8 <unfinished ...>
+ fsync(3 <unfinished ...>
+ fsync(14 <unfinished ...>
+ <... openat resumed>) = 18
+ fsync(18 <unfinished ...>
+ <... fsync resumed>) = 0
+ <... close resumed>) = 0
+ <... fsync resumed>) = 0
+ sigaltstack(0x7ffc124371e8, <unfinished ...>
+ <... fsync resumed>) = 0
+ close(18 <unfinished ...>
+ close(3 <unfinished ...>
+ openat(AT_FDCWD, 0x7ffa7065f3a0, O_RDONLY|O_CLOEXEC <unfinished ...>
+ <... close resumed>) = 0
+ <... close resumed>) = 0
+ <... openat resumed>) = 3
+ fstat(10, <unfinished ...>
+ fstat(9, <unfinished ...>
+ <... fstat resumed>0x7ffa7045e550) = 0
+ fsync(3 <unfinished ...>
+ <... sigaltstack resumed>NULL) = 0
+ <... fstat resumed>0x7ffa7025d550) = 0
+ pread64(16, <unfinished ...>
+ munmap(0x7ffa74245000, 12288 <unfinished ...>
+ pread64(13, <unfinished ...>
+ <... fsync resumed>) = 0
+ <... munmap resumed>) = 0
+ <... pread64 resumed>0x7ffa3c001bc8, 4096, 131896) = 4096
+ <... pread64 resumed>0x7ffa40001bd8, 4096, 24776) = 4096
+ close(3 <unfinished ...>
+ pwrite64(9, 0x7ffa3c001bc8, 4096, 0 <unfinished ...>
+ exit_group(0 <unfinished ...>
+ pwrite64(10, 0x7ffa40001bd8, 4096, 32768 <unfinished ...>
+ <... close resumed>) = ? <unavailable>
+ <... exit_group resumed>) = ?
+ <... pwrite64 resumed>) = ?
+ <... pwrite64 resumed>) = ?
<... futex resumed>) = ?
<... futex resumed>) = ?
<... futex resumed>) = ?
- <... futex resumed>) = -1 (errno 18446744073709551385)
- <... futex resumed>) = ?
- <... futex resumed>) = ?
- +++ exited with 255 +++
<... futex resumed>) = ?
<... futex resumed>) = ?
<... futex resumed>) = ?
<... futex resumed>) = ?
- +++ exited with 255 +++
- +++ exited with 255 +++
- <... futex resumed>) = ?
- +++ exited with 255 +++
- +++ exited with 255 +++
- +++ exited with 255 +++
- +++ exited with 255 +++
- +++ exited with 255 +++
- +++ exited with 255 +++
- +++ exited with 255 +++
- +++ exited with 255 +++
-+++ exited with 255 +++
+ <... futex resumed>) = ?
+ +++ exited with 0 +++
+ +++ exited with 0 +++
+ +++ exited with 0 +++
+ +++ exited with 0 +++
+ +++ exited with 0 +++
+ +++ exited with 0 +++
+ +++ exited with 0 +++
+ +++ exited with 0 +++
+ +++ exited with 0 +++
+ +++ exited with 0 +++
+ +++ exited with 0 +++
++++ exited with 0 +++