Skip to content

--allow-all required for reading from /dev/shm #30979

@corrideat

Description

@corrideat

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:

  1. 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)
  2. The condition is unrecoverable and deno incorrectly prompts for the read permission when it apparently needs all.

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 +++

Metadata

Metadata

Assignees

No one assigned

    Labels

    permissionsrelated to --allow-* flags

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions