-
Notifications
You must be signed in to change notification settings - Fork 6.2k
8365609: Fix several potential NULL native pointer dereferences in the desktop module #26799
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
base: master
Are you sure you want to change the base?
Conversation
…mon/java2d/opengl/OGLBlitLoops.c OGLBlitToSurfaceViaTexture() Found by Linux Verification Center (linuxtesting.org) with SVACE. Signed-off-by: Artem Semenov <[email protected]>.
…a2d/opengl/OGLBlitLoops.c OGLBlitSwToTexture() Found by Linux Verification Center (linuxtesting.org) with SVACE. Signed-off-by: Artem Semenov <[email protected]>.
…creen/splashscreen_gif.c SplashDecodeGif() Found by Linux Verification Center (linuxtesting.org) with SVACE. Signed-off-by: Artem Semenov <[email protected]>.
…/awt/gtk3_interface.c gtk3_load() Found by Linux Verification Center (linuxtesting.org) with SVACE. Signed-off-by: Artem Semenov <[email protected]>.
👋 Welcome back asemenov! A progress list of the required criteria for merging this PR into |
❗ This change is not yet ready to be integrated. |
Webrevs
|
It is better first to confirm whether this pointer can actually be NULL. If it cannot then remove the unnecessary earlier NULL check. |
There seem to be un-related changes in this PR. Please check. |
In the same file, line 551 calls OGLBlitToSurfaceViaTexture() from line 263, where NULL is passed in place of pf. Also, another function with a similar issue from the same file, OGLBlitSwToTexture() from line 396, is called with an existing pf. jboolean adjustAlpha = (pf != NULL && !pf->hasAlpha); I suggest keeping the NULL check for OGLBlitToSurfaceViaTexture() at line 263, while for OGLBlitSwToTexture() at line 396, the check can be replaced with an assert. |
In this PR, they asked not to create multiple tickets for the same issues… even if they are in different files… However, it’s not difficult for me to distribute the fixes across several tickets into different subcomponents if you think it’s necessary to do so. |
I see. From the bug subject I would never have guessed it touched GTK and gif decoding. And then the JBS issue and the PR should have a title change .. something like this |
fp_g_uuid_string_is_valid = //since: 2.52 | ||
dl_symbol("g_uuid_string_is_valid"); | ||
fp_g_variant_print = dl_symbol("g_variant_print"); // since 2.24 | ||
if (fp_glib_check_version != NULL) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know why we don't treat failing to find this symbol as a fatal error like we do for others such as this first one. dl_symbol will do a longjmp
fp_gtk_check_version = dl_symbol("gtk_check_version");
but for this one we just clear the error.
/* GLib */
fp_glib_check_version = dlsym(gtk3_libhandle, "glib_check_version");
if (!fp_glib_check_version) {
dlerror();
}
@azvegint any idea ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know why we don't treat failing to find this symbol as a fatal error like we do for others such as this first one.
It looks like the glib_check_version
was added but never used. The first instance of its use appears to be the added check for the methods used for Screencast. And it was overlooked that the fp_glib_check_version
can be null
.
The glib_check_version
is available since 2.6, and the 2.6.0 was released in 2004, so I guess we can safely replace the dlsym
with the dl_symbol
.
This will be better than remembering to protect it with a null check if we decide to use glib_check_version
later somewhere else.
- fp_glib_check_version = dlsym(gtk3_libhandle, "glib_check_version");
- if (!fp_glib_check_version) {
- dlerror();
- }
+ fp_glib_check_version = dl_symbol("glib_check_version");
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So that would be the proper fix here, not the proposed one.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know why we don't treat failing to find this symbol as a fatal error like we do for others such as this first one.
It looks like the
glib_check_version
was added but never used. The first instance of its use appears to be the added check for the methods used for Screencast. And it was overlooked that thefp_glib_check_version
can benull
.The
glib_check_version
is available since 2.6, and the 2.6.0 was released in 2004, so I guess we can safely replace thedlsym
with thedl_symbol
. This will be better than remembering to protect it with a null check if we decide to useglib_check_version
later somewhere else.- fp_glib_check_version = dlsym(gtk3_libhandle, "glib_check_version"); - if (!fp_glib_check_version) { - dlerror(); - } + fp_glib_check_version = dl_symbol("glib_check_version");
done
@@ -279,7 +279,8 @@ SplashDecodeGif(Splash * splash, GifFileType * gif) | |||
ImageRect dstRect; | |||
rgbquad_t fillColor = 0; // 0 is transparent | |||
|
|||
if (transparentColor < 0) { | |||
if (((colorMap != NULL) && (colorMap->Colors != NULL)) && |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can't easily verify that this is an impossible place to be if colorMap == null
so I guess this is OK
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can't easily verify that this is an impossible place to be if colorMap == null so I guess this is OK
Do you mean that this check should be removed or kept?
…awt_xawt/awt/gtk3_interface.c gtk3_load()" This reverts commit a369e3a.
…terface.c gtk3_load()
done |
src/java.desktop/share/native/libsplashscreen/splashscreen_gif.c
Outdated
Show resolved
Hide resolved
if (pf != NULL) { | ||
if (slowPath) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The current indentation does seem to be off.
GLvoid *pSrc = PtrCoord(srcInfo->rasBase,
sx, srcInfo->pixelStride,
sy, srcInfo->scanStride);
if (pf) {
if (slowPath) {
jint tmph = sh;
while (tmph > 0) {
...
The same applies to the other added if statement.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed.
Co-authored-by: Aleksandr Zvegintsev <[email protected]>
|
||
while (height > 0) { | ||
j2d_glTexSubImage2D(dstOps->textureTarget, 0, | ||
if (pf != NULL) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OGLBlitSwToTexture(&srcInfo, &pf, dstOps, |
OGLBlitSwToTexture is called with PixelFormat defined as
OGLPixelFormat PixelFormats[] = { | |
{ GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, | |
4, 1, 0, }, /* 0 - IntArgb */ | |
{ GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, | |
4, 1, 1, }, /* 1 - IntArgbPre */ | |
{ GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, | |
4, 0, 1, }, /* 2 - IntRgb */ | |
{ GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, | |
4, 0, 1, }, /* 3 - IntRgbx */ | |
{ GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, | |
4, 0, 1, }, /* 4 - IntBgr */ | |
{ GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, | |
4, 0, 1, }, /* 5 - IntBgrx */ | |
{ GL_RGB, GL_UNSIGNED_SHORT_5_6_5, | |
2, 0, 1, }, /* 6 - Ushort565Rgb */ | |
{ GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, | |
2, 0, 1, }, /* 7 - Ushort555Rgb */ | |
{ GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, | |
2, 0, 1, }, /* 8 - Ushort555Rgbx*/ | |
{ GL_LUMINANCE, GL_UNSIGNED_BYTE, | |
1, 0, 1, }, /* 9 - ByteGray */ | |
{ GL_LUMINANCE, GL_UNSIGNED_SHORT, | |
2, 0, 1, }, /*10 - UshortGray */ | |
{ GL_BGR, GL_UNSIGNED_BYTE, | |
1, 0, 1, }, /*11 - ThreeByteBgr */}; |
which is not null so not sure why pf will ever be null? Did you see it null anytime?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was discussed already. There's another call site that passes NULL.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh this is a different function. Not the one previously discussed, looks like it was added to the PR later.
This case at least currently cannot be called with NULL for the reason above.
colorMap->Colors && | ||
transparentColor < 0) { | ||
fillColor= MAKE_QUAD_GIF( | ||
colorMap->Colors[gif->SBackGroundColor], 0xff); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Dont we need to check for colorMap->Colors here too
colorMapBuf[i] = MAKE_QUAD_GIF(colorMap->Colors[i], 0xff); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The problem isn't the Colors member, it is colorMap. I'm not sure the new check for Colors is necessary.
If you look at giflib's allocator for this it will never return a colorMap without Colors allocated and the giflib code itself assumes that this is true.
jint tmph = sh; | ||
while (tmph > 0) { | ||
j2d_glTexSubImage2D(GL_TEXTURE_2D, 0, | ||
if (pf != NULL) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think any of these changes in this file are necessary.
pf is null IFF sw_surface == JNI_FALSE
and iin that case, we never end the loop where pf is needed.
Put another way, if you look at the call sites one
is
pf != null, srcOps == NULL, sw_surface == FALSE
the other is
pf == null, srcOps != NULL, sw_surface == TRUE
and you can see that srcOps would have the same theoretical issue except that it would be a bug to call it with the wrong value of sw_surface.
So revert all changes in this file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
The defect has been detected and confirmed in the function OGLBlitToSurfaceViaTexture() located in the file src/java.desktop/share/native/common/java2d/opengl/OGLBlitLoops.c with static code analysis. This defect can potentially lead to a null pointer dereference.
The pointer pf is dereferenced in line 324 without checking for nullptr, although earlier in line 274 the same pointer is checked for nullptr, which indicates that it can be null.
In the same file, line 551 calls OGLBlitToSurfaceViaTexture() from line 263, where NULL is passed in place of pf.
All other calls are fine.
Also, another function with a similar issue from the same file, OGLBlitSwToTexture() from line 396.
In src/java.desktop/unix/native/libawt_xawt/awt/gtk3_interface.c gtk3_load()
The pointer fp_glib_check_version can be null, but it is dereferenced without any check. Although in the same file, for example, line 280 contains a check, this check does not lead to termination of execution.
In src/java.desktop/share/native/libsplashscreen/splashscreen_gif.c SplashDecodeGif()
The pointer colorMap is dereferenced after it has been checked against nullptr in lines 151 and 206. Moreover, between these checks and the mentioned location (line 282), the pointer is not modified in any way.
According to this comment, this PR contains fixes for similar cases in other places.
Progress
Issue
Reviewing
Using
git
Checkout this PR locally:
$ git fetch https://git.openjdk.org/jdk.git pull/26799/head:pull/26799
$ git checkout pull/26799
Update a local copy of the PR:
$ git checkout pull/26799
$ git pull https://git.openjdk.org/jdk.git pull/26799/head
Using Skara CLI tools
Checkout this PR locally:
$ git pr checkout 26799
View PR using the GUI difftool:
$ git pr show -t 26799
Using diff file
Download this PR as a diff file:
https://git.openjdk.org/jdk/pull/26799.diff
Using Webrev
Link to Webrev Comment