public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Demi Marie Obenour <demiobenour@gmail.com>
To: Eric Biggers <ebiggers@kernel.org>,
	linux-crypto@vger.kernel.org,
	Herbert Xu <herbert@gondor.apana.org.au>
Cc: linux-kernel@vger.kernel.org, linux-hardening@vger.kernel.org,
	Taeyang Lee <0wn@theori.io>, Brian Pak <bpak@theori.io>,
	Juno Im <juno@theori.io>, Jungwon Lim <setuid0@theori.io>,
	Tim Becker <tjbecker@theori.io>, Feng Ning <feng@innora.ai>,
	stable@vger.kernel.org
Subject: Re: [PATCH] crypto: af_alg - Remove zero-copy support from AF_ALG
Date: Mon, 4 May 2026 02:54:27 -0400	[thread overview]
Message-ID: <79b24e6f-91a2-4dd0-a5f2-c01a9247ea9c@gmail.com> (raw)
In-Reply-To: <20260504061532.172013-1-ebiggers@kernel.org>


[-- Attachment #1.1.1: Type: text/plain, Size: 8273 bytes --]

On 5/4/26 02:15, Eric Biggers wrote:
> The zero-copy support is one of the riskiest aspects of AF_ALG.  It
> allows userspace to request cryptographic operations directly on
> pagecache pages of files like the 'su' binary.  It also allows userspace
> to concurrently modify the memory which is being operated on, a huge
> recipe for TOCTOU vulnerabilities.
> 
> While zero-copy support is more valuable in other areas of the kernel
> like the frequently used networking and file I/O code, it has far less
> value in AF_ALG, which is a niche UAPI.  AF_ALG primarily just exists
> for backwards compatibility with a small set of userspace programs such
> as 'iwd' that haven't yet been fixed to use userspace crypto code.
> 
> Originally AF_ALG was intended to be used to access hardware crypto
> accelerators.  However, it isn't an efficient interface for that anyway,
> and it turned out to be rarely used in this way in practice.
> 
> Thus, the risks of the zero-copy support in AF_ALG vastly outweigh its
> benefits.  Just remove it.
> 
> Note that this isn't a hard break, since the splice syscall is still
> supported.  The data is just now copied instead.  So it still works,
> just a bit slower in some cases.
> 
> Tested with libkcapi/test.sh.  All its test cases still pass.  I also
> verified that this would have prevented the copy.fail exploit as well.
> 
> Fixes: 8ff590903d5f ("crypto: algif_skcipher - User-space interface for skcipher operations")
> Fixes: 400c40cf78da ("crypto: algif - add AEAD support")
> Reported-by: Taeyang Lee <0wn@theori.io>
> Reported-by: Feng Ning <feng@innora.ai>
> Cc: stable@vger.kernel.org
> Signed-off-by: Eric Biggers <ebiggers@kernel.org>
> ---
>  Documentation/crypto/userspace-if.rst | 30 ++---------
>  crypto/af_alg.c                       | 73 +++++++++------------------
>  crypto/algif_aead.c                   |  8 +--
>  3 files changed, 32 insertions(+), 79 deletions(-)
> 
> diff --git a/Documentation/crypto/userspace-if.rst b/Documentation/crypto/userspace-if.rst
> index 021759198fe7..80eb2819901a 100644
> --- a/Documentation/crypto/userspace-if.rst
> +++ b/Documentation/crypto/userspace-if.rst
> @@ -325,37 +325,13 @@ CRYPTO_USER_API_RNG_CAVP option:
>     but only after the entropy has been set.
>  
>  Zero-Copy Interface
>  -------------------
>  
> -In addition to the send/write/read/recv system call family, the AF_ALG
> -interface can be accessed with the zero-copy interface of
> -splice/vmsplice. As the name indicates, the kernel tries to avoid a copy
> -operation into kernel space.
> -
> -The zero-copy operation requires data to be aligned at the page
> -boundary. Non-aligned data can be used as well, but may require more
> -operations of the kernel which would defeat the speed gains obtained
> -from the zero-copy interface.
> -
> -The system-inherent limit for the size of one zero-copy operation is 16
> -pages. If more data is to be sent to AF_ALG, user space must slice the
> -input into segments with a maximum size of 16 pages.
> -
> -Zero-copy can be used with the following code example (a complete
> -working example is provided with libkcapi):
> -
> -::
> -
> -    int pipes[2];
> -
> -    pipe(pipes);
> -    /* input data in iov */
> -    vmsplice(pipes[1], iov, iovlen, SPLICE_F_GIFT);
> -    /* opfd is the file descriptor returned from accept() system call */
> -    splice(pipes[0], NULL, opfd, NULL, ret, 0);
> -    read(opfd, out, outlen);
> +AF_ALG used to have zero-copy support, but it was removed due to it being a
> +frequent source of vulnerabilities.  For backwards compatibility the splice
> +system call is still supported, but the data will simply be copied.
>  
>  
>  Setsockopt Interface
>  --------------------
>  
> diff --git a/crypto/af_alg.c b/crypto/af_alg.c
> index 5a00c18eb145..fce0b87c2b65 100644
> --- a/crypto/af_alg.c
> +++ b/crypto/af_alg.c
> @@ -971,11 +971,11 @@ int af_alg_sendmsg(struct socket *sock, struct msghdr *msg, size_t size,
>  		struct scatterlist *sg;
>  		size_t len = size;
>  		ssize_t plen;
>  
>  		/* use the existing memory in an allocated page */
> -		if (ctx->merge && !(msg->msg_flags & MSG_SPLICE_PAGES)) {
> +		if (ctx->merge) {
>  			sgl = list_entry(ctx->tsgl_list.prev,
>  					 struct af_alg_tsgl, list);
>  			sg = sgl->sg + sgl->cur - 1;
>  			len = min_t(size_t, len,
>  				    PAGE_SIZE - sg->offset - sg->length);
> @@ -1015,64 +1015,41 @@ int af_alg_sendmsg(struct socket *sock, struct msghdr *msg, size_t size,
>  				 list);
>  		sg = sgl->sg;
>  		if (sgl->cur)
>  			sg_unmark_end(sg + sgl->cur - 1);
>  
> -		if (msg->msg_flags & MSG_SPLICE_PAGES) {
> -			struct sg_table sgtable = {
> -				.sgl		= sg,
> -				.nents		= sgl->cur,
> -				.orig_nents	= sgl->cur,
> -			};
> -
> -			plen = extract_iter_to_sg(&msg->msg_iter, len, &sgtable,
> -						  MAX_SGL_ENTS - sgl->cur, 0);
> -			if (plen < 0) {
> -				err = plen;
> +		do {
> +			struct page *pg;
> +			unsigned int i = sgl->cur;
> +
> +			plen = min_t(size_t, len, PAGE_SIZE);
> +
> +			pg = alloc_page(GFP_KERNEL);
> +			if (!pg) {
> +				err = -ENOMEM;
>  				goto unlock;
>  			}
>  
> -			for (; sgl->cur < sgtable.nents; sgl->cur++)
> -				get_page(sg_page(&sg[sgl->cur]));
> +			sg_assign_page(sg + i, pg);
> +
> +			err = memcpy_from_msg(page_address(sg_page(sg + i)),
> +					      msg, plen);
> +			if (err) {
> +				__free_page(sg_page(sg + i));
> +				sg_assign_page(sg + i, NULL);
> +				goto unlock;
> +			}
> +
> +			sg[i].length = plen;
>  			len -= plen;
>  			ctx->used += plen;
>  			copied += plen;
>  			size -= plen;
> -		} else {
> -			do {
> -				struct page *pg;
> -				unsigned int i = sgl->cur;
> -
> -				plen = min_t(size_t, len, PAGE_SIZE);
> -
> -				pg = alloc_page(GFP_KERNEL);
> -				if (!pg) {
> -					err = -ENOMEM;
> -					goto unlock;
> -				}
> -
> -				sg_assign_page(sg + i, pg);
> -
> -				err = memcpy_from_msg(
> -					page_address(sg_page(sg + i)),
> -					msg, plen);
> -				if (err) {
> -					__free_page(sg_page(sg + i));
> -					sg_assign_page(sg + i, NULL);
> -					goto unlock;
> -				}
> -
> -				sg[i].length = plen;
> -				len -= plen;
> -				ctx->used += plen;
> -				copied += plen;
> -				size -= plen;
> -				sgl->cur++;
> -			} while (len && sgl->cur < MAX_SGL_ENTS);
> -
> -			ctx->merge = plen & (PAGE_SIZE - 1);
> -		}
> +			sgl->cur++;
> +		} while (len && sgl->cur < MAX_SGL_ENTS);
> +
> +		ctx->merge = plen & (PAGE_SIZE - 1);
>  
>  		if (!size)
>  			sg_mark_end(sg + sgl->cur - 1);
>  	}
>  
> diff --git a/crypto/algif_aead.c b/crypto/algif_aead.c
> index cb651ab58d62..c6c2ce21895d 100644
> --- a/crypto/algif_aead.c
> +++ b/crypto/algif_aead.c
> @@ -7,14 +7,14 @@
>   * This file provides the user-space API for AEAD ciphers.
>   *
>   * The following concept of the memory management is used:
>   *
>   * The kernel maintains two SGLs, the TX SGL and the RX SGL. The TX SGL is
> - * filled by user space with the data submitted via sendmsg (maybe with
> - * MSG_SPLICE_PAGES).  Filling up the TX SGL does not cause a crypto operation
> - * -- the data will only be tracked by the kernel. Upon receipt of one recvmsg
> - * call, the caller must provide a buffer which is tracked with the RX SGL.
> + * filled by user space with the data submitted via sendmsg.  Filling up the TX
> + * SGL does not cause a crypto operation -- the data will only be tracked by the
> + * kernel. Upon receipt of one recvmsg call, the caller must provide a buffer
> + * which is tracked with the RX SGL.
>   *
>   * During the processing of the recvmsg operation, the cipher request is
>   * allocated and prepared. As part of the recvmsg operation, the processed
>   * TX buffers are extracted from the TX SGL into a separate SGL.
>   *
> 
> base-commit: 6d35786de28116ecf78797a62b84e6bf3c45aa5a

In light of https://lore.kernel.org/all/afYcc-tZFwvZZo76@ans-MacBook-Pro.local/,
yes please!

Should there be a Link: tag referencing that email?

With or without it:

Reviewed-by: Demi Marie Obenour <demiobenour@gmail.com>
-- 
Sincerely,
Demi Marie Obenour (she/her/hers)

[-- Attachment #1.1.2: OpenPGP public key --]
[-- Type: application/pgp-keys, Size: 7253 bytes --]

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

  reply	other threads:[~2026-05-04  6:54 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-05-04  6:15 [PATCH] crypto: af_alg - Remove zero-copy support from AF_ALG Eric Biggers
2026-05-04  6:54 ` Demi Marie Obenour [this message]
2026-05-04  6:56   ` Eric Biggers
2026-05-04  6:59     ` Demi Marie Obenour
2026-05-04  7:07       ` Eric Biggers
2026-05-04  7:10         ` [PATCH v2] " Eric Biggers
2026-05-04  9:24           ` Eric Biggers
2026-05-04 22:53             ` [PATCH v3] crypto: af_alg - Remove zero-copy support from skcipher and aead Eric Biggers
2026-05-04 16:07 ` [PATCH] crypto: af_alg - Remove zero-copy support from AF_ALG Ⓐlï P☮latel
2026-05-04 17:47   ` Eric Biggers
2026-05-04 18:26     ` Ⓐlï P☮latel
2026-05-04 22:25       ` Eric Biggers

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=79b24e6f-91a2-4dd0-a5f2-c01a9247ea9c@gmail.com \
    --to=demiobenour@gmail.com \
    --cc=0wn@theori.io \
    --cc=bpak@theori.io \
    --cc=ebiggers@kernel.org \
    --cc=feng@innora.ai \
    --cc=herbert@gondor.apana.org.au \
    --cc=juno@theori.io \
    --cc=linux-crypto@vger.kernel.org \
    --cc=linux-hardening@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=setuid0@theori.io \
    --cc=stable@vger.kernel.org \
    --cc=tjbecker@theori.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox