Bug 40022 - [i915] out-of-bounds write src/mesa/drivers/dri/i915/i915_fragprog.c:321
[i915] out-of-bounds write src/mesa/drivers/dri/i915/i915_fragprog.c:321
Status: CLOSED FIXED
Product: Mesa
Classification: Unclassified
Component: Drivers/DRI/i915
git
All All
: medium normal
Assigned To: Ian Romanick
:
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2011-08-11 10:13 UTC by Vinson Lee
Modified: 2011-11-05 22:46 UTC (History)
0 users

See Also:
i915 platform:
i915 features:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Vinson Lee 2011-08-11 10:13:12 UTC
mesa: 9cd64ec35acd54cbe0be4d03236d2c5a9d4be6fe (master)

From a Coverity defect report.


src/mesa/drivers/dri/i915/i915_fragprog.c
   301  /* 
   302   * TODO: consider moving this into core 
   303   */
   304  static bool calc_live_regs( struct i915_fragment_program *p )
   305  {
   306      const struct gl_fragment_program *program = &p->FragProg;
   307      GLuint regsUsed = 0xffff0000;
-> 308      uint8_t live_components[16] = { 0, };
   309      GLint i;
   310     
   311      for (i = program->Base.NumInstructions - 1; i >= 0; i--) {
   312          struct prog_instruction *inst = &program->Base.Instructions[i];
   313          int opArgs = _mesa_num_inst_src_regs(inst->Opcode);
   314          int a;
   315  
   316          /* Register is written to: unmark as live for this and preceeding ops */ 
   317          if (inst->DstReg.File == PROGRAM_TEMPORARY) {
-> 318              if (inst->DstReg.Index > 16)
   319                 return false;
   320  
-> 321              live_components[inst->DstReg.Index] &= ~inst->DstReg.WriteMask;
   322              if (live_components[inst->DstReg.Index] == 0)
   323                  regsUsed &= ~(1 << inst->DstReg.Index);
   324          }
   325  
   326          for (a = 0; a < opArgs; a++) {
   327              /* Register is read from: mark as live for this and preceeding ops */ 
   328              if (inst->SrcReg[a].File == PROGRAM_TEMPORARY) {
   329                  unsigned c;
   330  
   331                  if (inst->SrcReg[a].Index > 16)
   332                     return false;
   333  
   334                  regsUsed |= 1 << inst->SrcReg[a].Index;
   335  
   336                  for (c = 0; c < 4; c++) {
   337                      const unsigned field = GET_SWZ(inst->SrcReg[a].Swizzle, c);
   338  
   339                      if (field <= SWIZZLE_W)
   340                          live_components[inst->SrcReg[a].Index] |= (1U << field);
   341                  }
   342              }
   343          }
   344  
   345          p->usedRegs[i] = regsUsed;
   346      }
Comment 1 Chris Wilson 2011-09-30 14:14:59 UTC
commit 67582e6eef789324b527b4753065aea366145f4e
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Fri Sep 30 22:10:33 2011 +0100

    i915: out-of-bounds write in calc_live_regs()
    
    From a Coverity defect report.
    
    src/mesa/drivers/dri/i915/i915_fragprog.c
       301  /*
       302   * TODO: consider moving this into core
       303   */
       304  static bool calc_live_regs( struct i915_fragment_program *p )
       305  {
       306      const struct gl_fragment_program *program = &p->FragProg;
       307      GLuint regsUsed = 0xffff0000;
    -> 308      uint8_t live_components[16] = { 0, };
       309      GLint i;
       310
       311      for (i = program->Base.NumInstructions - 1; i >= 0; i--) {
       312          struct prog_instruction *inst =
    &program->Base.Instructions[i];
       313          int opArgs = _mesa_num_inst_src_regs(inst->Opcode);
       314          int a;
       315
       316          /* Register is written to: unmark as live for this and
    preceeding ops */
       317          if (inst->DstReg.File == PROGRAM_TEMPORARY) {
    -> 318              if (inst->DstReg.Index > 16)
       319                 return false;
       320
    -> 321              live_components[inst->DstReg.Index] &= ~inst->DstReg.WriteMask;
       322              if (live_components[inst->DstReg.Index] == 0)
       323                  regsUsed &= ~(1 << inst->DstReg.Index);
       324          }
       325
       326          for (a = 0; a < opArgs; a++) {
       327              /* Register is read from: mark as live for this and preceeding ops */
       328              if (inst->SrcReg[a].File == PROGRAM_TEMPORARY) {
       329                  unsigned c;
       330
       331                  if (inst->SrcReg[a].Index > 16)
       332                     return false;
       333
       334                  regsUsed |= 1 << inst->SrcReg[a].Index;
       335
       336                  for (c = 0; c < 4; c++) {
       337                      const unsigned field = GET_SWZ(inst->SrcReg[a].Swizzle, c);
       338
       339                      if (field <= SWIZZLE_W)
       340                          live_components[inst->SrcReg[a].Index] |= (1U << field);
       341                  }
       342              }
       343          }
       344
       345          p->usedRegs[i] = regsUsed;
       346      }
    
    Reported-by: Vinson Lee <vlee@vmware.com>
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=40022
    Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Comment 2 Vinson Lee 2011-11-05 22:46:33 UTC
mesa: adb7f1351e4c231184a6355573c01c7780135342 (master)

Verified fixed.