[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v5 for-4.9 3/4] hvm/dmop: Implement copy_{to, from}_guest_buf_offset() helpers
> -----Original Message----- > From: Andrew Cooper > Sent: 10 April 2017 10:57 > To: Paul Durrant <Paul.Durrant@xxxxxxxxxx>; Xen-devel <xen- > devel@xxxxxxxxxxxxx> > Cc: Jan Beulich <JBeulich@xxxxxxxx>; Julien Grall <julien.grall@xxxxxxx> > Subject: Re: [PATCH v5 for-4.9 3/4] hvm/dmop: Implement > copy_{to,from}_guest_buf_offset() helpers > > On 10/04/17 10:52, Paul Durrant wrote: > >> -----Original Message----- > >> From: Andrew Cooper > >> Sent: 10 April 2017 10:36 > >> To: Paul Durrant <Paul.Durrant@xxxxxxxxxx>; Xen-devel <xen- > >> devel@xxxxxxxxxxxxx> > >> Cc: Jan Beulich <JBeulich@xxxxxxxx>; Julien Grall <julien.grall@xxxxxxx> > >> Subject: Re: [PATCH v5 for-4.9 3/4] hvm/dmop: Implement > >> copy_{to,from}_guest_buf_offset() helpers > >> > >> On 10/04/17 10:11, Paul Durrant wrote: > >>>> -----Original Message----- > >>>> From: Andrew Cooper [mailto:andrew.cooper3@xxxxxxxxxx] > >>>> Sent: 07 April 2017 20:36 > >>>> To: Xen-devel <xen-devel@xxxxxxxxxxxxx> > >>>> Cc: Andrew Cooper <Andrew.Cooper3@xxxxxxxxxx>; Jan Beulich > >>>> <JBeulich@xxxxxxxx>; Paul Durrant <Paul.Durrant@xxxxxxxxxx>; Julien > >> Grall > >>>> <julien.grall@xxxxxxx> > >>>> Subject: [PATCH v5 for-4.9 3/4] hvm/dmop: Implement > >>>> copy_{to,from}_guest_buf_offset() helpers > >>>> > >>>> copy_{to,from}_guest_buf() are now implemented using an offset of > 0. > >>>> > >>>> Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> > >>>> --- > >>>> CC: Jan Beulich <JBeulich@xxxxxxxx> > >>>> CC: Paul Durrant <paul.durrant@xxxxxxxxxx> > >>>> CC: Julien Grall <julien.grall@xxxxxxx> > >>>> --- > >>>> xen/arch/x86/hvm/dm.c | 34 ++++++++++++++++++++++++---------- > >>>> 1 file changed, 24 insertions(+), 10 deletions(-) > >>>> > >>>> diff --git a/xen/arch/x86/hvm/dm.c b/xen/arch/x86/hvm/dm.c > >>>> index 3d8ae89..d584aba 100644 > >>>> --- a/xen/arch/x86/hvm/dm.c > >>>> +++ b/xen/arch/x86/hvm/dm.c > >>>> @@ -37,9 +37,9 @@ struct dmop_bufs { > >>>> #undef MAX_NR_BUFS > >>>> }; > >>>> > >>>> -static bool _raw_copy_from_guest_buf( > >>>> +static bool _raw_copy_from_guest_buf_offset( > >>>> const struct dmop_bufs *bufs, unsigned int idx, > >>>> - void *dst, size_t dst_bytes) > >>>> + size_t offset_bytes, void *dst, size_t dst_bytes) > >>>> { > >>>> size_t buf_bytes; > >>>> > >>>> @@ -48,17 +48,20 @@ static bool _raw_copy_from_guest_buf( > >>>> > >>>> buf_bytes = bufs->buf[idx].size; > >>>> > >>>> - if ( dst_bytes > buf_bytes ) > >>>> + if ( offset_bytes >= dst_bytes || > >>>> + (offset_bytes + dst_bytes) < offset_bytes || > >>>> + (offset_bytes + dst_bytes) > dst_bytes ) > >>>> return false; > >>>> > >>>> memset(dst, 0, dst_bytes); > >>>> > >>>> - return !copy_from_guest(dst, bufs->buf[idx].h, dst_bytes); > >>>> + return !copy_from_guest_offset(dst, bufs->buf[idx].h, > >>>> + offset_bytes, dst_bytes); > >>> Not sure what's going on here. 'buf_bytes' is being assigned but no > longer > >> seems to be used (since it's dropped from the if statement). Also, I'm not > >> entirely sure what range check that if statement is trying to perform. Can > we > >> at least have a comment it it's actually correct (which I'm not at all > convinced > >> of). > >> > >> That is actually because the if statement isn't correct. The final > >> comparison should be against buf_bytes, not dst_bytes. > > Ok, that makes more sense... so the first clause is checking for size_t > overflow, right? > > The first is a straight "is the offset off the end of the buffer", the > middle is a size_t overflow check (this is defined behaviour as size_t > is unsigned. It would be UB if size_t was signed), and the final was > supposed to be "(offset_bytes + dst_bytes) > buf_bytes" to check whether > the entire region wanting copying resides inside the buffer. > Sorry, I meant the middle clause, so with the fix that all makes sense now. > > > >> The problem is that copy_from_guest_offset() takes offset in units of > >> sizeof(typeof(*bufs->buf[idx].h)) (which in this case is bytes, until > >> the type of buf.h changes), while nr is strictly in bytes. My > >> conclusion after Friday's hacking is that this is also a recipe > >> security-relevant mistakes, and is fiendishly complicated to reason about. > > Anything using typeof() is a PITA to reason about IMO, so using the offset > variant is definitely going to be an improvement. > > I'm mulling over rewriting it all, because it is starting to get > embarrassing how many security issues we have in the existing > infrastructure. > Certainly removing some of the macrotization would make it easier to follow and, if copy_from_guest() is going to use typeof (for convenience of copying an op struct in the common case I guess) then it really should be single instance for safety, or preferably take an explicit type. Paul > ~Andrew _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx https://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |