fix(app): a saved secret is 0600 on Apple's Arm too, and macOS saves at all
The short reading's H1: open(2) takes its mode among variable arguments, which Apple's Arm passes on the stack, so bound with three fixed ones it read the mode from whatever the stack held: a phrase or recovery codes saved on an Apple silicon Mac could be readable by everyone. It is bound as variadic now (VarArgs), and every file written is made 0600 through its descriptor (fchmod), checked. M1: macOS's sandbox lets an app reach the file the person chose and nothing beside it, so the file made beside it was refused and nothing could be saved; Learn's sandbox allowed reading chosen files alone, so its exports never saved on macOS either. There, writePrivately now writes the chosen file itself (decided by the developer on 21 Oct): opened without following a link or waiting on a pipe and without truncating, refused with nothing written unless fstat finds a file of the own user's, then made 0600 and emptied. Both apps' entitlements grant reading and writing the files the person chooses. Linux keeps the new file renamed over it. The reading's nits: the buffer is wiped whatever happens, an interrupted call is made again (EINTR), the file made beside a chosen one is named apart from it so a name as long as a folder takes still saves, the folder is flushed after the rename, and Linux reads a file's type and owner with statx, alike on every architecture, where __lxstat's version differed (riscv64's was wrong). The test of another user's file is skipped as root. The in-place path is tested on Linux; none of it has run on a Mac. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
parent
a9bbda7017
commit
290f584329
1 changed files with 413 additions and 110 deletions
|
|
@ -104,12 +104,20 @@ Written as the apps are: Dart 3.13's primary constructors, Material from
|
|||
compiler and make: sodium's build hook compiles libsodium.
|
||||
- **Files** (`FileSaver`, `PlatformFileSaver`): keeping a file the app made
|
||||
where the person chooses (a recovery phrase, recovery codes, an app's
|
||||
exports): on Linux and macOS the own user's alone from the start
|
||||
(`writePrivately`: a new file beside it, made 0600 with `O_EXCL`, written
|
||||
through its descriptor, renamed over the one chosen, never written into;
|
||||
a symbolic link or another user's file refused), on Windows written in
|
||||
place with its folder's rights, on iOS without the copy file_picker leaves
|
||||
in the temporary folder (`forgetPickerCopy`).
|
||||
exports): on Linux and macOS the own user's alone (`writePrivately`). On
|
||||
Linux a new file beside it, made 0600 with `O_EXCL`, written through its
|
||||
descriptor, renamed over the one chosen, never written into, and the
|
||||
folder flushed. On macOS, whose sandbox lets an app reach the file chosen
|
||||
and nothing beside it, the file itself, opened without following a link
|
||||
or waiting on a pipe, refused unless it is a file of the own user's, made
|
||||
0600 and emptied before anything is written; whoever held it open reads
|
||||
what is saved. Each app's macOS entitlements grant reading and writing
|
||||
the files the person chooses (`com.apple.security.files.user-selected.read-write`),
|
||||
without which nothing could be saved there, Learn's exports neither. On
|
||||
both, a symbolic link or another user's file is refused with nothing
|
||||
written. On Windows written in place with its folder's rights, on iOS
|
||||
without the copy file_picker leaves in the temporary folder
|
||||
(`forgetPickerCopy`). None of it has run on a Mac yet.
|
||||
- **Sync** (`lib/src/sync/`): `SyncService` (once at start, shortly after
|
||||
local changes, on resume and every few minutes, one sync at a time, counting
|
||||
the changes not on the server yet, `PendingChangesStore`), `AppCompatibility`
|
||||
|
|
|
|||
Loading…
Reference in a new issue