public inbox for linux-s390@vger.kernel.org
 help / color / mirror / Atom feed
From: Janosch Frank <frankja@linux.ibm.com>
To: Steffen Eiden <seiden@linux.ibm.com>,
	kvm@vger.kernel.org, linux-s390@vger.kernel.org,
	linux-kernel@vger.kernel.org,
	Viktor Mihajlovski <mihajlov@linux.ibm.com>
Cc: Claudio Imbrenda <imbrenda@linux.ibm.com>,
	Nico Boehr <nrb@linux.ibm.com>,
	Christian Borntraeger <borntraeger@linux.ibm.com>,
	Heiko Carstens <hca@linux.ibm.com>,
	Hendrik Brueckner <brueckner@linux.ibm.com>
Subject: Re: [PATCH v3 2/6] s390/uvdevice: Add 'Add Secret' UVC
Date: Tue, 6 Jun 2023 16:18:43 +0200	[thread overview]
Message-ID: <981c660f-27cb-5cbd-f965-3ecc1b36aa7a@linux.ibm.com> (raw)
In-Reply-To: <20230606113736.2934503-3-seiden@linux.ibm.com>

On 6/6/23 13:37, Steffen Eiden wrote:
> Userspace can call the Add Secret Ultravisor Call
> using IOCTLs on the uvdevice.
> During the handling of the new IOCTL nr the uvdevice will do some sanity
> checks first. Then, copy the request data to kernel space, perform the
> Ultravisor command, and copy the return codes to userspace.
> If the Add Secret UV facility is not present,
> UV will return invalid command rc. This won't be fenced in the driver
> and does not result in a negative return value. This is also true for
> any other possible error code the UV can return.

The Add Secret UV call sends an encrypted and cryptographically verified 
request to the Ultravisor. The request inserts a protected guest's 
secret into the Ultravisor for later use.

The uvdevice is merely transporting the request from userspace to the 
Ultravisor. It's neither checking nor manipulating the request data.

> 
> Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
> ---
>   arch/s390/include/asm/uv.h            | 14 +++++++
>   arch/s390/include/uapi/asm/uvdevice.h |  4 ++
>   drivers/s390/char/uvdevice.c          | 57 +++++++++++++++++++++++++++
>   3 files changed, 75 insertions(+)
> 
> diff --git a/arch/s390/include/asm/uv.h b/arch/s390/include/asm/uv.h
> index 28a9ad57b6f1..1babc70ea5d4 100644
> --- a/arch/s390/include/asm/uv.h
> +++ b/arch/s390/include/asm/uv.h
> @@ -58,6 +58,7 @@
>   #define UVC_CMD_SET_SHARED_ACCESS	0x1000
>   #define UVC_CMD_REMOVE_SHARED_ACCESS	0x1001
>   #define UVC_CMD_RETR_ATTEST		0x1020
> +#define UVC_CMD_ADD_SECRET		0x1031
>   
>   /* Bits in installed uv calls */
>   enum uv_cmds_inst {
> @@ -88,6 +89,7 @@ enum uv_cmds_inst {
>   	BIT_UVC_CMD_DUMP_CPU = 26,
>   	BIT_UVC_CMD_DUMP_COMPLETE = 27,
>   	BIT_UVC_CMD_RETR_ATTEST = 28,
> +	BIT_UVC_CMD_ADD_SECRET = 29,
>   };
>   
>   enum uv_feat_ind {
> @@ -292,6 +294,18 @@ struct uv_cb_dump_complete {
>   	u64 reserved30[5];
>   } __packed __aligned(8);
>   
> +/*
> + * A common UV call struct for pv guests that contains a single address
> + * Examples:
> + * Add Secret
> + */
> +struct uv_cb_guest_addr {
> +	struct uv_cb_header header;
> +	u64 reserved08[3];
> +	u64 addr;
> +	u64 reserved28[4];
> +} __packed __aligned(8);
> +
>   static inline int __uv_call(unsigned long r1, unsigned long r2)
>   {
>   	int cc;
> diff --git a/arch/s390/include/uapi/asm/uvdevice.h b/arch/s390/include/uapi/asm/uvdevice.h
> index 9d9b684836c2..e77410226598 100644
> --- a/arch/s390/include/uapi/asm/uvdevice.h
> +++ b/arch/s390/include/uapi/asm/uvdevice.h
> @@ -69,6 +69,7 @@ struct uvio_uvdev_info {
>   #define UVIO_ATT_ARCB_MAX_LEN		0x100000
>   #define UVIO_ATT_MEASUREMENT_MAX_LEN	0x8000
>   #define UVIO_ATT_ADDITIONAL_MAX_LEN	0x8000
> +#define UVIO_ADD_SECRET_MAX_LEN		0x100000
>   
>   #define UVIO_DEVICE_NAME "uv"
>   #define UVIO_TYPE_UVC 'u'
> @@ -76,6 +77,7 @@ struct uvio_uvdev_info {
>   enum UVIO_IOCTL_NR {
>   	UVIO_IOCTL_UVDEV_INFO_NR = 0x00,
>   	UVIO_IOCTL_ATT_NR,
> +	UVIO_IOCTL_ADD_SECRET_NR,
>   	/* must be the last entry */
>   	UVIO_IOCTL_NUM_IOCTLS
>   };
> @@ -83,9 +85,11 @@ enum UVIO_IOCTL_NR {
>   #define UVIO_IOCTL(nr)		_IOWR(UVIO_TYPE_UVC, nr, struct uvio_ioctl_cb)
>   #define UVIO_IOCTL_UVDEV_INFO	UVIO_IOCTL(UVIO_IOCTL_UVDEV_INFO_NR)
>   #define UVIO_IOCTL_ATT		UVIO_IOCTL(UVIO_IOCTL_ATT_NR)
> +#define UVIO_IOCTL_ADD_SECRET	UVIO_IOCTL(UVIO_IOCTL_ADD_SECRET_NR)
>   
>   #define UVIO_SUPP_CALL(nr)	(1ULL << (nr))
>   #define UVIO_SUPP_UDEV_INFO	UVIO_SUPP_CALL(UVIO_IOCTL_UDEV_INFO_NR)
>   #define UVIO_SUPP_ATT		UVIO_SUPP_CALL(UVIO_IOCTL_ATT_NR)
> +#define UVIO_SUPP_ADD_SECRET	UVIO_SUPP_CALL(UVIO_IOCTL_ADD_SECRET_NR)
>   
>   #endif /* __S390_ASM_UVDEVICE_H */
> diff --git a/drivers/s390/char/uvdevice.c b/drivers/s390/char/uvdevice.c
> index 4efeebcaf382..c10554bc1fee 100644
> --- a/drivers/s390/char/uvdevice.c
> +++ b/drivers/s390/char/uvdevice.c
> @@ -37,6 +37,7 @@
>   static const u32 ioctl_nr_to_uvc_bit[] __initconst = {
>   	[UVIO_IOCTL_UVDEV_INFO_NR] = BIT_UVIO_INTERNAL,
>   	[UVIO_IOCTL_ATT_NR] = BIT_UVC_CMD_RETR_ATTEST,
> +	[UVIO_IOCTL_ADD_SECRET_NR] = BIT_UVC_CMD_ADD_SECRET,
>   };
>   
>   static_assert(ARRAY_SIZE(ioctl_nr_to_uvc_bit) == UVIO_IOCTL_NUM_IOCTLS);
> @@ -231,6 +232,59 @@ static int uvio_attestation(struct uvio_ioctl_cb *uv_ioctl)
>   	return ret;
>   }
>   
> +/** uvio_add_secret() - perform an Add Secret UVC
> + *
> + * @uv_ioctl: ioctl control block
> + *
> + * uvio_add_secret() performs the Add Secret Ultravisor Call. It verifies that
> + * the given userspace argument address is valid and its size is sane. Every
> + * other check is made by the Ultravisor (UV) and won't result in a negative
> + * return value. It copies the request to kernelspace, performs the UV-call, and
> + * copies the return codes to the ioctl control block. The argument has to point
> + * to an Add Secret Request Control Block. It is an encrypted and
> + * cryptographically verified request generated by userspace to insert the
> + * actual secret into the UV. If the Add Secret UV facility is not present, UV
> + * will return invalid command rc. This won't be fenced in the driver and does
> + * not result in a negative return value.
> + *
> + * Context: might sleep
> + *
> + * Return: 0 on success or a negative error code on error.
> + */

Maybe:

/** uvio_add_secret() - perform an Add Secret UVC 
 
 
 

  * 
 
 
 

  * @uv_ioctl: ioctl control block 
 
 
 

  * 
 
 
 

  * uvio_add_secret() performs the Add Secret Ultravisor Call. 
 
 
 

  * 
 
 
 

  * The given userspace argument address and size are verified to be 
 
 
 

  * valid but every other check is made by the Ultravisor 
 
 
 

  * (UV). Therefore UV errors won't result in a negative return 
 
 
 

  * value. The request is then copied to kernelspace, the UV-call is 
 
 
 

  * performed and the results are copied back to userspace. 
 
 
 

  * 
 
 
 

  * The argument has to point to an Add Secret Request Control Block 
 
 
 

  * which is an encrypted and cryptographically verified request that 
 
 
 

  * inserts a protected guest's secrets into the Ultravisor for later 
 
 
 

  * use. 
 
 
 

  * 
 
 
 

  * If the Add Secret UV facility is not present, UV will return 
 
 
 

  * invalid command rc. This won't be fenced in the driver and does not 
 
 
 

  * result in a negative return value. 
 
 
 

  * 
 
 
 

  * Context: might sleep 
 
 
 

  * 
 
 
 

  * Return: 0 on success or a negative error code on error. 
 
 
 

  */


> +static int uvio_add_secret(struct uvio_ioctl_cb *uv_ioctl)
> +{
> +	void __user *user_buf_arg = (void __user *)uv_ioctl->argument_addr;
> +	struct uv_cb_guest_addr uvcb = {
> +		.header.len = sizeof(uvcb),
> +		.header.cmd = UVC_CMD_ADD_SECRET,
> +	};
> +	void *asrcb = NULL;
> +	int ret;
> +
> +	if (uv_ioctl->argument_len > UVIO_ADD_SECRET_MAX_LEN)
> +		return -EINVAL;
> +	if (uv_ioctl->argument_len == 0)
> +		return -EINVAL;
> +
> +	asrcb = kvzalloc(uv_ioctl->argument_len, GFP_KERNEL);
> +	if (!asrcb)
> +		return -ENOMEM;
> +
> +	ret = -EFAULT;
> +	if (copy_from_user(asrcb, user_buf_arg, uv_ioctl->argument_len))
> +		goto out;
> +
> +	ret = 0;
> +	uvcb.addr = (u64)asrcb;
> +	uv_call_sched(0, (u64)&uvcb);
> +	uv_ioctl->uv_rc = uvcb.header.rc;
> +	uv_ioctl->uv_rrc = uvcb.header.rrc;
> +
> +out:
> +	kvfree(asrcb);
> +	return ret;
> +}
> +
>   static int uvio_copy_and_check_ioctl(struct uvio_ioctl_cb *ioctl, void __user *argp,
>   				     unsigned long cmd)
>   {
> @@ -275,6 +329,9 @@ static long uvio_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
>   	case UVIO_IOCTL_ATT_NR:
>   		ret = uvio_attestation(&uv_ioctl);
>   		break;
> +	case UVIO_IOCTL_ADD_SECRET_NR:
> +		ret = uvio_add_secret(&uv_ioctl);
> +		break;
>   	default:
>   		ret = -ENOIOCTLCMD;
>   		break;


  reply	other threads:[~2023-06-06 14:18 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-06-06 11:37 [PATCH v3 0/6] s390/uvdevice: Expose secret UVCs Steffen Eiden
2023-06-06 11:37 ` [PATCH v3 1/6] s390/uvdevice: Add info IOCTL Steffen Eiden
2023-06-06 13:33   ` Janosch Frank
2023-06-06 11:37 ` [PATCH v3 2/6] s390/uvdevice: Add 'Add Secret' UVC Steffen Eiden
2023-06-06 14:18   ` Janosch Frank [this message]
2023-06-06 11:37 ` [PATCH v3 3/6] s390/uvdevice: Add 'List Secrets' UVC Steffen Eiden
2023-06-06 11:37 ` [PATCH v3 4/6] s390/uvdevice: Add 'Lock Secret Store' UVC Steffen Eiden
2023-06-06 15:24   ` Janosch Frank
2023-06-06 11:37 ` [PATCH v3 5/6] s390/uv: replace scnprintf with sysfs_emit Steffen Eiden
2023-06-06 13:50   ` Janosch Frank
2023-06-06 11:37 ` [PATCH v3 6/6] s390/uv: Update query for secret-UVCs Steffen Eiden
2023-06-06 15:23   ` Janosch Frank

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=981c660f-27cb-5cbd-f965-3ecc1b36aa7a@linux.ibm.com \
    --to=frankja@linux.ibm.com \
    --cc=borntraeger@linux.ibm.com \
    --cc=brueckner@linux.ibm.com \
    --cc=hca@linux.ibm.com \
    --cc=imbrenda@linux.ibm.com \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-s390@vger.kernel.org \
    --cc=mihajlov@linux.ibm.com \
    --cc=nrb@linux.ibm.com \
    --cc=seiden@linux.ibm.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox