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

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
......@@ -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;
}
case PKEY_CLR2SECK: {
struct pkey_clr2seck __user *ucs = (void __user *)arg;
return rc;
}
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;
}
case PKEY_SEC2PROTK: {
struct pkey_sec2protk __user *usp = (void __user *)arg;
return rc;
}
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;
}
case PKEY_CLR2PROTK: {
struct pkey_clr2protk __user *ucp = (void __user *)arg;
return rc;
}
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;
}
case PKEY_FINDCARD: {
struct pkey_findcard __user *ufc = (void __user *)arg;
return rc;
}
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;
}
case PKEY_SKEY2PKEY: {
struct pkey_skey2pkey __user *usp = (void __user *)arg;
return 0;
}
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;
}
case PKEY_VERIFYKEY: {
struct pkey_verifykey __user *uvk = (void __user *)arg;
return rc;
}
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;
}
case PKEY_GENPROTK: {
struct pkey_genprotk __user *ugp = (void __user *)arg;
return rc;
}
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;
}
case PKEY_VERIFYPROTK: {
struct pkey_verifyprotk __user *uvp = (void __user *)arg;
return rc;
}
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;
}
case PKEY_KBLOB2PROTK: {
struct pkey_kblob2pkey __user *utp = (void __user *)arg;
return rc;
}
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;
}
case PKEY_GENSECK2: {
struct pkey_genseck2 __user *ugs = (void __user *)arg;
return rc;
}
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;
}
case PKEY_CLR2SECK2: {
struct pkey_clr2seck2 __user *ucs = (void __user *)arg;
return rc;
}
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;
}
case PKEY_VERIFYKEY2: {
struct pkey_verifykey2 __user *uvk = (void __user *)arg;
return rc;
}
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;
}
case PKEY_KBLOB2PROTK2: {
struct pkey_kblob2pkey2 __user *utp = (void __user *)arg;
return 0;
}
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;
}
case PKEY_APQNS4K: {
struct pkey_apqns4key __user *uak = (void __user *)arg;
return rc;
}
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;
}
case PKEY_APQNS4KT: {
struct pkey_apqns4keytype __user *uat = (void __user *)arg;
return rc;
}
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;
}
case PKEY_KBLOB2PROTK3: {
struct pkey_kblob2pkey3 __user *utp = (void __user *)arg;
return rc;
}
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;
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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment