Android security defense (III): seandroid zygote

Source: Internet
Author: User
Tags deprecated

Android security defense (III): seandroid zygote


In the Android system, all application processes and system service process systemserver are fork bred by zygote. The native acquisition of zygote mainly studies the access permissions of Dalvik/Vm/native/dalvik_system_zygote.cpp and seandroid control application resources. The entire Dalvik is also operated here.


First, let's take a look at the thrown dalviknativemethod dvm_dalvik_system_zygote. Compared with native Android, seandroid adds two string-type parameters in nativeforkandspecialize:

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 },}

So what are the two parameters? Continue with 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);}

We can see that two parameters are added: seinfo, which is used to define the seandroid information of the new process and nicename, which is used to define the new process name.

In static pid_t forkandspecializecommon (const U4 * ARGs, bool issystemserver), seandroid adds the setting SELinux security context code segment, seinfo and 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

The security context method of SELinux is set as follows:

#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

Next, the libcore/Dalvik/src/main/Java/Dalvik/system/zygote. Java and zygote classes are encapsulated. The seinfo and nicename parameters are added to the forkandspecialize method.

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);    }...}

The Startup Process of the android application is not described in detail. After the zygoteconnection object is set up for socket connection, the next step is to call the zygoteconnection. runonce function for further processing.

Source code location: Frameworks/base/CORE/Java/COM/Android/Internal/OS/zygoteconnection. java. Specifically, seandroid adds the zygote security policy function and calls it in 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;    }

Naturally, when starting a new process, seandroid information seinfo will also be added to frameworks/base/CORE/Java/Android/OS/process. java.

 


Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.