私は最後の試験に向けて勉強していて (yey!)、理解するのに苦労している問題に出くわしました。これは、ppm イメージ ファイルを読み取る関数で悪用される可能性のある脆弱性を少なくとも 2 つ見つけることになっている古い試験問題です。私が特定できる唯一の問題は、列や行に予期しない値が与えられた場合です。これは、大きすぎる (整数オーバーフローを引き起こす) または負の値であり、img->raster のサイズが正しくなく、ヒープベースの可能性が開かれます。バッファオーバーフロー攻撃。
私が推論できる限り、未チェックの malloc が悪用されることはありません。
struct image *read_ppm(FILE *fp)
{
int version;
int rows, cols, maxval;
int pixBytes=0, rowBytes=0, rasterBytes;
uint8_t *p;
struct image *img;
/* Read the magic number from the file */
if ((fscanf(fp, " P%d ", &version) < 1) || (version != 6)) {
return NULL;
}
/* Read the image dimensions and color depth from the file */
if (fscanf(fp, " %d %d %d ", &cols, &rows, &maxval) < 3) {
return NULL;
}
/* Calculate some sizes */
pixBytes = (maxval > 255) ? 6 : 3; // Bytes per pixel
rowBytes = pixBytes * cols; // Bytes per row
rasterBytes = rowBytes * rows; // Bytes for the whole image
/* Allocate the image structure and initialize its fields */
img = malloc(sizeof(*img));
if (img == NULL) return NULL;
img->rows = rows;
img->cols = cols;
img->depth = (maxval > 255) ? 2 : 1;
img->raster = (void*)malloc(rasterBytes);
/* Get a pointer to the first pixel in the raster data. */
/* It is to this pointer that all image data will be written. */
p = img->raster;
/* Iterate over the rows in the file */
while (rows--) {
/* Iterate over the columns in the file */
cols = img->cols;
while (cols--) {
/* Try to read a single pixel from the file */
if (fread(p, pixBytes, 1, fp) < 1) {
/* If the read fails, free memory and return */
free(img->raster);
free(img);
return NULL;
}
/* Advance the pointer to the next location to which we
should read a single pixel. */
p += pixBytes;
}
}
/* Return the image */
return img;
}
オリジナル (最後の質問): http://www.ida.liu.se/~TDDC90/exam/old/TDDC90%20TEN1%202009-12-22.pdf
助けてくれてありがとう。