Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CVE-2018-5785: fix issues with zero bitmasks #1148

Merged
merged 1 commit into from
Sep 22, 2018
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions src/bin/jp2/convertbmp.c
Original file line number Diff line number Diff line change
Expand Up @@ -435,16 +435,31 @@ static OPJ_BOOL bmp_read_info_header(FILE* IN, OPJ_BITMAPINFOHEADER* header)
header->biRedMask |= (OPJ_UINT32)getc(IN) << 16;
header->biRedMask |= (OPJ_UINT32)getc(IN) << 24;

if (!header->biRedMask) {
fprintf(stderr, "Error, invalid red mask value %d\n", header->biRedMask);
return OPJ_FALSE;
}

header->biGreenMask = (OPJ_UINT32)getc(IN);
header->biGreenMask |= (OPJ_UINT32)getc(IN) << 8;
header->biGreenMask |= (OPJ_UINT32)getc(IN) << 16;
header->biGreenMask |= (OPJ_UINT32)getc(IN) << 24;

if (!header->biGreenMask) {
fprintf(stderr, "Error, invalid green mask value %d\n", header->biGreenMask);
return OPJ_FALSE;
}

header->biBlueMask = (OPJ_UINT32)getc(IN);
header->biBlueMask |= (OPJ_UINT32)getc(IN) << 8;
header->biBlueMask |= (OPJ_UINT32)getc(IN) << 16;
header->biBlueMask |= (OPJ_UINT32)getc(IN) << 24;

if (!header->biBlueMask) {
fprintf(stderr, "Error, invalid blue mask value %d\n", header->biBlueMask);
return OPJ_FALSE;
}

header->biAlphaMask = (OPJ_UINT32)getc(IN);
header->biAlphaMask |= (OPJ_UINT32)getc(IN) << 8;
header->biAlphaMask |= (OPJ_UINT32)getc(IN) << 16;
Expand Down Expand Up @@ -831,6 +846,12 @@ opj_image_t* bmptoimage(const char *filename, opj_cparameters_t *parameters)
bmpmask32toimage(pData, stride, image, 0x00FF0000U, 0x0000FF00U, 0x000000FFU,
0x00000000U);
} else if (Info_h.biBitCount == 32 && Info_h.biCompression == 3) { /* bitmask */
if ((Info_h.biRedMask == 0U) && (Info_h.biGreenMask == 0U) &&
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what happens if one or two of the component mask is 0 and not the 3 ? Wouldn't there be an issue too ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, I see two different issues:

  • First issue: file declares BI_BITFIELDS and header size <= 56.

In this case I think we should just ignore the BI_BITFIELDS and proceed using default bitmask values.

My patch fixes this issue at line 848.

  • Second issue: file declares BI_BITFIELDS and header size >= 56 and one or more zero bitmasks.

This is the issue you speaking about.

Actually, we should be able to handle this case gracefully. After all, it's only one or two missing color channels right ? But this is not working right now, and there has to be a temporary solution. My opinion is: if we can't handle this case correctly, then we should declare it unsupported and forbid it.

This is what my patch does at line 438, 448 and 458.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK got it. Actually given your checks at line 438, 448, 458, when we are at line 849 either the 3 values are at 0, or they are all non-zero.

(Info_h.biBlueMask == 0U)) {
Info_h.biRedMask = 0x00FF0000U;
Info_h.biGreenMask = 0x0000FF00U;
Info_h.biBlueMask = 0x000000FFU;
}
bmpmask32toimage(pData, stride, image, Info_h.biRedMask, Info_h.biGreenMask,
Info_h.biBlueMask, Info_h.biAlphaMask);
} else if (Info_h.biBitCount == 16 && Info_h.biCompression == 0) { /* RGBX */
Expand Down