【Android】app调用wallpaperManager.setBitmap的隐藏权限
这是一个杞人忧天的问题,app中,可以通过wallpaperManager.setBitmap来设置壁纸,
private void setWallpaper() {// 获取 WallpaperManager 实例WallpaperManager wallpaperManager = WallpaperManager.getInstance(getApplicationContext());try {// 加载图片资源Bitmap wallpaperBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.test);// 设置壁纸wallpaperManager.setBitmap(wallpaperBitmap);// 提示用户成功设置壁纸Toast.makeText(MainActivity.this, "壁纸设置成功!", Toast.LENGTH_SHORT).show();} catch (IOException e) {// 捕获异常并提示用户失败Toast.makeText(MainActivity.this, "壁纸设置失败!", Toast.LENGTH_SHORT).show();e.printStackTrace();}
其原理是从系统中获取到壁纸文件如/data/system/users/0/wallpaper的fd,然后往里面写数据,
WallpaperManager.java
public int setBitmap(Bitmap fullImage, Rect visibleCropHint,boolean allowBackup, @SetWallpaperFlags int which, int userId)throws IOException {validateRect(visibleCropHint);if (sGlobals.mService == null) {Log.w(TAG, "WallpaperService not running");throw new RuntimeException(new DeadSystemException());}final Bundle result = new Bundle();final WallpaperSetCompletion completion = new WallpaperSetCompletion();try {ParcelFileDescriptor fd = sGlobals.mService.setWallpaper(null,mContext.getOpPackageName(), visibleCropHint, allowBackup,result, which, completion, userId);if (fd != null) {FileOutputStream fos = null;try {fos = new ParcelFileDescriptor.AutoCloseOutputStream(fd);fullImage.compress(Bitmap.CompressFormat.PNG, 90, fos);fos.close();completion.waitForCompletion();} finally {IoUtils.closeQuietly(fos);}}} catch (RemoteException e) {throw e.rethrowFromSystemServer();}return result.getInt(EXTRA_NEW_WALLPAPER_ID, 0); }
等等,根据以往的经验,进程访问app的fd会出现selinux问题,
Binder:1633_4: type=1400 audit(0.0:1289): avc: denied { use } for path="/dev/ashmem404ff234-1fa0-446f-b673-03155ada830c" dev="tmpfs" ino=3622 scontext=u:r:test_process:s0 tcontext=u:r:untrusted_app:s0:c114,c256,c512,c768 tclass=fd permissive=1
直接在adb shell里访问/data/system/users/0 是没有权限的,难道是有地方赋权了?
app写这个fd为什么没有出现权限问题呢,应该是有赋权,但还是引起了我们的好奇,去找找看
而有
app_domain(untrusted_app)
app_domain是个宏,
170#####################################
171# app_domain(domain)
172# Allow a base set of permissions required for all apps.
173define(`app_domain', `
174typeattribute $1 appdomain;
175# Label ashmem objects with our own unique type.
176tmpfs_domain($1)
177# Map with PROT_EXEC.
178allow $1 $1_tmpfs:file execute;
179neverallow { $1 -shell } { domain -$1 }:file no_rw_file_perms;
180neverallow { appdomain -shell -$1 } $1:file no_rw_file_perms;
181')
untrusted_app 有appdomain这个属性,所以可以访问system_server:fd use
得证