• H
    crypto: pcrypt - Avoid deadlock by using per-instance padata queues · bbefa1dd
    Herbert Xu 提交于
    If the pcrypt template is used multiple times in an algorithm, then a
    deadlock occurs because all pcrypt instances share the same
    padata_instance, which completes requests in the order submitted.  That
    is, the inner pcrypt request waits for the outer pcrypt request while
    the outer request is already waiting for the inner.
    
    This patch fixes this by allocating a set of queues for each pcrypt
    instance instead of using two global queues.  In order to maintain
    the existing user-space interface, the pinst structure remains global
    so any sysfs modifications will apply to every pcrypt instance.
    
    Note that when an update occurs we have to allocate memory for
    every pcrypt instance.  Should one of the allocations fail we
    will abort the update without rolling back changes already made.
    
    The new per-instance data structure is called padata_shell and is
    essentially a wrapper around parallel_data.
    
    Reproducer:
    
    	#include <linux/if_alg.h>
    	#include <sys/socket.h>
    	#include <unistd.h>
    
    	int main()
    	{
    		struct sockaddr_alg addr = {
    			.salg_type = "aead",
    			.salg_name = "pcrypt(pcrypt(rfc4106-gcm-aesni))"
    		};
    		int algfd, reqfd;
    		char buf[32] = { 0 };
    
    		algfd = socket(AF_ALG, SOCK_SEQPACKET, 0);
    		bind(algfd, (void *)&addr, sizeof(addr));
    		setsockopt(algfd, SOL_ALG, ALG_SET_KEY, buf, 20);
    		reqfd = accept(algfd, 0, 0);
    		write(reqfd, buf, 32);
    		read(reqfd, buf, 16);
    	}
    
    Reported-by: syzbot+56c7151cad94eec37c521f0e47d2eee53f9361c4@syzkaller.appspotmail.com
    Fixes: 5068c7a8 ("crypto: pcrypt - Add pcrypt crypto parallelization wrapper")
    Signed-off-by: NHerbert Xu <herbert@gondor.apana.org.au>
    Tested-by: NEric Biggers <ebiggers@kernel.org>
    Signed-off-by: NHerbert Xu <herbert@gondor.apana.org.au>
    bbefa1dd
padata.c 27.3 KB