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


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

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

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

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

dengpei@dengpei-pc:~$ adb shell
# cd /mnt/sdcard
# ls -al |grep "fileForTestRight.txt"
----rwxr-x    1 system   sdcard_rw         0 Jan 18 11:20 fileForTestRight.txt
# whoami
root
# 

文件

fileForTestRight.txt

权限:

system     --x

sdcard_r rwx

other        r_x


sdcrad 文件 权限定义由VoId 设置

gingerbread/system/vold/Volume.cpp


int Volume::mountVol() {
    dev_t deviceNodes[4];
    int n, i, rc = 0;
    char errmsg[255];

    if (getState() == Volume::State_NoMedia) {
        snprintf(errmsg, sizeof(errmsg),
                 "Volume %s %s mount failed - no media",
                 getLabel(), getMountpoint());
        mVm->getBroadcaster()->sendBroadcast(
                                         ResponseCode::VolumeMountFailedNoMedia,
                                         errmsg, false);
        errno = ENODEV;
        return -1;
    } else if (getState() != Volume::State_Idle) {
        errno = EBUSY;
        return -1;
    }

    if (isMountpointMounted(getMountpoint())) {
        SLOGW("Volume is idle but appears to be mounted - fixing");
        setState(Volume::State_Mounted);
        // mCurrentlyMountedKdev = XXX
        return 0;
    }

    n = getDeviceNodes((dev_t *) &deviceNodes, 4);
    if (!n) {
        SLOGE("Failed to get device nodes (%s)\n", strerror(errno));
        return -1;
    }

    for (i = 0; i < n; i++) {
        char devicePath[255];

        sprintf(devicePath, "/dev/block/vold/%d:%d", MAJOR(deviceNodes[i]),
                MINOR(deviceNodes[i]));

        SLOGI("%s being considered for volume %s\n", devicePath, getLabel());

        errno = 0;
        setState(Volume::State_Checking);

        if (Fat::check(devicePath)) {
            if (errno == ENODATA) {
                SLOGW("%s does not contain a FAT filesystem\n", devicePath);
                continue;
            }
            errno = EIO;
            /* Badness - abort the mount */
            SLOGE("%s failed FS checks (%s)", devicePath, strerror(errno));
            setState(Volume::State_Idle);
            return -1;
        }

        /*
         * Mount the device on our internal staging mountpoint so we can
         * muck with it before exposing it to non priviledged users.
         */
        errno = 0;
        if (Fat::doMount(devicePath, "/mnt/secure/staging", false, false, false,
                1000, 1015, 0702, true)) {
            SLOGE("%s failed to mount via VFAT (%s)\n", devicePath, strerror(errno));
            continue;
        }

        SLOGI("Device %s, target %s mounted @ /mnt/secure/staging", devicePath, getMountpoint());

        protectFromAutorunStupidity();

        if (createBindMounts()) {
            SLOGE("Failed to create bindmounts (%s)", strerror(errno));
            umount("/mnt/secure/staging");
            setState(Volume::State_Idle);
            return -1;
        }

        /*
         * Now that the bindmount trickery is done, atomically move the
         * whole subtree to expose it to non priviledged users.
         */
        if (doMoveMount("/mnt/secure/staging", getMountpoint(), false)) {
            SLOGE("Failed to move mount (%s)", strerror(errno));
            umount("/mnt/secure/staging");
            setState(Volume::State_Idle);
            return -1;
        }
        setState(Volume::State_Mounted);
        mCurrentlyMountedKdev = deviceNodes[i];
        return 0;
    }

    SLOGE("Volume %s found no suitable devices for mounting :(\n", getLabel());
    setState(Volume::State_Idle);

    return -1;
}

doMount(devicePath, "/mnt/secure/staging", false, false, false,
                1000, 1015, 0702, true)

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

继续查看:

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

/* This is the master Users and Groups config for the platform.
** DO NOT EVER RENUMBER.
*/

#define AID_ROOT             0  /* traditional unix root user */

#define AID_SYSTEM        1000  /* system server */

#define AID_RADIO         1001  /* telephony subsystem, RIL */
#define AID_BLUETOOTH     1002  /* bluetooth subsystem */
#define AID_GRAPHICS      1003  /* graphics devices */
#define AID_INPUT         1004  /* input devices */
#define AID_AUDIO         1005  /* audio devices */
#define AID_CAMERA        1006  /* camera devices */
#define AID_LOG           1007  /* log devices */
#define AID_COMPASS       1008  /* compass device */
#define AID_MOUNT         1009  /* mountd socket */
#define AID_WIFI          1010  /* wifi subsystem */
#define AID_ADB           1011  /* android debug bridge (adbd) */
#define AID_INSTALL       1012  /* group for installing packages */
#define AID_MEDIA         1013  /* mediaserver process */
#define AID_DHCP          1014  /* dhcp client */
#define AID_SDCARD_RW     1015  /* external storage write access */
#define AID_VPN           1016  /* vpn system */
#define AID_KEYSTORE      1017  /* keystore subsystem */
#define AID_USB           1018  /* USB devices */
#define AID_GPS           1021  /* GPS daemon */
#define AID_UNUSED1       1022  /* deprecated, DO NOT USE */
#define AID_RFU1          1023  /* RFU */
#define AID_RFU2          1024  /* RFU */
#define AID_NFC           1025  /* nfc subsystem */

#define AID_SHELL         2000  /* adb and debug shell user */
#define AID_CACHE         2001  /* cache access */
#define AID_DIAG          2002  /* access to diagnostic resources */

/* The 3000 series are intended for use as supplemental group id's only.
 * They indicate special Android capabilities that the kernel is aware of. */
#define AID_NET_BT_ADMIN  3001  /* bluetooth: create any socket */
#define AID_NET_BT        3002  /* bluetooth: create sco, rfcomm or l2cap sockets */
#define AID_INET          3003  /* can create AF_INET and AF_INET6 sockets */
#define AID_NET_RAW       3004  /* can create raw INET sockets */
#define AID_NET_ADMIN     3005  /* can configure interfaces and routing tables. */

#define AID_MISC          9998  /* access to misc storage */
#define AID_NOBODY        9999

#define AID_APP          10000 /* first app user */

可知 

AID_SYSTEM        1000  /* system server */
AID_SDCARD_RW     1015 /* external storage write access */
AID_APP          10000 /* first app user */


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

并记录在

# ls
accounts.db                       packages.xml
appwidgets.xml                    password.key
batterystats.bin                  registered_services
called_pre_boots.dat              shared_prefs
cameraCalFile.bin                 sync
confirmed_package_behavior.authz  theme
confirmed_package_behavior.log    throttle
customized_icons_1                trafficstats.bin
device_policies.xml               uiderrors.txt
dropbox                           usagestats
entropy.dat                       wallpaper_info.xml
gesture.key                       wallpapers
packages.list
# pwd
/data/system
# 

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

<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">
<sigs count="1">
<cert index="34" />
</sigs>
<perms>
<item name="android.permission.WRITE_EXTERNAL_STORAGE" />
</perms>


查看 data/data/app目录

# pwd
/data/data
# cd com.pathfindeng.test
# ls -al
drwxr-x--x    4 app_137  app_137       4096 Jan 18 11:20 .
drwxrwx--x  175 system   system       12288 Jan 18 10:51 ..
drwxr-xr-x    2 system   system        4096 Jan 18 11:20 lib
drwxrwx--x    2 app_137  app_137       4096 Jan 18 10:51 shared_prefs
# cd shar*
# ls -al
drwxrwx--x    2 app_137  app_137       4096 Jan 18 10:51 .
drwxr-x--x    4 app_137  app_137       4096 Jan 18 11:20 ..
-rw-rw----    1 app_137  app_137        112 Jan 18 10:51 MODE_APPEND.xml
-rw-rw----    1 app_137  app_137        113 Jan 18 10:51 MODE_PRIVATE.xml
-rw-rw-r--    1 app_137  app_137        120 Jan 18 10:51 MODE_WORLD_READABLE.xml
-rw-rw--w-    1 app_137  app_137        121 Jan 18 10:51 MODE_WORLD_WRITEABLE.xml

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

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

AppRightActivity.java

package com.pathfindeng.test;

import java.io.File;
import java.io.IOException;

import android.app.Activity;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.widget.Toast;

public class AppRightActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        setSharedPreferencesData();
        
    }
    
    
    public void setSdcardData(){
    	File sdcard = Environment.getExternalStorageDirectory();
    	
    	String[] fileNames = sdcard.list();
    	
    	
    	Log.d("pathfindeng","fileNames.length is "+fileNames.length);
    	
    	
    	File testRight = new File(sdcard, "fileForTestRight.txt");
    	
    	if(testRight.exists()){
    		testRight.delete();
    		Log.d("pathfindeng","delete file ok");
    	}else{
    		try {
				testRight.createNewFile();
				Log.d("pathfindeng","create file ok");
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
    	}
    	
    	Log.d("pathfindeng", testRight.canRead()+""+testRight.canWrite()+""+testRight.canExecute());
    	
    }
    
    
    public void setSharedPreferencesData (){
    	SharedPreferences mSharedPreferences;
    	Editor mEditor;
    	//
    	mSharedPreferences = getSharedPreferences("MODE_PRIVATE",MODE_PRIVATE);
    	
    	mEditor = mSharedPreferences.edit();
    	
    	mEditor.putString("right", "MODE_PRIVATE");
    	
    	mEditor.commit();
    	
    	//
    	mSharedPreferences = getSharedPreferences("MODE_WORLD_READABLE",MODE_WORLD_READABLE);
    	
    	mEditor = mSharedPreferences.edit();
    	
    	mEditor.putString("right", "MODE_WORLD_READABLE");
    	
    	mEditor.commit();
    	
    	//
    	mSharedPreferences = getSharedPreferences("MODE_WORLD_WRITEABLE",MODE_WORLD_WRITEABLE);
    	
    	mEditor = mSharedPreferences.edit();
    	
    	mEditor.putString("right", "MODE_WORLD_WRITEABLE");
    	
    	mEditor.commit();
    	
    	//
    	mSharedPreferences = getSharedPreferences("MODE_APPEND",MODE_APPEND);
    	
    	mEditor = mSharedPreferences.edit();
    	
    	mEditor.putString("right", "MODE_APPEND");
    	
    	mEditor.commit();
    	
    }

	/* (non-Javadoc)
	 * @see android.app.Activity#onResume()
	 */
	@Override
	protected void onResume() {
		// TODO Auto-generated method stub
		super.onResume();
		
		setSdcardData();
	}

	/* (non-Javadoc)
	 * @see android.app.Activity#onDestroy()
	 */
	@Override
	protected void onDestroy() {
		// TODO Auto-generated method stub
		super.onDestroy();
	}
    
    
    
}

manifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.pathfindeng.test"
    android:versionCode="1"
    android:versionName="1.0">

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

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <activity
            android:label="@string/app_name"
            android:name=".AppRightActivity" >
            <intent-filter >
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

继续查看

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

    <permission name="android.permission.WRITE_EXTERNAL_STORAGE" >
        <group gid="sdcard_rw" />
    </permission>

应用申请
WRITE_EXTERNAL_STORAGE
权限时

即拥有

sdcard_rw
组权限。

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



  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值