Skip to content

when keyring returns ENOENT, treat it as ENOKEY#94

Merged
Foxboron merged 1 commit intoFoxboron:masterfrom
Mic92:load-key-error
Jun 3, 2025
Merged

when keyring returns ENOENT, treat it as ENOKEY#94
Foxboron merged 1 commit intoFoxboron:masterfrom
Mic92:load-key-error

Conversation

@Mic92
Copy link
Contributor

@Mic92 Mic92 commented Jun 2, 2025

I get this error on this kernel:

Jun 02 15:26:27 turingmachine systemd[2442]: Started SSH Agent.
Jun 02 15:26:27 turingmachine ssh-tpm-agent[110960]: time=2025-06-02T15:26:27.740+02:00 level=INFO msg="Activated agent by socket"
Jun 02 15:27:00 turingmachine ssh-tpm-agent[110960]: time=2025-06-02T15:27:00.135+02:00 level=INFO msg="agent 13: failed getting pin for key: no such file or directory"

$ uname -a
Linux turingmachine 6.14.8 #1-NixOS SMP PREEMPT_DYNAMIC Thu May 22 12:31:58 UTC 2025 x86_64 GNU/Linux

It overall seems that caching doesn't seem to work for me with the kernel, but it's better to be able to type in the password instead of breaking ssh-agent-tpm

Open for better suggestions, but I need to have something working now, so I will use this patch until than.

@Foxboron
Copy link
Owner

Foxboron commented Jun 2, 2025

I think this makes sense. I'm still a bit unsure why this sometimes return ENOENT. But it could be that the kernel does not have the platform keyring or process keyring established?

Or ssh-tpm-agent is not allowed to make a process keyring?

@Mic92
Copy link
Contributor Author

Mic92 commented Jun 2, 2025

Here is the strace output.

139929 munmap(0x7fb390000000, 48234496) = 0
139929 mprotect(0x7fb38c000000, 135168, PROT_READ|PROT_WRITE) = 0
139929 rt_sigprocmask(SIG_SETMASK, ~[KILL STOP RTMIN RT_1], NULL, 8) = 0
139929 sigaltstack(NULL, {ss_sp=NULL, ss_flags=SS_DISABLE, ss_size=0}) = 0
139929 sigaltstack({ss_sp=0xc000204000, ss_flags=0, ss_size=32768}, NULL) = 0
139929 rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
139929 gettid()                         = 139929
139929 futex(0xc000200148, FUTEX_WAIT_PRIVATE, 0, NULL <unfinished ...>
139922 <... nanosleep resumed>NULL)     = 0
139922 futex(0xb6f580, FUTEX_WAIT_PRIVATE, 0, {tv_sec=60, tv_nsec=0} <unfinished ...>
139923 <... epoll_pwait resumed>[{events=EPOLLIN, data=0x7fb3b5bc9e100002}], 128, -1, NULL, 0) = 1
139923 futex(0xb6f580, FUTEX_WAKE_PRIVATE, 1) = 1
139922 <... futex resumed>)             = 0
139923 accept4(3,  <unfinished ...>
139922 nanosleep({tv_sec=0, tv_nsec=20000},  <unfinished ...>
139923 <... accept4 resumed>{sa_family=AF_UNIX}, [112 => 2], SOCK_CLOEXEC|SOCK_NONBLOCK) = 4
139922 <... nanosleep resumed>NULL)     = 0
139923 epoll_ctl(5, EPOLL_CTL_ADD, 4, {events=EPOLLIN|EPOLLOUT|EPOLLRDHUP|EPOLLET, data=0x7fb3b5bc9cf80002} <unfinished ...>
139922 nanosleep({tv_sec=0, tv_nsec=20000},  <unfinished ...>
139923 <... epoll_ctl resumed>)         = 0
139922 <... nanosleep resumed>NULL)     = 0
139923 getsockname(4,  <unfinished ...>
139922 nanosleep({tv_sec=0, tv_nsec=20000},  <unfinished ...>
139923 <... getsockname resumed>{sa_family=AF_UNIX, sun_path="/run/user/1000/ssh-tpm-agent.sock"}, [112 => 36]) = 0
139923 futex(0xc000200148, FUTEX_WAKE_PRIVATE, 1 <unfinished ...>
139922 <... nanosleep resumed>NULL)     = 0
139923 <... futex resumed>)             = 1
139929 <... futex resumed>)             = 0
139922 nanosleep({tv_sec=0, tv_nsec=20000},  <unfinished ...>
139923 accept4(3, 0xc00009cc34, [112], SOCK_CLOEXEC|SOCK_NONBLOCK) = -1 EAGAIN (Resource temporarily unavailable)
139923 read(4,  <unfinished ...>
139929 epoll_pwait(5,  <unfinished ...>
139922 <... nanosleep resumed>NULL)     = 0
139923 <... read resumed>"\0\0\1\376", 4) = 4
139922 nanosleep({tv_sec=0, tv_nsec=20000},  <unfinished ...>
139923 read(4,  <unfinished ...>
139929 <... epoll_pwait resumed>[{events=EPOLLIN|EPOLLOUT, data=0x7fb3b5bc9cf80002}], 128, 0, NULL, 0) = 1
139923 <... read resumed>"\33\0\0\0\30session-bind@openssh.com\0\0\1"..., 510) = 510
139922 <... nanosleep resumed>NULL)     = 0
139923 write(4, "\0\0\0\1", 4 <unfinished ...>
139929 epoll_pwait(5,  <unfinished ...>
139923 <... write resumed>)             = 4
139922 nanosleep({tv_sec=0, tv_nsec=20000},  <unfinished ...>
139923 write(4, "\5", 1 <unfinished ...>
139929 <... epoll_pwait resumed>[{events=EPOLLOUT, data=0x7fb3b5bc9cf80002}], 128, -1, NULL, 0) = 1
139923 <... write resumed>)             = 1
139923 read(4,  <unfinished ...>
139922 <... nanosleep resumed>NULL)     = 0
139923 <... read resumed>"\0\0\0\1", 4) = 4
139929 epoll_pwait(5,  <unfinished ...>
139922 nanosleep({tv_sec=0, tv_nsec=20000},  <unfinished ...>
139923 read(4, "\v", 1)                 = 1
139929 <... epoll_pwait resumed>[{events=EPOLLOUT, data=0x7fb3b5bc9cf80002}], 128, 0, NULL, 0) = 1
139923 write(4, "\0\0\0\210", 4 <unfinished ...>
139922 <... nanosleep resumed>NULL)     = 0
139923 <... write resumed>)             = 4
139922 nanosleep({tv_sec=0, tv_nsec=20000},  <unfinished ...>
139929 epoll_pwait(5,  <unfinished ...>
139923 write(4, "\f\0\0\0\1\0\0\0h\0\0\0\23ecdsa-sha2-nistp256"..., 136 <unfinished ...>
139929 <... epoll_pwait resumed>[{events=EPOLLOUT, data=0x7fb3b5bc9cf80002}], 128, -1, NULL, 0) = 1
139929 epoll_pwait(5,  <unfinished ...>
139923 <... write resumed>)             = 136
139929 <... epoll_pwait resumed>[{events=EPOLLOUT, data=0x7fb3b5bc9cf80002}], 128, 0, NULL, 0) = 1
139923 read(4,  <unfinished ...>
139922 <... nanosleep resumed>NULL)     = 0
139929 epoll_pwait(5,  <unfinished ...>
139923 <... read resumed>0xc000122620, 4) = -1 EAGAIN (Resource temporarily unavailable)
139922 nanosleep({tv_sec=0, tv_nsec=20000},  <unfinished ...>
139923 futex(0xc000093148, FUTEX_WAIT_PRIVATE, 0, NULL <unfinished ...>
139922 <... nanosleep resumed>NULL)     = 0
139922 futex(0xb6f580, FUTEX_WAIT_PRIVATE, 0, {tv_sec=60, tv_nsec=0} <unfinished ...>
139929 <... epoll_pwait resumed>[{events=EPOLLIN|EPOLLOUT, data=0x7fb3b5bc9cf80002}], 128, -1, NULL, 0) = 1
139929 futex(0xb6f580, FUTEX_WAKE_PRIVATE, 1) = 1
139922 <... futex resumed>)             = 0
139922 sched_yield( <unfinished ...>
139929 read(4,  <unfinished ...>
139922 <... sched_yield resumed>)       = 0
139922 nanosleep({tv_sec=0, tv_nsec=20000},  <unfinished ...>
139929 <... read resumed>"\0\0\2\304", 4) = 4
139929 read(4, "\r\0\0\0h\0\0\0\23ecdsa-sha2-nistp256\0\0\0\10"..., 708) = 708
139922 <... nanosleep resumed>NULL)     = 0
139922 nanosleep({tv_sec=0, tv_nsec=20000},  <unfinished ...>
139929 futex(0xc000093148, FUTEX_WAKE_PRIVATE, 1) = 1
139922 <... nanosleep resumed>NULL)     = 0
139929 futex(0xc000093948, FUTEX_WAKE_PRIVATE, 1 <unfinished ...>
139923 <... futex resumed>)             = 0
139929 <... futex resumed>)             = 1
139924 <... futex resumed>)             = 0
139922 nanosleep({tv_sec=0, tv_nsec=20000},  <unfinished ...>
139929 futex(0xc000200148, FUTEX_WAIT_PRIVATE, 0, NULL <unfinished ...>
139923 epoll_pwait(5,  <unfinished ...>
139924 request_key("user", "SHA256:Lhseyva2tRG4mrdjP04BUwPCY"..., "", 444320480 <unfinished ...>
139922 <... nanosleep resumed>NULL)     = 0
139923 <... epoll_pwait resumed>[], 128, 0, NULL, 0) = 0
139922 nanosleep({tv_sec=0, tv_nsec=20000},  <unfinished ...>
139923 epoll_pwait(5,  <unfinished ...>
139922 <... nanosleep resumed>NULL)     = 0
139924 <... request_key resumed>)       = -1 ENOENT (No such file or directory)
139922 nanosleep({tv_sec=0, tv_nsec=20000},  <unfinished ...>
139924 futex(0xc000200148, FUTEX_WAKE_PRIVATE, 1 <unfinished ...>
139929 <... futex resumed>)             = 0
139924 <... futex resumed>)             = 1
139929 nanosleep({tv_sec=0, tv_nsec=3000},  <unfinished ...>
139922 <... nanosleep resumed>NULL)     = 0
139929 <... nanosleep resumed>NULL)     = 0
139924 futex(0xc0000c2148, FUTEX_WAKE_PRIVATE, 1 <unfinished ...>
139929 futex(0xc000100148, FUTEX_WAKE_PRIVATE, 1 <unfinished ...>
139922 nanosleep({tv_sec=0, tv_nsec=20000},  <unfinished ...>
139929 <... futex resumed>)             = 1
139928 <... futex resumed>)             = 0
139925 <... futex resumed>)             = 0
139924 <... futex resumed>)             = 1
139928 futex(0xc0000c2148, FUTEX_WAIT_PRIVATE, 0, NULL <unfinished ...>
139925 futex(0xc000100148, FUTEX_WAIT_PRIVATE, 0, NULL <unfinished ...>
139922 <... nanosleep resumed>NULL)     = 0
139929 write(1, "time=2025-06-02T16:09:22.984+02:"..., 116 <unfinished ...>
139924 futex(0xc000093948, FUTEX_WAIT_PRIVATE, 0, NULL <unfinished ...>
139929 <... write resumed>)             = 116
139922 nanosleep({tv_sec=0, tv_nsec=20000},  <unfinished ...>
139929 write(4, "\0\0\0\1", 4 <unfinished ...>
139922 <... nanosleep resumed>NULL)     = 0
139929 <... write resumed>)             = 4
139922 nanosleep({tv_sec=0, tv_nsec=20000},  <unfinished ...>
139929 write(4, "\5", 1 <unfinished ...>
139923 <... epoll_pwait resumed>[{events=EPOLLOUT, data=0x7fb3b5bc9cf80002}], 128, -1, NULL, 0) = 1
139929 <... write resumed>)             = 1
139922 <... nanosleep resumed>NULL)     = 0
139929 read(4,  <unfinished ...>
139923 epoll_pwait(5,  <unfinished ...>
139929 <... read resumed>0xc000122620, 4) = -1 EAGAIN (Resource temporarily unavailable)
139922 nanosleep({tv_sec=0, tv_nsec=20000},  <unfinished ...>
139929 epoll_pwait(5,  <unfinished ...>
139923 <... epoll_pwait resumed>[{events=EPOLLOUT, data=0x7fb3b5bc9cf80002}], 128, 0, NULL, 0) = 1
139929 <... epoll_pwait resumed>[], 128, 0, NULL, 0) = 0
139922 <... nanosleep resumed>NULL)     = 0
139929 futex(0xc000200148, FUTEX_WAIT_PRIVATE, 0, NULL <unfinished ...>
139923 epoll_pwait(5,  <unfinished ...>
139922 futex(0xb6f580, FUTEX_WAIT_PRIVATE, 0, {tv_sec=60, tv_nsec=0} <unfinished ...>
139923 <... epoll_pwait resumed>[{events=EPOLLIN|EPOLLOUT|EPOLLHUP|EPOLLRDHUP, data=0x7fb3b5bc9cf80002}], 128, -1, NULL, 0) = 1
139923 futex(0xb6f580, FUTEX_WAKE_PRIVATE, 1) = 1
139922 <... futex resumed>)             = 0
139923 read(4,  <unfinished ...>
139922 nanosleep({tv_sec=0, tv_nsec=20000},  <unfinished ...>
139923 <... read resumed>"", 4)         = 0
139923 epoll_pwait(5,  <unfinished ...>
139922 <... nanosleep resumed>NULL)     = 0
139923 <... epoll_pwait resumed>[], 128, 0, NULL, 0) = 0
139922 nanosleep({tv_sec=0, tv_nsec=20000},  <unfinished ...>
139923 epoll_pwait(5,  <unfinished ...>
139922 <... nanosleep resumed>NULL)     = 0

You can see how request_key returns ENOENT.

@Mic92
Copy link
Contributor Author

Mic92 commented Jun 2, 2025

Mhm actually it seems to be expected that restarting ssh-tpm-agent resets the pin. So I think with this patch everything seems to work?

@Foxboron
Copy link
Owner

Foxboron commented Jun 2, 2025

Yes, killing the process should nuke the underlying process keyring we allocate for the cache. I suspect there is nothing wrong with the patch, I'm just confused why ENOENT are sometimes encountered.

@Mic92
Copy link
Contributor Author

Mic92 commented Jun 2, 2025

It's not sometimes but always for me.

@Foxboron
Copy link
Owner

Foxboron commented Jun 2, 2025

I'm thinking generally. Are you running a hardened kernel setup or a weird thing with nixos?

The issue has not been reported previously so i'm a bit at a loss.

@Mic92
Copy link
Contributor Author

Mic92 commented Jun 2, 2025

Pretty boring kernel with few patches:

nix-repl> linuxPackages_6_14.kernel.patches
[
  /home/joerg/git/nixpkgs/pkgs/os-specific/linux/kernel/bridge-stp-helper.patch
  /home/joerg/git/nixpkgs/pkgs/os-specific/linux/kernel/request-key-helper.patch
  /home/joerg/git/nixpkgs/pkgs/os-specific/linux/kernel/randstruct-provide-seed-5.19.patch
]

Here is the kernel config: https://gist.github.com/Mic92/1f2a7084be6278f38a64db31a5413b81

@Mic92
Copy link
Contributor Author

Mic92 commented Jun 2, 2025

Interesting:

~/git/nixpkgs main*
% ls -la /run/current-system/sw/bin/request-key
lsd: /run/current-system/sw/bin/request-key: No such file or directory (os error 2).

Maybe something is wrong here.

@Foxboron
Copy link
Owner

Foxboron commented Jun 2, 2025

The keyring subsystem is a bit interesting as they do some implicit calls to binaries when dealing with keys. It's a bit opaque to me how this exactly works.

@Foxboron
Copy link
Owner

Foxboron commented Jun 2, 2025

/home/joerg/git/nixpkgs/pkgs/os-specific/linux/kernel/request-key-helper.patch

Seems suspicious to me at least.

@Mic92 Mic92 force-pushed the load-key-error branch from 5546f4a to 3f3c55b Compare June 2, 2025 21:26
@Mic92
Copy link
Contributor Author

Mic92 commented Jun 2, 2025

After installing globally keyctl in NixOS, it works. Added some better error logging for users.

When keyctl is not available, the kernel keyring may return ENOENT
when trying to load a key. This commit adds a warning to inform the
user that the keyutils package is required for caching keys.
@Mic92 Mic92 force-pushed the load-key-error branch from 3f3c55b to 799365e Compare June 2, 2025 21:28
@Foxboron
Copy link
Owner

Foxboron commented Jun 2, 2025

After installing globally keyctl in NixOS, it works. Added some better error logging for users.

Then maybe that should be fixed in the test suite for ssh-tpm-agent instead of the sed patching in nixpkgs?

RE the patch.
I would maybe swap out the double if with a label and a goto? Does that feel less cloumsy? I can accept this regardless and fix it up later. I don't particularly mind.

@Foxboron Foxboron mentioned this pull request Jun 2, 2025
@Mic92
Copy link
Contributor Author

Mic92 commented Jun 2, 2025

Maybe we should in NixOS just have keyutils always installed by default, because builds like this would fail otherwise. At least on builders that need to build software.

@Foxboron
Copy link
Owner

Foxboron commented Jun 2, 2025

Regardless, I'm happy we solved this as we should handle this gracefully in ssh-tpm-agent :)

@Mic92
Copy link
Contributor Author

Mic92 commented Jun 3, 2025

RE the patch. I would maybe swap out the double if with a label and a goto? Does that feel less cloumsy? I can accept this regardless and fix it up later. I don't particularly mind.

Would love to implement that but don't know how you exactly envision that to look like. My attempt doesn't really seem to improve.

@Foxboron
Copy link
Owner

Foxboron commented Jun 3, 2025

That's fine. I'll merge this as-is and clean it up if I feel like it :) thanks for the patch!

@Foxboron Foxboron merged commit 5be6003 into Foxboron:master Jun 3, 2025
5 checks passed
@Foxboron
Copy link
Owner

Foxboron commented Jun 3, 2025

switch/case seemed cleaner to me.

9f1332b

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.

2 participants

Comments