java.lang.Error is swallowed by LoginContext#invoke

Weijun Wang weijun.wang at oracle.com
Tue Dec 25 08:47:01 UTC 2018


I just filed https://bugs.openjdk.java.net/browse/JDK-8215916.

Thanks,
Max

> On Dec 25, 2018, at 4:16 PM, Vincent <wenxiang.qiu at foxmail.com> wrote:
> 
> If an Error is thrown,  I would like that LoginContext's invoke() take it from InvocationTargetException and log the stack trace when debug is on. 
> 
> In fact I even wonder why Method's invoke() method turns unchecked Errors into checked InvocationTargetExceptions but it's out of the scope of this mail group.
> 
> ------------------ Original ------------------
> From:  "Weijun Wang"<weijun.wang at oracle.com>;
> Date:  Tue, Dec 25, 2018 03:44 PM
> To:  "Vincent"<wenxiang.qiu at foxmail.com>;
> Cc:  "security-dev at openjdk.java.net"<security-dev at openjdk.java.net>;
> Subject:  Re: java.lang.Error is swallowed by LoginContext#invoke
> 
> I see.
> 
> I am not sure we can fail here because historically we don't differentiate between a "system" failure and an "application" failure. Although the methods in LoginModule specify a LoginException, if another exception is thrown, we now treat it as a normal login error.
> 
> Maybe we can add more debug info. Do you have a suggested fix? I assume you see the "OPTIONAL failure" word but you'd like something like a stack trace?
> 
> Thanks,
> Max
> 
> > On Dec 25, 2018, at 3:26 PM, Vincent <wenxiang.qiu at foxmail.com> wrote:
> > 
> > Hi Max,
> > 
> > Thanks for your reply. 
> > Sorry I didn't mention it in my precedent mail, but I'm quite familiar with the usual debug process with JAAS and Krb5. Turning on these 3 debug switches was the first thing I went for when the problem occurred. But this time these didn't really help. That's why I wrote and used a new Krb5LoginModule to catch all Throwables and figured out the problem. The trouble here is that the problem is caused by wrong file permissions on some jar files used by Krb5LoginModule and thus an Error is thrown from deep down the call stack. It's not caught in Krb5LoginModule (it shouldn't) so debug logs turned on by debug=true and -Dsun.security.krb5.debug=true show nothing useful. When the Error is caught by LoginContext's invoke() (the Error is now wrapped in an InvocationTargetException by java reflection), LoginContext logs a failed optional login:
> > [LoginContext]: login OPTIONAL failure
> > And that's all. So the crucial problem is completely hidden.
> > I don't think we should blame Hadoop for setting Krb5LoginModule as optional because it wants to fallback to simple authentication when krb5 fails. Besides, Krb5LoginModule and other Krb5 related modules do their best to provide debug info on Kerberos matters. But if problem is caused by external errors such as wrong file permissions, it seems to be impossible to locate it without rewriting some code.
> > 
> > 
> > ------------------ Original ------------------
> > From:  "Weijun Wang"<weijun.wang at oracle.com>;
> > Date:  Tue, Dec 11, 2018 05:55 PM
> > To:  "Vincent"<wenxiang.qiu at foxmail.com>;
> > Cc:  "security-dev at openjdk.java.net"<security-dev at openjdk.java.net>;
> > Subject:  Re: java.lang.Error is swallowed by LoginContext#invoke
> > 
> > Does -Djava.security.debug=logincontext show anything? This is the formal way to debug JAAS.
> > 
> > Also, you can put debug=true in your Krb5LoginModule config entry and see what's happening, and there is always -Dsun.security.krb5.debug=true to show kerberos related debug info.
> > 
> > --Max
> > 
> > > On Dec 11, 2018, at 4:57 PM, Wenxiang <wenxiang.qiu at foxmail.com> wrote:
> > > 
> > > Hi everyone,
> > > 
> > > I was using Hadoop command line interface to access HDFS with a non-root user. After successfully running kinit, Hadoop FsShell fails with GSSException: No valid credentials provided (Mechanism level: Failed to find any Kerberos tgt). After using a subclassed Krb5LoginModule to print out necessary debug info, I found that the login module's login method failed because permissions of some jars in classpath are not properly set and process doesn't have read permissions to them. A java.lang.ExceptionInInitializerError is thrown. Because the login method is invoked via reflection in LoginContext, the ExceptionInInitializerError is wrapped in an InvocationTargetException and is caught in LoginContext#invoke. Since this Kerberos login module is optional and the following login module logins successfully, the exception is logged nowhere and the ExceptionInInitializerError thrown from deep in the call stack is completely swallowed silently, making debugging this problem extremely hard.
> > > 
> > > My point here is that codes in LoginModule are not supposed to catch and process java.lang.Error, and I am confused by the way that reflection method invocation in LoginContext#invoke just swallows silently errors thrown by the method invoked. When an Error occurs, it means something really bad happened. I think LoginContext#invoke should either propagate errors to upper codes, or at least log such events.
> > > 
> > > This error-swallowing behavior is consistent from jdk 7 to jdk 11. I would like to have some expert comments on this to help me understand this design. Thanks.
> > > 
> > > Wenxiang Qiu
> > 
> 



More information about the security-dev mailing list