美文网首页源码分析Android知识Android技术知识
Android 系统对permision的检测过程

Android 系统对permision的检测过程

作者: NiceDream | 来源:发表于2017-05-23 13:44 被阅读122次

    Android 系统对permision的检测过程
    RK3288 5.1 中以太网设置静态IP 对permission的检测

    简略的调用过程如下:

    frameworks\opt\net\ethernet\java\com\android\server\ethernet\EthernetServiceImpl.java

        public void setConfiguration(IpConfiguration config) {
            if (!mStarted.get()) {
                Log.w(TAG, "System isn't ready enough to change ethernet configuration");
            }
            enforceChangePermission();
            enforceConnectivityInternalPermission();
            synchronized (mIpConfiguration) {
                mEthernetConfigStore.writeIpAndProxyConfigurations(config);
    
                // TODO: this does not check proxy settings, gateways, etc.
                // Fix this by making IpConfiguration a complete representation of static configuration.
                if (!config.equals(mIpConfiguration)) {
                    mIpConfiguration = new IpConfiguration(config);
                    mTracker.stop();
                    mTracker.start(mContext, mHandler);
                }
            }
        }
    
       private void enforceConnectivityInternalPermission() {
            mContext.enforceCallingOrSelfPermission(
                    android.Manifest.permission.CONNECTIVITY_INTERNAL,
                    "ConnectivityService");
        }
    

    frameworks\base\core\java\android\app\ContextImpl.java

    public void enforceCallingOrSelfPermission(
                String permission, String message) {
            enforce(permission,
                    checkCallingOrSelfPermission(permission),
                    true,
                    Binder.getCallingUid(),
                    message);
    

    通过Binder这个类,可以获得调用服务的应用的ID,通过这个ID,可以获得应用的相关信息;

        @Override
        public int checkCallingOrSelfPermission(String permission) {
            if (permission == null) {
                throw new IllegalArgumentException("permission is null");
            }
    
            return checkPermission(permission, Binder.getCallingPid(),
                    Binder.getCallingUid());
        }
    
        @Override
        public int checkPermission(String permission, int pid, int uid) {
            if (permission == null) {
                throw new IllegalArgumentException("permission is null");
            }
    
            try {
                return ActivityManagerNative.getDefault().checkPermission(
                        permission, pid, uid);
            } catch (RemoteException e) {
                return PackageManager.PERMISSION_DENIED;
            }
        }
    

    frameworks\base\services\core\java\com\android\server\ActivityManagerService.java

        @Override
        public int checkPermission(String permission, int pid, int uid) {
            if (permission == null) {
                return PackageManager.PERMISSION_DENIED;
            }
            return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
        }
    
    
        int checkComponentPermission(String permission, int pid, int uid,
                int owningUid, boolean exported) {
            if (pid == MY_PID) {
                return PackageManager.PERMISSION_GRANTED;
            }
            return ActivityManager.checkComponentPermission(permission, uid,
                    owningUid, exported);
        }
    
    

    frameworks\base\core\java\android\app\ActivityManager.java

        /** @hide */
        public static int checkComponentPermission(String permission, int uid,
                int owningUid, boolean exported) {
            // Root, system server get to do everything.
            if (uid == 0 || uid == Process.SYSTEM_UID) {
                return PackageManager.PERMISSION_GRANTED;
            }
            // Isolated processes don't get any permissions.
            if (UserHandle.isIsolated(uid)) {
                return PackageManager.PERMISSION_DENIED;
            }
            // If there is a uid that owns whatever is being accessed, it has
            // blanket access to it regardless of the permissions it requires.
            if (owningUid >= 0 && UserHandle.isSameApp(uid, owningUid)) {
                return PackageManager.PERMISSION_GRANTED;
            }
            // If the target is not exported, then nobody else can get to it.
            if (!exported) {
                /*
                RuntimeException here = new RuntimeException("here");
                here.fillInStackTrace();
                Slog.w(TAG, "Permission denied: checkComponentPermission() owningUid=" + owningUid,
                        here);
                */
                return PackageManager.PERMISSION_DENIED;
            }
            if (permission == null) {
                return PackageManager.PERMISSION_GRANTED;
            }
            try {
                return AppGlobals.getPackageManager()
                        .checkUidPermission(permission, uid);
            } catch (RemoteException e) {
                // Should never happen, but if it does... deny!
                Slog.e(TAG, "PackageManager is dead?!?", e);
            }
            return PackageManager.PERMISSION_DENIED;
        }
        
    

    对于普通应用将通过PackageManagerService中保持的信息进行判断是否具有相应的权限;
    base/services/core/java/com/android/server/pm/PackageManagerService.java

        @Override
        public int checkUidPermission(String permName, int uid) {
            synchronized (mPackages) {
                Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
                if (obj != null) {
                    GrantedPermissions gp = (GrantedPermissions)obj;
                    if (gp.grantedPermissions.contains(permName)) {
                        return PackageManager.PERMISSION_GRANTED;
                    }
                } else {
                    ArraySet<String> perms = mSystemPermissions.get(uid);
                    if (perms != null && perms.contains(permName)) {
                        return PackageManager.PERMISSION_GRANTED;
                    }
                }
            }
            return PackageManager.PERMISSION_DENIED;
        }
    

    每次开机系统PackageManagerService都会还原现有app的安装信息,这些信息被放在/data/system/packages.xml里,由mSettings管理。另外/data/system/packages.list记录了app的uid和数据路径等信息。

    相关文章

      网友评论

      • Wu_android:你好。rk3288 你试过 用adb shell修改ip吗?修改了连不上

      本文标题:Android 系统对permision的检测过程

      本文链接:https://www.haomeiwen.com/subject/akowxxtx.html