-
Bug
-
Resolution: Duplicate
-
P3
-
None
-
7
-
x86
-
os_x
FULL PRODUCT VERSION :
java version "1.7.0_06-ea"
Java(TM) SE Runtime Environment (build 1.7.0_06-ea-b08)
Java HotSpot(TM) 64-Bit Server VM (build 23.0-b21, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Mac OS X only
EXTRA RELEVANT SYSTEM CONFIGURATION :
Smart Card reader attached to an OS X system along with a smart card.
A DESCRIPTION OF THE PROBLEM :
7195480, but I can't find a way to add more details.
CardTerminal.isCardPresent() always returns false.
REGRESSION. Last worked in version 6u31
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run this code on OS X with Oracle Java 7
TerminalFactory factory = TerminalFactory.getDefault();
List<CardTerminal> terminals = factory.terminals().list();
System.out.println("Terminals: " + terminals);
CardTerminal terminal = terminals.get(0);
System.out.println(terminal.isCardPresent()); // Always false
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Returns true when a card is present, false otherwise
ACTUAL -
CardTerminal.isCardPresent() always returns false.
The main issue here is the native layer in Java is reading the wrong part of the struct SCARD_READERSTATE after calling SCardGetStatusChange.
From Java_sun_security_smartcardio_PCSC_SCardGetStatusChange after the malloc call:
(gdb) c
Continuing.
Breakpoint 3, 0x000000010aa225b2 in Java_sun_security_smartcardio_PCSC_SCardGetStatusChange ()
3: x/8xw 4300546608
0x100552230: 0x00554aa0 0x00000001 0x00000000 0x00000000
0x100552240: 0x00000000 0x00000022 0x00000013 0x0096db3b
^^^^^^^^ ^^^^^^^^
| +--- Number of bytes in ATR
+--- Event State
2: /x $rax = 0x0
1: x/i $rip 0x10aa225b2 <Java_sun_security_smartcardio_PCSC_SCardGetStatusChange+265>: mov %rax,-0x50(%rbp)
(gdb) set {int}0x100552248 = 0xdeadbeef
(gdb) display
3: x/8xw 4300546608
0x100552230: 0x00554aa0 0x00000001 0x00000000 0x00000000
0x100552240: 0x00000000 0x00000022 0xdeadbeef 0x0096db3b
^^^^^^^^ ^^^^^^^^
| +--- Number of bytes in ATR
+--- Event State
2: /x $rax = 0x0
1: x/i $rip 0x10aa225b2 <Java_sun_security_smartcardio_PCSC_SCardGetStatusChange+265>: mov %rax,-0x50(%rbp)
(gdb) c
Continuing.
deadbeef <-- Printed from the JVM, the result of directly calling SCardGetStatusChange via reflection
^^^^^^^^
|
+---- Now in the JVM from a direct reflection call to SCardGetStatusChange
Program exited normally.
(gdb)
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
TerminalFactory factory = TerminalFactory.getDefault();
List<CardTerminal> terminals = factory.terminals().list();
System.out.println("Terminals: " + terminals);
CardTerminal terminal = terminals.get(0);
System.out.println(terminal.isCardPresent()); // Always false
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Since in OS X the method returns the number of bytes in the ATR rather than the event state, the main workaround is to test if the number of ATR bytes is non-zero.
To do so, code must be written that restricts its execution to Java versions after 1.7 and OS X only. The code must use reflection to directly call SCardGetStatusChange and check the value of the returned ATR size.
java version "1.7.0_06-ea"
Java(TM) SE Runtime Environment (build 1.7.0_06-ea-b08)
Java HotSpot(TM) 64-Bit Server VM (build 23.0-b21, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Mac OS X only
EXTRA RELEVANT SYSTEM CONFIGURATION :
Smart Card reader attached to an OS X system along with a smart card.
A DESCRIPTION OF THE PROBLEM :
7195480, but I can't find a way to add more details.
CardTerminal.isCardPresent() always returns false.
REGRESSION. Last worked in version 6u31
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run this code on OS X with Oracle Java 7
TerminalFactory factory = TerminalFactory.getDefault();
List<CardTerminal> terminals = factory.terminals().list();
System.out.println("Terminals: " + terminals);
CardTerminal terminal = terminals.get(0);
System.out.println(terminal.isCardPresent()); // Always false
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Returns true when a card is present, false otherwise
ACTUAL -
CardTerminal.isCardPresent() always returns false.
The main issue here is the native layer in Java is reading the wrong part of the struct SCARD_READERSTATE after calling SCardGetStatusChange.
From Java_sun_security_smartcardio_PCSC_SCardGetStatusChange after the malloc call:
(gdb) c
Continuing.
Breakpoint 3, 0x000000010aa225b2 in Java_sun_security_smartcardio_PCSC_SCardGetStatusChange ()
3: x/8xw 4300546608
0x100552230: 0x00554aa0 0x00000001 0x00000000 0x00000000
0x100552240: 0x00000000 0x00000022 0x00000013 0x0096db3b
^^^^^^^^ ^^^^^^^^
| +--- Number of bytes in ATR
+--- Event State
2: /x $rax = 0x0
1: x/i $rip 0x10aa225b2 <Java_sun_security_smartcardio_PCSC_SCardGetStatusChange+265>: mov %rax,-0x50(%rbp)
(gdb) set {int}0x100552248 = 0xdeadbeef
(gdb) display
3: x/8xw 4300546608
0x100552230: 0x00554aa0 0x00000001 0x00000000 0x00000000
0x100552240: 0x00000000 0x00000022 0xdeadbeef 0x0096db3b
^^^^^^^^ ^^^^^^^^
| +--- Number of bytes in ATR
+--- Event State
2: /x $rax = 0x0
1: x/i $rip 0x10aa225b2 <Java_sun_security_smartcardio_PCSC_SCardGetStatusChange+265>: mov %rax,-0x50(%rbp)
(gdb) c
Continuing.
deadbeef <-- Printed from the JVM, the result of directly calling SCardGetStatusChange via reflection
^^^^^^^^
|
+---- Now in the JVM from a direct reflection call to SCardGetStatusChange
Program exited normally.
(gdb)
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
TerminalFactory factory = TerminalFactory.getDefault();
List<CardTerminal> terminals = factory.terminals().list();
System.out.println("Terminals: " + terminals);
CardTerminal terminal = terminals.get(0);
System.out.println(terminal.isCardPresent()); // Always false
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Since in OS X the method returns the number of bytes in the ATR rather than the event state, the main workaround is to test if the number of ATR bytes is non-zero.
To do so, code must be written that restricts its execution to Java versions after 1.7 and OS X only. The code must use reflection to directly call SCardGetStatusChange and check the value of the returned ATR size.
- duplicates
-
JDK-7195480 javax.smartcardio does not detect cards on Mac OS X
-
- Closed
-