Hacker Newsnew | past | comments | ask | show | jobs | submit | ebiggers's commentslogin

As someone who works on the Linux kernel's cryptography code, the regularly occurring AF_ALG exploits are really frustrating. AF_ALG, which was added to the kernel many years ago without sufficient review, should not exist. It's very complex, and it exposes a massive attack surface to unprivileged userspace programs. And it's almost completely unnecessary, as userspace already has its own cryptography code to use. The kernel's cryptography code is just for in-kernel users (for example, dm-crypt).

The algorithm being used in this exploit, "authencesn", is even an IPsec implementation detail, which never should have been exposed to userspace as a general-purpose en/decryption API.

If you're in charge of the configuration for a Linux kernel, I strongly recommend disabling all CONFIG_CRYPTO_USER_API_* kconfig options. This would have made this bug, and also every past and future AF_ALG bug, unexploitable. In the unlikely event that you find that it breaks any userspace programs on your system, please help migrate them to userspace crypto code! For some it's already been done. But in general, AF_ALG has actually never been used much in the first place, other than in exploits.

I don't think there's much other option. This sort of userspace API might have been sort of okay many years ago. But it just doesn't stand up in a world with syzbot, LLM-assisted bug discovery, etc.


As I did not know what AF_ALG is in the first place I've searched for it and found this here:

https://www.chronox.de/libkcapi/html/ch01s02.html

It states the following:

> There are several reasons for AF_ALG:

> * The first and most important item is the access to hardware accelerators and hardware devices whose technical interface can only be accessed from the kernel mode / supervisor state of the processor. Such support cannot be used from user space except through AF_ALG.

> * When using user space libraries, all key material and other cryptographic sensitive parameters remains in the calling application's memory even when the application supplied the information to the library. When using AF_ALG, the key material and other sensitive parameters are handed to the kernel. The calling application now can reliably erase that information from its memory and just use the cipher handle to perform the cryptographic operations. If the application is cracked an attacker cannot obtain the key material.

> * On memory constrained systems like embedded systems, the additional memory footprint of a user space cryptographic library may be too much. As the kernel requires the kernel crypto API to be present, reusing existing code should reduce the memory footprint.

I can't judge whether this is a good justification, but there is one.


You should take note that this is written by the person that wrote the bad patch.

So grain of salt.


I've said I'm not sure about the validity of that reasoning.

I've liked it nevertheless for context, as augmentation to parent's post.


I feel like it should be possible to fulfill these advantages with a minimal, not very complex API. I.e. the grandparent's comment about IPsec implementation details doesn't make the cut, but a hardware accelerated cipher implementation does.

Please don't rely on my judgement for this being safe for production, but after blacklisting the modules, the provided python exploit failed.

Check if the following are modules

  grep CONFIG_CRYPTO_USER_API /boot/config-$(uname -r)
If they are, you can try blacklisting them

  /etc/modprobe.d/blacklist-crypto-user-api.conf
  
  """
  blacklist af_alg
  blacklist algif_hash
  blacklist algif_skcipher
  blacklist algif_rng
  blacklist algif_aead

  install af_alg /bin/false
  install algif_hash /bin/false
  install algif_skcipher /bin/false
  install algif_rng /bin/false
  install algif_aead /bin/false
  """

  update-initramfs -u
Can anyone comment on the ramifications this?

Or

  zgrep CONFIG_CRYPTO_USER_API /proc/config.gz

If iwd, or cryptsetup with certain non-default algorithms, isn't being used on the system, you should be fine. Not many programs use AF_ALG. It's possible there are others I'm not aware of, but it's quite rare.

To be clear, general-purpose Linux distros generally can't disable these kconfig options yet, due to these cases. But there are many Linux systems that simply don't need this functionality.

A good project for someone to work on would be to fix iwd and cryptsetup to always use userspace crypto, as they should.


is CONFIG_CRYPTO_USER_API needed for hw acceleration for cryptsetup (dm-crypt) disk encryption ?

No, dm-crypt just calls the kernel's crypto code directly.

I can’t comment on the ramifications, except to note that elsewhere in the thread this appears to not break anything (whether it makes userspace crypto a little less safe is academic, but that doesn’t matter if we have an easy local root shell), but I can verify the above fix does protect Ubuntu 24.04 from the exploit.

Just reboot after applying this change.


For anyone wondering: AF_ALG is a Linux socket interface that exposes the kernel’s crypto API via file descriptors, using normal read(2)/write(2) calls for hashing and encryption.

I wonder can the kernel just remove it and distros put on a compatiability layer.

It's already a configurable option in the kernel which can be fully disabled by distros if they wanted to provide their own compatibility layer, or just not ship any software that has a hard dependency on it.

I was completely unaware of https://syzbot.org, thanks for sharing!

> syzbot system continuously fuzzes main Linux kernel branches and automatically reports found bugs to kernel mailing lists. syzbot dashboard shows current statuses of bugs. All syzbot-reported bugs are also CCed to syzkaller-bugs mailing list. Direct all questions to syzkaller@googlegroups.com.


The primary benefit of AF_ALG is IMHO when it's combined with kernel keyrings, i.e. ALG_SET_KEY_BY_KEY_SERIAL.

To steal from the sibling post:

> * When using user space libraries, all key material and other cryptographic sensitive parameters remains in the calling application's memory even when the application supplied the information to the library. When using AF_ALG, the key material and other sensitive parameters are handed to the kernel. The calling application now can reliably erase that information [...]

It's even more than this: you can do crypto ops in user space without ever even having the key to begin with.

[Ed.: that said, maybe AF_ALG should be locked behind some CAP_*]

[Ed.#2: that said^2, I'm putting this one on authencesn, not AF_ALG. It's the extended sequence number juggling that went poorly, not AF_ALG at large. I bet this might even blow up in some strange hardware scenarios, "network packet on PCIe memory" or something like that - I'm speculating, though.]


It doesn't seem to actually get used that way in practice. ALG_SET_KEY_BY_KEY_SERIAL didn't even appear until just a few years ago. And either way, if the interface allows you to overwrite the su binary, whether it theoretically could provide some other security benefit becomes kind of irrelevant.

It is being used that way:

https://github.com/opensourcerouting/frr/blob/2b48e4f97fb021...

And, sure, if it breaks system security it's pointless. But so did "dirty pipe".

I do agree the number of issues in AF_ALG is annoying, which is why I suggested a CAP_* restriction. Maybe CAP_SYS_ADMIN in init_ns, that's kinda the big hammer.


Better implemented as another user space process than in the kernel.

You can't access TPMs that way.

Most of the Linux kernel crypto is not touching the TPM. If there is a TPM task, only that code should be in kernel, and it should be accessed from user space by a process with the appropriate token.

Yes, AF_ALG is exposing too many things, like authencesn, which has zero reason for being userspace accessible. It's a crypto mode specific to IPsec.

However,

> it should be accessed from user space by a process with the appropriate token.

That is AF_ALG. The operations it offers are what you need for full coverage. The issues with it are two:

- usage specific crypto in the kernel implements the same interfaces, and it doesn't have a filter for that, as mentioned above. It's not offering too many operations, it's offering too many algorithms.

- it's trying to be fast. I guess people also want to use crypto accelerators through it. (Which is kinda related to TPMs, there is accelerator hardware with built-in protected key storage...)

The CVE we're looking at here is in the intersection of both of these.


Good

I think it would be reasonable to deprecate af_alg in favor of a character device. It's more accessible that way. The downside is that the maintainers hate adding new ioctls. I think that's fair. But I don't think a "regular" device node would cover the functionality userland expects.

That said, elsewhere ITT it's pointed out there are only a few use cases so far.


It does enable address space separation of secret keys from user space, which some people love:

https://blog.cloudflare.com/the-linux-kernel-key-retention-s...

https://www.youtube.com/watch?v=7djRRjxaCKk

https://www.youtube.com/watch?v=lvZaDE578yc

So it's not as simple as "should not exist". I agree though that there doesn't seem to be a valid need to expose authencesn to user space.

Disclosure: I'm co-maintaining crypto/asymmetric_keys/ in the kernel and the author/presenter in the first two links is another co-maintainer.


That can be done in userspace too -- different userspace processes have different address spaces too.

The fact that the first link recommends using keyctl() for RSA private keys is also "interesting", given that the kernel's implementation of RSA isn't hardened against timing attacks (but userspace implementations of RSA typically are).


The CloudFlare blog discusses that idea when they talk about having an "agent process" to hold cryptographic material, but they list drawbacks like having to develop two processes, implement a well-defined interface, and enforce ACLs. I'm not convinced that "developing two processes" is a reason not to do it, since the kernel is effectively just the second process now, but everything else makes sense.

It's unfortunate though since this is one thing I think Windows does decently well. The Windows crypto and TLS APIs do use a key isolation process by default (LSASS) and have a stable interface for other processes to use it [0]. I imagine systemd could implement something similar, but I also know that there are very strong opinions about adding more surface area to systemd.

[0] https://blackhat.com/docs/us-16/materials/us-16-Kambic-Cunni...


> the kernel's implementation of RSA isn't hardened against timing attacks

Cloudflare is using custom BoringSSL-based crypto code in the kernel:

https://lore.kernel.org/all/CALrw=nEyTeP=6QcdEvaeMLZEq_pYB9W...


Many things, such as ksmbd seems ill-advised when looked at from security. New AI driven exploits era will likely make projects more wary to adding functions.

Removing this will make the friendly spooks at NSA very sad....

How did it get in? Isn’t Linus known for being rightfully fussy about what makes it into the kernel?

Would be an interesting story.


Linus has had been fussy about maybe like 5% of the things because even then he couldn't keep up with the sheer volume. Nowadays it's more like 1‰

any idea what software this will break once I turn this kernel configuration off?

iwd is the main culprit (for systems that use it instead of wpa_supplicant).

I think cryptsetup / LUKS also requires it with some non-default options. With the default options, it works fine with the kconfigs disabled.

There's not much else, as far as I know. Normally programs just use a userspace library instead, such as OpenSSL.


This is a great example of why so few people want to be a Linux kernel maintainer. Not only is it largely a thankless "job" where you get blamed for issues you didn't cause and are expected to do much of the work on your own time, but you can potentially get a misleading hit piece published about you and posted to Hacker News just for doing your job.

IMO, what the maintainer did (taking authorship and crediting the original author/reporter via Reported-by, after rewriting the entire patch including the commit message) was in line with kernel conventions. The lines are a bit blurry, and I think keeping the original author/reporter as at least a Co-developer would also have been acceptable. Still, people sometimes complain if they are kept as the author or co-developer if their patch is rewritten, as they don't want to "own" that rewritten patch and take blame for any issues in it. So pick your poison.

Ideally, more time would have been taken to work with the original author/reporter to get their patch in shape. Unfortunately, there isn't always time for that. In this case, the bug was reported to security@kernel.org as a security vulnerability, so that throws much of the usual process out the window; it needed to be fixed quickly. The maintainer went out of their way to get it fixed quickly, in a better way, and even added unit tests for it later. The original author/reporter was credited in both the fix commit and the pull request merge commit. Also note that the maintainer's commit is dated June 7 and was merged into mainline on June 9. So AFAICS, it predated the original author/reporter sending a revised patch; it postdated only the first patch.


I agree in general (also things have tendency to escalate to unnecessary drama through re-posts and comments on the social networks) but:

> as a security vulnerability, so that throws much of the usual process out the window; it needed to be fixed quickly

Was not the bug reported originally six years ago?


It may have been, but security impact is often not recognized right away. The older report was not sent to security@kernel.org and did not include a root cause analysis.


How were you comparing ISA-L and libdeflate? For decompression I've found that the latest version of libdeflate is slightly faster than ISA-L.


My extended benchmarks [0] use the rapidgzip, igzip, gzip, and pigz command line utilities and simply redirect the output to /dev/null to minimize I/O write interference. That's where I got the comparison of igzip to "zlib" as it is used in pigz. I did not compare libdeflate very often to these benchmarks, but before posting my comment, I quickly ran "time libdeflate-gzip -f -k -d 4GiB-base64.gz" inside /dev/shm, which took 20s vs. 9s for igzip.

libdeflate-gzip is something I built and installed a while ago from libdeflate/programs/gzip.c. lideflate-gzip -V prints: "gzip compression program v1.18. Copyright 2016 Eric Biggers". I am aware that lots of care also has to be taken with I/O, which might make the command line utility slower than the library interface, but doing the tests in /dev/shm hopefully alleviated this. I am also aware that base64-encoded random data is a weird test case but it has its pros because it is a kind of minimal benchmark for raw Huffman decoding speed without (many) LZ references that need to be resolved.

I redid the benchmark as outlined above with the three test files that I am also using for my extended benchmarks [0]:

    4GiB-base64.gz            -> libdeflate: 20.5 s, igzip: 9.4 s, rapidgzip: 1.5 s
    20xsilesia.tar.gz         -> libdeflate:  5.4 s, igzip: 6.6 s, rapidgzip: 1.8 s
    10xSRR22403185_2.fastq.gz -> libdeflate:  5.8 s, igzip: 5.5 s, rapidgzip: 1.9 s
File Sizes: Compressed -> Uncompressed:

    4GiB-base64.gz            : 4294967296 -> 3263906203
    20xsilesia.tar.gz         : 1364776140 -> 4239155200
    10xSRR22403185_2.fastq.gz :  970458140 -> 3618153020
In conclusion, it seems that it highly depends on the test case and the one I tested to, too quickly, check my statement is one of the outliers.

[0] https://github.com/mxmlnkn/rapidgzip#scaling-benchmarks-on-2...


I also did benchmarks with zlib and libarchivemount via their library interface here [0]. It has been a while that I have run them, so I forgot. Unfortunately, I did not add libdeflate. I did not even add ISA-l. At that point, I was already would have been glad if my custom-written gzip decompressor could match the speed of the gzip command line utility, which for some weird reason is half as fast as zlib.

[0] https://github.com/mxmlnkn/rapidgzip/blob/master/src/benchma...


Note that libdeflate has used essentially the same method since 2016 (https://github.com/ebiggers/libdeflate/blob/v0.4/lib/adler32...), though I recently switched it to use a slightly different method (https://github.com/ebiggers/libdeflate/blob/v1.12/lib/x86/ad...) that performs more consistently across different families of x86 CPUs.


> In this somewhat unusual case, the problem was found and corrected in the Linux kernel through a typical bug-fix process and not handled as a security vulnerability, so no CVE was assigned.

This isn't unusual. This is actually the usual case.

The unusual thing here is actually that someone downstream noticed they were missing a fix (probably because its LTP regression test was failing, which is also unusual because most kernel fixes don't have an LTP regression test).

More commonly, no one notices and these bugs never get fixed in downstream kernels that aren't staying up to-date with LTS; and there is never a CVE, an oss-security post, a Hacker News thread, etc. But these bugs are still there.


> More commonly, no one notices and these bugs never get fixed in downstream kernels that aren't staying up to-date with LTS

Actually a lot of RHEL subsystems are updated wholesale by including all upstream patches (not just those that go into LTS kernels), and this way all such fixes are automatically included.


Well, the longer that vulnerabilities are kept secret, the longer that users are unable to take any action to protect themselves, and the less incentive that vendors have to roll out fixes quickly and to prevent vulnerabilities in the first place. See the Project Zero disclosure FAQ: https://googleprojectzero.blogspot.com/p/vulnerability-discl...


SELinux actually does significantly reduce the kernel attack surface on Android, and it has made a lot of kernel vulnerabilites unexploitable on Android. This particular bug was simply one in the remaining attack surface.


syzbot is already fuzzing the latest two stable kernels and has found hundreds of bugs, including lots of use-after-frees. All these bugs are listed here:

- https://syzkaller.appspot.com/linux-4.14 - https://syzkaller.appspot.com/linux-4.19

As far as I know, no one is doing anything with the syzbot bugs against stable kernels directly, since no company using Linux is paying anyone to do it as their job. But some are getting fixed; e.g., some get reported against mainline too, then fixed and backported.


How complex it is to test all known issues against all current kernels?

A weekly report with some easy to understand graphs would probably convince more people to work on these bugs.


Time and cost, same as it would be to do it across all kernel versions, not just current ones. Theoretically could be done pretty simply via a CI/CD pipeline if someone wrote solid test cases for the issues found by the fuzzier.


Thats my point! Make this part of the kernel regression and also run it on the old kernels.


AFAICS, this was exposed by the addition of sockfs_setattr() in v4.10. So it's incorrect to claim that kernels older than that are vulnerable, even though the code being fixed was older.

Also, note that there may not actually be a proof-of-concept exploit yet, beyond a reproducer causing a KASAN splat. When people request a CVE for a use-after-free bug they usually just assume that code execution may be possible. (Exploits can be very creative.)


(I'm one of the authors of the blog post)

We considered it, of course, along with many other block ciphers. However, heavily optimized Threefish-256 is 22.6 cycles per byte on Cortex-A7 (by far the most common CPU this is needed on) which is over twice as slow as Adiantum. Threefish-512 and Threefish-1024 would be much slower still. We're already at the borderline of the performance needed to actually get all Android devices encrypted, so over 2x worse performance is a no-go.

Threefish also wasn't published as a standalone block cipher but rather was part of Skein, which lost the SHA-3 competition. Therefore it hasn't received as much cryptanalysis as ChaCha and AES, and probably won't get much more in the future.

Finally, note that unlike Adiantum, Threefish isn't a wide-block cipher, where flipping one bit in the sector scrambles all other bits. So comparing its complexity directly to Adiantum's is somewhat unfair. Other wide-block modes such as HCH and HCTR are also more complex than narrow-block modes.


Thank you for the additional insight!


Consider applying for YC's Summer 2026 batch! Applications are open till May 4

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: