All of lore.kernel.org
 help / color / mirror / Atom feed
From: Eric Biggers <ebiggers3@gmail.com>
To: "Stephan Müller" <smueller@chronox.de>
Cc: herbert@gondor.apana.org.au,
	syzbot
	<bot+3401d9494b9380f7244bcc7fec49680878fccba6@syzkaller.appspotmail.com>,
	davem@davemloft.net, linux-crypto@vger.kernel.org,
	linux-kernel@vger.kernel.org, syzkaller-bugs@googlegroups.com
Subject: Re: [PATCH v2] crypto: AF_ALG - race-free access of encryption flag
Date: Tue, 28 Nov 2017 14:40:49 -0800	[thread overview]
Message-ID: <20171128224049.GH45321@gmail.com> (raw)
In-Reply-To: <1943686.EAKghbSqDq@positron.chronox.de>

On Tue, Nov 28, 2017 at 10:33:09PM +0100, Stephan Müller wrote:
> Hi Herbert,
> 
> I verified the correctnes of the patch with Eric's test program.
> Without the patch, the issue is present. With the patch, the kernel
> happily lives ever after.
> 
> Changes v2: change the submission into a proper patch
> 
> Ciao
> Stephan
> 
> ---8<---
> 
> The function af_alg_get_rsgl may sleep to wait for additional data. In
> this case, the socket lock may be dropped. This allows user space to
> change values in the socket data structure. Hence, all variables of the
> context that are needed before and after the af_alg_get_rsgl must be
> copied into a local variable.
> 
> This issue applies to the ctx->enc variable only. Therefore, this
> value is copied into a local variable that is used for all operations
> before and after the potential sleep and lock release. This implies that
> any changes on this variable while the kernel waits for data will only
> be picked up in another recvmsg operation.
> 

This isn't enough because ->aead_assoclen is also affected.  Below is a program
which causes a crash even with your patch applied.

Also I feel this is just papering over the real problem which is that the wait
is in the wrong place -- and therefore the socket lock is being dropped in the
wrong place.  If it's necessary at all it seems it should happen earlier, before
the stuff from the 'ctx' starts being used.  At the very least, it is very
difficult to understand whether the current code is correct or not.  (Which
usually means it's not.)

#include <linux/if_alg.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <time.h>
#include <unistd.h>

#define SOL_ALG 0x117
#define ALG_SET_AEAD_ASSOCLEN 4

int main()
{
	srand(time(NULL));
        for (;;) {
                int algfd, reqfd;
                char buf[12];
                char key[16] = { 0 };
                struct sockaddr_alg addr = {
                        .salg_type = "aead",
                        .salg_name = "gcm(aes)",
                };
                struct {
                        struct cmsghdr hdr;
                        __u32 op;
                } set_op = {
                        .hdr = {
                                .cmsg_len = sizeof(set_op),
                                .cmsg_level = SOL_ALG,
                                .cmsg_type = ALG_SET_OP,
                        },
			.op = ALG_OP_ENCRYPT,
                };
                struct msghdr set_op_msg = {
                        .msg_control = &set_op,
                        .msg_controllen = sizeof(set_op),
                };
                struct {
                        struct cmsghdr hdr1;
                        __u32 assoclen;
                        struct cmsghdr hdr2;
                        __u32 op;
                } set_assoclen = {
                        .hdr1 = {
                                .cmsg_len = sizeof(set_assoclen),
                                .cmsg_level = SOL_ALG,
                                .cmsg_type = ALG_SET_AEAD_ASSOCLEN,
                        },
			.assoclen = 1000,
                        .hdr2 = {
                                .cmsg_len = sizeof(set_assoclen),
                                .cmsg_level = SOL_ALG,
                                .cmsg_type = ALG_SET_OP,
                        },
			.op = ALG_OP_ENCRYPT,
                };
                struct msghdr set_assoclen_msg = {
			.msg_iov = &(struct iovec) { .iov_base = buf,
						     .iov_len = 64 },
			.msg_iovlen = 1,
                        .msg_control = &set_assoclen,
                        .msg_controllen = sizeof(set_assoclen),
                };

                algfd = socket(AF_ALG, SOCK_SEQPACKET, 0);

                bind(algfd, (void *)&addr, sizeof(addr));

                setsockopt(algfd, SOL_ALG, ALG_SET_KEY, key, sizeof(key));

                reqfd = accept(algfd, NULL, NULL);

                sendmsg(reqfd, &set_op_msg, 0);

                if (fork() == 0) {
			usleep(rand() % 10000);
                        sendmsg(reqfd, &set_assoclen_msg, 0);
                        break;
                }

		usleep(rand() % 10000);
                read(reqfd, buf, sizeof(buf));
                wait(NULL);
		close(algfd);
		close(reqfd);
        }
}

  reply	other threads:[~2017-11-28 22:40 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-11-27 18:56 general protection fault in blkcipher_walk_done syzbot
2017-11-28  5:37 ` Eric Biggers
2017-11-28  7:53   ` Eric Biggers
2017-11-28  8:31     ` Stephan Mueller
2017-11-28  9:03   ` Stephan Mueller
2017-11-28 21:33     ` [PATCH v2] crypto: AF_ALG - race-free access of encryption flag Stephan Müller
2017-11-28 22:40       ` Eric Biggers [this message]
2017-11-28 23:02       ` Herbert Xu
2017-11-29  6:48         ` Stephan Mueller
2017-11-29  7:10           ` Herbert Xu
2017-11-29  7:17             ` Stephan Mueller
2017-11-29 10:17               ` [PATCH] crypto: AF_ALG - wait for data at beginning of recvmsg Stephan Müller
2017-11-29 10:22                 ` Herbert Xu
2017-11-29 10:28                   ` Stephan Mueller
2017-11-29 10:42                     ` Herbert Xu
2017-11-29 11:02                       ` [PATCH v2] " Stephan Müller
2017-12-11 11:45                         ` Herbert Xu
2017-11-29 11:05             ` [PATCH v2] crypto: AF_ALG - race-free access of encryption flag Stephan Müller
2017-11-29 12:17               ` Herbert Xu
2017-12-11 19:10 ` general protection fault in blkcipher_walk_done 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=20171128224049.GH45321@gmail.com \
    --to=ebiggers3@gmail.com \
    --cc=bot+3401d9494b9380f7244bcc7fec49680878fccba6@syzkaller.appspotmail.com \
    --cc=davem@davemloft.net \
    --cc=herbert@gondor.apana.org.au \
    --cc=linux-crypto@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=smueller@chronox.de \
    --cc=syzkaller-bugs@googlegroups.com \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.