On Mon, Feb 27, 2017 at 10:52:14AM +0100, Reyk Floeter wrote:
> Reminder: using IMSG_SIZE_CHECK() in user-facing imsg handlers is a
> bad thing as an invalid imsg would kill the daemon (via fatal).
> 
> OK?
> 
>     Add size checks for imsg received over the control socket.
>     
>     Additionally, make sure that vmd never fatal()s when receiving an
>     invalid imsg from an arbitrary user over the control socket.
> 

ok gilles@


> diff --git usr.sbin/vmd/control.c usr.sbin/vmd/control.c
> index 5e0141f..cda7df9 100644
> --- usr.sbin/vmd/control.c
> +++ usr.sbin/vmd/control.c
> @@ -286,11 +286,13 @@ control_close(int fd, struct control_sock *cs)
>  void
>  control_dispatch_imsg(int fd, short event, void *arg)
>  {
> -     struct control_sock     *cs = arg;
> -     struct privsep          *ps = cs->cs_env;
> -     struct ctl_conn         *c;
> -     struct imsg              imsg;
> -     int                      n, v, ret = 0;
> +     struct control_sock             *cs = arg;
> +     struct privsep                  *ps = cs->cs_env;
> +     struct ctl_conn                 *c;
> +     struct imsg                      imsg;
> +     struct vmop_create_params        vmc;
> +     struct vmop_id                   vid;
> +     int                              n, v, ret = 0;
>  
>       if ((c = control_connbyfd(fd)) == NULL) {
>               log_warn("%s: fd %d: not found", __func__, fd);
> @@ -347,7 +349,8 @@ control_dispatch_imsg(int fd, short event, void *arg)
>                       c->flags |= CTL_CONN_NOTIFY;
>                       break;
>               case IMSG_CTL_VERBOSE:
> -                     IMSG_SIZE_CHECK(&imsg, &v);
> +                     if (IMSG_DATA_SIZE(&imsg) < sizeof(v))
> +                             goto fail;
>  
>                       memcpy(&v, imsg.data, sizeof(v));
>                       log_setverbose(v);
> @@ -355,17 +358,34 @@ control_dispatch_imsg(int fd, short event, void *arg)
>                       proc_forward_imsg(ps, &imsg, PROC_PARENT, -1);
>                       break;
>               case IMSG_VMDOP_START_VM_REQUEST:
> +                     if (IMSG_DATA_SIZE(&imsg) < sizeof(vmc))
> +                             goto fail;
> +                     if (proc_compose_imsg(ps, PROC_PARENT, -1,
> +                         imsg.hdr.type, fd, -1,
> +                         imsg.data, IMSG_DATA_SIZE(&imsg)) == -1) {
> +                             control_close(fd, cs);
> +                             return;
> +                     }
> +                     break;
>               case IMSG_VMDOP_TERMINATE_VM_REQUEST:
> -             case IMSG_VMDOP_GET_INFO_VM_REQUEST:
> -                     imsg.hdr.peerid = fd;
> -
> +                     if (IMSG_DATA_SIZE(&imsg) < sizeof(vid))
> +                             goto fail;
>                       if (proc_compose_imsg(ps, PROC_PARENT, -1,
> -                         imsg.hdr.type, imsg.hdr.peerid, -1,
> +                         imsg.hdr.type, fd, -1,
>                           imsg.data, IMSG_DATA_SIZE(&imsg)) == -1) {
>                               control_close(fd, cs);
>                               return;
>                       }
>                       break;
> +             case IMSG_VMDOP_GET_INFO_VM_REQUEST:
> +                     if (IMSG_DATA_SIZE(&imsg) != 0)
> +                             goto fail;
> +                     if (proc_compose_imsg(ps, PROC_PARENT, -1,
> +                         imsg.hdr.type, fd, -1, NULL, 0) == -1) {
> +                             control_close(fd, cs);
> +                             return;
> +                     }
> +                     break;
>               case IMSG_VMDOP_LOAD:
>               case IMSG_VMDOP_RELOAD:
>               case IMSG_CTL_RESET:
> @@ -384,6 +404,8 @@ control_dispatch_imsg(int fd, short event, void *arg)
>       return;
>  
>   fail:
> +     if (ret == 0)
> +             ret = EINVAL;
>       imsg_compose_event(&c->iev, IMSG_CTL_FAIL,
>           0, 0, -1, &ret, sizeof(ret));
>       imsg_flush(&c->iev.ibuf);
> 

-- 
Gilles Chehade

https://www.poolp.org                                          @poolpOrg

Reply via email to