Skip to content

Two soundness fixes based on KEYCTL_READ interface misunderstanding - #23

Open
197g wants to merge 2 commits into
landhb:mainfrom
197g:main
Open

197g wants to merge 2 commits into
landhb:mainfrom
197g:main

Conversation

@197g

@197g 197g commented Nov 3, 2026 •

Copy link
Copy Markdown

The method always returns the actual size of the underlying item. It was used instead similar to read where it indicates the filled buffer size. Treating it as such, and in consequence trusting it to not exceed the passed-in capacity, is incorrect. See commit descriptions for details.

I've add tests that utilize the Thread and Process keyring since I really don't like any of them potentially polluting my persistent session keyring during development. That just makes results of reading from either of these potentially flaky. I'd update the other tests but that's out of scope for a security relevant PR.

At least for get_links the misunderstanding of the argument and result seem to have propagated into the test design. The capacity arguments are commonly the magic constant 200, the selection of which masked both the out-of-bounds problem of Vec::set_len—due to most rings being much smaller—and the semantic disagreement of its unit being bytes and not keycounts. If there's a learning here you're in a better position to propagate it across the code base.

Fixes: #22

197g added 2 commits November 3, 2026 10:07
The safe traits AsMut/AsRef place no strict requirements on their
implementations to provide a stable result, i.e. dereference to the same
buffer when called multiple times. It's thus always wrong to recombine
the results from two separate calls, especially address and length data
when their Target is a slice. Instead, the buffer must be queried once
and that slice be retained.
Two counts: the size of the buffer passed was not its length in bytes
but its item count, making the kernel only fill it at most partially.
The kernel enforces that the length is a multiple of the identifier size
for keyrings (it won't partially write IDs with unclear endianess).

More crucially, we'd trust the returned length when in reality the
*actual* length of the keyring is returned and *not* the filled size as
with a call to `read`. This would lead to a `Vec`'s length exceeding its
capacity and thus an out of bounds reference in the later iteration.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Out-of-bounds read in KeyRing::get_links when the buffer is too small

1 participant