brintos

brintos / linux-shallow public Read only

0
0
Text · 28.9 KiB · 0da7c1a Raw
1323 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * af_alg: User-space algorithm interface4 *5 * This file provides the user-space API for algorithms.6 *7 * Copyright (c) 2010 Herbert Xu <herbert@gondor.apana.org.au>8 */9 10#include <linux/atomic.h>11#include <crypto/if_alg.h>12#include <linux/crypto.h>13#include <linux/init.h>14#include <linux/kernel.h>15#include <linux/key.h>16#include <linux/key-type.h>17#include <linux/list.h>18#include <linux/module.h>19#include <linux/net.h>20#include <linux/rwsem.h>21#include <linux/sched.h>22#include <linux/sched/signal.h>23#include <linux/security.h>24#include <linux/string.h>25#include <keys/user-type.h>26#include <keys/trusted-type.h>27#include <keys/encrypted-type.h>28 29struct alg_type_list {30	const struct af_alg_type *type;31	struct list_head list;32};33 34static struct proto alg_proto = {35	.name			= "ALG",36	.owner			= THIS_MODULE,37	.obj_size		= sizeof(struct alg_sock),38};39 40static LIST_HEAD(alg_types);41static DECLARE_RWSEM(alg_types_sem);42 43static const struct af_alg_type *alg_get_type(const char *name)44{45	const struct af_alg_type *type = ERR_PTR(-ENOENT);46	struct alg_type_list *node;47 48	down_read(&alg_types_sem);49	list_for_each_entry(node, &alg_types, list) {50		if (strcmp(node->type->name, name))51			continue;52 53		if (try_module_get(node->type->owner))54			type = node->type;55		break;56	}57	up_read(&alg_types_sem);58 59	return type;60}61 62int af_alg_register_type(const struct af_alg_type *type)63{64	struct alg_type_list *node;65	int err = -EEXIST;66 67	down_write(&alg_types_sem);68	list_for_each_entry(node, &alg_types, list) {69		if (!strcmp(node->type->name, type->name))70			goto unlock;71	}72 73	node = kmalloc(sizeof(*node), GFP_KERNEL);74	err = -ENOMEM;75	if (!node)76		goto unlock;77 78	type->ops->owner = THIS_MODULE;79	if (type->ops_nokey)80		type->ops_nokey->owner = THIS_MODULE;81	node->type = type;82	list_add(&node->list, &alg_types);83	err = 0;84 85unlock:86	up_write(&alg_types_sem);87 88	return err;89}90EXPORT_SYMBOL_GPL(af_alg_register_type);91 92int af_alg_unregister_type(const struct af_alg_type *type)93{94	struct alg_type_list *node;95	int err = -ENOENT;96 97	down_write(&alg_types_sem);98	list_for_each_entry(node, &alg_types, list) {99		if (strcmp(node->type->name, type->name))100			continue;101 102		list_del(&node->list);103		kfree(node);104		err = 0;105		break;106	}107	up_write(&alg_types_sem);108 109	return err;110}111EXPORT_SYMBOL_GPL(af_alg_unregister_type);112 113static void alg_do_release(const struct af_alg_type *type, void *private)114{115	if (!type)116		return;117 118	type->release(private);119	module_put(type->owner);120}121 122int af_alg_release(struct socket *sock)123{124	if (sock->sk) {125		sock_put(sock->sk);126		sock->sk = NULL;127	}128	return 0;129}130EXPORT_SYMBOL_GPL(af_alg_release);131 132void af_alg_release_parent(struct sock *sk)133{134	struct alg_sock *ask = alg_sk(sk);135	unsigned int nokey = atomic_read(&ask->nokey_refcnt);136 137	sk = ask->parent;138	ask = alg_sk(sk);139 140	if (nokey)141		atomic_dec(&ask->nokey_refcnt);142 143	if (atomic_dec_and_test(&ask->refcnt))144		sock_put(sk);145}146EXPORT_SYMBOL_GPL(af_alg_release_parent);147 148static int alg_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)149{150	const u32 allowed = CRYPTO_ALG_KERN_DRIVER_ONLY;151	struct sock *sk = sock->sk;152	struct alg_sock *ask = alg_sk(sk);153	struct sockaddr_alg_new *sa = (void *)uaddr;154	const struct af_alg_type *type;155	void *private;156	int err;157 158	if (sock->state == SS_CONNECTED)159		return -EINVAL;160 161	BUILD_BUG_ON(offsetof(struct sockaddr_alg_new, salg_name) !=162		     offsetof(struct sockaddr_alg, salg_name));163	BUILD_BUG_ON(offsetof(struct sockaddr_alg, salg_name) != sizeof(*sa));164 165	if (addr_len < sizeof(*sa) + 1)166		return -EINVAL;167 168	/* If caller uses non-allowed flag, return error. */169	if ((sa->salg_feat & ~allowed) || (sa->salg_mask & ~allowed))170		return -EINVAL;171 172	sa->salg_type[sizeof(sa->salg_type) - 1] = 0;173	sa->salg_name[addr_len - sizeof(*sa) - 1] = 0;174 175	type = alg_get_type(sa->salg_type);176	if (PTR_ERR(type) == -ENOENT) {177		request_module("algif-%s", sa->salg_type);178		type = alg_get_type(sa->salg_type);179	}180 181	if (IS_ERR(type))182		return PTR_ERR(type);183 184	private = type->bind(sa->salg_name, sa->salg_feat, sa->salg_mask);185	if (IS_ERR(private)) {186		module_put(type->owner);187		return PTR_ERR(private);188	}189 190	err = -EBUSY;191	lock_sock(sk);192	if (atomic_read(&ask->refcnt))193		goto unlock;194 195	swap(ask->type, type);196	swap(ask->private, private);197 198	err = 0;199 200unlock:201	release_sock(sk);202 203	alg_do_release(type, private);204 205	return err;206}207 208static int alg_setkey(struct sock *sk, sockptr_t ukey, unsigned int keylen)209{210	struct alg_sock *ask = alg_sk(sk);211	const struct af_alg_type *type = ask->type;212	u8 *key;213	int err;214 215	key = sock_kmalloc(sk, keylen, GFP_KERNEL);216	if (!key)217		return -ENOMEM;218 219	err = -EFAULT;220	if (copy_from_sockptr(key, ukey, keylen))221		goto out;222 223	err = type->setkey(ask->private, key, keylen);224 225out:226	sock_kzfree_s(sk, key, keylen);227 228	return err;229}230 231#ifdef CONFIG_KEYS232 233static const u8 *key_data_ptr_user(const struct key *key,234				   unsigned int *datalen)235{236	const struct user_key_payload *ukp;237 238	ukp = user_key_payload_locked(key);239	if (IS_ERR_OR_NULL(ukp))240		return ERR_PTR(-EKEYREVOKED);241 242	*datalen = key->datalen;243 244	return ukp->data;245}246 247static const u8 *key_data_ptr_encrypted(const struct key *key,248					unsigned int *datalen)249{250	const struct encrypted_key_payload *ekp;251 252	ekp = dereference_key_locked(key);253	if (IS_ERR_OR_NULL(ekp))254		return ERR_PTR(-EKEYREVOKED);255 256	*datalen = ekp->decrypted_datalen;257 258	return ekp->decrypted_data;259}260 261static const u8 *key_data_ptr_trusted(const struct key *key,262				      unsigned int *datalen)263{264	const struct trusted_key_payload *tkp;265 266	tkp = dereference_key_locked(key);267	if (IS_ERR_OR_NULL(tkp))268		return ERR_PTR(-EKEYREVOKED);269 270	*datalen = tkp->key_len;271 272	return tkp->key;273}274 275static struct key *lookup_key(key_serial_t serial)276{277	key_ref_t key_ref;278 279	key_ref = lookup_user_key(serial, 0, KEY_NEED_SEARCH);280	if (IS_ERR(key_ref))281		return ERR_CAST(key_ref);282 283	return key_ref_to_ptr(key_ref);284}285 286static int alg_setkey_by_key_serial(struct alg_sock *ask, sockptr_t optval,287				    unsigned int optlen)288{289	const struct af_alg_type *type = ask->type;290	u8 *key_data = NULL;291	unsigned int key_datalen;292	key_serial_t serial;293	struct key *key;294	const u8 *ret;295	int err;296 297	if (optlen != sizeof(serial))298		return -EINVAL;299 300	if (copy_from_sockptr(&serial, optval, optlen))301		return -EFAULT;302 303	key = lookup_key(serial);304	if (IS_ERR(key))305		return PTR_ERR(key);306 307	down_read(&key->sem);308 309	ret = ERR_PTR(-ENOPROTOOPT);310	if (!strcmp(key->type->name, "user") ||311	    !strcmp(key->type->name, "logon")) {312		ret = key_data_ptr_user(key, &key_datalen);313	} else if (IS_REACHABLE(CONFIG_ENCRYPTED_KEYS) &&314			   !strcmp(key->type->name, "encrypted")) {315		ret = key_data_ptr_encrypted(key, &key_datalen);316	} else if (IS_REACHABLE(CONFIG_TRUSTED_KEYS) &&317			   !strcmp(key->type->name, "trusted")) {318		ret = key_data_ptr_trusted(key, &key_datalen);319	}320 321	if (IS_ERR(ret)) {322		up_read(&key->sem);323		key_put(key);324		return PTR_ERR(ret);325	}326 327	key_data = sock_kmalloc(&ask->sk, key_datalen, GFP_KERNEL);328	if (!key_data) {329		up_read(&key->sem);330		key_put(key);331		return -ENOMEM;332	}333 334	memcpy(key_data, ret, key_datalen);335 336	up_read(&key->sem);337	key_put(key);338 339	err = type->setkey(ask->private, key_data, key_datalen);340 341	sock_kzfree_s(&ask->sk, key_data, key_datalen);342 343	return err;344}345 346#else347 348static inline int alg_setkey_by_key_serial(struct alg_sock *ask,349					   sockptr_t optval,350					   unsigned int optlen)351{352	return -ENOPROTOOPT;353}354 355#endif356 357static int alg_setsockopt(struct socket *sock, int level, int optname,358			  sockptr_t optval, unsigned int optlen)359{360	struct sock *sk = sock->sk;361	struct alg_sock *ask = alg_sk(sk);362	const struct af_alg_type *type;363	int err = -EBUSY;364 365	lock_sock(sk);366	if (atomic_read(&ask->refcnt) != atomic_read(&ask->nokey_refcnt))367		goto unlock;368 369	type = ask->type;370 371	err = -ENOPROTOOPT;372	if (level != SOL_ALG || !type)373		goto unlock;374 375	switch (optname) {376	case ALG_SET_KEY:377	case ALG_SET_KEY_BY_KEY_SERIAL:378		if (sock->state == SS_CONNECTED)379			goto unlock;380		if (!type->setkey)381			goto unlock;382 383		if (optname == ALG_SET_KEY_BY_KEY_SERIAL)384			err = alg_setkey_by_key_serial(ask, optval, optlen);385		else386			err = alg_setkey(sk, optval, optlen);387		break;388	case ALG_SET_AEAD_AUTHSIZE:389		if (sock->state == SS_CONNECTED)390			goto unlock;391		if (!type->setauthsize)392			goto unlock;393		err = type->setauthsize(ask->private, optlen);394		break;395	case ALG_SET_DRBG_ENTROPY:396		if (sock->state == SS_CONNECTED)397			goto unlock;398		if (!type->setentropy)399			goto unlock;400 401		err = type->setentropy(ask->private, optval, optlen);402	}403 404unlock:405	release_sock(sk);406 407	return err;408}409 410int af_alg_accept(struct sock *sk, struct socket *newsock,411		  struct proto_accept_arg *arg)412{413	struct alg_sock *ask = alg_sk(sk);414	const struct af_alg_type *type;415	struct sock *sk2;416	unsigned int nokey;417	int err;418 419	lock_sock(sk);420	type = ask->type;421 422	err = -EINVAL;423	if (!type)424		goto unlock;425 426	sk2 = sk_alloc(sock_net(sk), PF_ALG, GFP_KERNEL, &alg_proto, arg->kern);427	err = -ENOMEM;428	if (!sk2)429		goto unlock;430 431	sock_init_data(newsock, sk2);432	security_sock_graft(sk2, newsock);433	security_sk_clone(sk, sk2);434 435	/*436	 * newsock->ops assigned here to allow type->accept call to override437	 * them when required.438	 */439	newsock->ops = type->ops;440	err = type->accept(ask->private, sk2);441 442	nokey = err == -ENOKEY;443	if (nokey && type->accept_nokey)444		err = type->accept_nokey(ask->private, sk2);445 446	if (err)447		goto unlock;448 449	if (atomic_inc_return_relaxed(&ask->refcnt) == 1)450		sock_hold(sk);451	if (nokey) {452		atomic_inc(&ask->nokey_refcnt);453		atomic_set(&alg_sk(sk2)->nokey_refcnt, 1);454	}455	alg_sk(sk2)->parent = sk;456	alg_sk(sk2)->type = type;457 458	newsock->state = SS_CONNECTED;459 460	if (nokey)461		newsock->ops = type->ops_nokey;462 463	err = 0;464 465unlock:466	release_sock(sk);467 468	return err;469}470EXPORT_SYMBOL_GPL(af_alg_accept);471 472static int alg_accept(struct socket *sock, struct socket *newsock,473		      struct proto_accept_arg *arg)474{475	return af_alg_accept(sock->sk, newsock, arg);476}477 478static const struct proto_ops alg_proto_ops = {479	.family		=	PF_ALG,480	.owner		=	THIS_MODULE,481 482	.connect	=	sock_no_connect,483	.socketpair	=	sock_no_socketpair,484	.getname	=	sock_no_getname,485	.ioctl		=	sock_no_ioctl,486	.listen		=	sock_no_listen,487	.shutdown	=	sock_no_shutdown,488	.mmap		=	sock_no_mmap,489	.sendmsg	=	sock_no_sendmsg,490	.recvmsg	=	sock_no_recvmsg,491 492	.bind		=	alg_bind,493	.release	=	af_alg_release,494	.setsockopt	=	alg_setsockopt,495	.accept		=	alg_accept,496};497 498static void alg_sock_destruct(struct sock *sk)499{500	struct alg_sock *ask = alg_sk(sk);501 502	alg_do_release(ask->type, ask->private);503}504 505static int alg_create(struct net *net, struct socket *sock, int protocol,506		      int kern)507{508	struct sock *sk;509	int err;510 511	if (sock->type != SOCK_SEQPACKET)512		return -ESOCKTNOSUPPORT;513	if (protocol != 0)514		return -EPROTONOSUPPORT;515 516	err = -ENOMEM;517	sk = sk_alloc(net, PF_ALG, GFP_KERNEL, &alg_proto, kern);518	if (!sk)519		goto out;520 521	sock->ops = &alg_proto_ops;522	sock_init_data(sock, sk);523 524	sk->sk_destruct = alg_sock_destruct;525 526	return 0;527out:528	return err;529}530 531static const struct net_proto_family alg_family = {532	.family	=	PF_ALG,533	.create	=	alg_create,534	.owner	=	THIS_MODULE,535};536 537static void af_alg_link_sg(struct af_alg_sgl *sgl_prev,538			   struct af_alg_sgl *sgl_new)539{540	sg_unmark_end(sgl_prev->sgt.sgl + sgl_prev->sgt.nents - 1);541	sg_chain(sgl_prev->sgt.sgl, sgl_prev->sgt.nents + 1, sgl_new->sgt.sgl);542}543 544void af_alg_free_sg(struct af_alg_sgl *sgl)545{546	int i;547 548	if (sgl->sgt.sgl) {549		if (sgl->need_unpin)550			for (i = 0; i < sgl->sgt.nents; i++)551				unpin_user_page(sg_page(&sgl->sgt.sgl[i]));552		if (sgl->sgt.sgl != sgl->sgl)553			kvfree(sgl->sgt.sgl);554		sgl->sgt.sgl = NULL;555	}556}557EXPORT_SYMBOL_GPL(af_alg_free_sg);558 559static int af_alg_cmsg_send(struct msghdr *msg, struct af_alg_control *con)560{561	struct cmsghdr *cmsg;562 563	for_each_cmsghdr(cmsg, msg) {564		if (!CMSG_OK(msg, cmsg))565			return -EINVAL;566		if (cmsg->cmsg_level != SOL_ALG)567			continue;568 569		switch (cmsg->cmsg_type) {570		case ALG_SET_IV:571			if (cmsg->cmsg_len < CMSG_LEN(sizeof(*con->iv)))572				return -EINVAL;573			con->iv = (void *)CMSG_DATA(cmsg);574			if (cmsg->cmsg_len < CMSG_LEN(con->iv->ivlen +575						      sizeof(*con->iv)))576				return -EINVAL;577			break;578 579		case ALG_SET_OP:580			if (cmsg->cmsg_len < CMSG_LEN(sizeof(u32)))581				return -EINVAL;582			con->op = *(u32 *)CMSG_DATA(cmsg);583			break;584 585		case ALG_SET_AEAD_ASSOCLEN:586			if (cmsg->cmsg_len < CMSG_LEN(sizeof(u32)))587				return -EINVAL;588			con->aead_assoclen = *(u32 *)CMSG_DATA(cmsg);589			break;590 591		default:592			return -EINVAL;593		}594	}595 596	return 0;597}598 599/**600 * af_alg_alloc_tsgl - allocate the TX SGL601 *602 * @sk: socket of connection to user space603 * Return: 0 upon success, < 0 upon error604 */605static int af_alg_alloc_tsgl(struct sock *sk)606{607	struct alg_sock *ask = alg_sk(sk);608	struct af_alg_ctx *ctx = ask->private;609	struct af_alg_tsgl *sgl;610	struct scatterlist *sg = NULL;611 612	sgl = list_entry(ctx->tsgl_list.prev, struct af_alg_tsgl, list);613	if (!list_empty(&ctx->tsgl_list))614		sg = sgl->sg;615 616	if (!sg || sgl->cur >= MAX_SGL_ENTS) {617		sgl = sock_kmalloc(sk,618				   struct_size(sgl, sg, (MAX_SGL_ENTS + 1)),619				   GFP_KERNEL);620		if (!sgl)621			return -ENOMEM;622 623		sg_init_table(sgl->sg, MAX_SGL_ENTS + 1);624		sgl->cur = 0;625 626		if (sg)627			sg_chain(sg, MAX_SGL_ENTS + 1, sgl->sg);628 629		list_add_tail(&sgl->list, &ctx->tsgl_list);630	}631 632	return 0;633}634 635/**636 * af_alg_count_tsgl - Count number of TX SG entries637 *638 * The counting starts from the beginning of the SGL to @bytes. If639 * an @offset is provided, the counting of the SG entries starts at the @offset.640 *641 * @sk: socket of connection to user space642 * @bytes: Count the number of SG entries holding given number of bytes.643 * @offset: Start the counting of SG entries from the given offset.644 * Return: Number of TX SG entries found given the constraints645 */646unsigned int af_alg_count_tsgl(struct sock *sk, size_t bytes, size_t offset)647{648	const struct alg_sock *ask = alg_sk(sk);649	const struct af_alg_ctx *ctx = ask->private;650	const struct af_alg_tsgl *sgl;651	unsigned int i;652	unsigned int sgl_count = 0;653 654	if (!bytes)655		return 0;656 657	list_for_each_entry(sgl, &ctx->tsgl_list, list) {658		const struct scatterlist *sg = sgl->sg;659 660		for (i = 0; i < sgl->cur; i++) {661			size_t bytes_count;662 663			/* Skip offset */664			if (offset >= sg[i].length) {665				offset -= sg[i].length;666				bytes -= sg[i].length;667				continue;668			}669 670			bytes_count = sg[i].length - offset;671 672			offset = 0;673			sgl_count++;674 675			/* If we have seen requested number of bytes, stop */676			if (bytes_count >= bytes)677				return sgl_count;678 679			bytes -= bytes_count;680		}681	}682 683	return sgl_count;684}685EXPORT_SYMBOL_GPL(af_alg_count_tsgl);686 687/**688 * af_alg_pull_tsgl - Release the specified buffers from TX SGL689 *690 * If @dst is non-null, reassign the pages to @dst. The caller must release691 * the pages. If @dst_offset is given only reassign the pages to @dst starting692 * at the @dst_offset (byte). The caller must ensure that @dst is large693 * enough (e.g. by using af_alg_count_tsgl with the same offset).694 *695 * @sk: socket of connection to user space696 * @used: Number of bytes to pull from TX SGL697 * @dst: If non-NULL, buffer is reassigned to dst SGL instead of releasing. The698 *	 caller must release the buffers in dst.699 * @dst_offset: Reassign the TX SGL from given offset. All buffers before700 *	        reaching the offset is released.701 */702void af_alg_pull_tsgl(struct sock *sk, size_t used, struct scatterlist *dst,703		      size_t dst_offset)704{705	struct alg_sock *ask = alg_sk(sk);706	struct af_alg_ctx *ctx = ask->private;707	struct af_alg_tsgl *sgl;708	struct scatterlist *sg;709	unsigned int i, j = 0;710 711	while (!list_empty(&ctx->tsgl_list)) {712		sgl = list_first_entry(&ctx->tsgl_list, struct af_alg_tsgl,713				       list);714		sg = sgl->sg;715 716		for (i = 0; i < sgl->cur; i++) {717			size_t plen = min_t(size_t, used, sg[i].length);718			struct page *page = sg_page(sg + i);719 720			if (!page)721				continue;722 723			/*724			 * Assumption: caller created af_alg_count_tsgl(len)725			 * SG entries in dst.726			 */727			if (dst) {728				if (dst_offset >= plen) {729					/* discard page before offset */730					dst_offset -= plen;731				} else {732					/* reassign page to dst after offset */733					get_page(page);734					sg_set_page(dst + j, page,735						    plen - dst_offset,736						    sg[i].offset + dst_offset);737					dst_offset = 0;738					j++;739				}740			}741 742			sg[i].length -= plen;743			sg[i].offset += plen;744 745			used -= plen;746			ctx->used -= plen;747 748			if (sg[i].length)749				return;750 751			put_page(page);752			sg_assign_page(sg + i, NULL);753		}754 755		list_del(&sgl->list);756		sock_kfree_s(sk, sgl, struct_size(sgl, sg, MAX_SGL_ENTS + 1));757	}758 759	if (!ctx->used)760		ctx->merge = 0;761	ctx->init = ctx->more;762}763EXPORT_SYMBOL_GPL(af_alg_pull_tsgl);764 765/**766 * af_alg_free_areq_sgls - Release TX and RX SGLs of the request767 *768 * @areq: Request holding the TX and RX SGL769 */770static void af_alg_free_areq_sgls(struct af_alg_async_req *areq)771{772	struct sock *sk = areq->sk;773	struct alg_sock *ask = alg_sk(sk);774	struct af_alg_ctx *ctx = ask->private;775	struct af_alg_rsgl *rsgl, *tmp;776	struct scatterlist *tsgl;777	struct scatterlist *sg;778	unsigned int i;779 780	list_for_each_entry_safe(rsgl, tmp, &areq->rsgl_list, list) {781		atomic_sub(rsgl->sg_num_bytes, &ctx->rcvused);782		af_alg_free_sg(&rsgl->sgl);783		list_del(&rsgl->list);784		if (rsgl != &areq->first_rsgl)785			sock_kfree_s(sk, rsgl, sizeof(*rsgl));786	}787 788	tsgl = areq->tsgl;789	if (tsgl) {790		for_each_sg(tsgl, sg, areq->tsgl_entries, i) {791			if (!sg_page(sg))792				continue;793			put_page(sg_page(sg));794		}795 796		sock_kfree_s(sk, tsgl, areq->tsgl_entries * sizeof(*tsgl));797	}798}799 800/**801 * af_alg_wait_for_wmem - wait for availability of writable memory802 *803 * @sk: socket of connection to user space804 * @flags: If MSG_DONTWAIT is set, then only report if function would sleep805 * Return: 0 when writable memory is available, < 0 upon error806 */807static int af_alg_wait_for_wmem(struct sock *sk, unsigned int flags)808{809	DEFINE_WAIT_FUNC(wait, woken_wake_function);810	int err = -ERESTARTSYS;811	long timeout;812 813	if (flags & MSG_DONTWAIT)814		return -EAGAIN;815 816	sk_set_bit(SOCKWQ_ASYNC_NOSPACE, sk);817 818	add_wait_queue(sk_sleep(sk), &wait);819	for (;;) {820		if (signal_pending(current))821			break;822		timeout = MAX_SCHEDULE_TIMEOUT;823		if (sk_wait_event(sk, &timeout, af_alg_writable(sk), &wait)) {824			err = 0;825			break;826		}827	}828	remove_wait_queue(sk_sleep(sk), &wait);829 830	return err;831}832 833/**834 * af_alg_wmem_wakeup - wakeup caller when writable memory is available835 *836 * @sk: socket of connection to user space837 */838void af_alg_wmem_wakeup(struct sock *sk)839{840	struct socket_wq *wq;841 842	if (!af_alg_writable(sk))843		return;844 845	rcu_read_lock();846	wq = rcu_dereference(sk->sk_wq);847	if (skwq_has_sleeper(wq))848		wake_up_interruptible_sync_poll(&wq->wait, EPOLLIN |849							   EPOLLRDNORM |850							   EPOLLRDBAND);851	sk_wake_async_rcu(sk, SOCK_WAKE_WAITD, POLL_IN);852	rcu_read_unlock();853}854EXPORT_SYMBOL_GPL(af_alg_wmem_wakeup);855 856/**857 * af_alg_wait_for_data - wait for availability of TX data858 *859 * @sk: socket of connection to user space860 * @flags: If MSG_DONTWAIT is set, then only report if function would sleep861 * @min: Set to minimum request size if partial requests are allowed.862 * Return: 0 when writable memory is available, < 0 upon error863 */864int af_alg_wait_for_data(struct sock *sk, unsigned flags, unsigned min)865{866	DEFINE_WAIT_FUNC(wait, woken_wake_function);867	struct alg_sock *ask = alg_sk(sk);868	struct af_alg_ctx *ctx = ask->private;869	long timeout;870	int err = -ERESTARTSYS;871 872	if (flags & MSG_DONTWAIT)873		return -EAGAIN;874 875	sk_set_bit(SOCKWQ_ASYNC_WAITDATA, sk);876 877	add_wait_queue(sk_sleep(sk), &wait);878	for (;;) {879		if (signal_pending(current))880			break;881		timeout = MAX_SCHEDULE_TIMEOUT;882		if (sk_wait_event(sk, &timeout,883				  ctx->init && (!ctx->more ||884						(min && ctx->used >= min)),885				  &wait)) {886			err = 0;887			break;888		}889	}890	remove_wait_queue(sk_sleep(sk), &wait);891 892	sk_clear_bit(SOCKWQ_ASYNC_WAITDATA, sk);893 894	return err;895}896EXPORT_SYMBOL_GPL(af_alg_wait_for_data);897 898/**899 * af_alg_data_wakeup - wakeup caller when new data can be sent to kernel900 *901 * @sk: socket of connection to user space902 */903static void af_alg_data_wakeup(struct sock *sk)904{905	struct alg_sock *ask = alg_sk(sk);906	struct af_alg_ctx *ctx = ask->private;907	struct socket_wq *wq;908 909	if (!ctx->used)910		return;911 912	rcu_read_lock();913	wq = rcu_dereference(sk->sk_wq);914	if (skwq_has_sleeper(wq))915		wake_up_interruptible_sync_poll(&wq->wait, EPOLLOUT |916							   EPOLLRDNORM |917							   EPOLLRDBAND);918	sk_wake_async_rcu(sk, SOCK_WAKE_SPACE, POLL_OUT);919	rcu_read_unlock();920}921 922/**923 * af_alg_sendmsg - implementation of sendmsg system call handler924 *925 * The sendmsg system call handler obtains the user data and stores it926 * in ctx->tsgl_list. This implies allocation of the required numbers of927 * struct af_alg_tsgl.928 *929 * In addition, the ctx is filled with the information sent via CMSG.930 *931 * @sock: socket of connection to user space932 * @msg: message from user space933 * @size: size of message from user space934 * @ivsize: the size of the IV for the cipher operation to verify that the935 *	   user-space-provided IV has the right size936 * Return: the number of copied data upon success, < 0 upon error937 */938int af_alg_sendmsg(struct socket *sock, struct msghdr *msg, size_t size,939		   unsigned int ivsize)940{941	struct sock *sk = sock->sk;942	struct alg_sock *ask = alg_sk(sk);943	struct af_alg_ctx *ctx = ask->private;944	struct af_alg_tsgl *sgl;945	struct af_alg_control con = {};946	long copied = 0;947	bool enc = false;948	bool init = false;949	int err = 0;950 951	if (msg->msg_controllen) {952		err = af_alg_cmsg_send(msg, &con);953		if (err)954			return err;955 956		init = true;957		switch (con.op) {958		case ALG_OP_ENCRYPT:959			enc = true;960			break;961		case ALG_OP_DECRYPT:962			enc = false;963			break;964		default:965			return -EINVAL;966		}967 968		if (con.iv && con.iv->ivlen != ivsize)969			return -EINVAL;970	}971 972	lock_sock(sk);973	if (ctx->init && !ctx->more) {974		if (ctx->used) {975			err = -EINVAL;976			goto unlock;977		}978 979		pr_info_once(980			"%s sent an empty control message without MSG_MORE.\n",981			current->comm);982	}983	ctx->init = true;984 985	if (init) {986		ctx->enc = enc;987		if (con.iv)988			memcpy(ctx->iv, con.iv->iv, ivsize);989 990		ctx->aead_assoclen = con.aead_assoclen;991	}992 993	while (size) {994		struct scatterlist *sg;995		size_t len = size;996		ssize_t plen;997 998		/* use the existing memory in an allocated page */999		if (ctx->merge && !(msg->msg_flags & MSG_SPLICE_PAGES)) {1000			sgl = list_entry(ctx->tsgl_list.prev,1001					 struct af_alg_tsgl, list);1002			sg = sgl->sg + sgl->cur - 1;1003			len = min_t(size_t, len,1004				    PAGE_SIZE - sg->offset - sg->length);1005 1006			err = memcpy_from_msg(page_address(sg_page(sg)) +1007					      sg->offset + sg->length,1008					      msg, len);1009			if (err)1010				goto unlock;1011 1012			sg->length += len;1013			ctx->merge = (sg->offset + sg->length) &1014				     (PAGE_SIZE - 1);1015 1016			ctx->used += len;1017			copied += len;1018			size -= len;1019			continue;1020		}1021 1022		if (!af_alg_writable(sk)) {1023			err = af_alg_wait_for_wmem(sk, msg->msg_flags);1024			if (err)1025				goto unlock;1026		}1027 1028		/* allocate a new page */1029		len = min_t(unsigned long, len, af_alg_sndbuf(sk));1030 1031		err = af_alg_alloc_tsgl(sk);1032		if (err)1033			goto unlock;1034 1035		sgl = list_entry(ctx->tsgl_list.prev, struct af_alg_tsgl,1036				 list);1037		sg = sgl->sg;1038		if (sgl->cur)1039			sg_unmark_end(sg + sgl->cur - 1);1040 1041		if (msg->msg_flags & MSG_SPLICE_PAGES) {1042			struct sg_table sgtable = {1043				.sgl		= sg,1044				.nents		= sgl->cur,1045				.orig_nents	= sgl->cur,1046			};1047 1048			plen = extract_iter_to_sg(&msg->msg_iter, len, &sgtable,1049						  MAX_SGL_ENTS - sgl->cur, 0);1050			if (plen < 0) {1051				err = plen;1052				goto unlock;1053			}1054 1055			for (; sgl->cur < sgtable.nents; sgl->cur++)1056				get_page(sg_page(&sg[sgl->cur]));1057			len -= plen;1058			ctx->used += plen;1059			copied += plen;1060			size -= plen;1061			ctx->merge = 0;1062		} else {1063			do {1064				struct page *pg;1065				unsigned int i = sgl->cur;1066 1067				plen = min_t(size_t, len, PAGE_SIZE);1068 1069				pg = alloc_page(GFP_KERNEL);1070				if (!pg) {1071					err = -ENOMEM;1072					goto unlock;1073				}1074 1075				sg_assign_page(sg + i, pg);1076 1077				err = memcpy_from_msg(1078					page_address(sg_page(sg + i)),1079					msg, plen);1080				if (err) {1081					__free_page(sg_page(sg + i));1082					sg_assign_page(sg + i, NULL);1083					goto unlock;1084				}1085 1086				sg[i].length = plen;1087				len -= plen;1088				ctx->used += plen;1089				copied += plen;1090				size -= plen;1091				sgl->cur++;1092			} while (len && sgl->cur < MAX_SGL_ENTS);1093 1094			ctx->merge = plen & (PAGE_SIZE - 1);1095		}1096 1097		if (!size)1098			sg_mark_end(sg + sgl->cur - 1);1099	}1100 1101	err = 0;1102 1103	ctx->more = msg->msg_flags & MSG_MORE;1104 1105unlock:1106	af_alg_data_wakeup(sk);1107	release_sock(sk);1108 1109	return copied ?: err;1110}1111EXPORT_SYMBOL_GPL(af_alg_sendmsg);1112 1113/**1114 * af_alg_free_resources - release resources required for crypto request1115 * @areq: Request holding the TX and RX SGL1116 */1117void af_alg_free_resources(struct af_alg_async_req *areq)1118{1119	struct sock *sk = areq->sk;1120	struct af_alg_ctx *ctx;1121 1122	af_alg_free_areq_sgls(areq);1123	sock_kfree_s(sk, areq, areq->areqlen);1124 1125	ctx = alg_sk(sk)->private;1126	ctx->inflight = false;1127}1128EXPORT_SYMBOL_GPL(af_alg_free_resources);1129 1130/**1131 * af_alg_async_cb - AIO callback handler1132 * @data: async request completion data1133 * @err: if non-zero, error result to be returned via ki_complete();1134 *       otherwise return the AIO output length via ki_complete().1135 *1136 * This handler cleans up the struct af_alg_async_req upon completion of the1137 * AIO operation.1138 *1139 * The number of bytes to be generated with the AIO operation must be set1140 * in areq->outlen before the AIO callback handler is invoked.1141 */1142void af_alg_async_cb(void *data, int err)1143{1144	struct af_alg_async_req *areq = data;1145	struct sock *sk = areq->sk;1146	struct kiocb *iocb = areq->iocb;1147	unsigned int resultlen;1148 1149	/* Buffer size written by crypto operation. */1150	resultlen = areq->outlen;1151 1152	af_alg_free_resources(areq);1153	sock_put(sk);1154 1155	iocb->ki_complete(iocb, err ? err : (int)resultlen);1156}1157EXPORT_SYMBOL_GPL(af_alg_async_cb);1158 1159/**1160 * af_alg_poll - poll system call handler1161 * @file: file pointer1162 * @sock: socket to poll1163 * @wait: poll_table1164 */1165__poll_t af_alg_poll(struct file *file, struct socket *sock,1166			 poll_table *wait)1167{1168	struct sock *sk = sock->sk;1169	struct alg_sock *ask = alg_sk(sk);1170	struct af_alg_ctx *ctx = ask->private;1171	__poll_t mask;1172 1173	sock_poll_wait(file, sock, wait);1174	mask = 0;1175 1176	if (!ctx->more || ctx->used)1177		mask |= EPOLLIN | EPOLLRDNORM;1178 1179	if (af_alg_writable(sk))1180		mask |= EPOLLOUT | EPOLLWRNORM | EPOLLWRBAND;1181 1182	return mask;1183}1184EXPORT_SYMBOL_GPL(af_alg_poll);1185 1186/**1187 * af_alg_alloc_areq - allocate struct af_alg_async_req1188 *1189 * @sk: socket of connection to user space1190 * @areqlen: size of struct af_alg_async_req + crypto_*_reqsize1191 * Return: allocated data structure or ERR_PTR upon error1192 */1193struct af_alg_async_req *af_alg_alloc_areq(struct sock *sk,1194					   unsigned int areqlen)1195{1196	struct af_alg_ctx *ctx = alg_sk(sk)->private;1197	struct af_alg_async_req *areq;1198 1199	/* Only one AIO request can be in flight. */1200	if (ctx->inflight)1201		return ERR_PTR(-EBUSY);1202 1203	areq = sock_kmalloc(sk, areqlen, GFP_KERNEL);1204	if (unlikely(!areq))1205		return ERR_PTR(-ENOMEM);1206 1207	ctx->inflight = true;1208 1209	areq->areqlen = areqlen;1210	areq->sk = sk;1211	areq->first_rsgl.sgl.sgt.sgl = areq->first_rsgl.sgl.sgl;1212	areq->last_rsgl = NULL;1213	INIT_LIST_HEAD(&areq->rsgl_list);1214	areq->tsgl = NULL;1215	areq->tsgl_entries = 0;1216 1217	return areq;1218}1219EXPORT_SYMBOL_GPL(af_alg_alloc_areq);1220 1221/**1222 * af_alg_get_rsgl - create the RX SGL for the output data from the crypto1223 *		     operation1224 *1225 * @sk: socket of connection to user space1226 * @msg: user space message1227 * @flags: flags used to invoke recvmsg with1228 * @areq: instance of the cryptographic request that will hold the RX SGL1229 * @maxsize: maximum number of bytes to be pulled from user space1230 * @outlen: number of bytes in the RX SGL1231 * Return: 0 on success, < 0 upon error1232 */1233int af_alg_get_rsgl(struct sock *sk, struct msghdr *msg, int flags,1234		    struct af_alg_async_req *areq, size_t maxsize,1235		    size_t *outlen)1236{1237	struct alg_sock *ask = alg_sk(sk);1238	struct af_alg_ctx *ctx = ask->private;1239	size_t len = 0;1240 1241	while (maxsize > len && msg_data_left(msg)) {1242		struct af_alg_rsgl *rsgl;1243		ssize_t err;1244		size_t seglen;1245 1246		/* limit the amount of readable buffers */1247		if (!af_alg_readable(sk))1248			break;1249 1250		seglen = min_t(size_t, (maxsize - len),1251			       msg_data_left(msg));1252 1253		if (list_empty(&areq->rsgl_list)) {1254			rsgl = &areq->first_rsgl;1255		} else {1256			rsgl = sock_kmalloc(sk, sizeof(*rsgl), GFP_KERNEL);1257			if (unlikely(!rsgl))1258				return -ENOMEM;1259		}1260 1261		rsgl->sgl.need_unpin =1262			iov_iter_extract_will_pin(&msg->msg_iter);1263		rsgl->sgl.sgt.sgl = rsgl->sgl.sgl;1264		rsgl->sgl.sgt.nents = 0;1265		rsgl->sgl.sgt.orig_nents = 0;1266		list_add_tail(&rsgl->list, &areq->rsgl_list);1267 1268		sg_init_table(rsgl->sgl.sgt.sgl, ALG_MAX_PAGES);1269		err = extract_iter_to_sg(&msg->msg_iter, seglen, &rsgl->sgl.sgt,1270					 ALG_MAX_PAGES, 0);1271		if (err < 0) {1272			rsgl->sg_num_bytes = 0;1273			return err;1274		}1275 1276		sg_mark_end(rsgl->sgl.sgt.sgl + rsgl->sgl.sgt.nents - 1);1277 1278		/* chain the new scatterlist with previous one */1279		if (areq->last_rsgl)1280			af_alg_link_sg(&areq->last_rsgl->sgl, &rsgl->sgl);1281 1282		areq->last_rsgl = rsgl;1283		len += err;1284		atomic_add(err, &ctx->rcvused);1285		rsgl->sg_num_bytes = err;1286	}1287 1288	*outlen = len;1289	return 0;1290}1291EXPORT_SYMBOL_GPL(af_alg_get_rsgl);1292 1293static int __init af_alg_init(void)1294{1295	int err = proto_register(&alg_proto, 0);1296 1297	if (err)1298		goto out;1299 1300	err = sock_register(&alg_family);1301	if (err != 0)1302		goto out_unregister_proto;1303 1304out:1305	return err;1306 1307out_unregister_proto:1308	proto_unregister(&alg_proto);1309	goto out;1310}1311 1312static void __exit af_alg_exit(void)1313{1314	sock_unregister(PF_ALG);1315	proto_unregister(&alg_proto);1316}1317 1318module_init(af_alg_init);1319module_exit(af_alg_exit);1320MODULE_DESCRIPTION("Crypto userspace interface");1321MODULE_LICENSE("GPL");1322MODULE_ALIAS_NETPROTO(AF_ALG);1323