Hello, Can anyone confirm this bug? Thanks!
Wenwen On Fri, Oct 19, 2018 at 8:47 AM Wenwen Wang <wang6...@umn.edu> wrote: > > In msc_data_sz(), the 'valid_dw' field of the msc block descriptor 'bdesc' > is firstly checked to see whether the descriptor has a valid data width. If > yes, i.e., 'bdesc->valid_dw' is not 0, the data size of this descriptor > will be returned. It is worth noting that the data size is calculated from > 'bdesc->valid_dw'. The problem here is that 'bdesc' actually points to a > consistent DMA region, which is allocated through dma_alloc_coherent() in > msc_buffer_win_alloc(). Given that the device also has the permission to > access this DMA region, it is possible that a malicious device controlled > by an attacker can modify the 'valid_dw' field after the if statement but > before the return statement in msc_data_sz(). Through this way, the device > can bypass the check and supply unexpected data width. > > This patch copies the 'valid_dw' field to a local variable and then > performs the check and the calculation on the local variable to avoid the > above issue. > > Signed-off-by: Wenwen Wang <wang6...@umn.edu> > --- > drivers/hwtracing/intel_th/msu.h | 6 ++++-- > 1 file changed, 4 insertions(+), 2 deletions(-) > > diff --git a/drivers/hwtracing/intel_th/msu.h > b/drivers/hwtracing/intel_th/msu.h > index 9cc8ace..b7d846e 100644 > --- a/drivers/hwtracing/intel_th/msu.h > +++ b/drivers/hwtracing/intel_th/msu.h > @@ -79,10 +79,12 @@ struct msc_block_desc { > > static inline unsigned long msc_data_sz(struct msc_block_desc *bdesc) > { > - if (!bdesc->valid_dw) > + u32 valid_dw = bdesc->valid_dw; > + > + if (!valid_dw) > return 0; > > - return bdesc->valid_dw * 4 - MSC_BDESC; > + return valid_dw * 4 - MSC_BDESC; > } > > static inline bool msc_block_wrapped(struct msc_block_desc *bdesc) > -- > 2.7.4 >