android sdcard文件访问权限与apk应用 userid 访问权限的关系。

时间:2021-09-28 12:50:16

分类: Android   5302人阅读  评论(0)  收藏  举报


问题:应用在AndroidManifest.xml 文件 申请WRITE_EXTERNAL_STORAGE 权限即可对sdcard 下文件进行操作。

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

应用的用户id 和所属组是什么?

adb shell 查看 sdcard 文件读写执行权限:

[plain]  view plain copy
  1. dengpei@dengpei-pc:~$ adb shell  
  2. # cd /mnt/sdcard  
  3. # ls -al |grep "fileForTestRight.txt"  
  4. ----rwxr-x    1 system   sdcard_rw         0 Jan 18 11:20 fileForTestRight.txt  
  5. # whoami  
  6. root  
  7. #   

文件 

fileForTestRight.txt

权限:

system     --x

sdcard_r rwx

other        r_x


sdcrad 文件 权限定义由VoId 设置

gingerbread/system/vold/Volume.cpp


[cpp]  view plain copy
  1. int Volume::mountVol() {  
  2.     dev_t deviceNodes[4];  
  3.     int n, i, rc = 0;  
  4.     char errmsg[255];  
  5.   
  6.     if (getState() == Volume::State_NoMedia) {  
  7.         snprintf(errmsg, sizeof(errmsg),  
  8.                  "Volume %s %s mount failed - no media",  
  9.                  getLabel(), getMountpoint());  
  10.         mVm->getBroadcaster()->sendBroadcast(  
  11.                                          ResponseCode::VolumeMountFailedNoMedia,  
  12.                                          errmsg, false);  
  13.         errno = ENODEV;  
  14.         return -1;  
  15.     } else if (getState() != Volume::State_Idle) {  
  16.         errno = EBUSY;  
  17.         return -1;  
  18.     }  
  19.   
  20.     if (isMountpointMounted(getMountpoint())) {  
  21.         SLOGW("Volume is idle but appears to be mounted - fixing");  
  22.         setState(Volume::State_Mounted);  
  23.         // mCurrentlyMountedKdev = XXX  
  24.         return 0;  
  25.     }  
  26.   
  27.     n = getDeviceNodes((dev_t *) &deviceNodes, 4);  
  28.     if (!n) {  
  29.         SLOGE("Failed to get device nodes (%s)\n", strerror(errno));  
  30.         return -1;  
  31.     }  
  32.   
  33.     for (i = 0; i < n; i++) {  
  34.         char devicePath[255];  
  35.   
  36.         sprintf(devicePath, "/dev/block/vold/%d:%d", MAJOR(deviceNodes[i]),  
  37.                 MINOR(deviceNodes[i]));  
  38.   
  39.         SLOGI("%s being considered for volume %s\n", devicePath, getLabel());  
  40.   
  41.         errno = 0;  
  42.         setState(Volume::State_Checking);  
  43.   
  44.         if (Fat::check(devicePath)) {  
  45.             if (errno == ENODATA) {  
  46.                 SLOGW("%s does not contain a FAT filesystem\n", devicePath);  
  47.                 continue;  
  48.             }  
  49.             errno = EIO;  
  50.             /* Badness - abort the mount */  
  51.             SLOGE("%s failed FS checks (%s)", devicePath, strerror(errno));  
  52.             setState(Volume::State_Idle);  
  53.             return -1;  
  54.         }  
  55.   
  56.         /* 
  57.          * Mount the device on our internal staging mountpoint so we can 
  58.          * muck with it before exposing it to non priviledged users. 
  59.          */  
  60.         errno = 0;  
  61.         if (Fat::doMount(devicePath, "/mnt/secure/staging"falsefalsefalse,  
  62.                 1000, 1015, 0702, true)) {  
  63.             SLOGE("%s failed to mount via VFAT (%s)\n", devicePath, strerror(errno));  
  64.             continue;  
  65.         }  
  66.   
  67.         SLOGI("Device %s, target %s mounted @ /mnt/secure/staging", devicePath, getMountpoint());  
  68.   
  69.         protectFromAutorunStupidity();  
  70.   
  71.         if (createBindMounts()) {  
  72.             SLOGE("Failed to create bindmounts (%s)", strerror(errno));  
  73.             umount("/mnt/secure/staging");  
  74.             setState(Volume::State_Idle);  
  75.             return -1;  
  76.         }  
  77.   
  78.         /* 
  79.          * Now that the bindmount trickery is done, atomically move the 
  80.          * whole subtree to expose it to non priviledged users. 
  81.          */  
  82.         if (doMoveMount("/mnt/secure/staging", getMountpoint(), false)) {  
  83.             SLOGE("Failed to move mount (%s)", strerror(errno));  
  84.             umount("/mnt/secure/staging");  
  85.             setState(Volume::State_Idle);  
  86.             return -1;  
  87.         }  
  88.         setState(Volume::State_Mounted);  
  89.         mCurrentlyMountedKdev = deviceNodes[i];  
  90.         return 0;  
  91.     }  
  92.   
  93.     SLOGE("Volume %s found no suitable devices for mounting :(\n", getLabel());  
  94.     setState(Volume::State_Idle);  
  95.   
  96.     return -1;  
  97. }  

[cpp]  view plain copy
  1. doMount(devicePath, "/mnt/secure/staging"falsefalsefalse,  
  2.                 1000, 1015, 0702, true)  

定义 uid 1000 gid 1015 文件读写执行权限 为 0702 
即 075  ---rwxr-x

继续查看:

gingerbread/system/core/include/private/android_filesystem_config.h

[cpp]  view plain copy
  1. /* This is the master Users and Groups config for the platform. 
  2. ** DO NOT EVER RENUMBER. 
  3. */  
  4.   
  5. #define AID_ROOT             0  /* traditional unix root user */  
  6.   
  7. #define AID_SYSTEM        1000  /* system server */  
  8.   
  9. #define AID_RADIO         1001  /* telephony subsystem, RIL */  
  10. #define AID_BLUETOOTH     1002  /* bluetooth subsystem */  
  11. #define AID_GRAPHICS      1003  /* graphics devices */  
  12. #define AID_INPUT         1004  /* input devices */  
  13. #define AID_AUDIO         1005  /* audio devices */  
  14. #define AID_CAMERA        1006  /* camera devices */  
  15. #define AID_LOG           1007  /* log devices */  
  16. #define AID_COMPASS       1008  /* compass device */  
  17. #define AID_MOUNT         1009  /* mountd socket */  
  18. #define AID_WIFI          1010  /* wifi subsystem */  
  19. #define AID_ADB           1011  /* android debug bridge (adbd) */  
  20. #define AID_INSTALL       1012  /* group for installing packages */  
  21. #define AID_MEDIA         1013  /* mediaserver process */  
  22. #define AID_DHCP          1014  /* dhcp client */  
  23. #define AID_SDCARD_RW     1015  /* external storage write access */  
  24. #define AID_VPN           1016  /* vpn system */  
  25. #define AID_KEYSTORE      1017  /* keystore subsystem */  
  26. #define AID_USB           1018  /* USB devices */  
  27. #define AID_GPS           1021  /* GPS daemon */  
  28. #define AID_UNUSED1       1022  /* deprecated, DO NOT USE */  
  29. #define AID_RFU1          1023  /* RFU */  
  30. #define AID_RFU2          1024  /* RFU */  
  31. #define AID_NFC           1025  /* nfc subsystem */  
  32.   
  33. #define AID_SHELL         2000  /* adb and debug shell user */  
  34. #define AID_CACHE         2001  /* cache access */  
  35. #define AID_DIAG          2002  /* access to diagnostic resources */  
  36.   
  37. /* The 3000 series are intended for use as supplemental group id's only. 
  38.  * They indicate special Android capabilities that the kernel is aware of. */  
  39. #define AID_NET_BT_ADMIN  3001  /* bluetooth: create any socket */  
  40. #define AID_NET_BT        3002  /* bluetooth: create sco, rfcomm or l2cap sockets */  
  41. #define AID_INET          3003  /* can create AF_INET and AF_INET6 sockets */  
  42. #define AID_NET_RAW       3004  /* can create raw INET sockets */  
  43. #define AID_NET_ADMIN     3005  /* can configure interfaces and routing tables. */  
  44.   
  45. #define AID_MISC          9998  /* access to misc storage */  
  46. #define AID_NOBODY        9999  
  47.   
  48. #define AID_APP          10000 /* first app user */  

可知 

[cpp]  view plain copy
  1. AID_SYSTEM        1000  /* system server */  
[cpp]  view plain copy
  1. AID_SDCARD_RW     1015 /* external storage write access */  
[cpp]  view plain copy
  1. AID_APP          10000 /* first app user */  


每个 apk 安装时 PackageInstaller 都会分配一个 userid

并记录在 

[plain]  view plain copy
  1. # ls  
  2. accounts.db                       packages.xml  
  3. appwidgets.xml                    password.key  
  4. batterystats.bin                  registered_services  
  5. called_pre_boots.dat              shared_prefs  
  6. cameraCalFile.bin                 sync  
  7. confirmed_package_behavior.authz  theme  
  8. confirmed_package_behavior.log    throttle  
  9. customized_icons_1                trafficstats.bin  
  10. device_policies.xml               uiderrors.txt  
  11. dropbox                           usagestats  
  12. entropy.dat                       wallpaper_info.xml  
  13. gesture.key                       wallpapers  
  14. packages.list  
  15. # pwd  
  16. /data/system  
  17. #   

package.xml中,同时也包含 uses-permission 信息

[html]  view plain copy
  1. <package name="com.pathfindeng.test" codePath="/data/app/com.pathfindeng.test-1.apk" nativeLibraryPath="/data/data/com.pathfindeng.test/lib" flags="268435456" ft="134eed493a0" it="134eeba07a2" ut="134eed49801" version="1" userId="10137">  
  2. <sigs count="1">  
  3. <cert index="34" />  
  4. </sigs>  
  5. <perms>  
  6. <item name="android.permission.WRITE_EXTERNAL_STORAGE" />  
  7. </perms>  


查看 data/data/app目录

[plain]  view plain copy
  1. # pwd  
  2. /data/data  
  3. # cd com.pathfindeng.test  
  4. # ls -al  
  5. drwxr-x--x    4 app_137  app_137       4096 Jan 18 11:20 .  
  6. drwxrwx--x  175 system   system       12288 Jan 18 10:51 ..  
  7. drwxr-xr-x    2 system   system        4096 Jan 18 11:20 lib  
  8. drwxrwx--x    2 app_137  app_137       4096 Jan 18 10:51 shared_prefs  
  9. # cd shar*  
  10. # ls -al  
  11. drwxrwx--x    2 app_137  app_137       4096 Jan 18 10:51 .  
  12. drwxr-x--x    4 app_137  app_137       4096 Jan 18 11:20 ..  
  13. -rw-rw----    1 app_137  app_137        112 Jan 18 10:51 MODE_APPEND.xml  
  14. -rw-rw----    1 app_137  app_137        113 Jan 18 10:51 MODE_PRIVATE.xml  
  15. -rw-rw-r--    1 app_137  app_137        120 Jan 18 10:51 MODE_WORLD_READABLE.xml  
  16. -rw-rw--w-    1 app_137  app_137        121 Jan 18 10:51 MODE_WORLD_WRITEABLE.xml  

可以看出应用id 为137 其实为 10137. 及该用户权限,所属组权限。

该应用主要代码,及manifest文件

AppRightActivity.java

[java]  view plain copy
  1. package com.pathfindeng.test;  
  2.   
  3. import java.io.File;  
  4. import java.io.IOException;  
  5.   
  6. import android.app.Activity;  
  7. import android.content.SharedPreferences;  
  8. import android.content.SharedPreferences.Editor;  
  9. import android.os.Bundle;  
  10. import android.os.Environment;  
  11. import android.util.Log;  
  12. import android.widget.Toast;  
  13.   
  14. public class AppRightActivity 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.         setSharedPreferencesData();  
  21.           
  22.     }  
  23.       
  24.       
  25.     public void setSdcardData(){  
  26.         File sdcard = Environment.getExternalStorageDirectory();  
  27.           
  28.         String[] fileNames = sdcard.list();  
  29.           
  30.           
  31.         Log.d("pathfindeng","fileNames.length is "+fileNames.length);  
  32.           
  33.           
  34.         File testRight = new File(sdcard, "fileForTestRight.txt");  
  35.           
  36.         if(testRight.exists()){  
  37.             testRight.delete();  
  38.             Log.d("pathfindeng","delete file ok");  
  39.         }else{  
  40.             try {  
  41.                 testRight.createNewFile();  
  42.                 Log.d("pathfindeng","create file ok");  
  43.             } catch (IOException e) {  
  44.                 // TODO Auto-generated catch block  
  45.                 e.printStackTrace();  
  46.             }  
  47.         }  
  48.           
  49.         Log.d("pathfindeng", testRight.canRead()+""+testRight.canWrite()+""+testRight.canExecute());  
  50.           
  51.     }  
  52.       
  53.       
  54.     public void setSharedPreferencesData (){  
  55.         SharedPreferences mSharedPreferences;  
  56.         Editor mEditor;  
  57.         //  
  58.         mSharedPreferences = getSharedPreferences("MODE_PRIVATE",MODE_PRIVATE);  
  59.           
  60.         mEditor = mSharedPreferences.edit();  
  61.           
  62.         mEditor.putString("right""MODE_PRIVATE");  
  63.           
  64.         mEditor.commit();  
  65.           
  66.         //  
  67.         mSharedPreferences = getSharedPreferences("MODE_WORLD_READABLE",MODE_WORLD_READABLE);  
  68.           
  69.         mEditor = mSharedPreferences.edit();  
  70.           
  71.         mEditor.putString("right""MODE_WORLD_READABLE");  
  72.           
  73.         mEditor.commit();  
  74.           
  75.         //  
  76.         mSharedPreferences = getSharedPreferences("MODE_WORLD_WRITEABLE",MODE_WORLD_WRITEABLE);  
  77.           
  78.         mEditor = mSharedPreferences.edit();  
  79.           
  80.         mEditor.putString("right""MODE_WORLD_WRITEABLE");  
  81.           
  82.         mEditor.commit();  
  83.           
  84.         //  
  85.         mSharedPreferences = getSharedPreferences("MODE_APPEND",MODE_APPEND);  
  86.           
  87.         mEditor = mSharedPreferences.edit();  
  88.           
  89.         mEditor.putString("right""MODE_APPEND");  
  90.           
  91.         mEditor.commit();  
  92.           
  93.     }  
  94.   
  95.     /* (non-Javadoc) 
  96.      * @see android.app.Activity#onResume() 
  97.      */  
  98.     @Override  
  99.     protected void onResume() {  
  100.         // TODO Auto-generated method stub  
  101.         super.onResume();  
  102.           
  103.         setSdcardData();  
  104.     }  
  105.   
  106.     /* (non-Javadoc) 
  107.      * @see android.app.Activity#onDestroy() 
  108.      */  
  109.     @Override  
  110.     protected void onDestroy() {  
  111.         // TODO Auto-generated method stub  
  112.         super.onDestroy();  
  113.     }  
  114.       
  115.       
  116.       
  117. }  

manifest.xml

[html]  view plain copy
  1. <manifest xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     package="com.pathfindeng.test"  
  3.     android:versionCode="1"  
  4.     android:versionName="1.0">  
  5.   
  6.     <uses-sdk android:minSdkVersion="10" />  
  7.       
  8.     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />  
  9.   
  10.     <application  
  11.         android:icon="@drawable/ic_launcher"  
  12.         android:label="@string/app_name" >  
  13.         <activity  
  14.             android:label="@string/app_name"  
  15.             android:name=".AppRightActivity" >  
  16.             <intent-filter >  
  17.                 <action android:name="android.intent.action.MAIN" />  
  18.   
  19.                 <category android:name="android.intent.category.LAUNCHER" />  
  20.             </intent-filter>  
  21.         </activity>  
  22.     </application>  
  23.   
  24. </manifest>  

继续查看

/gingerbread/frameworks/base/data/etc/platform.xml

[html]  view plain copy
  1. <permission name="android.permission.WRITE_EXTERNAL_STORAGE" >  
  2.     <group gid="sdcard_rw" />  
  3. </permission>  

应用申请
[html]  view plain copy
  1. WRITE_EXTERNAL_STORAGE  
权限时

即拥有

[html]  view plain copy
  1. sdcard_rw  
组权限。

所以即可解答开篇提出的问题。