- 由于本人水平有限,所以框架相关漏洞分析的会较详细,很多媒体和短距的漏洞,写的较为简略,有兴趣的读者可以自行阅读原始patch,还请理解。
2021-12-01 security patch level vulnerability details
Framework
CVE-2021-0955
- MediaProvider中的FuseDaemon存在UAF漏洞,只影响Android 11。
if (size < 0) fuse_reply_err(req, -size); else {
- fuse_reply_write(req, size);
- // Execute Record before fuse_reply_write to avoid the following ordering:
- // fuse_reply_write -> pf_release (destroy handle) -> Record (use handle after free)
fuse->fadviser.Record(h->fd, size); - fuse_reply_write(req, size);
}
} - 影响版本:11
- 致谢信息:Mitch Phillips using GWP-ASan
CVE-2021-0970
- GpsNavigationMessage的序列化错误
- if (parcel.dataAvail() >= Integer.SIZE) {
- int status = parcel.readInt();
- navigationMessage.setStatus((short) status);
- } else {
- navigationMessage.setStatus(STATUS_UNKNOWN);
- }
- int status = parcel.readInt();
- navigationMessage.setStatus((short) status);
-
API中的readInt会一路调用到
Parcel.cpp
中的readAligned// frameworks/native/libs/binder/Parcel.cpp template<class T> status_t Parcel::readAligned(T *pArg) const { static_assert(PAD_SIZE_UNSAFE(sizeof(T)) == sizeof(T)); if ((mDataPos+sizeof(T)) <= mDataSize) { if (mObjectsSize > 0) { status_t err = validateReadData(mDataPos + sizeof(T)); if(err != NO_ERROR) { // Still increment the data position by the expected length mDataPos += sizeof(T); return err; } } const void* data = mData+mDataPos; mDataPos += sizeof(T); *pArg = *reinterpret_cast<const T*>(data); return NO_ERROR; } else { return NOT_ENOUGH_DATA; } }
- 这是一个模板函数,当readInt的时候会传入int32_t作为模板类型,然后可以看到这个函数里面的validateReadData是可以保证不会出现读越界的。
- GpsNavigationMessage中的代码本意也是做这个判断,担心dataAvail不够一个int的长度,然而判断用的是Integer.SIZE,这个值实际上是32。而dataAvail返回的是字节数(如果用Integer.BYTE可能还好点)。
size_t Parcel::dataAvail() const { size_t result = dataSize() - dataPosition(); if (result > INT32_MAX) { LOG_ALWAYS_FATAL("result too big: %zu", result); } return result; }
- 所以这个操作不仅多此一举,而且还判断错了。补丁就是去掉没用的检查代码
- 影响版本:9, 10, 11, 12
- 致谢信息:MyTyrannosaurusBuddy
CVE-2021-0704
- AccountManagerService中改了一下帐号请求通知(account request notification)的字符串,看起来是里面带上了请求权限的应用名字。
- 影响版本:9, 10, 11
- 致谢信息:Edward Cunningham of Google
Media Framework
CVE-2021-0967
- external/tremolo中的漏洞,在Android 9上面可以远程利用。
- 影响版本:9, 10, 11, 12
- 致谢信息:无
CVE-2021-0964
- C2SoftMp3Dec软解里面的数值计算问题,后续导致越界写入。
mConfig->inputBufferCurrentLength = (inSize - inPos); mConfig->inputBufferMaxLength = 0; mConfig->inputBufferUsedLength = 0;
- mConfig->outputFrameSize = (calOutSize – outSize);
- mConfig->outputFrameSize = (calOutSize – outSize) / sizeof(int16_t);
mConfig->pOutputBuffer = reinterpret_cast<int16_t *> (wView.data() + outSize); - 影响版本:9, 10, 11, 12
- 致谢信息:无
System
CVE-2021-0968
- 蓝牙组件内存分配器的问题,防止无符号的size高位为1,也就是整数溢出中将负数当作size_t传入osi_malloc或者osi_calloc来分配超大内存的情况,现在就不能再分配了。
void* osi_malloc(size_t size) {
- CHECK(static_cast<ssize_t>(size) >= 0);
size_t real_size = allocation_tracker_resize_for_canary(size);
void* ptr = malloc(real_size);
CHECK(ptr);```diff void* osi_calloc(size_t size) {</code></pre></li> <li>CHECK(static_cast<ssize_t>(size) >= 0); size_t real_size = allocation_tracker_resize_for_canary(size); void* ptr = calloc(1, real_size); CHECK(ptr); <pre><code></code></pre></li> <li>影响版本:9, 10, 11, 12</li> <li>致谢信息:Vijay Prakash and Ruian Duan, Palo Alto Networks Inc</li> </ul> <h4>CVE-2021-0956</h4> <ul> <li>NFC组件中的越界写 <pre><code class="language-diff"> if (mTechListTail < (MAX_NUM_TECHNOLOGY - 1)) { mNumTechList = mTechListTail;</code></pre></li> <li>} else {</li> <li>LOG(ERROR) << StringPrintf("%s: exceed max=%d", fn, MAX_NUM_TECHNOLOGY);</li> <li>android_errorWriteLog(0x534e4554, "189942532");</li> <li>goto TheEnd; } <pre><code></code></pre></li> <li>影响版本:11, 12 </li> <li>致谢信息:Nguyễn Hoàng Thạch (d4rkn3ss) of STAR Labs</li> </ul> <h4>CVE-2021-0953</h4> <ul> <li>QuickSearchBox组件中的SearchWidgetProvider存在不安全的PendingIntent。由于OEM的定制,这个漏洞可能不影响部分OEM的系统。 <pre><code class="language-diff"> private void setOnClickActivityIntent(Context context, RemoteViews views, int viewId, Intent intent) {</code></pre></li> <li>intent.setPackage(context.getPackageName()); PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0); views.setOnClickPendingIntent(viewId, pendingIntent); } <pre><code></code></pre></li> <li>影响版本:9, 10, 11, 12</li> <li>致谢信息:无</li> </ul> <h4>CVE-2021-0954</h4> <ul> <li>com.android.internal.app.ResolverActivity的点击劫持问题,添加SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS标志。</li> <li>影响版本:10, 11</li> <li>致谢信息:无</li> </ul> <h4>CVE-2021-0963</h4> <ul> <li>com.android.keychain.KeyChainActivity的点击劫持问题,添加SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS标志并使用setFilterTouchesWhenObscured(true)。</li> <li>影响版本:9, 10, 11, 12</li> <li>致谢信息:Tianyi Hu (胡天易) of Bytedance Wuheng Lab</li> </ul> <h4>CVE-2021-0965</h4> <ul> <li>防止恶意应用调用com.android.settings.bluetooth.BluetoothPairingDialog来伪造蓝牙配对窗口,添加android.permission.BLUETOOTH_PRIVILEGED权限来保护。</li> <li>影响版本:9, 10, 11, 12</li> <li>致谢信息:Yu-Cheng Lin (林禹成) (@AndroBugs)</li> </ul> <h4>CVE-2021-0952</h4> <ul> <li>通讯录应用选联系人头像并编辑的AttachPhotoActivity,限制只调用系统应用来进行联系人头像编辑,防止第三方应用在没有权限的情况下从Intent中读取到通讯录。由于OEM的定制,这个漏洞可能不影响部分OEM的系统。 <pre><code class="language-java">private ResolveInfo getIntentHandler(Intent intent) { final List<ResolveInfo> resolveInfos = getPackageManager() .queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY | PackageManager.MATCH_SYSTEM_ONLY); return (resolveInfos != null && resolveInfos.size() > 0) ? resolveInfos.get(0) : null; }</code></pre></li> <li>影响版本:9, 10, 11, 12</li> <li>致谢信息:Sithija</li> </ul> <h4>CVE-2021-0966</h4> <ul> <li>在编译AIDL文件的时候,如果enum没有默认值,则用0进行填充。</li> <li>影响版本:11, 12</li> <li>致谢信息:Jann Horn of Google Project Zero</li> </ul> <h4>CVE-2021-0958</h4> <ul> <li>KeyStore 2.0中km_compat的问题,TBD。<code>https://android.googlesource.com/platform/system/security/+/b7f303146fecc166260aced8de677dfc7322f7a3</code></li> <li>影响版本:11, 12</li> <li>致谢信息:无</li> </ul> <h4>CVE-2021-0969</h4> <ul> <li>AP名称为空会导致NPE <pre><code class="language-diff"> public String getTitle() {</code></pre></li> <li>if (isPasspoint()) {</li> <li>if (isPasspoint() && !TextUtils.isEmpty(mConfig.providerFriendlyName)) { return mConfig.providerFriendlyName;</li> <li>} else if (isPasspointConfig()) {</li> <li>} else if (isPasspointConfig() && !TextUtils.isEmpty(mProviderFriendlyName)) { return mProviderFriendlyName;</li> <li>} else if (isOsuProvider()) {</li> <li>} else if (isOsuProvider() && !TextUtils.isEmpty(mOsuProvider.getFriendlyName())) { return mOsuProvider.getFriendlyName();</li> <li>} else {</li> <li>} else if (!TextUtils.isEmpty(getSsidStr())) { return getSsidStr();</li> <li>} else {</li> <li>return ""; } } <pre><code></code></pre></li> <li>影响版本:10, 11</li> <li>致谢信息:无</li> </ul> <h2>2021-12-05 security patch level vulnerability details</h2> <h2>2021-11-01 security patch level vulnerability details</h2> <h3>Framework</h3> <h4>CVE-2021-0799</h4> <ul> <li>在ActivityThread中,使用ArrayMap来管理ProviderKey,而不是使用SparseArray,因为ArrayMap可以更好的处理Hash碰撞场景。ActivityThread是位于应用进程中,不太清楚这个漏洞的具体利用场景。</li> <li>影响版本:12</li> <li>致谢信息:Makoto Onuki of Google</li> </ul> <h4>CVE-2021-0921</h4> <ul> <li> <p>跨进程传递ParsingPackage的时候,传递复杂对象,先写入长度再写入内容,这里传递的是一个<code>Map<String, ArraySet<PublicKey>></code>嵌套类型</p> <pre><code class="language-java"> /** * Writes the keyset mapping to the provided package. {@code null} mappings are permitted. */ public static void writeKeySetMapping(@NonNull Parcel dest, @NonNull Map<String, ArraySet<PublicKey>> keySetMapping) { if (keySetMapping == null) { dest.writeInt(-1); return; } final int N = keySetMapping.size(); dest.writeInt(N); for (String key : keySetMapping.keySet()) { dest.writeString(key); ArraySet<PublicKey> keys = keySetMapping.get(key); if (keys == null) { dest.writeInt(-1); continue; } final int M = keys.size(); dest.writeInt(M); for (int j = 0; j < M; j++) { dest.writeSerializable(keys.valueAt(j)); } } }</code></pre> </li> </ul> <p>/**</p> <ul> <li>Reads a keyset mapping from the given parcel at the given data position. May return</li> <li> <p>{@code null} if the serialized mapping was {@code null}. */ @NonNull public static ArrayMap<String, ArraySet<PublicKey>> readKeySetMapping(@NonNull Parcel in) { final int N = in.readInt(); if (N == -1) { return null; }</p> <p>ArrayMap<String, ArraySet<PublicKey>> keySetMapping = new ArrayMap<>(); for (int i = 0; i < N; ++i) { String key = in.readString(); final int M = in.readInt(); if (M == -1) { keySetMapping.put(key, null); continue; }</p> <pre><code>ArraySet<PublicKey> keys = new ArraySet<>(M); for (int j = 0; j < M; ++j) { PublicKey pk = (PublicKey) in.readSerializable(); keys.add(pk); } keySetMapping.put(key, keys);</code></pre> <p>}</p> <p>return keySetMapping; }</p> <pre><code> - 影响版本:11 - 致谢信息:Zinuo Han (weibo.com/ele7enxxh) of Amber Security Lab, OPPO Mobile Telecommunications Corp. Ltd.</code></pre> </li> </ul> <h4>CVE-2021-0923</h4> <ul> <li>当Internal类型的权限所有者变更时,收回权限 <pre><code class="language-diff"></code></pre></li> <li>if (permission.isRuntime() && (ownerChanged || wasNonRuntime)) {</li> <li>// If this is a runtime permission and the owner has changed, or this wasn't a runtime</li> <li>// permission, then permission state should be cleaned up</li> <li>if ((permission.isInternal() && ownerChanged)</li> <li>|| (permission.isRuntime() && (ownerChanged || wasNonRuntime))) {</li> <li>// If this is an internal/runtime permission and the owner has changed, or this wasn't a</li> <li>// runtime permission, then permission state should be cleaned up. permission.mDefinitionChanged = true; } <pre><code></code></pre></li> <li>ownerChanged的条件是,系统应用重新定义了非系统权限的时候,这种场景应该非常少,可能是一个非系统应用在OTA升级之后变成了系统应用 <pre><code class="language-java">@NonNull public static Permission createOrUpdate(@Nullable Permission permission, @NonNull PermissionInfo permissionInfo, @NonNull AndroidPackage pkg, @NonNull Collection<Permission> permissionTrees, boolean isOverridingSystemPermission) { // Allow system apps to redefine non-system permissions boolean ownerChanged = false; if (permission != null && !Objects.equals(permission.mPermissionInfo.packageName, permissionInfo.packageName)) { if (pkg.isSystem()) { if (permission.mType == Permission.TYPE_CONFIG && !permission.mReconciled) { // It's a built-in permission and no owner, take ownership now permissionInfo.flags |= PermissionInfo.FLAG_INSTALLED; permission.mPermissionInfo = permissionInfo; permission.mReconciled = true; permission.mUid = pkg.getUid(); } else if (!isOverridingSystemPermission) { Slog.w(TAG, "New decl " + pkg + " of permission " + permissionInfo.name + " is system; overriding " + permission.mPermissionInfo.packageName); ownerChanged = true; permission = null; } } } //... }</code></pre></li> <li>影响版本:12</li> <li>致谢信息:Xianlin Wu(吴宪林) of OPPO Amber Security Lab</li> </ul> <h4>CVE-2021-0926</h4> <ul> <li>限制第三方应用调用NfcImportVCardActivity,增加android.permission.DISPATCH_NFC_MESSAGE权限管控</li> <li>影响版本:9, 10, 11, 12</li> <li>致谢信息:Yu-Cheng Lin (林禹成) (@AndroBugs)</li> </ul> <h4>CVE-2021-0933</h4> <ul> <li>CompanionDeviceActivity中潜在的XSS问题,使用<code>Html.escapeHtml</code>对显示名称进行过滤。</li> <li>影响版本:9, 10, 11, 12</li> <li>致谢信息:无</li> </ul> <h4>CVE-2020-13871</h4> <ul> <li>sqlite漏洞 CVE-2020-15358 and CVE-2020-13871修复</li> <li>影响版本:11</li> <li>致谢信息:无</li> </ul> <h4>CVE-2021-0653</h4> <ul> <li>NetworkPolicyManagerService中的<code>com.android.server.net.action.SNOOZE_WARNING</code>广播增加接收者,防止第三方应用收到该广播</li> <li>影响版本:9, 10, 11</li> <li>致谢信息:Yu-Cheng Lin (林禹成) (@AndroBugs)</li> </ul> <h4>CVE-2021-0922</h4> <ul> <li>INTERACT_ACROSS_PROFILE这个appop是授予给了package,但是如果有两个packages使用了shareUserId的话,允许只有一个package有此权限,此时enforceCrossUserOrProfilePermission接口校验会出现问题,因为其底层调用的是getPackagesForUid接口,但是对于shareUserId的场景,会返回随机的一个package,因为有多个package对应同一个uid。解决方案是将这个appop授予给一个uid,而不是package,因为Android应用沙箱本质上是保护的uid,而不是package。</li> <li>影响版本:11</li> <li>致谢信息:Khouloud Mansouri of Google</li> </ul> <h3>Media Framework</h3> <h4>CVE-2021-0928</h4> <ul> <li>在向Android Camera 2接口传递OutputConfiguration等对象时存在不正确的异常捕获,会导致返回空对象</li> <li>共有四个对象存在此问题 <ul> <li>OutputConfiguration</li> <li>VendorTagDescriptor</li> <li>VendorTagDescriptorCache</li> <li>SessionConfiguration</li> </ul></li> <li>影响版本:9, 10, 11</li> <li>致谢信息:Michał Bednarski (michalbednarski)</li> </ul> <h4>CVE-2021-0650</h4> <ul> <li>sonivox组件的WT_InterpolateNoLoop中存在越界读</li> <li>影响版本:9, 10, 11</li> <li>致谢信息:无</li> </ul> <h3>System</h3> <h4>CVE-2021-0918</h4> <ul> <li>GATT远程代码执行漏洞</li> <li>影响版本:12</li> <li>致谢信息:Xianfeng Lu(卢先锋) and Lei Ai(艾磊) of OPPO Amber Security Lab</li> </ul> <h4>CVE-2021-0930</h4> <ul> <li>NFC的pn8x实现中,phNxpNciHal_process_ext_rsp函数存在越界写入 <pre><code class="language-diff"></code></pre></li> <li>if (*p_len <= (p_ntf[2] + 2)) {</li> <li>android_errorWriteLog(0x534e4554, "181660091");</li> <li>NXPLOG_NCIHAL_E("length error!");</li> <li>return NFCSTATUS_FAILED;</li> <li>} <pre><code></code></pre></li> <li>影响版本:9, 10, 11, 12</li> <li>致谢信息:Chaoyuan Peng (@ret2happy)</li> </ul> <h4>CVE-2021-0434</h4> <ul> <li>更改了蓝牙权限授予中不清晰的警告文本,防止钓鱼欺骗</li> <li>影响版本:9, 10, 11</li> <li>致谢信息:Christophe Devine, ANSSI</li> </ul> <h4>CVE-2021-0649</h4> <ul> <li>VpnManagerService中的stopVpnProfile() & startVpnProfile函数,没有对调用者进行校验,导致可以关闭其他应用开启的VPN。 <pre><code class="language-diff"> @Override public void startVpnProfile(@NonNull String packageName) {</code></pre></li> <li>final int user = UserHandle.getUserId(mDeps.getCallingUid());</li> <li>final int callingUid = Binder.getCallingUid();</li> <li>verifyCallingUidAndPackage(packageName, callingUid);</li> <li>final int user = UserHandle.getUserId(callingUid); synchronized (mVpns) { throwIfLockdownEnabled(); mVpns.get(user).startVpnProfile(packageName); //... @Override public void stopVpnProfile(@NonNull String packageName) {</li> <li>final int user = UserHandle.getUserId(mDeps.getCallingUid());</li> <li>final int callingUid = Binder.getCallingUid();</li> <li>verifyCallingUidAndPackage(packageName, callingUid);</li> <li>final int user = UserHandle.getUserId(callingUid); synchronized (mVpns) { mVpns.get(user).stopVpnProfile(packageName); } //... <pre><code></code></pre></li> <li>影响版本:11</li> <li>致谢信息:Aman Pandey of bugsmirror</li> </ul> <h4>CVE-2021-0932</h4> <ul> <li>SystemUI中的NavigationModeController存在不安全的PendingIntent <pre><code class="language-diff"> .setStyle(new Notification.BigTextStyle()) .setSmallIcon(R.drawable.ic_info) .setAutoCancel(true)</code></pre></li> <li>.setContentIntent(PendingIntent.getActivity(context, 0, new Intent(), 0));</li> <li>.setContentIntent(PendingIntent.getActivity(context, 0, new Intent(),</li> <li>PendingIntent.FLAG_IMMUTABLE)); context.getSystemService(NotificationManager.class).notify(TAG, 0, builder.build()); } <pre><code></code></pre></li> <li>影响版本:10</li> <li>致谢信息:Yu-Cheng Lin (林禹成) (@AndroBugs)</li> </ul> <h4>CVE-2021-0925</h4> <ul> <li>NFC t4t中cc_file_rsp_len初始化时被赋值为0,实际应该是T4T_CC_FILE_MIN_LEN,应该是会导致越界读。</li> <li>影响版本:12</li> <li>致谢信息:Android Security Red Team</li> </ul> <h4>CVE-2021-0931</h4> <ul> <li>BluetoothDevice中获取远端设备别名时过滤换行符,防止文本折断。</li> <li>影响版本:9, 10, 11, 12</li> <li>致谢信息:无</li> </ul> <h4>CVE-2021-0919</h4> <ul> <li>libbinder中uptimeMillis的精度丢失,应为int64_t,该问题会导致设备正常时间约为1个月,不是很清楚会导致什么。</li> <li>影响版本:9, 10, 11</li> <li>致谢信息:无</li> </ul> <h2>2021-11-05 security patch level vulnerability details</h2> <h3>Android TV</h3> <h4>CVE-2021-0889</h4> <ul> <li>该漏洞允许远程攻击者静默配对一个电视并且实现远程代码执行,漏洞代码补丁还没有发布。</li> </ul> <h4>CVE-2021-0927</h4> <ul> <li>TvInputManagerService中的requestChannelBrowsable函数,在<code>Binder.clearCallingIdentity()</code>之后调用了<code>Binder.getCallingUid()</code>,导致权限绕过</li> </ul> <h2>2021-10-01 security patch level vulnerability details</h2> <h3>Android runtime</h3> <h4>CVE-2021-0703</h4> <h3>Framework</h3> <h4>CVE-2021-0652</h4> <ul> <li>VectorDrawable中的条件竞争问题</li> </ul> <h4>CVE-2021-0705</h4> <ul> <li>利用通知实现后台限制绕过,细节待分析</li> </ul> <h4>CVE-2021-0708</h4> <ul> <li>同上个月公告的CVE-2021-0683,不知道为何又放了一遍</li> </ul> <h4>CVE-2020-15358</h4> <ul> <li>sqlite的两个漏洞CVE-2020-15358和CVE-2020-13871</li> </ul> <h4>CVE-2021-0702</h4> <h4>CVE-2021-0651</h4> <h3>Media Framework</h3> <h4>CVE-2021-0483</h4> <h3>System</h3> <h4>CVE-2021-0643</h4> <ul> <li>SubscriptionManager.getAllActiveSubscriptionInfoList接口会泄露ICCID</li> </ul> <h4>CVE-2021-0706</h4> <ul> <li>SystemUI中的DISABLE_PLUGIN动态广播接收器添加权限 <pre><code class="language-diff"> filter.addAction(Intent.ACTION_PACKAGE_CHANGED); filter.addAction(Intent.ACTION_PACKAGE_REPLACED); filter.addAction(Intent.ACTION_PACKAGE_REMOVED);</code></pre></li> <li>filter.addDataScheme("package");</li> <li>mContext.registerReceiver(this, filter); filter.addAction(PLUGIN_CHANGED); filter.addAction(DISABLE_PLUGIN); filter.addDataScheme("package");</li> <li>mContext.registerReceiver(this, filter, PluginInstanceManager.PLUGIN_PERMISSION, null); mContext.registerReceiver(this, filter); filter = new IntentFilter(Intent.ACTION_USER_UNLOCKED); mContext.registerReceiver(this, filter); <pre><code></code></pre></li> </ul> <h2>2021-10-05 security patch level vulnerability details</h2> <h3>System</h3> <h4>CVE-2021-0870</h4> <h2>2021-09-01 security patch level vulnerability details</h2> <h3>Framework</h3> <h4>CVE-2021-0687</h4> <ul> <li>Layout导致的远程拒绝服务漏洞,具体细节仍在调查中(与发现者交流)</li> </ul> <h4>CVE-2021-0595</h4> <h4>CVE-2021-0683</h4> <ul> <li>am命令的dumpheap功能存在任意文件删除漏洞,会以system_server的身份删除攻击者指定文件名的文件 <pre><code class="language-java">int runTraceIpcStop(PrintWriter pw) throws RemoteException { final PrintWriter err = getErrPrintWriter(); String opt; String filename = null; while ((opt=getNextOption()) != null) { if (opt.equals("--dump-file")) { filename = getNextArgRequired(); } else { err.println("Error: Unknown option: " + opt); return -1; } } if (filename == null) { err.println("Error: Specify filename to dump logs to."); return -1; } File file = new File(filename); file.delete(); //... }</code></pre></li> </ul> <h4>CVE-2021-0684</h4> <h4>CVE-2021-0685</h4> <ul> <li>移除了ParsedIntentInfo的Parcelable Creator,避免在Parcel传递数组时的size不匹配导致的错误。</li> </ul> <h4>CVE-2021-0688</h4> <ul> <li>锁定屏幕的lockNow和updateLockscreenTimeout存在条件竞争,可能导致在lockNow执行后未立即锁屏,而是锁屏超时时间被updateLockscreenTimeout的结果覆盖。</li> </ul> <h4>CVE-2021-0686</h4> <ul> <li>getDefaultSmsPackage接口添加跨用户检查。</li> </ul> <h3>Media Framework</h3> <h4>CVE-2021-0689</h4> <h4>CVE-2021-0690</h4> <h3>System</h3> <h4>CVE-2021-0598</h4> <ul> <li>NFC的确认连接界面ConfirmConnectActivity增加SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS标志</li> </ul> <h4>CVE-2021-0692</h4> <ul> <li>对FirstScreenBroadcast的PendingIntent设置FLAG_IMMUTABLE标志</li> </ul> <h4>CVE-2021-0428</h4> <ul> <li>SubscriptionController和SubscriptionInfo中多个接口存在标识符泄露漏洞,包括以下接口: <ul> <li>SubscriptionInfo.getCardString</li> <li>SubscriptionInfo.getIccId</li> <li>SubscriptionController.getSubscriptionInfoListFromCacheHelper</li> </ul></li> </ul> <h4>CVE-2021-0644</h4> <ul> <li>SubscriptionInfo的mGroupUUID字段可被仅有READ_PHONE_STATE权限的应用用于不可重置的标识符,要求具有READ_DEVICE_IDENTIFIERS的权限才能访问此字段。</li> </ul> <h4>CVE-2021-0682</h4> <h4>CVE-2021-0693</h4> <ul> <li>Shell应用(com.android.shell)的HeapDumpProvider对外暴露,会导致在开发者选项中点击“收集堆转储信息”后,被第三方应用直接读取到dump文件。 <pre><code class="language-diff"> <provider android:name=".HeapDumpProvider" android:authorities="com.android.shell.heapdump" android:grantUriPermissions="true"</code></pre></li> <li>android:exported="true" /></li> <li>android:exported="false" /> <pre><code></code></pre></li> </ul> <h4>CVE-2021-0691</h4> <ul> <li>在Android 11的SEPolicy中错误地允许了system_app标签写入apk_data_file标签文件,这将导致本地文件写入转化为代码执行,通过写入<code>/data/app</code>中某应用的<code>base.apk</code>或者<code>lib64</code>下的动态库文件可实现。 <pre><code class="language-diff"> # Settings need to access app name and icon from asec allow system_app asec_apk_file:file r_file_perms;</code></pre></li> </ul> <h2>-# Allow system_app (adb data loader) to write data to /data/incremental -allow system_app apk_data_file:file write;</h2> <h2>-# Allow system app (adb data loader) to read logs -allow system_app incremental_control_file:file r_file_perms;</h2> <h1>Allow system apps (like Settings) to interact with statsd</h1> <p>binder_call(system_app, statsd)</p> <pre><code> ## 2021-08-01 security patch level vulnerability details ### Framework #### CVE-2021-0640 - statsd中noteAtomLogged函数,atomId参数可以传入负值,导致整数溢出以及越界写 ```diff void StatsdStats::noteAtomLogged(int atomId, int32_t timeSec) { lock_guard<std::mutex> lock(mLock); - if (atomId <= kMaxPushedAtomId) { + if (atomId >= 0 && atomId <= kMaxPushedAtomId) { mPushedAtomStats[atomId]++; } else { + if (atomId < 0) { + android_errorWriteLog(0x534e4554, "187957589"); + } if (mNonPlatformPushedAtomStats.size() < kMaxNonPlatformPushedAtoms) { mNonPlatformPushedAtomStats[atomId]++; }
CVE-2021-0645
- 对于ExternalStorageProvider,不允许访问/sdcard/Android中的文件。
CVE-2021-0646
- sqlite中使用精度大于2147483647的浮点数会导致缓冲区溢出,通过编译时限制浮点数最大精度为100000000来解决。测试代码:
select (printf('%.2147483647G',0.01));
Media Framework
CVE-2021-0519
System
CVE-2021-0591
- 在系统设置中,BluetoothPermissionActivity是一个导出组件,接受用户传入的Intent并发送广播,而Intent中可以指定广播的接收者,从而实现以system uid发送广播给任意未导出的或带有权限的广播接收器,但攻击者无法决定其他参数。
// packages/apps/Settings/src/com/android/settings/bluetooth/BluetoothPermissionActivity.java mReturnPackage = i.getStringExtra(BluetoothDevice.EXTRA_PACKAGE_NAME); mReturnClass = i.getStringExtra(BluetoothDevice.EXTRA_CLASS_NAME); //... if (mReturnPackage != null && mReturnClass != null) { intent.setClassName(mReturnPackage, mReturnClass); } //... sendBroadcast(intent, android.Manifest.permission.BLUETOOTH_ADMIN);
- 利用此漏洞可实现越权恢复出厂设置,只需要将组件指定为:
android/com.android.server.MasterClearReceiver
CVE-2021-0593
- 在系统设置中,DevicePickerFragment是导出组件DevicePickerActivity的一部分,接受了用户传入给DevicePickerActivity的Intent,并发送广播,同样地Intent中可以指定广播的接收者,从而实现system uid发送广播给任意未导出的或带有权限的广播接收器,但攻击者无法决定其他参数。
// packages/apps/Settings/src/com/android/settings/bluetooth/DevicePickerFragment.java mLaunchPackage = intent.getStringExtra(BluetoothDevicePicker.EXTRA_LAUNCH_PACKAGE); mLaunchClass = intent.getStringExtra(BluetoothDevicePicker.EXTRA_LAUNCH_CLASS); //... if (mLaunchPackage != null && mLaunchClass != null) { intent.setClassName(mLaunchPackage, mLaunchClass); } getActivity().sendBroadcast(intent, Manifest.permission.BLUETOOTH_ADMIN);
- 利用此漏洞可实现越权恢复出厂设置,只需要将组件指定为:
android/com.android.server.MasterClearReceiver
CVE-2021-0584
- Parcel内存布局的一个问题,比较复杂需要些时间去研究,原始内容:
verify embedded buffer matches address in parent
Below is a diagram showing what scatter gather would look like where we
have one reference to a buffer, and then we have a single embedded
buffer. For instance, 'a1' might be the hidl_vec object and 'a2' might
be the data pointer in this object. In practice, there might be
arbitrarily many levels (this happens when structures contain vectors
which contain structures etc…).legend:
"…." – random data we don't care about
"|" – some position in the data
"<a#>" – some constant addressoffsets into Parcel's mData:
…..….<a1>…. ….. ….<a2>…. …..
^ ^ ^ ^– 'buffer' field of structure (binder object structure) – mObjects[child] – binder object structure 'buffer' field \- mObjects[parent] (binder object structure) kernel-owned ro buffer @ address a1 ('parent' buffer) .......<a3>.................... ^ \- parent buffer as address + parent offset (in the example, this would be the data field of hidl_vec. This should be a2). kernel-owned ro buffer @ address a2 ('child' buffer) ............................ (any random data)
What was happening here was that by maliciously constructing
mObjects[child] to be null, there would be no child object, so the
kernel wouldn't know to fixup the embedded buffer (<a3>) and it
would be unchanged.#### CVE-2021-0641 - getAvailableSubscriptionInfoList接口仍旧使用
READ_PHONE_STATE
权限保护,存在问题,应改为由READ_PRIVILEGED_PHONE_STATE
特许权限保护。 #### CVE-2021-0642 - 为CONFIGURE_VOICEMAIL这个intent-filter提高优先级,设为1000。 ## 2021-08-05 security patch level vulnerability ## 2021-07-01 security patch level vulnerability details ### Framework #### CVE-2021-0441 - 允许MediaProvier权限弹框显示超过两行的文本。 #### CVE-2021-0486 - 当应用降级到API 28以下或者在API 29中申请完全存储权限时(回退场景),撤销已授予的存储权限。 - 因为在Scoped Storage的模式下,已授予的存储权限只限于媒体目录的访问,这时在回退场景之后如果存储权限保留,会导致应用直接可以访问全部外部存储,修改后需要用户重新进行授权。 - Scoped Storage:[https://source.android.google.cn/devices/storage/scoped](https://source.android.google.cn/devices/storage/scoped) ### Media Framework #### CVE-2021-0587 #### CVE-2021-0601 ### System #### CVE-2020-0417 - GpsNetIniticatedHandler的Notification中写入了不必要的PendingIntent,且PendingIntent没有指定包名,会导致经典PendingIntent劫持攻击。 #### CVE-2021-0585 - 检查libfmq中,对MessageQueue进行读写操作时,长度是否对齐 ```diff auto writePtr = mWritePtr->load(std::memory_order_relaxed); + if (writePtr % sizeof(T) != 0) { + hardware::details::logError( + "The write pointer has become misaligned. Writing to the queue is no longer " + "possible."); + return false; + } size_t writeOffset = writePtr % mDesc->getSize();</code></pre> <pre><code class="language-diff"> auto readPtr = mReadPtr->load(std::memory_order_relaxed); + if (writePtr % sizeof(T) != 0 || readPtr % sizeof(T) != 0) { + hardware::details::logError( + "The write or read pointer has become misaligned. Reading from the queue is no " + "longer possible."); + return false; + } if (writePtr - readPtr > mDesc->getSize()) { mReadPtr->store(writePtr, std::memory_order_release);</code></pre> <h4>CVE-2021-0586</h4> <ul> <li>为蓝牙设备选择界面DevicePickerActivity添加SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS,防止悬浮窗覆盖。</li> </ul> <h4>CVE-2021-0589</h4> <ul> <li>蓝牙btm_acl中的数组越界写入,这个问题是从本地触发的。 <pre><code class="language-diff"> bool BTM_TryAllocateSCN(uint8_t scn) { /* Make sure we don't exceed max port range. * Stack reserves scn 1 for HFP, HSP we still do the correct way. */</code></pre></li> <li>if ((scn >= BTM_MAX_SCN) || (scn == 1)) return false;</li> <li>if ((scn >= BTM_MAX_SCN) || (scn == 1) || (scn == 0)) return false; /<em> check if this port is available </em>/ if (!btm_cb.btm_scn[scn - 1]) { btm_cb.btm_scn[scn - 1] = true; return true; } return (false); /<em> Port was busy </em>/ } <pre><code> ```diff bool BTM_FreeSCN(uint8_t scn) { BTM_TRACE_DEBUG("BTM_FreeSCN "); - if (scn <= BTM_MAX_SCN) {
- if (scn <= BTM_MAX_SCN && scn > 0) {
btm_cb.btm_scn[scn – 1] = false;
return (true);
} else {
return (false); / Illegal SCN passed in /
}
}#### CVE-2021-0594
- NFC确认连接的界面,处理NDFF消息中的蓝牙设备名称字段存在CRLF注入,导致对话框文本换行,使用户无法准确看到蓝牙设备名称。
- String btExtraName = launchIntent.getStringExtra(BluetoothDevice.EXTRA_NAME);
String confirmString = String.format(res.getString(R.string.confirm_pairing), - launchIntent.getStringExtra(BluetoothDevice.EXTRA_NAME));
- "\"" + btExtraName.replaceAll("\r|\n", "") + "\"");
CVE-2021-0600
- 设备管理员请求界面存在HTML注入,导致界面显示异常。
- mAddMsgText = getIntent().getCharSequenceExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION);
- final CharSequence addMsgCharSequence = getIntent().getCharSequenceExtra(
- DevicePolicyManager.EXTRA_ADD_EXPLANATION);
- if (addMsgCharSequence != null) {
- mAddMsgText = addMsgCharSequence.toString();
- }
CVE-2021-0602
- 在访客模式下,不允许编辑Wi-Fi详细设置,而是显示一个阻止的页面。
CVE-2021-0588
- 发送蓝牙MAP客户端消息广播时,要求接收者必须有
RECEIVE_SMS
权限,并且如果有默认的短信应用,则仅发给默认短信应用。 - mService.sendBroadcast(intent);
- // Only send to the current default SMS app if one exists
- String defaultMessagingPackage = Telephony.Sms.getDefaultSmsPackage(mService);
- if (defaultMessagingPackage != null) {
- intent.setPackage(defaultMessagingPackage);
- }
- mService.sendBroadcast(intent, android.Manifest.permission.RECEIVE_SMS);
CVE-2021-0590
- 移除了
android.net.conn.NETWORK_CONDITIONS_MEASURED
广播,防止预置应用可获取到SSID和BSSID。
CVE-2021-0596
- phNciNfc_RecvMfResp中的越界读取
- if (2 > RspBuffInfo->wLen) {
- android_errorWriteLog(0x534e4554, "181346550");
- return NFCSTATUS_FAILED;
- }
uint8_t rspAck = RspBuffInfo->pBuff[RspBuffInfo->wLen – 2];```diff
- CONTENT_URI,
- CONTENT_URI_LIMIT_1,
new String[] {NUMBER},
TYPE + " = " + OUTGOING_TYPE,
null, - DEFAULT_SORT_ORDER + " LIMIT 1");
- DEFAULT_SORT_ORDER);
```diff
- return;
}
}
}
<li>if ((PHNCINFC_EXTNID_SIZE + PHNCINFC_EXTNSTATUS_SIZE) ></li>
<li>RspBuffInfo->wLen) {</li>
<li>android_errorWriteLog(0x534e4554, "181346550");</li>
<li>return NFCSTATUS_FAILED;</li>
<li>}
/<em> DataLen = TotalRecvdLen – (sizeof(RspId) + sizeof(Status)) </em>/
wPldDataSize = ((RspBuffInfo->wLen) –
(PHNCINFC_EXTNID_SIZE + PHNCINFC_EXTNSTATUS_SIZE));
<pre><code></code></pre></li>
</ul>
<h4>CVE-2021-0597</h4>
<ul>
<li>对VoIP模块中的SIP广播添加<code>USE_SIP</code>权限
<pre><code class="language-diff"></code></pre></li>
<li>mContext.sendBroadcast(intent);</li>
<li>mContext.sendBroadcast(intent, android.Manifest.permission.USE_SIP);
<pre><code></code></pre></li>
</ul>
<h4>CVE-2021-0599</h4>
<ul>
<li>对于通知超时广播的PendingIntent添加接收者,防止经典PendingIntent攻击。
<pre><code class="language-diff">
final PendingIntent pi = PendingIntent.getBroadcast(getContext(),
REQUEST_CODE_TIMEOUT,
new Intent(ACTION_NOTIFICATION_TIMEOUT)</code></pre></li>
<li>.setPackage(PackageManagerService.PLATFORM_PACKAGE_NAME)
.setData(new Uri.Builder().scheme(SCHEME_TIMEOUT)
.appendPath(record.getKey()).build())
.addFlags(Intent.FLAG_RECEIVER_FOREGROUND)
<pre><code></code></pre></li>
</ul>
<h4>CVE-2021-0604</h4>
<ul>
<li>不允许蓝牙分享文件功能从<code>MmsFileProvider</code>分享文件
<pre><code class="language-diff">
// This will allow more 3rd party applications to share files via
// bluetooth
if ("content".equals(scheme)) {</code></pre></li>
<li>if (fromExternal && BluetoothOppUtility.isForbiddenContent(uri)) {</li>
<li>EventLog.writeEvent(0x534e4554, "179910660", -1, uri.toString());</li>
<li>Log.e(TAG, "Content from forbidden URI is not allowed.");</li>
<li>return SEND_FILE_INFO_ERROR;</li>
<li>}</li>
<li>
<pre><code> contentType = contentResolver.getType(uri);</code></pre>
<pre><code></code></pre>
</li>
</ul>
<pre><code class="language-diff">+ static boolean isForbiddenContent(Uri uri) {
+ if ("com.android.bluetooth.map.MmsFileProvider".equals(uri.getHost())) {
+ return true;
+ }
+ return false;
+ }
+</code></pre>
<h2>2021-07-05 security patch level vulnerability</h2>
<h3>Framework</h3>
<h4>CVE-2020-0368</h4>
<ul>
<li>通话记录数据库中的SQL注入,由于该数据库中语音信箱的内容受<code>READ_VOICEMAIL</code>权限保护,如果攻击者仅有<code>READ_CALL_LOG</code>权限,但没有<code>READ_VOICEMAIL</code>权限,那么不允许通过SQL注入等方式读取语音信箱的信息。
<pre><code class="language-diff">
/**</code></pre></li>
<li>
<ul>
<li>Form of {@link #CONTENT_URI} which limits the query results to a single result.</li>
</ul>
</li>
<li>*/</li>
<li>private static final Uri CONTENT_URI_LIMIT_1 = CONTENT_URI.buildUpon()</li>
<li>.appendQueryParameter(LIMIT_PARAM_KEY, "1")</li>
<li>.build();</li>
<li>
</li>
<li>/**
<pre><code>
“`diff
c = resolver.query(
<li>final SQLiteQueryBuilder qb = new SQLiteQueryBuilder();</li>
<li>qb.setTables(Tables.CALLS);</li>
<li>qb.setProjectionMap(sCallsProjectionMap);</li>
<li>qb.setStrict(true);</li>
<li>// If the caller doesn't have READ_VOICEMAIL, make sure they can't</li>
<li>// do any SQL shenanigans to get access to the voicemails. If the caller does have the</li>
<li>// READ_VOICEMAIL permission, then they have sufficient permissions to access any data in</li>
<li>// the database, so the strict check is unnecessary.</li>
<li>if (!mVoicemailPermissions.callerHasReadAccess(getCallingPackage())) {</li>
<li>qb.setStrictGrammar(true);</li>
<li>}
<pre><code></code></pre></li>
</ul>
<h3>System</h3>
<h4>CVE-2021-0514</h4>
<h4>CVE-2021-0515</h4>
<ul>
<li>将V8升级到8.8.278.14版本</li>
</ul>
<h4>CVE-2021-0603</h4>
<ul>
<li>为联系人选择界面ContactSelectionActivity添加
SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS,防止悬浮窗覆盖。</li>
</ul>
<h2>2021-06-01 security patch level vulnerability details</h2>
<h3>Android runtime</h3>
<h4>CVE-2021-0511</h4>
<h3>Framework</h3>
<h4>CVE-2021-0521</h4>
<ul>
<li>PackageManagerService中的getAllPackages()接口没有权限保护,可以不受用户、InstantApp和包可见性限制来读取所有已安装应用的包名。该问题由</li>
<li>Android 11中的软件包可见性:<a href="https://developer.android.google.cn/about/versions/11/privacy/package-visibility">https://developer.android.google.cn/about/versions/11/privacy/package-visibility</a></li>
<li>Instant App的软件包可见性限制:<a href="https://source.android.google.cn/compatibility/cts/cts-instant#restrictions">https://source.android.google.cn/compatibility/cts/cts-instant#restrictions</a></li>
</ul>
<h3>Media Framework</h3>
<h4>CVE-2021-0508</h4>
<h4>CVE-2021-0509</h4>
<h4>CVE-2021-0510</h4>
<h4>CVE-2021-0520</h4>
<ul>
<li>四个都是DRM组件中的内存漏洞</li>
</ul>
<h3>System</h3>
<h4>CVE-2021-0507</h4>
<ul>
<li>蓝牙avrc_ctrl_pars_vendor_cmd中的越界写入,可导致远程代码执行。</li>
</ul>
<h4>CVE-2021-0516</h4>
<h4>CVE-2021-0505</h4>
<ul>
<li>防止从管理员配置的VPN中断开,逻辑漏洞</li>
<li>Android 7.0中的始终开启VPN:<a href="https://developer.android.google.cn/guide/topics/connectivity/vpn#always-on">https://developer.android.google.cn/guide/topics/connectivity/vpn#always-on</a></li>
</ul>
<h4>CVE-2021-0506</h4>
<ul>
<li>为ActivityPicker界面(隐式Intent启动Activity时候的选择窗口)添加SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS,防止悬浮窗覆盖。</li>
</ul>
<h4>CVE-2021-0523</h4>
<ul>
<li>为WifiScanModeActivity界面添加SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS,防止悬浮窗覆盖。</li>
</ul>
<h4>CVE-2021-0504</h4>
<ul>
<li>蓝牙avrc_pars_browse_rsp中的越界读取,可导致信息泄露。</li>
</ul>
<h4>CVE-2021-0517</h4>
<ul>
<li>
</li>
</ul>
<h4>CVE-2021-0522</h4>
<ul>
<li>蓝牙AVRCP中使用SdpCb时,错误地将RawAddress的引用而不是值本身当作参数,导致地址泄露。</li>
</ul>
<h2>2021-06-05 security patch level vulnerability details</h2>
<h2>2021-05-01 security patch level vulnerability details</h2>
<h3>Framework</h3>
<h4>CVE-2021-0472</h4>
<ul>
<li>LockTaskController的shouldLockKeyguard方法中,调用了LockPatternUtils的isSecure方法,该方法接受的userId参数必须是实际的userId,不能接受UserHandle.USER_CURRENT,定义如下:
<pre><code class="language-java">// frameworks/base/core/java/android/os/UserHandle.java
/** @hide A user id to indicate the currently active user **/
@UnsupportAppUsage
public static final @UserIdInt int USER_CURRENT = -2;
//…</code></pre></li>
<li>从UserHandle的源码可以看出,USER_CURRENT的值实际上是-2,这个值只有在创建UserHandle的时候才有效,直接使用-2作为userId显然是不正确的。该漏洞由Google的Edward Cunningham发现。</li>
</ul>
<h4>CVE-2021-0485</h4>
<ul>
<li>SystemUI组件会限制画中画窗口最小大小为48dp(防止1dp画中画保活?)。关于Android画中画功能请参阅<a href="https://source.android.google.cn/devices/tech/display/pip">https://source.android.google.cn/devices/tech/display/pip</a>
<pre><code class="language-xml"><!–
The overridable minimal size of a PiP task, in both dimensions.
Different from default_minimal_size_pip_resizable_task, this is to limit the dimension
when the pinned stack size is overridden by app via minWidth/minHeight.
–>
<dimen name="overridable_minimal_size_pip_resizable_task">48dp</dimen></code></pre></li>
<li>该漏洞由Cognizant的Dimitrios Valsamaras发现。</li>
</ul>
<h4>CVE-2021-0487</h4>
<ul>
<li>为CalendarDebugActivity界面 (话说这个界面是干嘛的?) 配置HIDE_NON_SYSTEM_OVERLAY_WINDOWS权限,防止悬浮窗覆盖。该漏洞由hard_<strong>__</strong>发现。</li>
</ul>
<h3>Media Framework</h3>
<h4>CVE-2021-0482</h4>
<h4>CVE-2021-0484</h4>
<h3>System</h3>
<h4>CVE-2021-0473</h4>
<ul>
<li>NFC在处理T3T Tag的时候存在内存泄漏、越界写入和Double Free。该漏洞由Google Project Zero的Ned Williamson发现。</li>
</ul>
<h4>CVE-2021-0474</h4>
<ul>
<li>蓝牙在处理超长AVCT commands时出现溢出
<pre><code class="language-diff">
if (cr == AVCT_CMD && (p_pkt->layer_specific & AVCT_DATA_CTRL &&</code></pre></li>
<li>AVRC_PACKET_LEN < sizeof(p_pkt->len))) {</li>
<li>/<em> Ignore the invalid AV/C command frame </em>/</li>
<li>p_drop_msg = "dropped – too long AV/C cmd frame size";</li>
<li>p_pkt->len > AVRC_PACKET_LEN)) {</li>
<li>android_errorWriteLog(0x534e4554, "177611958");</li>
<li>AVRC_TRACE_WARNING("%s: Command length %d too long: must be at most %d",</li>
<li><strong>func</strong>, p_pkt->len, AVRC_PACKET_LEN);
osi_free(p_pkt);
return;
}
<pre><code></code></pre></li>
</ul>
<h4>CVE-2021-0475</h4>
<ul>
<li>蓝牙在L2CAP连接Socket关闭后返回,感觉是一个UAF问题,该漏洞由L.O. Team的Wenwen Wang and Fei发现。
<pre><code class="language-diff">
<< ": unable to push data to socket – closing fixed channel";
BTA_JvL2capCloseLE(sock->handle);
btsock_l2cap_free_l(sock);</code></pre></li>
<li>return;
}
<pre><code>
“`diff
<< ": unable to push data to socket – closing channel";
BTA_JvL2capClose(sock->handle);
btsock_l2cap_free_l(sock);
CVE-2021-0476
- btif_av.cc中对std::map未进行加锁,该问题由GWP-ASan发现。
CVE-2021-0477
- 在SystemUI的ScreenshotNotificationsController中,对截屏错误的PendingInten添加FLAG_IMMUTABLE标志。
CVE-2021-0481
- 在设置多用户的用户头像时,避免使用非法的URI作为图片来源。
# packages/apps/Settings/src/com/android/settings/users/EditUserPhotoController.java } final Uri pictureUri = data != null && data.getData() != null ? data.getData() : mTakePictureUri;
- // Check if the result is a content uri
- if (!ContentResolver.SCHEME_CONTENT.equals(pictureUri.getScheme())) {
- Log.e(TAG, "Invalid pictureUri scheme: " + pictureUri.getScheme());
- EventLog.writeEvent(0x534e4554, "172939189", -1, pictureUri.getPath());
- return false;
- }
-
CVE-2021-0466
- 仅在使用随机WLAN MAC地址时才使用EUI64 IPv6 link-local address generation (不太懂)。该漏洞由Google的Bram Bonné发现。
CVE-2021-0480
- SnoozeHelper中的PendingIntent添加目标包名,使其成为显式Intent。该漏洞由Yu-Cheng Lin (林禹成) (@AndroBugs)发现。
# frameworks/base/services/core/java/com/android/server/notification/SnoozeHelper.java return PendingIntent.getBroadcast(mContext, REQUEST_CODE_REPOST, new Intent(REPOST_ACTION)
- .setPackage(PackageManagerService.PLATFORM_PACKAGE_NAME)
.setData(new Uri.Builder().scheme(REPOST_SCHEME).appendPath(key).build())
.addFlags(Intent.FLAG_RECEIVER_FOREGROUND)
.putExtra(EXTRA_KEY, key)
2021-05-05 security patch level vulnerability details
2021-04-01 security patch level vulnerability details
Framework
CVE-2021-0400
- 在使用紧急呼叫服务时,不信任模拟位置的返回。在Android里面允许用户在开发者选项中“选择模拟位置信息应用”,授予一个第三方应用模拟位置的权限,这样系统就会从这个来源获取位置坐标信息。该问题由Google的Soonil Nagarkar发现。
CVE-2021-0426
- statsd遥测进程中的LogEvent模块,在parsePrimaryFieldFirstUidAnnotation函数中存在一个堆缓冲区溢出导致的越界写。该问题由360 Alpha Lab的Xiaobo Xiang和Guang Gong发现。
- Android 9包含statsd遥测功能,statsd可收集应用使用情况、电池和进程统计信息以及崩溃数据。这些数据会经过分析并用于改进产品、硬件和服务。
- 关于statsd的更多信息详见:https://source.android.google.cn/devices/architecture/modular-system/statsd
CVE-2021-0427
- statsd遥测进程中的LogEvent模块,在parseExclusiveStateAnnotation函数中存在一个堆缓冲区溢出导致的越界写。该问题由360 Alpha Lab的Xiaobo Xiang和Guang Gong发现。
- 0426和0427这两个漏洞新增了一些测试用例,可以有助于理解这两个问题,位于:
// frameworks/base/cmds/statsd/tests/LogEvent_test.cpp TEST(LogEventTest, TestExclusiveStateAnnotationAfterTooManyFields) TEST(LogEventTest, TestUidAnnotationAfterTooManyFields) TEST(LogEventTest, TestAttributionChainEndIndexAfterTooManyFields) TEST(LogEventTest, TestEmptyAttributionChainWithPrimaryFieldFirstUidAnnotation)
CVE-2021-0432
- statsd遥测进程中的StatsPullerManager模块,在ForceClearCache和ClearCacheIfNecessary函数中操作了共享资源kAllPullAtomInfo但未使用锁,可能在Puller注册或取消注册过程中存在条件竞争问题。该问题由GWP-ASan发现。
CVE-2021-0438
- WindowManagerService中有一个hidden的flag名为NO_INPUT_CHANNEL,允许应用程序创建一个没有输入通道的窗口。在Android R以前,这会导致窗口被错误地配置一个FLAG_OBSCURED标志,导致窗口覆盖攻击,具体效果待实测。该问题由Google的Rob Carr发现。
CVE-2021-0439
-
PowerManagerService中的setPowerBoostWithHandle函数和setPowerModeWithHandle函数,由于缺失边界检查导致越界写问题。
static void setPowerBoostWithHandle(sp<IPowerAidl> handle, Boost boost, int32_t durationMs) { // Android framework only sends boost upto DISPLAY_UPDATE_IMMINENT. // Need to increase the array size if more boost supported. static std::array<std::atomic<HalSupport>, static_cast<int32_t>(Boost::DISPLAY_UPDATE_IMMINENT /* 1 */) + 1> boostSupportedArray = {HalSupport::UNKNOWN}; // Quick return if boost is not supported by HAL // *** 传入一个负数可绕过大于1的校验,导致后续写boostSupportedArray数组溢出 *** if (boost > Boost::DISPLAY_UPDATE_IMMINENT /* 1 */ || boostSupportedArray[static_cast<int32_t>(boost)] == HalSupport::OFF) { ALOGV("Skipped setPowerBoost %s because HAL doesn't support it", toString(boost).c_str()); return; } if (boostSupportedArray[static_cast<int32_t>(boost)] == HalSupport::UNKNOWN) { bool isSupported = false; handle->isBoostSupported(boost, &isSupported); // *** OOB Write *** boostSupportedArray[static_cast<int32_t>(boost)] = isSupported ? HalSupport::ON : HalSupport::OFF; if (!isSupported) { ALOGV("Skipped setPowerBoost %s because HAL doesn't support it", toString(boost).c_str()); return; } } auto ret = handle->setBoost(boost, durationMs); processPowerHalReturn(ret.isOk(), "setPowerBoost"); }
- Boost的定义
enum class Boost : int32_t { INTERACTION = 0, DISPLAY_UPDATE_IMMINENT = 1, ML_ACC = 2, AUDIO_LAUNCH = 3, CAMERA_LAUNCH = 4, CAMERA_SHOT = 5, };
-
setPowerModeWithHandle的问题是一样的
static bool setPowerModeWithHandle(sp<IPowerAidl> handle, Mode mode, bool enabled) { // Android framework only sends mode upto DISPLAY_INACTIVE. // Need to increase the array if more mode supported. static std::array<std::atomic<HalSupport>, static_cast<int32_t>(Mode::DISPLAY_INACTIVE) + 1> modeSupportedArray = {HalSupport::UNKNOWN}; // Quick return if mode is not supported by HAL // *** 传入一个负数可绕过大于9的校验,导致后续写modeSupportedArray数组溢出 *** if (mode > Mode::DISPLAY_INACTIVE || modeSupportedArray[static_cast<int32_t>(mode)] == HalSupport::OFF) { ALOGV("Skipped setPowerMode %s because HAL doesn't support it", toString(mode).c_str()); return false; } if (modeSupportedArray[static_cast<int32_t>(mode)] == HalSupport::UNKNOWN) { bool isSupported = false; handle->isModeSupported(mode, &isSupported); // *** OOB Write *** modeSupportedArray[static_cast<int32_t>(mode)] = isSupported ? HalSupport::ON : HalSupport::OFF; if (!isSupported) { ALOGV("Skipped setPowerMode %s because HAL doesn't support it", toString(mode).c_str()); return false; } } auto ret = handle->setMode(mode, enabled); processPowerHalReturn(ret.isOk(), "setPowerMode"); return ret.isOk(); }
- Mode的定义
enum class Mode : int32_t { DOUBLE_TAP_TO_WAKE = 0, LOW_POWER = 1, SUSTAINED_PERFORMANCE = 2, FIXED_PERFORMANCE = 3, VR = 4, LAUNCH = 5, EXPENSIVE_RENDERING = 6, INTERACTIVE = 7, DEVICE_IDLE = 8, DISPLAY_INACTIVE = 9, AUDIO_STREAMING_LOW_LATENCY = 10, CAMERA_STREAMING_SECURE = 11, CAMERA_STREAMING_LOW = 12, CAMERA_STREAMING_MID = 13, CAMERA_STREAMING_HIGH = 14, };
CVE-2021-0442
- 在InputApplicationHandle中,仅更新Native层的InputApplicationHandle一次,以避免条件竞争问题。该问题由小米的Mingming Wang发现。
CVE-2021-0443
- 在多用户切换时终止截图进程,以避免信息泄露。该问题由Elliott Brooks发现。
CVE-2021-0444
- 在QuickContact的onActivityResult中,将不再返回Intent的data。该问题由Oversecured Inc.的Sergey Toshin发现。
Media Framework
CVE-2021-0437
- DrmPlugin中的mPlayPolicy由于条件竞争问题可被Double Free。该问题由Chong Wang发现。
CVE-2021-0436
- CryptoPlugin中存在一个整数溢出问题,会导致越界读造成信息泄露。该问题由Chong Wang发现。
CVE-2021-0471
- CryptoPlugin中存在一个整数溢出问题,会导致越界读造成信息泄露。该问题由Chong Wang发现。
System
CVE-2021-0430
- NFC在处理MIFARE Classic卡的TLV时存在一个越界写入,可造成远程代码执行。该问题由Google Project Zero的Ned Williamson发现。
CVE-2021-0429
- 在SensorService的HAL接口中存在一个UAF漏洞。该问题由GWP-ASan发现。
CVE-2021-0433
- 为CompanionDeviceManager配置HIDE_NON_SYSTEM_OVERLAY_WINDOWS权限,防止悬浮窗覆盖。
CVE-2021-0446
- 为vCard联系人导入流程配置HIDE_NON_SYSTEM_OVERLAY_WINDOWS权限,防止悬浮窗覆盖。
CVE-2021-0431
- 在蓝牙AVRC模块中,使用calloc而不是malloc进行内存分配,以保证初始化时会以0填充缓冲区,防止信息泄露。该问题由L.O. Team的Cusas发现。
CVE-2021-0435
- 在蓝牙AVRC模块中,使用calloc而不是malloc进行内存分配,以保证初始化时会以0填充缓冲区,防止信息泄露。该问题由L.O. Team的Cusas发现。
2021-04-05 security patch level vulnerability details
2021-03-01 security patch level vulnerability details
Android runtime
CVE-2021-0395
- init在重启过程中存在一个潜在的UAF漏洞,由于init在遍历需停止的服务列表时使用原始的服务对象指针,遍历到已停止的服务时可能存在UAF漏洞。
Framework
CVE-2021-0391
- 对多用户选择窗口添加
SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS
标志,防止悬浮窗劫持攻击。
CVE-2021-0398
- 在ActiveServices的
bindServiceLocked
方法中,调用shouldAllowWhileInUsePermissionInFgsLocked()
方法时传入了Binder.getCallingPid()
和Binder.getCallingUid()
的返回值作为pid和uid。然而在调用这些方法之前,先调用了Binder.clearCallingIdentity()
,这会导致获取到的pid和uid不正确。// frameworks/base/services/core/java/com/android/server/am/ActiveServices.java int bindServiceLocked(IApplicationThread caller, IBinder token, Intent service, String resolvedType, final IServiceConnection connection, int flags, String instanceName, String callingPackage, final int userId) throws TransactionTooLargeException { //...
- final int callingPid = Binder.getCallingPid();
- final int callingUid = Binder.getCallingUid();
//…
final long origId = Binder.clearCallingIdentity();
//…
if (!s.mAllowWhileInUsePermissionInFgs) {
s.mAllowWhileInUsePermissionInFgs =
shouldAllowWhileInUsePermissionInFgsLocked(callingPackage, - Binder.getCallingPid(), Binder.getCallingUid(),
- callingPid, callingUid,
service, s, false);
}
//…
}
System
CVE-2021-0397
- 只会发起SDP扫描一次,如果已经有进行中的扫描,则直接返回。
// system/bt/bta/ag/bta_ag_sdp.cc
- if (p_scb->p_disc_db != nullptr) {
- android_errorWriteLog(0x534e4554, "174052148");
- APPL_TRACE_ERROR("Discovery already in progress… returning.");
- return;
- }
-
#### CVE-2017-14491
- 在dnsmasq 2.78之前的版本中基于堆的缓冲区溢出允许远程攻击者通过精心设计的DNS响应导致拒绝服务(崩溃)或执行任意代码。这是一个历史漏洞。
- 详细分析:https://www.anquanke.com/post/id/87085
CVE-2021-0393
- V8的NewCapacity函数中存在一个堆缓冲区溢出,可能导致整型溢出。这是一个2018年的V8历史漏洞。
- 详情:https://bugs.chromium.org/p/chromium/issues/detail?id=914736
CVE-2021-0396
- V8的Builtins_MovExtraWideHandler中存在参数个数溢出,应该不能超过65534个。这是一个2018年的V8历史漏洞。
- 详情:https://bugs.chromium.org/p/chromium/issues/detail?id=902610
CVE-2021-0390
- 对WifiConfigManager中的部分Wi-Fi操作相关接口,要求必须是前台才允许调用。
CVE-2021-0392
-
wificond中存在一个UAF漏洞,该漏洞是从上游同步的。
// system/connectivity/wificond/main.cpp android::wificond::NetlinkUtils netlink_utils(&netlink_manager); android::wificond::ScanUtils scan_utils(&netlink_manager);
-
unique_ptr<android::wificond::Server> server(new android::wificond::Server(
-
android::sp<android::wificond::Server> server(new android::wificond::Server(
unique_ptr<InterfaceTool>(new InterfaceTool),
&netlink_utils,
&scan_utils)); -
RegisterServiceOrCrash(server.get());
-
RegisterServiceOrCrash(server);
WifiKeystoreHalConnector keystore_connector;
keystore_connector.start();
CVE-2021-0394
- 在ART的代码中,对
JNI::NewStringUTF()
增加校验,并且增加了SafetyNet日志记录。
2021-03-05 security patch level vulnerability details
2021-02-01 security patch level vulnerability details
Android runtime
CVE-2021-0341
- 在external/okhttp中拒绝非ASCII字符的主机名和SANs,主要涉及okhttp证书校验中主机名校验(HostnameVerifier)的部分。
Framework
CVE-2021-0302
- 为应用动态权限授予窗口添加了遮挡时过滤点击保护
android:filterTouchesWhenObscured=true
,这样一来当有悬浮窗遮挡权限授予窗口时,点击将不起作用,这样有助于防止权限授予时的点击劫持。 - 详细了解点击劫持保护:https://developer.android.google.cn/reference/android/view/View#security
CVE-2021-0305
- 为特殊应用权限(应用和通知-高级-特殊应用权限)中的权限开关添加了遮挡时过滤点击保护
android:filterTouchesWhenObscured=true
。
CVE-2021-0314
- 对确认卸载应用窗口添加
SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS
标志,防止悬浮窗劫持攻击。
CVE-2021-0327
- 在AMS的
getContentProviderImpl
方法里,最后有一段代码可能抛出异常,中断这个方法的执行。所以将其放入try-finally里面,并且确保在finally的时候可以正确的执行restoreCallingIdentity
,清除Binder调用者的CallingUid,保证后续的Binder.getCallingUid
可以取到正常的值。
CVE-2021-0330
- 在storaged进程中少了一个锁(mutex lock),这个漏洞似乎无法利用,应该是源代码审计看到的。
CVE-2021-0334
- 从ResolverActivity中去掉了updateIntentVerificationStatusAsUser接口。
- 该接口和“使用已安装的应用打开链接”功能有关,旨在授予App对其所声明的域的完全验证权限,也就是说,对于目标域的Web链接,将总是跳转到该App。但这允许App接管无主的链接,如果用户在“使用应用打开”的对话框中选择了该App并且点击了“始终”按钮,后续该链接都会跳转到该App,不会提示用户。
- Google认为该API的所有用法可能都是非预期的,应该将该API删除。
CVE-2021-0337
- 在FileSystemProvider中,当文件被删除、重命名或者移动之后,去除该文件所有的URI权限。
- 该Provider是提供给存储访问框架使用的,旨在让应用没有存储权限的情况下,也可以访问由用户指定的单个文件,用户选择文件之后,应用可以通过URI来访问该文件,该访问能力即由FileSystemProvider提供,如果用户选择的文件被删除、重命名或者移动,但URI权限没有去除,会造成应用意外访问到其他文件。
CVE-2021-0339
- 限制App跳转动画的最大时间,限制过渡动画的最长时间为3秒(原先为10秒)。
CVE-2021-0340
- MediaProvider的修复,使IsoInerface能处理64位和文件末尾的box长度,这样可避免视频文件的位置数据解析错误。
CVE-2021-0338
- 在SettingsProvider中修复固定字体大小比例检查器,限制范围为0.85-1.3之间,原先的检查只要求大于0即可,该值设置的过大或者过于逼近0会导致系统无法显示而造成拒绝服务。
Media Framework
CVE-2021-0325
- 在libavc中增加校验,图片中的first_mb_in_slice不能>=mbs
u2_first_mb_in_slice = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf); if(u2_first_mb_in_slice >= (ps_dec->u2_frm_ht_in_mbs * ps_dec->u2_frm_wd_in_mbs))) { //... }
CVE-2021-0332
- SurfaceFlinger里面把一段代码换了个位置,提交信息也没有具体解释原因。
CVE-2021-0335
- libstagefright的MediaCodec中的信息泄露问题。
System
CVE-2021-0326
- 在wpa_supplicant_8的p2p.c中,当拷贝
wps_sec_dev_type_list
时没有校验其长度,导致wps_sec_dev_type_list
超长时出现问题。if (dev->info.wps_sec_dev_type_list_len > WPS_SEC_DEV_TYPE_MAX_LEN) { android_errorWriteLog(0x534e4554, "172937525"); dev->info.wps_sec_dev_type_list_len = WPS_SEC_DEV_TYPE_MAX_LEN; } os_memcpy(dev->info.wps_sec_dev_type_list, cli->sec_dev_types, dev->info.wps_sec_dev_type_list_len)
CVE-2021-0328
- GATT服务端会在发送GATT批量扫描结果广播之前,对发起扫描的GATT客户端添加和GATT普通扫描相同的权限检查。
CVE-2021-0329
- 在GATT的AdvertiseManager中,传递不存在的GATT Advertiser ID会导致越界访问。
CVE-2021-0331
- 对通知使用权的Activity添加
SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS
标志,防止悬浮窗劫持攻击。
CVE-2021-0333
- 对蓝牙权限授予(例如蓝牙授予通讯录、通话记录等的权限)的Activity添加
SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS
标志,防止悬浮窗劫持攻击。
CVE-2021-0336
- 限定
BluetoothDevice.ACTION_CONNECTION_ACCESS_REPLY
这一Intent的接收者必须为com.android.bluetooth
,这个Intent用于传递蓝牙权限的授予状态。