[Spice-devel] [PATCH spice-server 05/12] Make QXLMessage handling safe

Jonathon Jongsma jjongsma at redhat.com
Thu Oct 20 21:15:59 UTC 2016


On Thu, 2016-10-20 at 06:08 -0400, Frediano Ziglio wrote:
> > 
> > 
> > I think that a commit saying "Make X safe" really deserves a bit
> > longer
> > description about what was unsafe, whether it's easily
> > reproducible,
> > what the impact of the bug is, etc.
> > 
> 
> The QXLMessage has no size so potentially a guest could give an
> address that cause the string to overflow out of the video memory.
> The current solution is to parse the message, release the resources
> associated without printing the message from the client.
> This also considering that the QXLMessage usage was deprecated
> a while ago (I don't know exactly when).
> This patches limit the string to 100000 characters (guest can feed
> so much logs in other way) and limit to video memory.
> Marc-Andre time ago sent a patch to remove entirely the handling
> of this message however I rejected pointing out that this would
> cause a leak in any guest using it.
> Another solution would be to just release the guest resource
> and mark as definitively obsolete this message.
> 
> Frediano


OK, can you add a bit of this back story to the commit log?

Acked-by: Jonathon Jongsma <jjongsma at redhat.com>



> 
> > 
> > 
> > On Tue, 2016-10-18 at 10:09 +0100, Frediano Ziglio wrote:
> > > 
> > > Signed-off-by: Frediano Ziglio <fziglio at redhat.com>
> > > ---
> > >  server/memslot.c       | 14 ++++++++++++++
> > >  server/memslot.h       |  3 +++
> > >  server/red-parse-qxl.c | 11 +++++++++++
> > >  server/red-parse-qxl.h |  1 +
> > >  server/red-worker.c    |  3 +--
> > >  5 files changed, 30 insertions(+), 2 deletions(-)
> > > 
> > > diff --git a/server/memslot.c b/server/memslot.c
> > > index 99c63e4..75cb75f 100644
> > > --- a/server/memslot.c
> > > +++ b/server/memslot.c
> > > @@ -71,6 +71,20 @@ int memslot_validate_virt(RedMemSlotInfo
> > > *info,
> > > unsigned long virt, int slot_id,
> > >      return 1;
> > >  }
> > >  
> > > +unsigned long memslot_max_size_virt(RedMemSlotInfo *info,
> > > +                                    unsigned long virt, int
> > > slot_id,
> > > +                                    uint32_t group_id)
> > > +{
> > > +    MemSlot *slot;
> > > +
> > > +    slot = &info->mem_slots[group_id][slot_id];
> > > +
> > > +    if (virt < slot->virt_start_addr || virt > slot-
> > > >virt_end_addr)
> > > {
> > > +        return 0;
> > > +    }
> > > +    return slot->virt_end_addr - virt;
> > > +}
> > > +
> > >  /*
> > >   * return virtual address if successful, which may be 0.
> > >   * returns 0 and sets error to 1 if an error condition occurs.
> > > diff --git a/server/memslot.h b/server/memslot.h
> > > index a29837c..5046d0f 100644
> > > --- a/server/memslot.h
> > > +++ b/server/memslot.h
> > > @@ -55,6 +55,9 @@ static inline int
> > > memslot_get_generation(RedMemSlotInfo *info, uint64_t addr)
> > >  
> > >  int memslot_validate_virt(RedMemSlotInfo *info, unsigned long
> > > virt,
> > > int slot_id,
> > >                            uint32_t add_size, uint32_t group_id);
> > > +unsigned long memslot_max_size_virt(RedMemSlotInfo *info,
> > > +                                    unsigned long virt, int
> > > slot_id,
> > > +                                    uint32_t group_id);
> > >  unsigned long memslot_get_virt(RedMemSlotInfo *info, QXLPHYSICAL
> > > addr, uint32_t add_size,
> > >                         int group_id, int *error);
> > >  
> > > diff --git a/server/red-parse-qxl.c b/server/red-parse-qxl.c
> > > index d75e27e..77533ca 100644
> > > --- a/server/red-parse-qxl.c
> > > +++ b/server/red-parse-qxl.c
> > > @@ -1300,6 +1300,9 @@ int red_get_message(RedMemSlotInfo *slots,
> > > int
> > > group_id,
> > >  {
> > >      QXLMessage *qxl;
> > >      int error;
> > > +    int memslot_id;
> > > +    unsigned long len;
> > > +    uint8_t *end;
> > >  
> > >      /*
> > >       * security alert:
> > > @@ -1314,6 +1317,14 @@ int red_get_message(RedMemSlotInfo *slots,
> > > int
> > > group_id,
> > >      red->release_info_ext.info      = &qxl->release_info;
> > >      red->release_info_ext.group_id  = group_id;
> > >      red->data                       = qxl->data;
> > > +    memslot_id = memslot_get_id(slots, addr+sizeof(*qxl));
> > > +    len = memslot_max_size_virt(slots, ((intptr_t)
> > > qxl)+sizeof(*qxl), memslot_id, group_id);
> > > +    len = MIN(len, 100000);
> > > +    end = (uint8_t *)memchr(qxl->data, 0, len);
> > > +    if (end == NULL) {
> > > +        return 1;
> > > +    }
> > > +    red->len = end - qxl->data;
> > >      return 0;
> > >  }
> > >  
> > > diff --git a/server/red-parse-qxl.h b/server/red-parse-qxl.h
> > > index 0da20ad..e174ccc 100644
> > > --- a/server/red-parse-qxl.h
> > > +++ b/server/red-parse-qxl.h
> > > @@ -74,6 +74,7 @@ typedef struct RedUpdateCmd {
> > >  
> > >  typedef struct RedMessage {
> > >      QXLReleaseInfoExt release_info_ext;
> > > +    int len;
> > >      uint8_t *data;
> > >  } RedMessage;
> > >  
> > > diff --git a/server/red-worker.c b/server/red-worker.c
> > > index bbc971c..3784261 100644
> > > --- a/server/red-worker.c
> > > +++ b/server/red-worker.c
> > > @@ -238,8 +238,7 @@ static int red_process_display(RedWorker
> > > *worker,
> > > int *ring_is_empty)
> > >                  break;
> > >              }
> > >  #ifdef DEBUG
> > > -            /* alert: accessing message.data is insecure */
> > > -            spice_warning("MESSAGE: %s", message.data);
> > > +            spice_warning("MESSAGE: %.*s", message.len,
> > > message.data);
> > >  #endif
> > >              red_qxl_release_resource(worker->qxl,
> > > message.release_info_ext);
> > >              red_put_message(&message);
> > 


More information about the Spice-devel mailing list