Android UID allocation, viewing and related knowledge

Posted by alsouno on Tue, 18 Jan 2022 19:13:40 +0100

  • The meaning and function of uid pid gid gids
  • Allocation of UIDs
  • View several ways to apply UID
  • Obtain the package name through uid, and obtain uid through package name

All the sample code involved below is based on Android 8.1.

1. Meaning and function of uid PID GID GIDS

Uid: the uid in Android is used to identify an application. The uid is assigned during application installation and will not change during the period when the application exists on the mobile phone. An application can only have one uid. Multiple applications can share the same uid using sharedUserId, provided that the signatures of these applications are the same.
pid: process ID, variable
gid: corresponding to the concept of user group in linux, gid in android is equal to uid
GIDS: a GIDS is equivalent to a set of permissions. A UID can be associated with GIDS, indicating that the UID has multiple permissions
A process is the sandbox of the host application, which generally has a UID and multiple GIDS. Each process can only access the files within the permission range of the UID and the interfaces allowed by the GIDS, which constitute the most basic security foundation of Android.

2. UID allocation:

The UID and GID of the app are confirmed during installation. The key codes are as follows:
In PMS:

private PackageParser.Package scanPackageDirtyLI(PackageParser.Package pkg,
                                                 final int policyFlags, final int scanFlags, long currentTime, @Nullable UserHandle user)
        throws PackageManagerException {
    if (DEBUG_PACKAGE_SCANNING) {
        if ((policyFlags & PackageParser.PARSE_CHATTY) != 0)
            Log.d(TAG, "Scanning package " + pkg.packageName);
    }
    
    applyPolicy(pkg, policyFlags);
    .....................................

        if (pkgSetting == null) {
            .......................
            // SIDE EFFECTS; updates system state; move elsewhere
            if (origPackage != null) {
                mSettings.addRenamedPackageLPw(pkg.packageName, origPackage.name);
            }
            //PMS maintains the mSettings data structure, which stores the installation information of all applications
            mSettings.addUserToSettingLPw(pkgSetting);
        } else {
            // REMOVE SharedUserSetting from method; update in a separate call.
            //
            // TODO(narayan): This update is bogus. nativeLibraryDir & primaryCpuAbi,
            // secondaryCpuAbi are not known at this point so we always update them
            // to null here, only to reset them at a later point.
            Settings.updatePackageSetting(pkgSetting, disabledPkgSetting, suid, destCodeFile,
                    pkg.applicationInfo.nativeLibraryDir, pkg.applicationInfo.primaryCpuAbi,
                    pkg.applicationInfo.secondaryCpuAbi, pkg.applicationInfo.flags,
                    pkg.applicationInfo.privateFlags, pkg.getChildPackageNames(),
                    UserManagerService.getInstance(), usesStaticLibraries,
                    pkg.usesStaticLibrariesVersions);
        }
        ....................
    return pkg;
}

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

/**
 * Registers a user ID with the system. Potentially allocates a new user ID.
 * @throws PackageManagerException If a user ID could not be allocated.
 */
void addUserToSettingLPw(PackageSetting p) throws PackageManagerException {
    if (p.appId == 0) {
        // Assign new user ID
        p.appId = newUserIdLPw(p);
    } else {
        // Add new setting to list of user IDs
        addUserIdLPw(p.appId, p, p.name);
    }
    if (p.appId < 0) {
        PackageManagerService.reportSettingsProblem(Log.WARN,
                "Package " + p.name + " could not be assigned a valid UID");
        throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE,
                "Package " + p.name + " could not be assigned a valid UID");
    }
}
    // Allocation of UIDs
    // Returns -1 if we could not find an available UserId to assign
    private int newUserIdLPw(Object obj) {
        // Let's be stupidly inefficient for now...
        final int N = mUserIds.size();
        //Starting from 0, find the first unused ID. this corresponds to the case where the previous application is removed. Reuse the previous ID
        for (int i = mFirstAvailableUid; i < N; i++) {
            if (mUserIds.get(i) == null) {
                mUserIds.set(i, obj);
                return Process.FIRST_APPLICATION_UID + i;
            }
        }

        //A maximum of 9999 apps can be installed
        // None left?
        if (N > (Process.LAST_APPLICATION_UID-Process.FIRST_APPLICATION_UID)) {
            return -1;
        }

        mUserIds.add(obj);
        // It can explain why the UID of ordinary applications starts from 10000
        return Process.FIRST_APPLICATION_UID + N;
    }

3. Several ways to view application UID s

Method 1: ps command calculation

This u0_a106 means that the application is an application under user 0 (primary user), and the id is 106. As mentioned earlier, the UID of ordinary applications starts from 10000, so the final calculated UID is 10106
The UID calculation in the case of multiple users is similar:


 

You can see that the userID of the working user is 14, which is the same later. The calculation method is:

    /**
     * Returns the uid that is composed from the userId and the appId.
     * @hide
     */
    public static int getUid(@UserIdInt int userId, @AppIdInt int appId) {
        if (MU_ENABLED) {//Does it support multiple users
            //PER_USER_RANGE is 100000
            return userId * PER_USER_RANGE + (appId % PER_USER_RANGE);
        } else {
            return appId;
        }
    }

Therefore, the UID applied in the last workspace is 100000 * 14 + 10106 = 1410106

Method 2: view through pid

10854 in column 2 is com tencent. Mm the current PID number of the process, and then execute
cat proc/pid No. / status
You will get a large string of data, which contains UID information

Method 3: if the mobile phone has root permission, you can export data / system / packages List file, where you can see the package names and corresponding UID s of all applications

Method 4: get the instance of ApplicationInfo of the application through the code, ApplicationInfo Uid, refer to section 4


4. Obtain package name through uid, and obtain uid through package name

  • Get UID by package name
        PackageManager mPm = getPackageManager();
        try {
            ApplicationInfo applicationInfo = mPm.getApplicationInfo("com.tencent.mm", 0);
            int uid = applicationInfo.uid;
            Toast.makeText(MainActivity.this, "" + uid, Toast.LENGTH_SHORT).show();
        }catch (Exception e){
            e.printStackTrace();
        }

  • Get package name by UID
String packagename = getPackageManager().getNameForUid(uid);

Article reprint:

Android UID allocation, viewing and related knowledge

Topics: Java Android Apache