Android system_server无法访问sdcard目录问题记录(Android 4.4 mtk平台)
一、原因
原因:Android具有system权限为什么不可以访问SDcard
官方文档解释
Processes that continue holding open fds on the sdcard a little after it is
requested to be unmounted will be killed so that it can unmount.
We don’t want the system process to be able to access the sdcard to avoid
these kinds of issues (and just general security cleanliness), so that it
does not have permission to access it.
中文翻译
sdcard属于易插拔的外部设备,如果说我们系统app可以访问sdcard,并且一直持有sdcard中相应文件的fds(文件句柄),如果我们sdcard这时候拔除,
这时系统app就有可能因为fds文件句柄没有被killed,但是系统app一般是不可以被killed,因为你想想如果我们的主页launcher被killed了或者其他重要系统app被killed
就有可能导致一系列安全问题,如主页crash或者手机重启等等,也就是我一拔sdcard结果手机死机了的悲剧结果
简单总结就是以前的sdcard卡是可插拔的,如果系统进程去访问sdcard目录,会持有sdcard文件句柄,如果sdcard被拔除,可能会导致系统崩溃,故官方做了这个限制。但是目前的sdcard一般是内置的,不可插拔,一般不会存在这种情况。
二、解决方法
1、方法一
参考链接:【framework】framework中为systemserver添加权限
问题解决思路:查看system_server是否属于sdcard读写相关用户组**
解决过程
- 查看sdcard目录信息
红框标注的地方为所属用户组信息,进程属于这个用户组才能访问sdcard目录
- 查看
sdcard_r
对应的用户组id
头文件位置:system/core/include/private/android_filesystem_config.h
#define AID_ROOT 0 /* traditional unix root user */#define AID_SYSTEM 1000 /* system server */#define AID_RADIO 1001 /* telephony subsystem, RIL */
#define AID_BLUETOOTH 1002 /* bluetooth subsystem */
#define AID_GRAPHICS 1003 /* graphics devices */
#define AID_INPUT 1004 /* input devices */
#define AID_AUDIO 1005 /* audio devices */
#define AID_CAMERA 1006 /* camera devices */
#define AID_LOG 1007 /* log devices */
#define AID_COMPASS 1008 /* compass device */
#define AID_MOUNT 1009 /* mountd socket */
#define AID_WIFI 1010 /* wifi subsystem */
#define AID_ADB 1011 /* android debug bridge (adbd) */
#define AID_INSTALL 1012 /* group for installing packages */
#define AID_MEDIA 1013 /* mediaserver process */
#define AID_DHCP 1014 /* dhcp client */
#define AID_SDCARD_RW 1015 /* external storage write access */
#define AID_VPN 1016 /* vpn system */
#define AID_KEYSTORE 1017 /* keystore subsystem */
#define AID_USB 1018 /* USB devices */
#define AID_DRM 1019 /* DRM server */
#define AID_MDNSR 1020 /* MulticastDNSResponder (service discovery) */
#define AID_GPS 1021 /* GPS daemon */
#define AID_UNUSED1 1022 /* deprecated, DO NOT USE */
#define AID_MEDIA_RW 1023 /* internal media storage write access */
#define AID_MTP 1024 /* MTP USB driver access */
#define AID_UNUSED2 1025 /* deprecated, DO NOT USE */
#define AID_DRMRPC 1026 /* group for drm rpc */
#define AID_NFC 1027 /* nfc subsystem */
#define AID_SDCARD_R 1028 /* external storage read access */
#define AID_CLAT 1029 /* clat part of nat464 */
#define AID_LOOP_RADIO 1030 /* loop radio devices */
#define AID_MEDIA_DRM 1031 /* MediaDrm plugins */
#define AID_PACKAGE_INFO 1032 /* access to installed package details */
#define AID_SDCARD_PICS 1033 /* external storage photos access */
#define AID_SDCARD_AV 1034 /* external storage audio/video access */
#define AID_SDCARD_ALL 1035 /* access all users external storage */#define AID_SHELL 2000 /* adb and debug shell user */
#define AID_CACHE 2001 /* cache access */
#define AID_DIAG 2002 /* access to diagnostic resources *//* The 3000 series are intended for use as supplemental group id's only.* They indicate special Android capabilities that the kernel is aware of. */
#define AID_NET_BT_ADMIN 3001 /* bluetooth: create any socket */
#define AID_NET_BT 3002 /* bluetooth: create sco, rfcomm or l2cap sockets */
#define AID_INET 3003 /* can create AF_INET and AF_INET6 sockets */
#define AID_NET_RAW 3004 /* can create raw INET sockets */
#define AID_NET_ADMIN 3005 /* can configure interfaces and routing tables. */
#define AID_NET_BW_STATS 3006 /* read bandwidth statistics */
#define AID_NET_BW_ACCT 3007 /* change bandwidth statistics accounting */
#define AID_NET_BT_STACK 3008 /* bluetooth: access config files */#define AID_MISC 9998 /* access to misc storage */
#define AID_NOBODY 9999#define AID_APP 10000 /* first app user */#define AID_ISOLATED_START 99000 /* start of uids for fully isolated sandboxed processes */
#define AID_ISOLATED_END 99999 /* end of uids for fully isolated sandboxed processes */#define AID_USER 100000 /* offset for uid ranges for each user */#define AID_SHARED_GID_START 50000 /* start of gids for apps in each user to share */
#define AID_SHARED_GID_END 59999 /* start of gids for apps in each user to share */
由以上头文件可查看到一下这行定义
#define AID_SDCARD_R 1028 /* external storage read access */
所以sdcard_r
对应的groud_id 为1028
- 查看system_server 进程信息
① 查看uid
② 查看进程详细信息
cd proc/1863
cat status
从上图可以看出system_server并不属于
sdcard_r(1028)
用户组,所以没有读写sdcard目录的权限,所以system_server在读写sdcard文件的时候会报(Permission denied)
错误(不过也可能是别的原因)
- 修改system_server 用户组
system_server是由ZygoteInit类负责初始化和启动的,相关的代码在
frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
文件中。其中关键的启动代码如下。从代码中可以看到,在启动sysetm_server时通过–setgroups为其设置了所属用户组。
private static boolean startSystemServer()throws MethodAndArgsCaller, RuntimeException {long capabilities = posixCapabilitiesAsBits(OsConstants.CAP_KILL,OsConstants.CAP_NET_ADMIN,OsConstants.CAP_NET_BIND_SERVICE,OsConstants.CAP_NET_BROADCAST,OsConstants.CAP_NET_RAW,OsConstants.CAP_SYS_MODULE,OsConstants.CAP_SYS_NICE,OsConstants.CAP_SYS_RESOURCE,OsConstants.CAP_SYS_TIME,OsConstants.CAP_SYS_TTY_CONFIG);/* Hardcoded command line to start the system server */String args[] = {"--setuid=1000","--setgid=1000","--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1032,3001,3002,3003,3006,3007","--capabilities=" + capabilities + "," + capabilities,"--runtime-init","--nice-name=system_server","com.android.server.SystemServer",};ZygoteConnection.Arguments parsedArgs = null;int pid;try {parsedArgs = new ZygoteConnection.Arguments(args);ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);/* Request to fork the system server process */pid = Zygote.forkSystemServer(parsedArgs.uid, parsedArgs.gid,parsedArgs.gids,parsedArgs.debugFlags,null,parsedArgs.permittedCapabilities,parsedArgs.effectiveCapabilities);} catch (IllegalArgumentException ex) {throw new RuntimeException(ex);}/* For child process */if (pid == 0) {handleSystemServerProcess(parsedArgs);}return true;}
我们可以在--setgroups
添加1028
(不是固定的,根据实际情况)
重新编译framework
并烧录验证,可以查看进程信息
验证用户组是否添加成功。
1、方法二
解决思路:提高system_server权限
代码路径:dalvik/vm/native/dalvik_system_Zygote.cpp
/** Utility routine to fork zygote and specialize the child process.*/
static pid_t forkAndSpecializeCommon(const u4* args, bool isSystemServer)
{pid_t pid;uid_t uid = (uid_t) args[0];gid_t gid = (gid_t) args[1];ArrayObject* gids = (ArrayObject *)args[2];u4 debugFlags = args[3];ArrayObject *rlimits = (ArrayObject *)args[4];u4 mountMode = MOUNT_EXTERNAL_NONE;int64_t permittedCapabilities, effectiveCapabilities;char *seInfo = NULL;char *niceName = NULL;if (isSystemServer) {/** Don't use GET_ARG_LONG here for now. gcc is generating code* that uses register d8 as a temporary, and that's coming out* scrambled in the child process. b/3138621*///permittedCapabilities = GET_ARG_LONG(args, 5);//effectiveCapabilities = GET_ARG_LONG(args, 7);permittedCapabilities = args[5] | (int64_t) args[6] << 32;effectiveCapabilities = args[7] | (int64_t) args[8] << 32;} else {mountMode = args[5];permittedCapabilities = effectiveCapabilities = 0;StringObject* seInfoObj = (StringObject*)args[6];if (seInfoObj) {seInfo = dvmCreateCstrFromString(seInfoObj);if (!seInfo) {ALOGE("seInfo dvmCreateCstrFromString failed");dvmAbort();}}StringObject* niceNameObj = (StringObject*)args[7];if (niceNameObj) {niceName = dvmCreateCstrFromString(niceNameObj);if (!niceName) {ALOGE("niceName dvmCreateCstrFromString failed");dvmAbort();}}}......
从以上代码分析中可以看到,如果是
system_server(isSystemServer)
u4 mountMode = MOUNT_EXTERNAL_NONE;
从代码分析,如果是系统进程的情况下,通过mountMode
控制,让系统进程不能访问sdcard
目录
(但是海思方案也是这样定义,但是system_sever也能正常访问sdcard目录,可能是底层文件系统不一样导致,还有待研究)
我们再查看mountMode
参数枚举,可以看到
//代码位置:dalvik/vm/native/dalvik_system_Zygote.cpp
enum {MOUNT_EXTERNAL_NONE = 0,MOUNT_EXTERNAL_SINGLEUSER = 1,MOUNT_EXTERNAL_MULTIUSER = 2,MOUNT_EXTERNAL_MULTIUSER_ALL = 3,
};
我们修改默认的mountMode
参数
如上图,修改
mountMode
参数为MOUNT_EXTERNAL_MULTIUSER_ALL
,允许所有的用户访问(可能会造成别的问题,谨慎修改),修改完成后单编/整编进行验证。
三、总结
因为在项目中,有个需求是需要在system_server中去读取sdcard文件,发现了system_server竟然不能访问sdcard目录文件,起先感觉到很奇怪,在我们印象中系统进程的权限一般都高于普通应用进程,普通应用都能正常读写,system_server竟然不能?通过查询资料,发现其中端倪,故写此文章记录一下问题,方便以后翻阅。
以上分析属于笔者自己理解如果有错误请大神指出,欢迎转载
Android system_server无法访问sdcard目录问题记录(Android 4.4 mtk平台)相关推荐
- android代码无法访问data目录,解决Android7.1.1中无法打开/data目录的问题
C:\Users\Administrator>cd F:\AndroidSDK\platform-tools C:\Users\Administrator>F: F:\AndroidSDK ...
- Android SELinux开发入门指南之正确姿势解决访问data目录权限问题
Android SELinux开发入门指南之正确姿势解决访问data目录权限问题 Android SELinux开发多场景实战指南目录: Android SELinux开发入门指南之SELinux ...
- android 访问data目录、6.0模拟器读写sdcard、相关sdcard路径
转载请标明出处: http://blog.csdn.net/xx326664162/article/details/52259980 文章出自:薛瑄的博客 你也可以查看我的其他同类文章,也会让你有一定 ...
- Android中访问sdcard路径的几种方式
以前的Android(4.1之前的版本)中,SDcard路径通过"/sdcard"或者"/mnt/sdcard"来表示,而在JellyBean(安卓4.1)系统 ...
- Android studio File Explorer sdcard文件怎么访问
DexClassLoader myDexClassLoader = new DexClassLoader(//模拟器都没上传到手机sd卡里怎么也读出来了这个类,//说明就是找到的本地的类,//如果上传 ...
- Android存储访问及目录
原文:Android存储访问及目录 Android存储访问及目录 Android的外部存储 Android支持外部存储(case-insensitive filesystem with immutab ...
- android访问asset目录下的资源
android提供了AssetManager来访问asset目录下的资源, 在activity中通过getAssets()获取AssetManager 常用的api如下: 1.列举路径下的资源Stri ...
- Android获取SDcard目录及创建文件夹;
获取sdcard目录 public static String getSDPath() {File sdDir = null;boolean sdCardExist = Environment.get ...
- android预置资源到data分区,Android R 如何访问Android/data目录?
前言 Android R上分区存储的限制得到进一步加强,无论APP的targetsdkversion是多少,都将无法访问Android/data和Android/obb这二个应用私有目录.这无疑对会部 ...
- Android实现Mtp访问浏览手机存储(一)访问Mtp目录
MTP,全称是 Media Transfer Protocol(媒体传输协议),它是微软的一个为计算机和便携式设备之间传输图像.音乐等所定制的协议.MTP 的应用分两种角色,一个是作为 Initiat ...
最新文章
- 用mkfs.jffs2 命令制作jffs2镜像文件 (转)
- 电脑开机3秒就重启循环_U盘如何变成万能维修工具?分享3款PE制作软件,小白秒变电脑高手...
- Express + Element-ui 实现图片/文件上传
- 驳《阿里「Java开发手册」中的1个bug》?
- L-BFGS算法/Broyden族/BFGS算法/阻尼牛顿法的Python实现代码
- EBITDA的计算公式
- Python批量提取PowerPoint文件中所有幻灯片标题和备注文本
- 升级到NVelocity1.1版本
- Pattern类正则表达式的编译表示形式
- 基于pycrfsuite和sklearn_crfsuite的命名实体识别NER实战【以CoNLL2002数据集为基准】
- uni-app image组件当显示不出图片时显示默认图片
- 电容电感充电曲线仿真图
- cie色度图matlab,带你解读 CIE1931色度图
- android官方开发文档中学英文-uniformly distributed int(均匀分布的整数)
- 关于按钮“按下”效果的两种实现
- java小算盘金钱存银行1秒算出每一年的利息及存款,利息一目了然
- 解锁“绿色计算产业白皮书”,海量数据携手绿盟成员共促生态繁荣
- 【Java】IntellIDEA软件的安装
- tcp socket 和 socket文件
- 如何提高模型的泛化能力
热门文章
- COJ 3012 LZJ的问题 (有向图判环)
- Python实现网络爬虫
- 【数据可视化】Echarts世界地图需要的数据 - JSON格式世界国家中英文对照表
- 虚拟主机,VPS,云主机之间的区别?
- Java 深入面向对象
- vostro3470装win7_dell latitude3470怎么安装win7系统
- 【笔记】C++之SLT的常用容器
- win10家庭版不能远程连接,升级企业版过程
- 020.3.25普及C组 母鸡下蛋(hen)【纪中】【模拟】
- ResultSet.TYPE_SCROLL_SENSITIVE到底发生了什么?