您的位置:首页 > 移动开发 > Android开发

android_framework_permissions

2015-07-27 14:56 411 查看
1 Android 安全机制概述

Android安全机制在三个方面来体现。分别从kernel,dalvik, framework三个层次管理。在kernel方面,android系统引入SE linux;在dalvik方面引入沙箱隔离技术;在framework层面引入应用权限控制。详细如下:

A. SE Linux:Linux内核层的安全增强,是一套独立于传统Linux权限访问控制的强制性权限控制机制。Google已将这套机制移植到Android内核,增强了内核的安全性。

B. 沙箱隔离:沙箱是基于不同应用之间User ID的不同而实现的,其本质是Linux对于不同用户间访问权限的隔离。每个APP和系统进程都被分配唯一并且固定的User Id,这个uid与内核层进程的uid对应。每个APP在各自独立的Dalvik虚拟机中运行,拥有独立的地址空间和资源。运行于Dalvik虚拟机中的 进程必须依托内核层Linux进程而存在,因此Android使用Dalvik虚拟机和Linux的文件访问控制来实现沙箱机制。

C. 应用权限控制:Android应用需要申请相应的权限才能访问系统的资源和信息,大多数权限由Android框架层的API进行控制,另一部分权限映射到应用所在的Group ID上,由Linux内核做出控制。

2 UID,GID,GIDS说明与设置(android L)

2.1 UID, GID, GIDS说明

Android 的权限分离的基础是建立在 Linux 已有的 uid 、 gid 、 gids 基础上的 。

UID: Android 在安装一个应用程序,就会为它分配一个 uid。

GID: 对于普通应用程序来说, gid 等于uid。

GIDS: gids 是由框架在 Application 安装过程中生成,与 Application 申请的具体权限相关。 如果 Application 申请的相应的 permission 被 granted ,而且 中有对应的 gid s , 那么 这个 Application 的 gids 中将 包含这个 gid s

2.2 UID, GID, GIDS 设置

1 Android启动某一个App应用,创建进程:

frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

private final void startProcessLocked(ProcessRecord app, String hostingType,

String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs)

{

........

int uid = app.uid;

........

permGids = pm.getPackageGids(app.info.packageName);

........

System.arraycopy(permGids, 0, gids, 2, permGids.length);

........

Process.ProcessStartResult startResult = Process.start(entryPoint,

app.processName, uid, uid, gids, debugFlags, mountExternal,

app.info.targetSdkVersion, app.info.seinfo,

requiredAbi, instructionSet,

app.info.dataDir, entryPointArgs);

........

}

frameworks/base/core/java/android/os/Process.java

public static final ProcessStartResult start(final String processClass,

final String niceName,

int uid, int gid, int[] gids,

int debugFlags, int mountExternal,

int targetSdkVersion,

String seInfo,

String abi,

String instructionSet,

String appDataDir,

String[] zygoteArgs) {

........

return startViaZygote(processClass, niceName, uid, gid, gids,

debugFlags, mountExternal, targetSdkVersion, seInfo,

abi, instructionSet, appDataDir, zygoteArgs);

........

}

private static ProcessStartResult startViaZygote(final String processClass,

final String niceName,

final int uid, final int gid,

final int[] gids,

int debugFlags, int mountExternal,

int targetSdkVersion,

String seInfo,

String abi,

String instructionSet,

String appDataDir,

String[] extraArgs)

throws ZygoteStartFailedEx {

........

argsForZygote.add("--runtime-init");

argsForZygote.add("--setuid=" + uid);

argsForZygote.add("--setgid=" + gid);

........

sb.append("--setgroups=");

........

argsForZygote.add(sb.toString());

........

return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);

}

frameworks/base/core/java/com/android/internal/os/Zygote.java

public static int forkAndSpecialize(int uid, int gid, int[] gids, int debugFlags,

int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose,

String instructionSet, String appDataDir) {

........

int pid = nativeForkAndSpecialize(

uid, gid, gids, debugFlags, rlimits,

mountExternal, seInfo, niceName, fdsToClose,

instructionSet, appDataDir);

........

}

frameworks/base/core/jni/com_android_internal_os_Zygote.cpp

static pid_t ForkAndSpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray javaGids,

jint debug_flags, jobjectArray javaRlimits,

jlong permittedCapabilities,

jlong effectiveCapabilities,

jint mount_external,

jstring java_se_info, jstring java_se_name,

bool is_system_server, jintArray fdsToClose,

jstring instructionSet, jstring dataDir) {

........

pid_t pid = fork();

........

SetGids(env, javaGids);

........

int rc = setresgid(gid, gid, gid);

........

rc = setresuid(uid, uid, uid);

........

}

创建进程完毕,同时该进程设置了相应的uid, gid, gids

3 app权限信息的加载过程

所有App权限信息保存在/data/system/packages.xml。 系统启动后,会检查/data/system/packages.xml 是否存在。这个文件是在解析 apk 时由writeLP()创建的,里面记录了系统的 permissions,以及每个 apk name, codePath, flags, ts, version, uesrid 等信息,这些信息主要通过 apk 的AndroidManifest.xml 解析获取,解析完 apk 后将更新信息写入这个文件并保存到 flash,下次开机直接从里面读取相关信息添加到内存相关列表中。当有
apk升级,安装或删除时会更新这个文件。

3.1 SystemServer中启动PackageManagerService

frameworks/base/services/java/com/android/server/SystemServer.java

mPackageManagerService = PackageManagerService.main(mSystemContext,

mInstaller,mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);

frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java

mSettings = new Settings(context);

frameworks/base/services/core/java/com/android/server/pm/Settings.java

mSettingsFilename = new File(mSystemDir, "packages.xml");

mBackupSettingsFilename = new File(mSystemDir, "packages-backup.xml");

mPackageListFilename = new File(mSystemDir, "packages.list");

FileUtils.setPermissions(mPackageListFilename, 0660,

SYSTEM_UID, PACKAGE_INFO_GID);

读取/data/目录下文件: /data/packages.xml, /data/packages.list

frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java

mSettings.insertPackageSettingLPw(pkgSetting, pkg);

// Add the new setting to mPackages

mPackages.put(pkg.applicationInfo.packageName, pkg);

@Override

public int[] getPackageGids(String packageName) {

........

PackageParser.Package p = mPackages.get(packageName);

........

final PackageSetting ps = (PackageSetting)p.mExtras;

return ps.getGids();

........

}

3.2 安装新应用权限信息的写入过程

frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java

a. installNewPackageLI()

b. PackageParser.Package newPackage = scanPackageLI(pkg,

parseFlags, scanFlags, System.currentTimeMillis(), user);

c. updateSettingsLI(newPackage, installerPackageName, null, null, res);

d. mSettings.writeLPr();

将解析的每个 apk 的信息保存到 packages.xml 和 packages.list 文件里,
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: