1. Download our Official Android App: Forums for Android!

Apps UID - why can share file. Practical usage UID?

Discussion in 'Android Development' started by chihwahli, Jan 5, 2012.

  1. chihwahli

    chihwahli Newbie
    Thread Starter
    Rank:
    None
    Points:
    35
    Posts:
    13
    Joined:
    Jan 4, 2012

    Jan 4, 2012
    13
    0
    35
    Hello android masters,

    Android recruit reporting.

    Could someone tell me about android UID? I searched but could not find any usefull information and/or working sample prog about UID.

    I programmed 2 apps:
    1 to create a file on the android SD card.
    2nd app reads the text from the SD card file.

    additional info:
    - Both app use the same android vm on my eclipse Android SDK
    - package names should not matter, but I gave them different names: com.xxx and
    com.yyy

    The text is written to my logcat in my linux terminal. I could read the SD file created by the other app. I did not use sharedUserId. I thought that every app gets it's own UID, and that they could not share files.

    Could someone tell me why I can, without setting UID?
    2nd question: How is UID used practically? didn't see any sample programs that use UID.

    Many thanks in advance.
     

    Advertisement

  2. jiminaus

    jiminaus Well-Known Member
    Rank:
    None
    Points:
    63
    Posts:
    190
    Joined:
    Oct 27, 2011

    Oct 27, 2011
    190
    36
    63
    Sydney, Australia
    There's no protection on the SD card. They're typically formatted with some kind of FAT filesystem. FAT filesystems doesn't support access permissions.

    The restrictions of one app not accessing another app's data only applies to internal storage.
     
    chihwahli likes this.
  3. chihwahli

    chihwahli Newbie
    Thread Starter
    Rank:
    None
    Points:
    35
    Posts:
    13
    Joined:
    Jan 4, 2012

    Jan 4, 2012
    13
    0
    35
    Thanks jiminaus that is usefull info.

    Is there another way to share a variable and use UID?, so that I can share data between apps. I am researching the use of UID and sharing data. Normally apps operate in different vm's. Thus totally isolated from eachother.

    (I know of SQLite, etc. But that is not the research I have to do for my study. Will add that in my report as a possible way to share data between apps)

    Any more volunteers who might enlighten me about UID?
     
  4. jiminaus

    jiminaus Well-Known Member
    Rank:
    None
    Points:
    63
    Posts:
    190
    Joined:
    Oct 27, 2011

    Oct 27, 2011
    190
    36
    63
    Sydney, Australia
  5. chihwahli

    chihwahli Newbie
    Thread Starter
    Rank:
    None
    Points:
    35
    Posts:
    13
    Joined:
    Jan 4, 2012

    Jan 4, 2012
    13
    0
    35
    Yes, although I have read them, perhaps I missed something. Let me quote what I understand from it.

    Quotes from Security and Permissions | Android Developers
    Setting sharedUserId: "By doing this, for purposes of security the two packages are then treated as being the same application, with the same user ID and file permissions.... Any data stored by an application will be assigned that application's user ID, and not normally accessible to other packages"
    Quote: android:sharedUserIdThe name of a Linux user ID that will be shared with other applications. By default, Android assigns each application its own unique user ID. However, if this attribute is set to the same value for two or more applications, they will all share the same ID — provided that they are also signed by the same certificate. Application with the same user ID can access each other's data and, if desired, run in the same process.How to implement: add this line to the androidManifest.xml: "android:sharedUserId="com.cwli"
    My thoughts: Thus when 2 apps have the same UID, they could run in the same process


    An Android app does not have permissions unless you set them in the Androidmanifest.xml file. An app can enforce their own permissions that are not found in manifest.permission.

    Quotes from Android Security Overview | Android Open Source
    Android application runtime: "Applications are sandboxed at kernel level..."

    Filesystem permissions: "In a UNIX-style environment, filesystem permissions ensure that one user cannot alter or read another user's files. In the case of Android, each application runs as its own user. Unless the developer explicitly exposes files to other applications, files created by one application cannot be read or altered by another application." My thought: It's possible to create a file in Android filesystem and then give other apps permission to read it.
    From the link Is it possible to access the SQLite-database of an Android-app on my phone? - Stack Overflow, the database is stored in "/data/data/your.applications.package/databases" This means I could let a 2nd app gain access if I set the same UID?

    Did I miss some important fact and/or is my last assumption possible? (based on security perhaps
    not the best way)
     
  6. jiminaus

    jiminaus Well-Known Member
    Rank:
    None
    Points:
    63
    Posts:
    190
    Joined:
    Oct 27, 2011

    Oct 27, 2011
    190
    36
    63
    Sydney, Australia
    Yes. But the name doesn't relate to Java packages. It'll effectively become a Linux user. So I would advised against dots in the name. Perhaps, cwliappsuite or cwli_app_suite.


    Yes.


    The security in AndroidManifest.xml is really just about filesystem and process security by way of sharing of user IDs. Manifest.permission file is about access to the features of the Android platform. I can't see a way to extend this to something like "this app by developer X can access this other app's data by developer A".


    Possibly. I've not investigated this.

    At the most basic, you can make a file or database world readable and/or world writable via the flags parameter of android.content.Context#openFileOutput(String, int) or android.content.Context#openOrCreateDatabase(String, int, SQLiteDatabase.CursorFactory).

    If you want finer-grain control, then this could be more difficult.

    On Linux, if you wanted to 2 users to be able to shared files, you'd create a Unix group and added the 2 users to that group. You'd then set the group of those files to be this new Unix group and get the file group file permission to be group readable (and writeable, if appropriate).

    Again on Linux, if the filesystem support ACLs you grant and revoke permissions to files by adding ACLs.

    But you can't create groups on Android and you can't can users to groups on Android. And I don't know of a way to manipulate either traditional UNIX file permissions or ACLs via the Android Java API.


    Yes. But don't forget both apps need to signed with the same certificate.
     
  7. chihwahli

    chihwahli Newbie
    Thread Starter
    Rank:
    None
    Points:
    35
    Posts:
    13
    Joined:
    Jan 4, 2012

    Jan 4, 2012
    13
    0
    35
  8. chihwahli

    chihwahli Newbie
    Thread Starter
    Rank:
    None
    Points:
    35
    Posts:
    13
    Joined:
    Jan 4, 2012

    Jan 4, 2012
    13
    0
    35
    Tried internal storage. I have 2 sample apps:
    1) Creates the internal storage, it's a variable. The same program opens this
    variable and prints it's contains to logcat. (to verify it can be written /
    read)
    2) The 2nd app tries to read from this variable.

    Remark: I did not use UID. (and every apk file gets signed with it's own UID)
    Internal storage code is partly from: http://developer.android.com/guide/topics/data/datastorage.html#filesInternal

    Question 1: How come I can access the variable?


    I used openFileInput. Could it be that a file is created on the SD. That explains it why it could be accessed. I tried adb shell and went into a few directories, but could not find the file. Any help is appreciated!

    Code (Text):
    1.  
    2.  
    3. package com.cwli;
    4.  
    5. import java.io.BufferedReader;
    6. import java.io.FileInputStream;
    7. import java.io.FileNotFoundException;
    8. import java.io.FileOutputStream;
    9. import java.io.IOException;
    10. import java.io.InputStream;
    11. import java.io.InputStreamReader;
    12.  
    13. import android.app.Activity;
    14. import android.content.Context;
    15. import android.content.ContextWrapper;
    16. import android.os.Bundle;
    17.  
    18. public class Internal_storage_create_readActivity extends Activity {
    19.     private static final String IDS_LIST_FILE_NAME = null;
    20.  
    21.     /** Called when the activity is first created. */
    22.     @Override
    23.     public void onCreate(Bundle savedInstanceState) {
    24.         super.onCreate(savedInstanceState);
    25.         setContentView(R.layout.main);
    26.        
    27.         try {
    28.             createReadStorage();
    29.         } catch (FileNotFoundException e) {
    30.             // TODO Auto-generated catch block
    31.             e.printStackTrace();
    32.         } catch (IOException e) {
    33.             // TODO Auto-generated catch block
    34.             e.printStackTrace();
    35.         }
    36.     }
    37.    
    38.     public void createReadStorage() throws IOException
    39.     {
    40.         String FILENAME = "hello_file";
    41.         String string = "hello from internal..storage!";
    42.  
    43.         FileOutputStream fos = null;
    44.         try {
    45.             fos = openFileOutput(FILENAME, Context.MODE_PRIVATE);
    46.         } catch (FileNotFoundException e) {
    47.             // TODO Auto-generated catch block
    48.             e.printStackTrace();
    49.         }
    50.         try {
    51.             fos.write(string.getBytes());
    52.         } catch (IOException e) {
    53.             // TODO Auto-generated catch block
    54.             e.printStackTrace();            
    55.         }
    56.        
    57.         try {
    58.             fos.close();
    59.         } catch (IOException e) {
    60.             // TODO Auto-generated catch block
    61.             e.printStackTrace();
    62.         }
    63.        
    64.          InputStream instream = openFileInput(FILENAME);
    65.  
    66.             if (instream != null) {
    67.                 // prepare the file for reading
    68.                 InputStreamReader inputreader = new InputStreamReader(instream);
    69.                 BufferedReader buffreader = new BufferedReader(inputreader);
    70.  
    71.                 String line;
    72.  
    73.                 // read every line of the file into the line-variable, on line at the time
    74.                 while (( line = buffreader.readLine()) != null) {
    75.                     System.out.println("--------------------------------");
    76.                     System.out.println(line);
    77.                     System.out.println("--------------------------------");
    78.                 }
    79.  
    80.               }
    81.  
    82.        
    83.        
    84.     }
    85. }
    86.  
    87.  

    Code (Text):
    1.  
    2.  
    3. package com.cwli;
    4.  
    5. import java.io.BufferedReader;
    6. import java.io.FileNotFoundException;
    7. import java.io.IOException;
    8. import java.io.InputStream;
    9. import java.io.InputStreamReader;
    10.  
    11. import android.app.Activity;
    12. import android.os.Bundle;
    13.  
    14. public class Internal_storage_readActivity extends Activity {
    15.     /** Called when the activity is first created. */
    16.     @Override
    17.     public void onCreate(Bundle savedInstanceState) {
    18.         super.onCreate(savedInstanceState);
    19.         setContentView(R.layout.main);
    20.        
    21.         try {
    22.             lezen();
    23.         } catch (IOException e) {
    24.             // TODO Auto-generated catch block
    25.             e.printStackTrace();
    26.         }
    27.     }
    28.    
    29.     public void lezen() throws IOException
    30.     {
    31.    
    32.     String FILENAME = "hello_file";
    33.     InputStream instream = openFileInput(FILENAME);
    34.  
    35.     if (instream != null)
    36.     {
    37.         // prepare the file for reading
    38.         InputStreamReader inputreader = new InputStreamReader(instream);
    39.         BufferedReader buffreader = new BufferedReader(inputreader);
    40.  
    41.         String line;
    42.  
    43.         // read every line of the file into the line-variable, on line at the time
    44.         while (( line = buffreader.readLine()) != null)
    45.         {
    46.             System.out.println("--------------------------------");
    47.             System.out.println(line);
    48.             System.out.println("--------------------------------");
    49.         }
    50.  
    51.    
    52.        
    53.         }
    54.     }
    55. }
    56.  
    57.  
     
  9. jiminaus

    jiminaus Well-Known Member
    Rank:
    None
    Points:
    63
    Posts:
    190
    Joined:
    Oct 27, 2011

    Oct 27, 2011
    190
    36
    63
    Sydney, Australia
    Please edit the post above and surround your code with [CODE] ... [/CODE] tags so your code is readable.

    The easiest way to do this is to highlight the code and then click the # button in the post editor's toolbar.
     
  10. chihwahli

    chihwahli Newbie
    Thread Starter
    Rank:
    None
    Points:
    35
    Posts:
    13
    Joined:
    Jan 4, 2012

    Jan 4, 2012
    13
    0
    35
    The code tags are added.
     
  11. jiminaus

    jiminaus Well-Known Member
    Rank:
    None
    Points:
    63
    Posts:
    190
    Joined:
    Oct 27, 2011

    Oct 27, 2011
    190
    36
    63
    Sydney, Australia
    You did ask before somewhere where the file was stored. For me, on Android 4.0.1, the file was stored in /data/data/com.cwli/files/hello_file.

    It can't be that came for me that the file is being created on an SD card, because my Galaxy Nexus doesn't have an SD card and all its file systems (including the "fake" /mnt/sdcard file system) support file permissions.

    Yet when I run your code, it does work as you say.

    However if I change the package in AndroidManifest.xml of the second app, the second app does fail with access denied.

    That doesn't make sense to me. Even if two apps are in the same package, they shouldn't be able to access each others data.
     
  12. chihwahli

    chihwahli Newbie
    Thread Starter
    Rank:
    None
    Points:
    35
    Posts:
    13
    Joined:
    Jan 4, 2012

    Jan 4, 2012
    13
    0
    35
    Thanks for verifying jiminaus. <thumbs up>.

    I searched and found this link: Android package security - Stack Overflow

    It seems I read wrongly or posts on internet about UID are not always right and contributed to my confusion. As you (jiminaus) have tested, if you change the Android packet name, you could not access the data of the other app, but if you changed both to the same packet name, you could.

    Thus at this moment I guess that the same UID is given based on the same packet name. Packets with the same packet name in the AndroidManifest.xml , all get the same UID.....? Thus "all apps/apk files get a different UID, seems to be wrong perhaps...

    Going to try something out....
     
  13. chihwahli

    chihwahli Newbie
    Thread Starter
    Rank:
    None
    Points:
    35
    Posts:
    13
    Joined:
    Jan 4, 2012

    Jan 4, 2012
    13
    0
    35
    More info about the previous two apps.

    Logcat from my create internal storage app:
    I/ActivityManager( 91): Start proc com.cwli for activity com.cwli/.Internal_storage_create_readActivity: pid=643 uid=10044 gids={}
    remark: The UID is 10044 and proces ID is 643

    Logcat from my read app:
    I/ActivityManager( 91): Start proc com.cwli for activity com.cwli/.Internal_storage_readActivity: pid=713 uid=10044 gids={}
    W/NetworkManagementSocketTagger( 91): setKernelCountSet(10044, 1) failed with errno -2
    I/System.out( 713): --------------------------------
    I/System.out( 713): hello from internal..storage!
    I/System.out( 713): --------------------------------
    D/gralloc_goldfish( 713): Emulator without GPU emulation detected.
    remark: As you can see the uid is 10044 with the proces ID 713

    So this confirms that both apps are really running with the same UID, and thus can access eachothers data. Do notice that they have different process ID's..... As far as I know, program would not be able to access eachothers data, because they are a different process. Threads on the other hand can access eachothers data, because they share the same memory space.

    Going to try:
    - different package name and try to read data, check UID, if it's really different.
    - What if UID is different and PID is the same. Any prog running as the same process, would be able to access eachothers data, or is Android different?
     
  14. chihwahli

    chihwahli Newbie
    Thread Starter
    Rank:
    None
    Points:
    35
    Posts:
    13
    Joined:
    Jan 4, 2012

    Jan 4, 2012
    13
    0
    35
    3rd app just reads like the 2nd app, but changed the packet name from com.cwli to com.ccc. Now it looks in a different directory and the UID is different as you could see below:

    I/ActivityManager( 77): Start proc com.ccc for activity com.ccc/.Internal_storage_read_different_packagenameActivity: pid=674 uid=10045 gids={}
    W/NetworkManagementSocketTagger( 77): setKernelCountSet(10045, 1) failed with errno -2
    D/dalvikvm( 233): GC_CONCURRENT freed 310K, 5% free 9494K/9927K, paused 3ms+5ms
    W/System.err( 674): java.io.FileNotFoundException: /data/data/com.ccc/files/hello_file: open failed: ENOENT (No such file or directory)

    Result: Indeed. cannot access the file. Because it's running in it's own memory space...

    4th app:
    - different package names
    - used same sharedUserId: android:sharedUserId="com.bread"


    Result: app did not install:

    D/AndroidRuntime( 916): Shutting down VM
    W/dalvikvm( 916): threadid=1: thread exiting with uncaught exception (group=0x409c01f8)
    E/AndroidRuntime( 916): FATAL EXCEPTION: main
    E/AndroidRuntime( 916): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.cwli/com.cwli.Internal_storage_create_UID1Activity}: java.lang.NullPointerException

    Althought it's clear how to run apps under de same UID, the use of android:sharedUserId eludes me still. Why does it not install when I set sharedUserID?
     
  15. jiminaus

    jiminaus Well-Known Member
    Rank:
    None
    Points:
    63
    Posts:
    190
    Joined:
    Oct 27, 2011

    Oct 27, 2011
    190
    36
    63
    Sydney, Australia
    Process IDs (PIDs) are just a runtime number. Every process that runs get's its own ID. Every time you run an app, it will get a different PID.

    But you're right that if your apps are running literally at the same time, and you see the same PID then yes they are running in the same Java virtual machine in the same memory space.

    However, this is not a requirement to being able to access each other's files. The only requirement is that they have the same UID, so that the filesystem permission checks pass.


    Do you also notice that you can't have multiple apps with the same package installed at the same time? I didn't notice it as first, but when I ran your second app, it replaced the first app. It looks from Android's perspective, that the second app was an some kind of upgrade or replacement to first app. This explains why the two apps got the same UID without sharedUserId.


    Your third app couldn't access the file because the file didn't exist, not because access was denied. However, if you hardcoded the file path in your third app to the file created by your first app, I think your third app would be denied access.


    For sharedUserId to work, both your first app and your fourth app need to have this same attribute with the same value. Don't use dots in the name. This name has nothing to do with Java packages, it's ultimately related to Linux usernames.

    Remove your first app. Then install and run your first app after adding sharedUserId. Then install and run your fourth app after updating its sharedUserId to match the value of your first app's sharedUserId. Now your fourth app should run under the same UID as your first app be able to access each other's file.
     
  16. chihwahli

    chihwahli Newbie
    Thread Starter
    Rank:
    None
    Points:
    35
    Posts:
    13
    Joined:
    Jan 4, 2012

    Jan 4, 2012
    13
    0
    35
    Hmm, Android SDK gives an error if I don't use the dots.

    The logcat error:
    ): <manifest> specifies bad sharedUserId name "com_bread": must have at least one '.' separator
     
  17. chihwahli

    chihwahli Newbie
    Thread Starter
    Rank:
    None
    Points:
    35
    Posts:
    13
    Joined:
    Jan 4, 2012

    Jan 4, 2012
    13
    0
    35
    Thank you jiminaus for pointing out a few things. I understand this better now. Thursday I will give a presentation with others about Android programming (SDK - NDK) Finishing the last few things and make presentation sheets. By the way: Wish you (and other readers a very good 2012 amen!
     

Share This Page

Loading...