delete mbuhl from Cc:.

From: YASUOKA Masahiko <yasu...@openbsd.org>
Date: Sat, 19 Nov 2022 16:37:47 +0900 (JST)

> On Sat, 19 Nov 2022 14:41:18 +0900 (JST)
> YASUOKA Masahiko <yasu...@openbsd.org> wrote:
>> On Wed, 12 Oct 2022 07:58:20 +0900 (JST)
>> YASUOKA Masahiko <yasu...@openbsd.org> wrote:
>>> On Wed, 05 Oct 2022 13:37:35 +0900 (JST)
>>> Masato Asou <a...@soum.co.jp> wrote:
>>>> From: "Theo de Raadt" <dera...@openbsd.org>
>>>> Date: Tue, 04 Oct 2022 21:58:13 -0600
>>>>> Userland may not ask the kernel to allocate such a huge object.  The
>>>>> kernel address space is quite small.  First off, huge allocations will
>>>>> fail.
>>>>> 
>>>>> But it is worse -- the small kernel address space is shared for many
>>>>> purposes, so large allocations will harm the other subsystems.
>>>>> 
>>>>> As written, this diff is too dangerous.  Arbitrary allocation inside
>>>>> the kernel is not reasonable.  object sizes requested by userland must
>>>>> be small, or the operations must be cut up, which does create impact
>>>>> on atomicity or other things.
>>>> 
>>>> As you pointed out, it is not a good idea to allocate large spaces
>>>> in kernel.
>>>> 
>>>> Would it be better to keep the current fixed length?
>>> 
>>> Currently the value on VMware may be truncated silently.  It's simply
>>> broken.  I think we should fix it by having a way to know if the value
>>> is reached the limit.
>>> 
>>> Also I think we should be able to pass larger size of data.  Since at
>>> least on VMware, people is useing for parameters when deployment
>>> through OVF tamplate.  Sometimes the parameter includes large data
>>> like X.509 certificate.
>>> 
>>> https://docs.vmware.com/en/VMware-vSphere/7.0/com.vmware.vsphere.vm_admin.doc/GUID-D0F9E3B9-B77B-4DEF-A982-49B9F6358FF3.html
>>> 
>>> What do you think?
>>> 
>>>> Prepare a variable like kern.maxpvbus and default it to
>>>> 4096.  Futhermore, how about free() after copyout() to user space?
>>> 
>>> I suppose we can use the space prepared by the userland directly.
>> 
>> I admit there is no way to use the user space directly in case of the
>> vmware.
>> 
>> But current vmt(4) uses the buffer in vmt_softc for all RPC commands.
>> The buffer seems to have beeen created for RPC done by the tclo
>> process.  The tclo process executes RPC periodically, so having a long
>> term buffer does make sense.
>> 
>> On the otherhand, pvbus(4) prepares a buffer for
>> PVBUSIOC_KV{READ|WRITE} and pass it to the driver handler.  So vmt(4)
>> can use the buffer.
>> 
>> The diff is to change vmt(4) to use the buffer given by pvbuf(4) for
>> the rpc output directly.  Also make it return EMSGSIZE when the buffer
>> is not enough instead of truncating silently.
>> 
>> The diff is first step.  We need to more hack for pvbus(4) and
>> vmt(4).  For example, the buffer size pvbuf(4) allocates is not enough
>> to store the size user requested, since vmt(4) neeeds extra 2 bytes
>> for the RPC output.
>> 
>> +    bcopy(value + 2, value, valuelen - 2);
>> 
>> 
>> But I'd like to commit this first.
>> 
>> ok?
> 
> sorry, using existing vm_rpc_send_rpci_tx_buf() or
> vm_rpci_response_successful() wasn't good idea and had a bug.
> 
> Let me update the diff.

ok asou@

> Index: sys/dev/pv/vmt.c
> ===================================================================
> RCS file: /var/cvs/openbsd/src/sys/dev/pv/vmt.c,v
> retrieving revision 1.26
> diff -u -p -r1.26 vmt.c
> --- sys/dev/pv/vmt.c  8 Sep 2022 10:22:06 -0000       1.26
> +++ sys/dev/pv/vmt.c  19 Nov 2022 07:32:47 -0000
> @@ -491,9 +491,12 @@ int
>  vmt_kvop(void *arg, int op, char *key, char *value, size_t valuelen)
>  {
>       struct vmt_softc *sc = arg;
> -     char *buf = NULL, *ptr;
> +     struct vm_rpc rpci;
> +     char *buf = NULL;
>       size_t bufsz;
>       int error = 0;
> +     uint32_t rlen;
> +     uint16_t ack;
>  
>       bufsz = VMT_RPC_BUFLEN;
>       buf = malloc(bufsz, M_TEMP, M_WAITOK | M_ZERO);
> @@ -520,25 +523,52 @@ vmt_kvop(void *arg, int op, char *key, c
>               goto done;
>       }
>  
> -     if (vm_rpc_send_rpci_tx(sc, "%s", buf) != 0) {
> -             DPRINTF("%s: error sending command: %s\n", DEVNAME(sc), buf);
> +     if (vm_rpc_open(&rpci, VM_RPC_OPEN_RPCI) != 0) {
> +             DPRINTF("%s: rpci channel open failed\n", DEVNAME(sc));
>               sc->sc_rpc_error = 1;
>               error = EIO;
>               goto done;
>       }
>  
> -     if (vm_rpci_response_successful(sc) == 0) {
> -             DPRINTF("%s: host rejected command: %s\n", DEVNAME(sc), buf);
> -             error = EINVAL;
> +     if (vm_rpc_send(&rpci, buf, bufsz) != 0) {
> +             DPRINTF("%s: unable to send rpci command\n", DEVNAME(sc));
> +             sc->sc_rpc_error = 1;
> +             error = EIO;
>               goto done;
>       }
>  
> -     /* skip response that was tested in vm_rpci_response_successful() */
> -     ptr = sc->sc_rpc_buf + 2;
> +     if (vm_rpc_get_length(&rpci, &rlen, &ack) != 0) {
> +             DPRINTF("%s: failed to get length of rpci response data\n",
> +                 DEVNAME(sc));
> +             sc->sc_rpc_error = 1;
> +             error = EIO;
> +             goto done;
> +     }
>  
> -     /* might truncate, copy anyway but return error */
> -     if (strlcpy(value, ptr, valuelen) >= valuelen)
> -             error = ENOMEM;
> +     if (rlen > 0) {
> +             if (rlen + 1 > valuelen) {
> +                     error = EMSGSIZE;
> +                     goto done;
> +             }
> +
> +             if (vm_rpc_get_data(&rpci, value, rlen, ack) != 0) {
> +                     DPRINTF("%s: failed to get rpci response data\n",
> +                         DEVNAME(sc));
> +                     sc->sc_rpc_error = 1;
> +                     error = EIO;
> +                     goto done;
> +             }
> +             /* test if response success  */
> +             if (rlen < 2 || value[0] != '1' || value[1] != ' ') {
> +                     DPRINTF("%s: host rejected command: %s\n", DEVNAME(sc),
> +                         buf);
> +                     error = EINVAL;
> +                     goto done;
> +             }
> +             /* skip response that was tested */
> +             bcopy(value + 2, value, valuelen - 2);
> +             value[rlen - 2] = '\0';
> +     }
>  
>   done:
>       free(buf, M_TEMP, bufsz);

Reply via email to