Android 安全攻防(三): SEAndroid Zygote
在Android系统中,所有的应用程序进程,以及系统服务进程SystemServer都是由Zygote孕育fork出来的。 Zygote的native获取主要研究dalvik/vm/native/dalvik_system_Zygote.cpp,SEAndroid管控应用程序资源存取权限,对于整个dalvik,也正是在此动的手脚。
首先看抛出的DalvikNativeMethoddvm_dalvik_system_Zygote,与原生Android相比,SEAndroid 在nativeForkAndSpecialize 增加传入了两个String类型的参数:
const DalvikNativeMethod dvm_dalvik_system_Zygote[] = {
{"nativeFork", "()I",
Dalvik_dalvik_system_Zygote_fork },
{ "nativeForkAndSpecialize", "(II[II[[ILjava/lang/String;Ljava/lang/String;)I",
Dalvik_dalvik_system_Zygote_forkAndSpecialize },
{ "nativeForkSystemServer", "(II[II[[IJJ)I",
Dalvik_dalvik_system_Zygote_forkSystemServer },
{ "nativeExecShell", "(Ljava/lang/String;)V",
Dalvik_dalvik_system_Zygote_execShell },
{ NULL, NULL, NULL },
}
那么这两个参数是什么呢?继续追一下
forkAndSpecialize。
/* native public static int forkAndSpecialize(int uid, int gid,
* int[] gids, int debugFlags, String seInfo, String niceName);
*/
static void Dalvik_dalvik_system_Zygote_forkAndSpecialize(const u4* args,
JValue* pResult)
{
pid_t pid;
pid = forkAndSpecializeCommon(args, false);
RETURN_INT(pid);
}
可以看到,增加传入的2个参数一个是seInfo,用于定义新进程的SEAndroid信息,一个是niceName,用于定义新进程名。
在static pid_t forkAndSpecializeCommon(const u4* args, bool isSystemServer)中,其中SEAndroid加入了设置SELinux安全上下文代码段,seInfo和niceName:
#ifdef HAVE_SELINUX
err = setSELinuxContext(uid, isSystemServer, seInfo, niceName);
if (err < 0) {
LOGE("cannot set SELinux context: %s\n", strerror(errno));
dvmAbort();
}
free(seInfo);
free(niceName);
#endif
其中设置SELinux安全上下文方法实现:
#ifdef HAVE_SELINUX
/*
* Set SELinux security context.
*
* Returns 0 on success, -1 on failure.
*/
static int setSELinuxContext(uid_t uid, bool isSystemServer,
const char *seInfo, const char *niceName)
{
#ifdef HAVE_ANDROID_OS
return selinux_android_setcontext(uid, isSystemServer, seInfo, niceName);
#else
return 0;
#endif
}
#endif
再往上一层就到了libcore/dalvik/src/main/java/dalvik/system/Zygote.java ,Zygote类的封装,对应forkAndSpecialize方法中添加seInfo和niceName参数传递。
public class Zygote {
...
public static int forkAndSpecialize(int uid, int gid, int[] gids,
int debugFlags, int[][] rlimits, String seInfo, String niceName) {
preFork();
int pid = nativeForkAndSpecialize(uid, gid, gids, debugFlags, rlimits, seInfo, niceName);
postFork();
return pid;
}
native public static int nativeForkAndSpecialize(int uid, int gid,
int[] gids, int debugFlags, int[][] rlimits, String seInfo, String niceName);
/**
* Forks a new VM instance.
* @deprecated use {@link Zygote#forkAndSpecialize(int, int, int[], int, int[][])}
*/
@Deprecated
public static int forkAndSpecialize(int uid, int gid, int[] gids,
boolean enableDebugger, int[][] rlimits) {
int debugFlags = enableDebugger ? DEBUG_ENABLE_DEBUGGER : 0;
return forkAndSpecialize(uid, gid, gids, debugFlags, rlimits, null, null);
}
...
}
Android应用程序启动流程不再赘述,当建立了ZygoteConnection对象用于socket连接后,接下来就是调用ZygoteConnection.runOnce函数进一步处理了。
源码位置:frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java,其中,SEAndroid增加zygote安全策略函数,在runOnce中调用。
/**
* Applies zygote security policy.
* Based on the credentials of the process issuing a zygote command:
* <ol>
* <li> uid 0 (root) may specify --invoke-with to launch Zygote with a
* wrapper command.
* <li> Any other uid may not specify any invoke-with argument.
* </ul>
*
* @param args non-null; zygote spawner arguments
* @param peer non-null; peer credentials
* @throws ZygoteSecurityException
*/
private static void applyInvokeWithSecurityPolicy(Arguments args, Credentials peer,
String peerSecurityContext)
throws ZygoteSecurityException {
int peerUid = peer.getUid();
if (args.invokeWith != null && peerUid != 0) {
throw new ZygoteSecurityException("Peer is not permitted to specify "
+ "an explicit invoke-with wrapper command");
}
if (args.invokeWith != null) {
boolean allowed = SELinux.checkSELinuxAccess(peerSecurityContext,
peerSecurityContext,
"zygote",
"specifyinvokewith");
if (!allowed) {
throw new ZygoteSecurityException("Peer is not permitted to specify "
+ "an explicit invoke-with wrapper command");
}
}
}
/**
* Applies zygote security policy for SEAndroid information.
*
* @param args non-null; zygote spawner arguments
* @param peer non-null; peer credentials
* @throws ZygoteSecurityException
*/
private static void applyseInfoSecurityPolicy(
Arguments args, Credentials peer, String peerSecurityContext)
throws ZygoteSecurityException {
int peerUid = peer.getUid();
if (args.seInfo == null) {
// nothing to check
return;
}
if (!(peerUid == 0 || peerUid == Process.SYSTEM_UID)) {
// All peers with UID other than root or SYSTEM_UID
throw new ZygoteSecurityException(
"This UID may not specify SEAndroid info.");
}
boolean allowed = SELinux.checkSELinuxAccess(peerSecurityContext,
peerSecurityContext,
"zygote",
"specifyseinfo");
if (!allowed) {
throw new ZygoteSecurityException(
"Peer may not specify SEAndroid info");
}
return;
}
理所当然的,在启动一个新的进程时,frameworks/base/core/java/android/os/Process.java中也会加入SEAndroid信息seInfo。
分享到:
相关推荐
Android Zygote启动流程源码解析
Android启动,第二大阶段,Zygote启动。 紧接上一篇《 Android启动-init介绍》Linux内核启动之后,执行第一个进程 Init,init会启动本地服务,创建Zygote等。 这里我们就来研究一下Zygote启动过程。
Zygote在Android系统扮演着不可或缺的角色,Android系统的启动首先需要Zygote参与,比如启动SystemService , 还有一个就是孵化应用的进程,比如我们创建一个Activity也是需要Zygote参与. Zygote 启动分为两个部分: 1....
Zygote可以说是Android开发面试很高频的一道问题,但总有小伙伴在回答这道问题总不能让面试满意, 在这你就要搞清楚面试问你对Zygote的理解时,面试官最想听到的和其实想问的应该是哪些?下面我们通过以下几点来剖析...
ubuntu12.04_roo用户无法使用_chrome_浏览器
模拟Android系统Zygote启动流程
( Android Zygote解析
1. OS级别,由bootloader载入linux kernel后(注:bootloader和制造商有关,一般都是自己修改后的bootloader,大同小异,无外乎加载了自己的安全机制,我们可以用最常见的uboot来考虑),kernel开始初始化, 并载入...
Android zygote服务/SystemServer启动流程/Activity创建,本文档继承Android init的分析,继续往下分析Zygote进程、SystemServer进程的创建、Activity的建立
本书是在分析Android源码的基础上展开的,而源码文件所在的路径一般都很长,例如,文件AndroidRuntime.cpp的真实路径就是framework/base/core/jni/AndroidRuntime.cpp。为了书 写方便起见,我们在各章节开头把该...
1.初探Android 2.Android开发环境搭建与编译 3.Android编译过程分析 4.android.mk初识 5.Android.mk学习1 6.Android.mk学习2 7.Android.mk学习3 8.Android启动课程大纲 9.Android启动模式 10.init启动分析 11.走入...
移植Android以及如何开发适合各种机器的应用程序,分析Android框架所需的基础知识,JNI(Java Native Interface)与Binder基础知识,Zygote、Service Manager、Service Server等Android核心组件,Android服务框架的...
主要介绍了详细分析Android中实现Zygote的源码,包括底层的C/C++代码以及Java代码部分入口,需要的朋友可以参考下
做一些Android应用程序安全性研究 基础知识 工具包 支持常规的APK编译与反编译功能 系统 查看各个版本的Android原始码 Android系统启动流程8.1.0_r1版本 根据r0ysue知识星球的内容画的流程图 参考链接: : ...
zygote启动过程zygote启动过程zygote启动过程zygote启动过程zygote启动过程
Android系统进程Zygote启动过程的源代码分析.pdf
ptrace注入与zygote区别和联系.V2EEptrace注入与zygote区别和联系.V2EE
第4章分析了Zygote、SystemServer等进程的工作机制,同时还讨论了Android的启动速度、虚拟机HeapSize的大小调整、Watchdog工作原理等问题;第5章讲解了Android系统中常用的类,包括sp、wp、RefBase、Thread等类,...