Commit 7344eea1 authored by Harald Freudenberger's avatar Harald Freudenberger Committed by Vasily Gorbik
Browse files

s390/pkey: Split pkey_unlocked_ioctl function



Split the very huge ioctl handling function pkey_unlocked_ioctl()
into individual functions per each IOCTL command.

There is no change in functional code coming with this patch.
The work is a simple copy-and-paste with the goal to have
the functionality absolutely untouched.

Signed-off-by: default avatarHarald Freudenberger <freude@linux.ibm.com>
Reviewed-by: default avatarHolger Dengler <dengler@linux.ibm.com>
Signed-off-by: default avatarVasily Gorbik <gor@linux.ibm.com>
parent c3dcb058
Loading
Loading
Loading
Loading
+490 −388
Original line number Diff line number Diff line
@@ -1344,15 +1344,10 @@ static void *_copy_apqns_from_user(void __user *uapqns, size_t nr_apqns)
	return memdup_user(uapqns, nr_apqns * sizeof(struct pkey_apqn));
}

static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd,
				unsigned long arg)
static int pkey_ioctl_genseck(struct pkey_genseck __user *ugs)
{
	int rc;

	switch (cmd) {
	case PKEY_GENSECK: {
		struct pkey_genseck __user *ugs = (void __user *)arg;
	struct pkey_genseck kgs;
	int rc;

	if (copy_from_user(&kgs, ugs, sizeof(kgs)))
		return -EFAULT;
@@ -1362,11 +1357,14 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd,
	if (!rc && copy_to_user(ugs, &kgs, sizeof(kgs)))
		rc = -EFAULT;
	memzero_explicit(&kgs, sizeof(kgs));
		break;

	return rc;
}
	case PKEY_CLR2SECK: {
		struct pkey_clr2seck __user *ucs = (void __user *)arg;

static int pkey_ioctl_clr2seck(struct pkey_clr2seck __user *ucs)
{
	struct pkey_clr2seck kcs;
	int rc;

	if (copy_from_user(&kcs, ucs, sizeof(kcs)))
		return -EFAULT;
@@ -1376,11 +1374,14 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd,
	if (!rc && copy_to_user(ucs, &kcs, sizeof(kcs)))
		rc = -EFAULT;
	memzero_explicit(&kcs, sizeof(kcs));
		break;

	return rc;
}
	case PKEY_SEC2PROTK: {
		struct pkey_sec2protk __user *usp = (void __user *)arg;

static int pkey_ioctl_sec2protk(struct pkey_sec2protk __user *usp)
{
	struct pkey_sec2protk ksp;
	int rc;

	if (copy_from_user(&ksp, usp, sizeof(ksp)))
		return -EFAULT;
@@ -1392,11 +1393,14 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd,
	if (!rc && copy_to_user(usp, &ksp, sizeof(ksp)))
		rc = -EFAULT;
	memzero_explicit(&ksp, sizeof(ksp));
		break;

	return rc;
}
	case PKEY_CLR2PROTK: {
		struct pkey_clr2protk __user *ucp = (void __user *)arg;

static int pkey_ioctl_clr2protk(struct pkey_clr2protk __user *ucp)
{
	struct pkey_clr2protk kcp;
	int rc;

	if (copy_from_user(&kcp, ucp, sizeof(kcp)))
		return -EFAULT;
@@ -1408,11 +1412,14 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd,
	if (!rc && copy_to_user(ucp, &kcp, sizeof(kcp)))
		rc = -EFAULT;
	memzero_explicit(&kcp, sizeof(kcp));
		break;

	return rc;
}
	case PKEY_FINDCARD: {
		struct pkey_findcard __user *ufc = (void __user *)arg;

static int pkey_ioctl_findcard(struct pkey_findcard __user *ufc)
{
	struct pkey_findcard kfc;
	int rc;

	if (copy_from_user(&kfc, ufc, sizeof(kfc)))
		return -EFAULT;
@@ -1420,14 +1427,17 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd,
			  &kfc.cardnr, &kfc.domain, 1);
	pr_debug("%s cca_findcard()=%d\n", __func__, rc);
	if (rc < 0)
			break;
		return rc;
	if (copy_to_user(ufc, &kfc, sizeof(kfc)))
		return -EFAULT;
		break;

	return 0;
}
	case PKEY_SKEY2PKEY: {
		struct pkey_skey2pkey __user *usp = (void __user *)arg;

static int pkey_ioctl_skey2pkey(struct pkey_skey2pkey __user *usp)
{
	struct pkey_skey2pkey ksp;
	int rc;

	if (copy_from_user(&ksp, usp, sizeof(ksp)))
		return -EFAULT;
@@ -1438,11 +1448,14 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd,
	if (!rc && copy_to_user(usp, &ksp, sizeof(ksp)))
		rc = -EFAULT;
	memzero_explicit(&ksp, sizeof(ksp));
		break;

	return rc;
}
	case PKEY_VERIFYKEY: {
		struct pkey_verifykey __user *uvk = (void __user *)arg;

static int pkey_ioctl_verifykey(struct pkey_verifykey __user *uvk)
{
	struct pkey_verifykey kvk;
	int rc;

	if (copy_from_user(&kvk, uvk, sizeof(kvk)))
		return -EFAULT;
@@ -1452,11 +1465,14 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd,
	if (!rc && copy_to_user(uvk, &kvk, sizeof(kvk)))
		rc = -EFAULT;
	memzero_explicit(&kvk, sizeof(kvk));
		break;

	return rc;
}
	case PKEY_GENPROTK: {
		struct pkey_genprotk __user *ugp = (void __user *)arg;

static int pkey_ioctl_genprotk(struct pkey_genprotk __user *ugp)
{
	struct pkey_genprotk kgp;
	int rc;

	if (copy_from_user(&kgp, ugp, sizeof(kgp)))
		return -EFAULT;
@@ -1467,11 +1483,14 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd,
	if (!rc && copy_to_user(ugp, &kgp, sizeof(kgp)))
		rc = -EFAULT;
	memzero_explicit(&kgp, sizeof(kgp));
		break;

	return rc;
}
	case PKEY_VERIFYPROTK: {
		struct pkey_verifyprotk __user *uvp = (void __user *)arg;

static int pkey_ioctl_verifyprotk(struct pkey_verifyprotk __user *uvp)
{
	struct pkey_verifyprotk kvp;
	int rc;

	if (copy_from_user(&kvp, uvp, sizeof(kvp)))
		return -EFAULT;
@@ -1479,12 +1498,15 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd,
				kvp.protkey.len, kvp.protkey.type);
	pr_debug("%s pkey_verifyprotkey()=%d\n", __func__, rc);
	memzero_explicit(&kvp, sizeof(kvp));
		break;

	return rc;
}
	case PKEY_KBLOB2PROTK: {
		struct pkey_kblob2pkey __user *utp = (void __user *)arg;

static int pkey_ioctl_kblob2protk(struct pkey_kblob2pkey __user *utp)
{
	struct pkey_kblob2pkey ktp;
	u8 *kkey;
	int rc;

	if (copy_from_user(&ktp, utp, sizeof(ktp)))
		return -EFAULT;
@@ -1499,14 +1521,17 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd,
	if (!rc && copy_to_user(utp, &ktp, sizeof(ktp)))
		rc = -EFAULT;
	memzero_explicit(&ktp, sizeof(ktp));
		break;

	return rc;
}
	case PKEY_GENSECK2: {
		struct pkey_genseck2 __user *ugs = (void __user *)arg;

static int pkey_ioctl_genseck2(struct pkey_genseck2 __user *ugs)
{
	size_t klen = KEYBLOBBUFSIZE;
	struct pkey_genseck2 kgs;
	struct pkey_apqn *apqns;
	u8 *kkey;
	int rc;

	if (copy_from_user(&kgs, ugs, sizeof(kgs)))
		return -EFAULT;
@@ -1525,7 +1550,7 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd,
	kfree(apqns);
	if (rc) {
		kfree_sensitive(kkey);
			break;
		return rc;
	}
	if (kgs.key) {
		if (kgs.keylen < klen) {
@@ -1541,14 +1566,17 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd,
	if (copy_to_user(ugs, &kgs, sizeof(kgs)))
		rc = -EFAULT;
	kfree_sensitive(kkey);
		break;

	return rc;
}
	case PKEY_CLR2SECK2: {
		struct pkey_clr2seck2 __user *ucs = (void __user *)arg;

static int pkey_ioctl_clr2seck2(struct pkey_clr2seck2 __user *ucs)
{
	size_t klen = KEYBLOBBUFSIZE;
	struct pkey_clr2seck2 kcs;
	struct pkey_apqn *apqns;
	u8 *kkey;
	int rc;

	if (copy_from_user(&kcs, ucs, sizeof(kcs)))
		return -EFAULT;
@@ -1571,7 +1599,7 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd,
	if (rc) {
		kfree_sensitive(kkey);
		memzero_explicit(&kcs, sizeof(kcs));
			break;
		return rc;
	}
	if (kcs.key) {
		if (kcs.keylen < klen) {
@@ -1590,12 +1618,15 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd,
		rc = -EFAULT;
	memzero_explicit(&kcs, sizeof(kcs));
	kfree_sensitive(kkey);
		break;

	return rc;
}
	case PKEY_VERIFYKEY2: {
		struct pkey_verifykey2 __user *uvk = (void __user *)arg;

static int pkey_ioctl_verifykey2(struct pkey_verifykey2 __user *uvk)
{
	struct pkey_verifykey2 kvk;
	u8 *kkey;
	int rc;

	if (copy_from_user(&kvk, uvk, sizeof(kvk)))
		return -EFAULT;
@@ -1608,16 +1639,19 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd,
	pr_debug("%s pkey_verifykey2()=%d\n", __func__, rc);
	kfree_sensitive(kkey);
	if (rc)
			break;
		return rc;
	if (copy_to_user(uvk, &kvk, sizeof(kvk)))
		return -EFAULT;
		break;

	return 0;
}
	case PKEY_KBLOB2PROTK2: {
		struct pkey_kblob2pkey2 __user *utp = (void __user *)arg;

static int pkey_ioctl_kblob2protk2(struct pkey_kblob2pkey2 __user *utp)
{
	struct pkey_apqn *apqns = NULL;
	struct pkey_kblob2pkey2 ktp;
	u8 *kkey;
	int rc;

	if (copy_from_user(&ktp, utp, sizeof(ktp)))
		return -EFAULT;
@@ -1640,14 +1674,17 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd,
	if (!rc && copy_to_user(utp, &ktp, sizeof(ktp)))
		rc = -EFAULT;
	memzero_explicit(&ktp, sizeof(ktp));
		break;

	return rc;
}
	case PKEY_APQNS4K: {
		struct pkey_apqns4key __user *uak = (void __user *)arg;

static int pkey_ioctl_apqns4k(struct pkey_apqns4key __user *uak)
{
	struct pkey_apqn *apqns = NULL;
	struct pkey_apqns4key kak;
	size_t nr_apqns, len;
	u8 *kkey;
	int rc;

	if (copy_from_user(&kak, uak, sizeof(kak)))
		return -EFAULT;
@@ -1670,7 +1707,7 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd,
	kfree_sensitive(kkey);
	if (rc && rc != -ENOSPC) {
		kfree(apqns);
			break;
		return rc;
	}
	if (!rc && kak.apqns) {
		if (nr_apqns > kak.apqn_entries) {
@@ -1689,13 +1726,16 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd,
	if (copy_to_user(uak, &kak, sizeof(kak)))
		rc = -EFAULT;
	kfree(apqns);
		break;

	return rc;
}
	case PKEY_APQNS4KT: {
		struct pkey_apqns4keytype __user *uat = (void __user *)arg;

static int pkey_ioctl_apqns4kt(struct pkey_apqns4keytype __user *uat)
{
	struct pkey_apqn *apqns = NULL;
	struct pkey_apqns4keytype kat;
	size_t nr_apqns, len;
	int rc;

	if (copy_from_user(&kat, uat, sizeof(kat)))
		return -EFAULT;
@@ -1712,7 +1752,7 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd,
	pr_debug("%s pkey_apqns4keytype()=%d\n", __func__, rc);
	if (rc && rc != -ENOSPC) {
		kfree(apqns);
			break;
		return rc;
	}
	if (!rc && kat.apqns) {
		if (nr_apqns > kat.apqn_entries) {
@@ -1731,14 +1771,17 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd,
	if (copy_to_user(uat, &kat, sizeof(kat)))
		rc = -EFAULT;
	kfree(apqns);
		break;

	return rc;
}
	case PKEY_KBLOB2PROTK3: {
		struct pkey_kblob2pkey3 __user *utp = (void __user *)arg;

static int pkey_ioctl_kblob2protk3(struct pkey_kblob2pkey3 __user *utp)
{
	u32 protkeylen = PROTKEYBLOBBUFSIZE;
	struct pkey_apqn *apqns = NULL;
	struct pkey_kblob2pkey3 ktp;
	u8 *kkey, *protkey;
	int rc;

	if (copy_from_user(&ktp, utp, sizeof(ktp)))
		return -EFAULT;
@@ -1764,7 +1807,7 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd,
	kfree_sensitive(kkey);
	if (rc) {
		kfree_sensitive(protkey);
			break;
		return rc;
	}
	if (ktp.pkey && ktp.pkeylen) {
		if (protkeylen > ktp.pkeylen) {
@@ -1780,8 +1823,67 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd,
	ktp.pkeylen = protkeylen;
	if (copy_to_user(utp, &ktp, sizeof(ktp)))
		return -EFAULT;
		break;

	return 0;
}

static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd,
				unsigned long arg)
{
	int rc;

	switch (cmd) {
	case PKEY_GENSECK:
		rc = pkey_ioctl_genseck((struct pkey_genseck __user *)arg);
		break;
	case PKEY_CLR2SECK:
		rc = pkey_ioctl_clr2seck((struct pkey_clr2seck __user *)arg);
		break;
	case PKEY_SEC2PROTK:
		rc = pkey_ioctl_sec2protk((struct pkey_sec2protk __user *)arg);
		break;
	case PKEY_CLR2PROTK:
		rc = pkey_ioctl_clr2protk((struct pkey_clr2protk __user *)arg);
		break;
	case PKEY_FINDCARD:
		rc = pkey_ioctl_findcard((struct pkey_findcard __user *)arg);
		break;
	case PKEY_SKEY2PKEY:
		rc = pkey_ioctl_skey2pkey((struct pkey_skey2pkey __user *)arg);
		break;
	case PKEY_VERIFYKEY:
		rc = pkey_ioctl_verifykey((struct pkey_verifykey __user *)arg);
		break;
	case PKEY_GENPROTK:
		rc = pkey_ioctl_genprotk((struct pkey_genprotk __user *)arg);
		break;
	case PKEY_VERIFYPROTK:
		rc = pkey_ioctl_verifyprotk((struct pkey_verifyprotk __user *)arg);
		break;
	case PKEY_KBLOB2PROTK:
		rc = pkey_ioctl_kblob2protk((struct pkey_kblob2pkey __user *)arg);
		break;
	case PKEY_GENSECK2:
		rc = pkey_ioctl_genseck2((struct pkey_genseck2 __user *)arg);
		break;
	case PKEY_CLR2SECK2:
		rc = pkey_ioctl_clr2seck2((struct pkey_clr2seck2 __user *)arg);
		break;
	case PKEY_VERIFYKEY2:
		rc = pkey_ioctl_verifykey2((struct pkey_verifykey2 __user *)arg);
		break;
	case PKEY_KBLOB2PROTK2:
		rc = pkey_ioctl_kblob2protk2((struct pkey_kblob2pkey2 __user *)arg);
		break;
	case PKEY_APQNS4K:
		rc = pkey_ioctl_apqns4k((struct pkey_apqns4key __user *)arg);
		break;
	case PKEY_APQNS4KT:
		rc = pkey_ioctl_apqns4kt((struct pkey_apqns4keytype __user *)arg);
		break;
	case PKEY_KBLOB2PROTK3:
		rc = pkey_ioctl_kblob2protk3((struct pkey_kblob2pkey3 __user *)arg);
		break;
	default:
		/* unknown/unsupported ioctl cmd */
		return -ENOTTY;