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

8262829: Native crash in Win32PrintServiceLookup.getAllPrinterNames() #2836

Closed
wants to merge 1 commit into from

Conversation

@aivanov-jdk
Copy link
Member

@aivanov-jdk aivanov-jdk commented Mar 4, 2021

Root cause:
getPrinterNames() has two calls to ::EnumPrinters. The first call is to get the required buffer size to contain the structures and any strings. The second call is to get the list of printers.

Yet the list of printers or the names of printers can change between the two calls. If it happens, the second call to EnumPrinters fails but it is not checked.

I couldn't reproduce the crash myself. However, I reproduced the failure in the second call to ::EnumPrinters by adding ::Sleep(500) and by renaming the printers so that the data doesn't fit into the allocated buffer:

1: bResult: 0, cbNeeded: 504, cReturned: 0
2: bResult: 0, cbNeeded: 512, cReturned: 0
    !!! error

During my testing, cReturned has always been zero whenever EnumPrinters fails.

The crash dumps show that cReturned is non-zero but the pPrinterEnum buffer doesn't contain valid data. Reading info4->pPrinterName at the line

utf_str = JNU_NewStringPlatform(env, info4->pPrinterName);

raises Access Violation exception.

The fix:
Check the return value of EnumPrinters and allow for 5 retries. If the function still returns failure, make sure cReturned is set to zero.

I'm going to close JDK-6996051 and JDK-8182683 reported previously about the same crash as duplicate of the current JDK-8262829.

Testing:
I used RemotePrinterStatusRefresh.java for testing, it shows the list of currently available printers. In the background I ran PrinterRename.ps1 PowerShell script which remains a printer, the script is attached to the JBS issue.

Without the fix, the list of available printers was empty occasionally because EnumPrinters returned failure and set cReturned to zero. With the fix, the list of printers is always filled.


Progress

  • Change must not contain extraneous whitespace
  • Commit message must refer to an issue
  • Change must be properly reviewed

Issue

  • JDK-8262829: Native crash in Win32PrintServiceLookup.getAllPrinterNames()

Reviewers

Download

$ git fetch https://git.openjdk.java.net/jdk pull/2836/head:pull/2836
$ git checkout pull/2836

@bridgekeeper
Copy link

@bridgekeeper bridgekeeper bot commented Mar 4, 2021

👋 Welcome back aivanov! A progress list of the required criteria for merging this PR into master will be added to the body of your pull request. There are additional pull request commands available for use with this pull request.

@openjdk openjdk bot added the rfr label Mar 4, 2021
@openjdk
Copy link

@openjdk openjdk bot commented Mar 4, 2021

@aivanov-jdk The following label will be automatically applied to this pull request:

  • 2d

When this pull request is ready to be reviewed, an "RFR" email will be sent to the corresponding mailing list. If you would like to change these labels, use the /label pull request command.

@openjdk openjdk bot added the 2d label Mar 4, 2021
@mlbridge
Copy link

@mlbridge mlbridge bot commented Mar 4, 2021

Webrevs

prrace
prrace approved these changes Mar 4, 2021
Copy link
Contributor

@prrace prrace left a comment

I guess this is OK and yes we should have been checking this.
Not sure we really got to the bottom of the real world problem because I'd expect the 2nd call just milliseconds after the first. But it could be that this happens during some system updates and we get one printer reconfigured message followed by another ..

@openjdk
Copy link

@openjdk openjdk bot commented Mar 4, 2021

@aivanov-jdk This change now passes all automated pre-integration checks.

ℹ️ This project also has non-automated pre-integration requirements. Please see the file CONTRIBUTING.md for details.

After integration, the commit message for the final commit will be:

8262829: Native crash in Win32PrintServiceLookup.getAllPrinterNames()

Reviewed-by: prr, psadhukhan, serb

You can use pull request commands such as /summary, /contributor and /issue to adjust it as needed.

At the time when this comment was updated there had been 43 new commits pushed to the master branch:

  • e1cad97: 8262862: Harden tests sun/security/x509/URICertStore/ExtensionsWithLDAP.java and krb5/canonicalize/Test.java
  • 2c0507e: 8261812: C2 compilation fails with assert(!had_error) failed: bad dominance
  • 9755782: 8157682: @inheritdoc doesn't work with @exception
  • 8c13d26: 8263050: move HtmlDocletWriter.verticalSeparator to IndexWriter
  • 8d3de4b: 8262844: (fs) FileStore.supportsFileAttributeView might return false negative in case of ext3
  • 75fb7cc: 8259228: Zero: rewrite (put|get)field from if-else chains to switches
  • 9730266: 8262973: Verify ParCompactionManager instance in PCAdjustPointerClosure
  • d91550e: 8262998: Vector API intrinsincs should not modify IR when bailing out
  • 80182f9: 8260925: HttpsURLConnection does not work with other JSSE provider.
  • dbef0ec: 6323374: (coll) Optimize Collections.unmodifiable* and synchronized*
  • ... and 33 more: https://git.openjdk.java.net/jdk/compare/0265ab63e4242a275aaf26199652f3f2a5e49bbf...master

As there are no conflicts, your changes will automatically be rebased on top of these commits when integrating. If you prefer to avoid this automatic rebasing, please check the documentation for the /integrate command for further details.

➡️ To integrate this PR with the above commit message to the master branch, type /integrate in a new comment.

@openjdk openjdk bot added the ready label Mar 4, 2021
::EnumPrinters(flags,
NULL, 4, pPrinterEnum, cbNeeded, &cbNeeded,
&cReturned);
::EnumPrinters(flags, NULL, 4, NULL,
Copy link
Member

@mrserb mrserb Mar 5, 2021

Choose a reason for hiding this comment

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

Don't we need to check that this method call succeeds? Probably it is a crash reason when the EnumPrinters fails but we use cbNeeded anyway for array allocation?

Copy link
Contributor

@prsadhuk prsadhuk Mar 5, 2021

Choose a reason for hiding this comment

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

I guess since we are changing this method anyway, can we use PRINTER_ENUM_CONNECTIONS flag instead of hardcoded 4 so that it is more informative!!

Copy link
Contributor

@prsadhuk prsadhuk Mar 5, 2021

Choose a reason for hiding this comment

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

ok, it is for flags and not for level. please ignore

Copy link
Member Author

@aivanov-jdk aivanov-jdk Mar 5, 2021

Choose a reason for hiding this comment

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

Don't we need to check that this method call succeeds? Probably it is a crash reason when the EnumPrinters fails but we use cbNeeded anyway for array allocation?

EnumPrinters always returns failure here because zero-sized buffer is too small to contain any data.

@aivanov-jdk
Copy link
Member Author

@aivanov-jdk aivanov-jdk commented Mar 5, 2021

I guess this is OK and yes we should have been checking this.
Not sure we really got to the bottom of the real world problem because I'd expect the 2nd call just milliseconds after the first. But it could be that this happens during some system updates and we get one printer reconfigured message followed by another ..

Most of the time, the crash happens when a client reconnects to their active session where a JVM is already running. On reconnect, the list of printers is synced with the local printers on the client. In such a scenario, other software could also update its list of printers as well as repaint its UI. If the system is under high load, it's not impossible to have a long enough pause between the calls.

mrserb
mrserb approved these changes Mar 5, 2021
@aivanov-jdk
Copy link
Member Author

@aivanov-jdk aivanov-jdk commented Mar 9, 2021

/integrate

@openjdk openjdk bot closed this Mar 9, 2021
@openjdk openjdk bot added integrated and removed ready rfr labels Mar 9, 2021
@openjdk
Copy link

@openjdk openjdk bot commented Mar 9, 2021

@aivanov-jdk Since your change was applied there have been 79 commits pushed to the master branch:

  • fbe40e8: 8252399: Update mapMulti documentation to use type test pattern instead of instanceof once JEP 375 exits preview
  • 0f2402d: 8263190: Update java.io, java.math, and java.text to use instanceof pattern variable
  • 4f0a12e: 8262323: do not special case JVMCI in tiered compilation policy
  • 3022baa: 8263167: IGV: build fails with "taskdef AutoUpdate cannot be found"
  • 0bc4562: 8263068: Rename safefetch.hpp to safefetch.inline.hpp
  • 5bfc5fd: 8263051: Modernize the code in the java.awt.color package
  • 5b9b170: 8262955: Unify os::fork_and_exec() across Posix platforms
  • 39b1113: 8262161: Refactor manual I/O stream copying in java.desktop to use new convenience APIs
  • 4e94760: 8263135: unique_ptr should not be used for types that are not pointers
  • f71b21b: 8263038: Optimize String.format for simple specifiers
  • ... and 69 more: https://git.openjdk.java.net/jdk/compare/0265ab63e4242a275aaf26199652f3f2a5e49bbf...master

Your commit was automatically rebased without conflicts.

Pushed as commit a6e34b3.

💡 You may see a message that your pull request was closed with unmerged commits. This can be safely ignored.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
4 participants