I found the following in the run-as code:
/* check that the data directory path is valid */
if (check_data_path(info.dataDir, info.uid) < 0) {
panic("Package '%s' has corrupt installation\n", pkgname);
return 1;
}
And the code of check_data_path and check_directory_ownership:
/* This function is used to check the data directory path for safety.
* We check that every sub-directory is owned by the 'system' user
* and exists and is not a symlink. We also check that the full
directory
* path is properly owned by the user ID.
*
* Return 0 on success, -1 on error.
*/
int
check_data_path(const char* dataPath, uid_t uid)
{
int nn;
/* the path should be absolute */
if (dataPath[0] != '/') {
errno = EINVAL;
return -1;
}
/* look for all sub-paths, we do that by finding
* directory separators in the input path and
* checking each sub-path independently
*/
for (nn = 1; dataPath[nn] != '\0'; nn++)
{
char subpath[PATH_MAX];
/* skip non-separator characters */
if (dataPath[nn] != '/')
continue;
/* handle trailing separator case */
if (dataPath[nn+1] == '\0') {
break;
}
/* found a separator, check that dataPath is not too long. */
if (nn >= (int)(sizeof subpath)) {
errno = EINVAL;
return -1;
}
/* reject any '..' subpath */
if (nn >= 3 &&
dataPath[nn-3] == '/' &&
dataPath[nn-2] == '.' &&
dataPath[nn-1] == '.') {
errno = EINVAL;
return -1;
}
/* copy to 'subpath', then check ownership */
memcpy(subpath, dataPath, nn);
subpath[nn] = '\0';
if (check_directory_ownership(subpath, AID_SYSTEM) < 0)
return -1;
}
/* All sub-paths were checked, now verify that the full data
* directory is owned by the application uid
*/
if (check_directory_ownership(dataPath, uid) < 0)
return -1;
/* all clear */
return 0;
}
/* Check that a given directory:
* - exists
* - is owned by a given uid/gid
* - is a real directory, not a symlink
* - isn't readable or writable by others
*
* Return 0 on success, or -1 on error.
* errno is set to EINVAL in case of failed check.
*/
static int
check_directory_ownership(const char* path, uid_t uid)
{
int ret;
struct stat st;
do {
ret = lstat(path, &st);
} while (ret < 0 && errno == EINTR);
if (ret < 0)
return -1;
/* must be a real directory, not a symlink */
if (!S_ISDIR(st.st_mode))
goto BAD;
/* must be owned by specific uid/gid */
if (st.st_uid != uid || st.st_gid != uid)
goto BAD;
/* must not be readable or writable by others */
if ((st.st_mode & (S_IROTH|S_IWOTH)) != 0)
goto BAD;
/* everything ok */
return 0;
BAD:
errno = EINVAL;
return -1;
}
When I extract system info, I obtain this:
Package [com.test] (469ddc60):
userId=10024 gids=[3002, 3001, 1006, 3003, 1007, 1015]
sharedUser=null
pkg=Package{4668fae8 com.test}
codePath=/data/app/com.test-2.apk
resourcePath=/data/app/com.test-2.apk
dataDir=/data/data/com.test
targetSdk=8
supportsScreens=[medium, large, small, resizeable, anyDensity]
timeStamp=1282493767000
signatures=PackageSignatures{466ac6f0 [466dbb48]}
permissionsFixed=true haveGids=true
pkgFlags=0x0 installStatus=1 enabled=0
grantedPermissions:
android.permission.WRITE_OWNER_DATA
... (I granted all permissions)
Here is an extract of my /data/data dir
drwxr-x--x app_24 app_24 2010-08-22 18:10 com.test
...
I can't see what's wrong. From Eclipse Android File Explorer view (if
that's the right place) it looks like the data dir is empty and no
right is given to others. Anyone has an idea?
So it looks like the