Monday, April 27, 2015

Running MATLAB 2012b on MAC OS X Yosemite

I have been trying to install the MATLAB 2012b on MAC OS X 10.10.3 (Yosemite), however, starting the application after installation keeps gives an error message "Unexpected Exception: There was an unexcepted exception" that refers to the path of log file with error details.





I checked what was inside the log file, and I have found the following message about the reason of the exception:


 com.mathworks.instutil.JNIException: java.lang.UnsatisfiedLinkError: Cant load library: /Applications/MATLAB_R2012b.app/bin/maci64/libinstutil.dylib  
 java.lang.UnsatisfiedLinkError: Cant load library: /Applications/MATLAB_R2012b.app/bin/maci64/libinstutil.dylib  


Doing a quick search about problems starting MATLAB on MAC OS X, I have found out that the reason might be the version of java that I am running.

I checked the version of java installed on my machine using


 java -version  
   

and the output was 
 java version "1.8.0_40"  
 Java(TM) SE Runtime Environment (build 1.8.0_40-b27)  
 Java HotSpot(TM) 64-Bit Server VM (build 25.40-b25, mixed mode)  


as I am running Oracle Java 1.8. 

I followed the instructions from this stack overflow answer, to remove the existing installation of Java 1.8 from my Mac.
sudo rm -rf /Library/Java/JavaVirtualMachines/jdk<version>.jdk
sudo rm -rf /Library/PreferencePanes/JavaControlPanel.prefPane
sudo rm -rf /Library/Internet\ Plug-Ins/JavaAppletPlugin.plugin

then I installed the Java for OS X from Apple:
https://support.apple.com/kb/dl1572?locale=en_US

Now, I tried again launching the MATLAB. I noticed that the error message have changed as now the application runs and I can view the splash screen but by the time when it is supposed to display the MATLAB desktop environment, it shows another error message instead.


The new error message is 

Error Starting Desktop:


 java.lang.NullPointerException   
  at com.mathworks.widgets.WindowsWidgetFactory$SearchAndClearButton.anyText(WindowsWidgetFactory.java:187)   
  at com.mathworks.widgets.WindowsWidgetFactory$SearchAndClearButton.getIcon(WindowsWidgetFactory.java:195)   
  at com.apple.laf.AquaButtonUI.setThemeBorder(AquaButtonUI.java:113)   
  at com.apple.laf.AquaButtonUI.installDefaults(AquaButtonUI.java:80)   
  at javax.swing.plaf.basic.BasicButtonUI.installUI(BasicButtonUI.java:88)   
  at javax.swing.JComponent.setUI(JComponent.java:664)   
  at javax.swing.AbstractButton.setUI(AbstractButton.java:1807)   
  at javax.swing.JButton.updateUI(JButton.java:146)   
  at javax.swing.AbstractButton.init(AbstractButton.java:2172)   
  at javax.swing.JButton.<init>(JButton.java:136)   


At this moment, I was able to start the MATLAB from the command line, but without the desktop GUI environment using the commands:
 sudo /Applications/MATLAB_R2012b.app/bin/matlab --nodesktop  
or 
 sudo /Applications/MATLAB_R2012b.app/bin/matlab --nojvm  

I tried installing X11 which is claimed to be required by MATLAB on OS X as stated here  but still the problem persists to happen.

Finally, I noticed that there is a bug report for this issue on MathWorks website that provides a patch for solving this issue. I downloaded the patch from https://www.mathworks.com/support/bugreports/1098655 , and  run at as described in the instruction on the page and now I can run MATLAB normally on my MAC Yosemite! :D :D



Sunday, April 26, 2015

Dissecting Android Permissions

What are Android Permissions ?



Android uses a fine-grained permission to control the application access to resources. APIs for accessing sensitive resources are actions are protected by permissions, the application developer must declare what permissions the application needs to operate correctly within the application manifest file “manifest.xml”. The syntax for that is :


<uses-permission android:name="string"
       android:maxSdkVersion="integer" />


where  android:name is the name of the required permission, and android:maxSdkversion is the highest API level at which the application needs to be granted this permission. Ths attribute is useful if the permission declared is no longer needed after a certain API level.


The list of all permissions defined by the base Android operating system can be found here:


In addition to those, the application developer can also define new permissions to control what other applications can interact with his application.


Example:


<uses-permission
    android:name="android.permission.WRITE_EXTERNAL_STORAGE"
    android:maxSdkVersion="18" />


This indicates that the application asks for being granted the “android.permission.WRITE_EXTERNAL_STORAGE” when installed on API level 18 or lower.


At  the time of application installation, the user will presented with a list of all permissions requested by the application (as declared in the manifest file) and it is up to him to proceed with the installation process, therefore granting it all permissions it needs, or cancel the installation process.


How permissions are maintained in Android ?

In Android, the PackageManger is responsible for managing the packages installation and permissions. You can use the package manager to view all installed packages on your Android system:


pm list packages


or list all permissions (including those that are defined by 3rd party application developers):


pm list permissions


Or you can also use it to install an application


pm install <APK_filename>


or to grant/ revoke permission to a package ?


pm grant <PACKAGE> <PERMISSION>
pm revoke <PACKAGE> <PERMISSION>


When you attempt to install an application, The PackageInstallerActivity invokes the PackageManager that is starts the installation process. The package manager communicates with the PackageManagerService to get the app installed via the installd daemon. The PackageManager runs within the “system_server process and the installd runs as a native service. Both of install daemon (installd) and system_server are started at the boot time.


Package+Installer.jpg
( Figure Courtesy of http://kpbird.blogspot.com/2012/10/in-depth-android-package-manager-and.html )


How does the installation process happen ?


A major difference between Android and Linux is that Android isolates each application from other applications to prevent malicious applications from snooping or crashing other installed application. This approach is known as “Sandboxing”, Android achieves this by considering each application as a different user.


At installation time, the PackageManager copies the APK file and any native libraries within the app to “/data/app/<package name>” directory (or “/system/app/<package name>” for system applications). Then, it decides a unique identifiers (UID) for the new application. The application UIDs are chosen in the range between 10,000 and 99,999 . As defined in ANDROID_FILESYSTEM_CONFIG


#define AID_APP          10000  /* first app user */


In addition to the UID, the application is also assigned a username to the maps to the UID (For example application with UID 10032 is assigned the user name u0_a32 )  and a data directory at “/data/data/<package name>”. Permissions for the data directory are set appropriately such that it is owned by the new created user for this application.


Although that by default Android assigns to each application a unique UID, two application can request to be running under the same UID by setting the same value of android:sharedUserId in their manifest files, this is only possible if both application are going to be signed by the same developer certificate. The two applications that share the same user id will share the same data directory and , if desired, run in the same process. The role of code signing in Android Security model is explained in more detail in this article.


For example,  the  application “nesl.ucla.edu.cameraap1” has been assigned the UID : 10057 and the user name “u0_a57”. The data directory for that app /data/data/nesl.ucla.edu.cameraapp1” is therefore owned by “u0_a57” user.




Also during the installation, the PackageManager adds new entries for the new installed package in “/data/system/packages.xml” and “/data/system/packages.list” files.


The “packages.xml”  also maintains information about installed packages, including the packagename, app directory (location of apk, and native libraries), their user ID, version number (as extracted from the manifest file), the certificate key by which the APK was signed and the list of permissions that have been granted to the application. Permissions are stored under the <perms> tag. Adding or removing items from this section may grant or revoke permission to the application. However, modification will not be reflected until the system_server (hosting the PackageManagerService) is restarted since the application permissions are cached as we will see later.


<package name="nesl.ucla.edu.cameraapp1" codePath="/data/app/nesl.ucla.edu.cameraapp1-2" nativeLibraryPath="/data/app/nesl.ucla.edu.cameraapp1-2/lib" flags="572998" ft="14cca4e4b58" it="14cca4cf54b" ut="14cca4e4ea5" version="1" userId="10057">
       <sigs count="1">
           <cert index="6" />
       </sigs>
       <perms>
           <item name="android.permission.CAMERA" />
       </perms>
       <proper-signing-keyset identifier="48" />
       <signing-keyset identifier="48" />
   </package>


while the “packages.list” file lists all installed packages their user identifiers (UID),  the location of their data directory, and the identifier of any groups (GIDs) they are member of.


nesl.ucla.edu.wifistatuslog 10058 1 /data/data/nesl.ucla.edu.wifistatuslog default 3003
nesl.ucla.edu.cameraapp1 10057 1 /data/data/nesl.ucla.edu.cameraapp1 default none


Note that granting some permissions to an application results in adding the applications UID into a members group. For example the package “nesl.ucla.edu.wifistatuslog”  (u0_a58) is a member of 3003 group (inet) because it has been granted the “android.permission.INTERNET” permission. The mapping between permissions and group IDs can be found at:
/etc/permissions/platform.xml” while the group identifier (GID) values for the groups are defined in ANDROID_FILESYSTEM_CONFIG.. Those kinds of permissions are enforced by at the low-level byl kernel itself.

Where does permission checking happen?



When the android device boots, the first process started by the linux kernel is init  (PID: 1) process that executes shell scripts defined inside /init.rc.


This goal of init.rc is to initialize the system environment by executing a series of commands.
The init.rc defines the user under each each service is going to run (for example: Zygote will run under the root user, while keystore service will be started under the keystore user).


One of the early processes started by init is the Zygote. Zygote is a daemon whose goal is to start additional services and to load libraries. It acts as a loader for each Dalvik process by creating a copy of itself (e.g. forking it self). The zygote is started by executing the “system/bin/app_process” command.


Then it is the  Zygote’s rule to start the system_server” process.  Therefore, the Zygote acts as the parent process oft he “system_server” and for any later running process.


ps | grep Zygote




Here, we notice that the Zygote is running the “root” user with PID = 3085 and PPID = 1


We also note that other running processes including the system_server have the Zygote’s PID (3085) assigned as their PPID.




ps -t -p 3339



Looking inside the source code of PackageMangerService


Within the constructor, PackageManagerService instantiates an object (mSettings) of Settings class


1300        mSettings = new Settings(context);


The object mSettings will be used deserialize package configurations from “packages.xml” file by calling:
                     


 mRestoredSettings = mSettings.readLPw(this, sUserManager.getUsers(false),
1393                    mSdkVersion, mOnlyCore);

Also: updates to the package settings are serialized to the “packages.xml” file using the mSettings instance.


1125                        mSettings.writeLPr();

The packageManagerService  exposes two public methods: checkPermission, and checkUidPermission  function that is given a package name or application UID have been granted the permission identified by permName, it will return either PackageManager.PERMISSION_GRANTED or PackageManager.PERMISSION_DENIED.



public int checkPermission(String permName, String pkgName) {
2373        synchronized (mPackages) {
2374            PackageParser.Package p = mPackages.get(pkgName);
2375            if (p != null && p.mExtras != null) {
2376                PackageSetting ps = (PackageSetting)p.mExtras;
2377                if (ps.sharedUser != null) {
2378                    if (ps.sharedUser.grantedPermissions.contains(permName)) {
2379                        return PackageManager.PERMISSION_GRANTED;
2380                    }
2381                } else if (ps.grantedPermissions.contains(permName)) {
2382                    return PackageManager.PERMISSION_GRANTED;
2383                }
2384            }
2385        }
2386        return PackageManager.PERMISSION_DENIED;
2387    }


@Override
2390    public int checkUidPermission(String permName, int uid) {
2391        synchronized (mPackages) {
2392            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
2393            if (obj != null) {
2394                GrantedPermissions gp = (GrantedPermissions)obj;
2395                if (gp.grantedPermissions.contains(permName)) {
2396                    return PackageManager.PERMISSION_GRANTED;
2397                }
2398            } else {
2399                ArraySet<String> perms = mSystemPermissions.get(uid);
2400                if (perms != null && perms.contains(permName)) {
2401                    return PackageManager.PERMISSION_GRANTED;
2402                }
2403            }
2404        }
2405        return PackageManager.PERMISSION_DENIED;
2406    }



Case Analysis : LocationManager



Within the LocationManagerService, the function getAllowedResolutionLevel is used to return finest resolution level allowed for the calling application. It returns RESOLUTION_LEVEL_NONE if the application is not granted location access at all.


 
private int getAllowedResolutionLevel(int pid, int uid) {
1006        if (mContext.checkPermission(android.Manifest.permission.ACCESS_FINE_LOCATION,
1007                pid, uid) == PackageManager.PERMISSION_GRANTED) {
1008            return RESOLUTION_LEVEL_FINE;
1009        } else if (mContext.checkPermission(android.Manifest.permission.ACCESS_COARSE_LOCATION,
1010                pid, uid) == PackageManager.PERMISSION_GRANTED) {
1011            return RESOLUTION_LEVEL_COARSE;
1012        } else {
1013            return RESOLUTION_LEVEL_NONE;
1014        }
1015    }