1.手机设置密码(pin,图案,密码都可以),重启手机,进入验证开机密码界面
2.连续输入错误5次密码,提示需要等到30s才能输入,在此期间重启手机,开机输入正确密码,但界面提示"密码错误"
3.基于步骤2),重启手机后,等待30s再输入正确密码,可以解锁开机
4.基于步骤2),连续输入5次密码(无论正确和错误的)都不能解锁,提示密码错误,5次后锁定,等待30s解锁后,输入正确密码,可以解锁开机
开机时,由KeyguardViewMediator调用KeyguardViewManager去show解锁
处理解锁在onPatternChecked函数
图案是调用checkPattern->doVerifyPattern->verifyChallenge->verifyCredential
然后通过AIDL方式远程调用GateKeeperProxy::verifyChallenge(gatekeeperd.cpp)
如果支持硬件的handle,那么通过HAL(GATEKEEPER_HARDWARE_MODULE_ID)去调用接口int (*verify)(...)
锁定上层的疑惑后,有qcom提供的patch
--- a/services/core/java/com/android/server/LockSettingsService.java
+++ b/services/core/java/com/android/server/LockSettingsService.java
@@ -1250,7 +1250,10 @@ public class LockSettingsService extends ILockSettings.Stub {
@Override
public VerifyCredentialResponse checkPattern(String pattern, int userId,
ICheckCredentialProgressCallback progressCallback) throws RemoteException {
- return doVerifyPattern(pattern, false, 0, userId, progressCallback);
+ VerifyCredentialResponse response = doVerifyPattern(pattern, false, 0, userId, progressCallback);
+ if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK)
+ retainPassword(pattern);
+ return response;
}
@Override
@@ -1321,7 +1324,10 @@ public class LockSettingsService extends ILockSettings.Stub {
@Override
public VerifyCredentialResponse checkPassword(String password, int userId,
ICheckCredentialProgressCallback progressCallback) throws RemoteException {
- return doVerifyPassword(password, false, 0, userId, progressCallback);
+ VerifyCredentialResponse response = doVerifyPassword(password, false, 0, userId, progressCallback);
+ if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK)
+ retainPassword(password);
+ return response;
}
但后来证明,该patch我们已经打进去了,依然会复现该问题
最后和qcom协同调查后,发现所有的android手机上都会保持这样的问题,包括google的几个亲儿子nexus5/6
所以该问题目前看来是google自己的设计问题,于是没有深究,不知道下个版本该问题是否会被fix掉。
1.手机进行FDE
2.FDE后设置手机密码
3.改变步骤2)的密码(比如从图形改为password等)
4.在3)后马上重启手机(用adb reboot更好)
5.开机,发现手机的密码是步骤2)的,没有成功修改到步骤3)
首先透过上层获取到get到的type是:
packages/apps/Settings/src/com/android/settings/CryptKeeper.java 中:
518 final IMountService service = getMountService();
519 passwordType = service.getPasswordType();
获取到的passwordType类型; getPasswordType,往下跟踪,调用的是mCryptConnector.execute("cryptfs", "getpwtype")去获取vold返回的type,期望是2(pattern),但是返回是3(pin);-----说明设置步骤3)没有成功,手机中保存的依然是上一次的密码
而在设置lock screen流程是,执行的是crypfs流程
mCryptConnector.execute("cryptfs", "changepw", CRYPTO_TYPES[type],
new SensitiveArg(currentPassword), new SensitiveArg(password));
会出现状态不一致,调用cryptfs->changepw去修改,实际的结果和期望不一样,目前怀疑cryptfs执行命令可能没有完全成功。
在上述changpw的地方埋了些log,发现changpw时候,如果在FDE后时间会很长,依次判断,假如在changpw过程没有完成时候去重启手机很符合复现情景
同时有并行同平台项目发现不会复现,经过确认,使用keymasterV0.3版本不会复现,keymasterV1.0会复现
所以和qcom检测方向是check这个changpw时间是否还有优化空间来避规这样的问题
手机未FDE时,changpw的时间大概是30ms左右
该问题同样出现在FDE以后,某一台手机开机时候提示解密失败,具体如下图:
在进入该界面后,手机无法进行任何操作(除了强制开关机)
从android给到的信息中,手机进入该情况,是在解密的时候被中断,导致解密数据失败,数据损坏,只能通过界面上的回复出厂设置reset
而我们获取到的log如下:
01-06 17:47:32.443 255 313 D Cryptfs : unmounting /data succeeded
01-06 17:47:53.049 255 313 E Cryptfs : Failed to mount decrypted data
01-06 17:47:53.054 255 313 I Cryptfs : Started framework to offer wipe
后来将log信息等给到qcom,也没有发现任务异常,只追到了qcom提供的库可能有异常
qcom在库中添加了log信息后,进行了上千次压力测试,没有复现
考虑到没有任何修改,复现概率超级低,并且目前没有发现问题原因,所以问题不了了之,如果有朋友对这样的问题有什么debug经验请不吝告知。多谢多谢