其实很多人研究过这个问题了,只是最近我碰到这次原因有些不同……
症状是在命令行执行命令碰到segmentation fault,logcat里有:
W/dalvikvm(12364): Exception Ljava/lang/NullPointerException; thrown while initializing Ljava/lang/System; W/dalvikvm(12364): Exception Ljava/lang/ExceptionInInitializerError; thrown while initializing Ljava/lang/ClassLoader$SystemClassLoader; .... I/dalvikvm(12364): java.lang.ExceptionInInitializerError: I/dalvikvm(12364): at java.lang.ClassLoader.getSystemClassLoader(ClassLoader.java:125) I/dalvikvm(12364): at dalvik.system.NativeStart.main(Native Method) I/dalvikvm(12364): Caused by: I/dalvikvm(12364): java.lang.ExceptionInInitializerError: I/dalvikvm(12364): at java.lang.ClassLoader.createSystemClassLoader(ClassLoader.java:100) .... I/dalvikvm(12364): Caused by: I/dalvikvm(12364): java.lang.NullPointerException: I/dalvikvm(12364): at java.util.Hashtable.put(Hashtable.java:365) I/dalvikvm(12364): at java.lang.System.initSystemProperties(System.java:286) I/dalvikvm(12364): at java.lang.System.getProperties(System.java:260) ....
原因大致上就是LD_LIBRARY_PATH里少了东西。ICS以后的系统,启动Android那套VM需要LD_LIBRARY_PATH里必须要有一些路径,默认是/vendor/lib和/system/lib,试下来至少要/system/lib,否则会找不到库,然后…… 不清楚之后发生了什么,反正最后就导致上面那个错误……
但是默认情况是有的,啥时候没有呢?其实这次碰见bug是因为,我为了弄到root把shell(/system/bin/mksh) setuid了…… 然后在shell里就一直有问题……
对于setuid的程序,启动时effective uid与uid不符,动态链接器便会调用linker_secure_env(),把LD_LIBRARY_PATH从环境里踢掉。ICS之后的系统又必须要这个值VM才能启动,于是就挂了……
其实这是个古老的安全机制,否则你LD_LIBRARY_PATH指到别的地方启动setuid程序,就能让他加载你的库,然后以root权限调用到你的库里去,那自然想干啥都行……
把sh的权限弄对之后就没事了……