Message ID | 20230623211457.102544-17-Julia.Lawall@inria.fr (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | use array_size | expand |
Hi Julia, On Fri, Jun 23, 2023 at 11:14:47PM +0200, Julia Lawall wrote: > Use array_size to protect against multiplication overflows. > > The changes were done using the following Coccinelle semantic patch: > > // <smpl> > @@ > expression E1, E2; > constant C1, C2; > identifier alloc = {vmalloc,vzalloc}; > @@ > > ( > alloc(C1 * C2,...) > | > alloc( > - (E1) * (E2) > + array_size(E1, E2) > ,...) > ) > // </smpl> > > Signed-off-by: Julia Lawall <Julia.Lawall@inria.fr> > > --- > drivers/gpu/drm/i915/gvt/gtt.c | 6 ++++-- > 1 file changed, 4 insertions(+), 2 deletions(-) > > diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c > index 4ec85308379a..df52385ad436 100644 > --- a/drivers/gpu/drm/i915/gvt/gtt.c > +++ b/drivers/gpu/drm/i915/gvt/gtt.c > @@ -1969,14 +1969,16 @@ static struct intel_vgpu_mm *intel_vgpu_create_ggtt_mm(struct intel_vgpu *vgpu) > return ERR_PTR(-ENOMEM); > } > > - mm->ggtt_mm.host_ggtt_aperture = vzalloc((vgpu_aperture_sz(vgpu) >> PAGE_SHIFT) * sizeof(u64)); > + mm->ggtt_mm.host_ggtt_aperture = > + vzalloc(array_size(vgpu_aperture_sz(vgpu) >> PAGE_SHIFT, sizeof(u64))); > if (!mm->ggtt_mm.host_ggtt_aperture) { > vfree(mm->ggtt_mm.virtual_ggtt); > vgpu_free_mm(mm); > return ERR_PTR(-ENOMEM); > } > > - mm->ggtt_mm.host_ggtt_hidden = vzalloc((vgpu_hidden_sz(vgpu) >> PAGE_SHIFT) * sizeof(u64)); > + mm->ggtt_mm.host_ggtt_hidden = > + vzalloc(array_size(vgpu_hidden_sz(vgpu) >> PAGE_SHIFT, sizeof(u64))); thanks for this patch, but I see an issue here. array_size() truncates the allocation to SIZE_MAX, and I'm OK with it. The problem is that no error is notified and the user doesn't know that a truncation has happened. So that if we save from an overflow here, we might encur to an unwanted access later when we would start using the array for the size we think is allocated. kmalloc_array(), for example, returns NULL of there is a multiplication overflow and I think that's a better behaviour, although more drastic. Andi > if (!mm->ggtt_mm.host_ggtt_hidden) { > vfree(mm->ggtt_mm.host_ggtt_aperture); > vfree(mm->ggtt_mm.virtual_ggtt);
On Mon, Jun 26, 2023 at 11:26:55AM +0200, Andi Shyti wrote: > > diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c > > index 4ec85308379a..df52385ad436 100644 > > --- a/drivers/gpu/drm/i915/gvt/gtt.c > > +++ b/drivers/gpu/drm/i915/gvt/gtt.c > > @@ -1969,14 +1969,16 @@ static struct intel_vgpu_mm *intel_vgpu_create_ggtt_mm(struct intel_vgpu *vgpu) > > return ERR_PTR(-ENOMEM); > > } > > > > - mm->ggtt_mm.host_ggtt_aperture = vzalloc((vgpu_aperture_sz(vgpu) >> PAGE_SHIFT) * sizeof(u64)); > > + mm->ggtt_mm.host_ggtt_aperture = > > + vzalloc(array_size(vgpu_aperture_sz(vgpu) >> PAGE_SHIFT, sizeof(u64))); > > if (!mm->ggtt_mm.host_ggtt_aperture) { > > vfree(mm->ggtt_mm.virtual_ggtt); > > vgpu_free_mm(mm); > > return ERR_PTR(-ENOMEM); > > } > > > > - mm->ggtt_mm.host_ggtt_hidden = vzalloc((vgpu_hidden_sz(vgpu) >> PAGE_SHIFT) * sizeof(u64)); > > + mm->ggtt_mm.host_ggtt_hidden = > > + vzalloc(array_size(vgpu_hidden_sz(vgpu) >> PAGE_SHIFT, sizeof(u64))); > > thanks for this patch, but I see an issue here. array_size() > truncates the allocation to SIZE_MAX, and I'm OK with it. > > The problem is that no error is notified and the user doesn't > know that a truncation has happened. So that if we save from an > overflow here, we might encur to an unwanted access later when we > would start using the array for the size we think is allocated. SIZE_MAX allocations are guaranteed to fail, so the NULL check will still return -ENOMEM. > > kmalloc_array(), for example, returns NULL of there is a > multiplication overflow and I think that's a better behaviour, > although more drastic. It's the same either way. regards, dan carpenter
diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c index 4ec85308379a..df52385ad436 100644 --- a/drivers/gpu/drm/i915/gvt/gtt.c +++ b/drivers/gpu/drm/i915/gvt/gtt.c @@ -1969,14 +1969,16 @@ static struct intel_vgpu_mm *intel_vgpu_create_ggtt_mm(struct intel_vgpu *vgpu) return ERR_PTR(-ENOMEM); } - mm->ggtt_mm.host_ggtt_aperture = vzalloc((vgpu_aperture_sz(vgpu) >> PAGE_SHIFT) * sizeof(u64)); + mm->ggtt_mm.host_ggtt_aperture = + vzalloc(array_size(vgpu_aperture_sz(vgpu) >> PAGE_SHIFT, sizeof(u64))); if (!mm->ggtt_mm.host_ggtt_aperture) { vfree(mm->ggtt_mm.virtual_ggtt); vgpu_free_mm(mm); return ERR_PTR(-ENOMEM); } - mm->ggtt_mm.host_ggtt_hidden = vzalloc((vgpu_hidden_sz(vgpu) >> PAGE_SHIFT) * sizeof(u64)); + mm->ggtt_mm.host_ggtt_hidden = + vzalloc(array_size(vgpu_hidden_sz(vgpu) >> PAGE_SHIFT, sizeof(u64))); if (!mm->ggtt_mm.host_ggtt_hidden) { vfree(mm->ggtt_mm.host_ggtt_aperture); vfree(mm->ggtt_mm.virtual_ggtt);
Use array_size to protect against multiplication overflows. The changes were done using the following Coccinelle semantic patch: // <smpl> @@ expression E1, E2; constant C1, C2; identifier alloc = {vmalloc,vzalloc}; @@ ( alloc(C1 * C2,...) | alloc( - (E1) * (E2) + array_size(E1, E2) ,...) ) // </smpl> Signed-off-by: Julia Lawall <Julia.Lawall@inria.fr> --- drivers/gpu/drm/i915/gvt/gtt.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)