staging: xgifb: ReadVBIOSTablData(): check the BIOS size
Check the BIOS size to avoid out of bounds array access. Disable LVDS in case errors are detected. Signed-off-by: Aaro Koskinen <aaro.koskinen@iki.fi> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
parent
82986dd9e7
commit
08ce239c10
@ -1093,13 +1093,12 @@ static void XGINew_SetDRAMSize_340(struct xgi_hw_device_info *HwDeviceExtension,
|
|||||||
xgifb_reg_set(pVBInfo->P3c4, 0x21, (unsigned short) (data | 0x20));
|
xgifb_reg_set(pVBInfo->P3c4, 0x21, (unsigned short) (data | 0x20));
|
||||||
}
|
}
|
||||||
|
|
||||||
static u8 *xgifb_copy_rom(struct pci_dev *dev)
|
static u8 *xgifb_copy_rom(struct pci_dev *dev, size_t *rom_size)
|
||||||
{
|
{
|
||||||
void __iomem *rom_address;
|
void __iomem *rom_address;
|
||||||
u8 *rom_copy;
|
u8 *rom_copy;
|
||||||
size_t rom_size;
|
|
||||||
|
|
||||||
rom_address = pci_map_rom(dev, &rom_size);
|
rom_address = pci_map_rom(dev, rom_size);
|
||||||
if (rom_address == NULL)
|
if (rom_address == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
@ -1107,8 +1106,8 @@ static u8 *xgifb_copy_rom(struct pci_dev *dev)
|
|||||||
if (rom_copy == NULL)
|
if (rom_copy == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
rom_size = min_t(size_t, rom_size, XGIFB_ROM_SIZE);
|
*rom_size = min_t(size_t, *rom_size, XGIFB_ROM_SIZE);
|
||||||
memcpy_fromio(rom_copy, rom_address, rom_size);
|
memcpy_fromio(rom_copy, rom_address, *rom_size);
|
||||||
|
|
||||||
done:
|
done:
|
||||||
pci_unmap_rom(dev, rom_address);
|
pci_unmap_rom(dev, rom_address);
|
||||||
@ -1123,27 +1122,37 @@ static void ReadVBIOSTablData(struct pci_dev *pdev,
|
|||||||
unsigned long i;
|
unsigned long i;
|
||||||
unsigned char j, k;
|
unsigned char j, k;
|
||||||
struct XGI21_LVDSCapStruct *lvds;
|
struct XGI21_LVDSCapStruct *lvds;
|
||||||
|
size_t vbios_size;
|
||||||
|
|
||||||
if (xgifb_info->chip != XG21)
|
if (xgifb_info->chip != XG21)
|
||||||
return;
|
return;
|
||||||
pVBInfo->IF_DEF_LVDS = 0;
|
pVBInfo->IF_DEF_LVDS = 0;
|
||||||
vbios = xgifb_copy_rom(pdev);
|
vbios = xgifb_copy_rom(pdev, &vbios_size);
|
||||||
if (vbios == NULL) {
|
if (vbios == NULL) {
|
||||||
dev_err(&pdev->dev, "video BIOS not available\n");
|
dev_err(&pdev->dev, "video BIOS not available\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (vbios_size <= 0x65)
|
||||||
|
goto error;
|
||||||
if (!(vbios[0x65] & 0x1)) {
|
if (!(vbios[0x65] & 0x1)) {
|
||||||
vfree(vbios);
|
vfree(vbios);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
pVBInfo->IF_DEF_LVDS = 1;
|
if (vbios_size <= 0x317)
|
||||||
|
goto error;
|
||||||
i = vbios[0x316] | (vbios[0x317] << 8);
|
i = vbios[0x316] | (vbios[0x317] << 8);
|
||||||
|
if (vbios_size <= i - 1)
|
||||||
|
goto error;
|
||||||
j = vbios[i - 1];
|
j = vbios[i - 1];
|
||||||
|
if (j == 0)
|
||||||
|
goto error;
|
||||||
if (j == 0xff)
|
if (j == 0xff)
|
||||||
j = 1;
|
j = 1;
|
||||||
k = 0;
|
k = 0;
|
||||||
lvds = &pVBInfo->XG21_LVDSCapList[0];
|
lvds = &pVBInfo->XG21_LVDSCapList[0];
|
||||||
do {
|
do {
|
||||||
|
if (vbios_size <= i + 24)
|
||||||
|
goto error;
|
||||||
lvds->LVDS_Capability = vbios[i] | (vbios[i + 1] << 8);
|
lvds->LVDS_Capability = vbios[i] | (vbios[i + 1] << 8);
|
||||||
lvds->LVDSHT = vbios[i + 2] | (vbios[i + 3] << 8);
|
lvds->LVDSHT = vbios[i + 2] | (vbios[i + 3] << 8);
|
||||||
lvds->LVDSVT = vbios[i + 4] | (vbios[i + 5] << 8);
|
lvds->LVDSVT = vbios[i + 4] | (vbios[i + 5] << 8);
|
||||||
@ -1166,6 +1175,11 @@ static void ReadVBIOSTablData(struct pci_dev *pdev,
|
|||||||
lvds++;
|
lvds++;
|
||||||
} while (j > 0 && k < ARRAY_SIZE(XGI21_LCDCapList));
|
} while (j > 0 && k < ARRAY_SIZE(XGI21_LCDCapList));
|
||||||
vfree(vbios);
|
vfree(vbios);
|
||||||
|
pVBInfo->IF_DEF_LVDS = 1;
|
||||||
|
return;
|
||||||
|
error:
|
||||||
|
dev_err(&pdev->dev, "video BIOS corrupted\n");
|
||||||
|
vfree(vbios);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void XGINew_ChkSenseStatus(struct xgi_hw_device_info *HwDeviceExtension,
|
static void XGINew_ChkSenseStatus(struct xgi_hw_device_info *HwDeviceExtension,
|
||||||
|
Loading…
Reference in New Issue
Block a user