`EACCES` is returned if the file mode bit (i.e., user/group/other rwx
bits) disallow access. `EPERM` is returned if something else denies
access (immutable bit, SELinux, capabilities, etc). This somewhat subtle
no-access distinction is part of POSIX. For now map both to
`error.PermissionDenied` to keep the error signature unchanged. See
duopoly.
This PR is effecitvely an update/simplification of PR #19193.
Tested locally with an immutable file.
Fixes#22733 and #19162.
readAtLeast is greedy and will read the entire length of the buffer if it can. However, reading past the end of the cert in this case is useless, so reading the full length of the buffer just puts an increasingly large (due to the growth algorithm of ArrayList) collection of wasted bytes after each cert in cb.bytes.
In practical terms, this ends up saving potentially millions of bytes of wasted reads/allocations. In my testing, after reading the keychain files on my machine, cb.bytes ends up with these capacities:
- Before: cb.bytes.capacity = 32720747
- After: cb.bytes.capacity = 251937
That's a decrease of 99.2%
Additionally, swaps to readNoEof since it should be an error to hit EOF without reading the full cert size.
* std.crypto: add the ability to explicitly tag a value as secret
It turns out that Valgrind can be a very useful tool to check that secrets
are not leaked via side channels involving lookups or conditional jumps.
Valgrind tracks uninitialized data, and memcheck reports operations
involving uninitialized values. By permanently or temporarily telling
Valgrind that a memory region containing secrets is uninitialized, we can
detect common side-channel vulnerabilities.
For example, the following code snippets would immediately report that the
result is not computed in constant time:
```zig
classify(&key);
const len = std.mem.indexOfScalar(u8, &key, 0);
```
```zig
classify(&key);
const idx = key[0];
x += idx;
```
```zig
var x: [4]u8 = undefined;
std.crypto.random.bytes(&x);
classify(&x);
if (std.mem.eql(u8, "test", &x)) return;
```
This is not fool-proof, but it can help a lot to detect unwanted compiler
optimizations.
Also, right now, this is relying on Valgrind primitives, but these
annotations can be used to do more interesting things later, especially with
our own code generation backends.
* Update for Zig 0.14
* Remove checks for Valgrind enablement
Four tests in lib/std/posix/test.zig were disabled because they created
fixed-name files in the current working directory, and this caused
problems if tests were running in parallel with other build's tests.
This PR fixes those tests to all use `std.testing.tmpDir` to create unique
temporary names and directories.
Also clean the tests up to more consistently use `defer` to clean up, or
to just rely on tmpDir cleanup to remove individual files.
Working on these tests revealed a bunch of stale WASI code paths in
posix.zig, fixed by replacing stale `wast.AT.FDCWD` references with just
`AT.FDCWD`.
Fixes#14968.
* bcrypt: make silently_truncate_password a member of Params
This removes the need for having both `bcrypt()` and
`bcryptWithTruncation()` in the public API.
And whether truncation happens or not becomes even more explicit.
* Update crypto benchmark
In the original PR that implemented this (https://github.com/ziglang/zig/pull/14325), it included a list of references for the keychain format. Multiple of those references include the checks that are added in this commit, and empirically this fixes the loading of a real keychain file that was previously failing (it had both a record with offset 0 and a record with cert_size 0).
Fixes#22870
Functions like isMinGW() and isGnuLibC() have a good reason to exist: They look
at multiple components of the target. But functions like isWasm(), isDarwin(),
isGnu(), etc only exist to save 4-8 characters. I don't think this is a good
enough reason to keep them, especially given that:
* It's not immediately obvious to a reader whether target.isDarwin() means the
same thing as target.os.tag.isDarwin() precisely because isMinGW() and similar
functions *do* look at multiple components.
* It's not clear where we would draw the line. The logical conclusion before
this commit would be to also wrap Arch.isX86(), Os.Tag.isSolarish(),
Abi.isOpenHarmony(), etc... this obviously quickly gets out of hand.
* It's nice to just have a single correct way of doing something.
* arm_apcs is the long dead "OABI" which we never had working support for.
* arm_aapcs16_vfp is for arm-watchos-none which is a dead target that we've
dropped support for.
In the MAC finalization function, concatenated tags at odd positions
were not absorbed into the correct lane.
Spotted by a Tigerbeetle regression test and reported by Rafael Batiati
(@batiati) — Thanks!
The check is not needed, since we are already checking for the os
at line 847 and returning at 916 when the check succeeds.
Therefore, at 926, we know the os is not windows.
breaking change to the fuzz testing API; it now passes a type-safe
context parameter to the fuzz function.
libfuzzer is reworked to select inputs from the entire corpus.
I tested that it's roughly as good as it was before in that it can find
the panics in the simple examples, as well as achieve decent coverage on
the tokenizer fuzz test.
however I think the next step here will be figuring out why so many
points of interest are missing from the tokenizer in both Debug and
ReleaseSafe modes.
does not quite close#20803 yet since there are some more important
things to be done, such as opening the previous corpus, continuing
fuzzing after finding bugs, storing the length of the inputs, etc.