【android】几个和密码相关的问题分析(开机密码输入无效、FDE后改变密码无效、FDE后解密失败)
密码输入无效问题
复现步骤:
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掉。
手机FDE后改变密码无效
复现步骤:
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左右
-------------------------LOG---------------------------------------------
手机FDE后,第一次设置密码,changpw的耗时是10s左右01-01 00:01:15.058 4913 6342 E CryptdConnector: ***Like: {9 cryptfs changepw pattern [scrubbed] [scrubbed]} changpw time is (11334ms)
01-01 00:01:15.075 4913 6342 E CryptdConnector: NDC Command {9 cryptfs changepw pattern [scrubbed] [scrubbed]} took too long (11334ms)
手机FDE后,除第一次以外,后续changpw的耗时大约在7s左右
01-01 00:02:47.825 263 268 D VoldCryptCmdListener: cryptfs changepw pin {}
01-01 00:02:55.499 4913 5387 E CryptdConnector: ***Like: {17 cryptfs changepw pin [scrubbed] [scrubbed]} changpw time is (7685ms)
01-01 00:02:55.505 4913 5387 E CryptdConnector: NDC Command {17 cryptfs changepw pin [scrubbed] [scrubbed]} took too long (7685ms)
01-01 00:03:24.218 263 268 D VoldCryptCmdListener: cryptfs changepw pattern {}
01-01 00:03:31.720 4913 5386 E CryptdConnector: ***Like: {22 cryptfs changepw pattern [scrubbed] [scrubbed]} changpw time is (7508ms)
01-01 00:03:31.726 4913 5386 E CryptdConnector: NDC Command {22 cryptfs changepw pattern [scrubbed] [scrubbed]} took too long (7508ms)
手机FDE后,将手机快速重启中断changpw后,出现异常,然后去抓取changpw的耗时也在7s左右
01-01 00:08:16.802 6135 6148 E CryptdConnector: ***Like: {17 cryptfs fixate_newest_user_key_auth 0} changpw time is (17ms)
01-01 00:08:24.512 6135 8038 E CryptdConnector: ***Like: {18 cryptfs changepw pin [scrubbed] [scrubbed]} changpw time is (7547ms)
其次,在FDE后,以下changpw造成的耗时也增加了接近10倍:
01-01 00:29:14.926 6135 6135 E NetdConnector: ***Like: {15 bandwidth setglobalalert 2097152} changpw time is (272ms)
01-01 00:29:14.938 6135 6914 E NetdConnector: ***Like: {16 interface getcfg p2p0} changpw time is (174ms)
01-01 00:29:14.964 6135 6914 E NetdConnector: ***Like: {17 interface setcfg p2p0 0.0.0.0 0 up multicast broadcast} changpw time is (19ms)
01-01 00:29:15.601 6135 6135 E NetdConnector: ***Like: {18 firewall enable_chain standby} changpw time is (283ms)
01-01 00:29:15.634 6135 6135 E NetdConnector: ***Like: {19 firewall enable blacklist} changpw time is (13ms)
FDE解密失败
该问题同样出现在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经验请不吝告知。多谢多谢