1

Something is basically pretty messed up on my phone. It looks like everything is running. But sometimes I can't open something or something crashes. The logcat shows a lot of permission denied.

A simple example is com.oneplus.calculator: I don't notice anything wrong when operating it. But in the Logcat I see:

09-25 14:42:35.662 29331 13606 E libEGL  : error opening cache file /data/user_de/0/com.oneplus.calculator/code_cache/com.android.skia.shaders_cache: Permission denied (13)
09-25 14:42:35.675 29331 13606 E libEGL  : error opening cache file /data/user_de/0/com.oneplus.calculator/code_cache/com.android.opengl.shaders_cache: Permission denied (13)

When comparing the DAC (Direct Access Control) with a healthy phone, I don't see any differences:

drwx------ 4 u0_a153 u0_a153 3488 2023-09-25 10:05 com.oneplus.calculator
    drwxrws--x 2 u0_a153 u0_a153_cache 3488 1971-12-27 23:26 cache
    drwxrws--x 2 u0_a153 u0_a153_cache 3488 2022-01-03 14:49 code_cache
        -r-------- 1 u0_a153 u0_a153_cache 113084 2023-07-10 15:31 com.android.opengl.shaders_cache
        -r-------- 1 u0_a153 u0_a153_cache  45136 2023-07-10 15:31 com.android.skia.shaders_cache

dumpsys package com.oneplus.calculator: userId=10153

ps -A | grep calculator: u0_a153 27212 993 6770376 106716 do_epoll_wait 0 S com.oneplus.calculator

In some cases it helps to simply delete the file in question. If it is recreated automatically then logcat is clean. Since DAC looks the same afterwards, I am assuming there is something else preventing the access.

I am quite lost when it comes to checking file/ambient capabilities, MAC and further permission control of the Android framework. How can I debug this? Is it possible to get more detailed information exactly what permission is denied?

Android 13, OnePlus 8 Pro IN2023

Any help would be appreciated, many thanks,
Zweikeks

1 Answer 1

1

Here's what I found out so far, correct me if I'm wrong.

File permissions of Android 13 on data partition

Permissions are stored in the inode of a file or directory.

  • ls -a and the like lists the traditional permissions.
  • lsattr is used to view the attributes. lsattr und chattr have been present on my OnePlus 8 Pro with Android 13 in /system/bin. (They only work with a supported file system, otherwise error 'Inappropriate ioctl for device'.)
  • getfattr is a general tool to look at the extended attributes - XATTR. (There are more specialized tools for specific attributes like getfacl, getcap, ls -Z etc.)
    Within Termux pkg install attr to get the tools getfattr and setfattr.
    (setfattr works only with a supported file system, otherwise error 'Operation not supported on transport endpoint'.)
    The use of getfattr is a bit clumsy. Per default it shows only the user namespace. To display all, the recommended way is
    getfattr -d -m ^ -- file_or_dir
    getfattr -d -m ^ -R -- file_or_dir      recursively
    (-m ^ matches start of any string without need for escaping the parameter, double dash -- is needed as a separator in case the filename or directory starts with a dash)

Linux implements a whole range of different permission concepts.

  • DAC, Discretionary Access Control, is the traditional Linux security with the rwx bits plus the more advanced features setuid, setgid, sticky.
    No differences compared to a working system. No change in behavior when I chmod 777 files and folders for testing.
  • ACL, Access Control Lists, as far as I read, are supposedly not used on Android.
    However, I had lots of ACL labels attached as XATTR. Only at /data/media/0 and below. Samba, while not configured to use ACL, labelled the top directory of the share with system.posix_acl_default. This has been inherited by all the files and directories below.
    setfattr doesn't work recursively by itself. So I used 'find' which also shows hidden files. I have deleted all the useless labels with:
    find 0 -exec setfattr -h -x system.posix_acl_default {} ;
    find 0 -exec setfattr -h -x system.posix_acl_access {} ;
    Not related to my problem, though.
  • Ambient capabilities are set in the /system/etc/init/*.rc for boot processes and services.
    They determine which processes can execute which functions and which resources are allowed to use.
    The content of /system/etc/init is identical on both systems. I don't think that this has anything to do with my problem.
  • Attributes attached to files.
    The man page of chattr lists all possible attributes. On the data partition there are mostly E (encrypted), I (indexed), N (inode data present), sometimes e (block extents). These are all characteristics how the file is stored, not typical permission control. Large amounts of files have the same attribute combination set.
    Only on four files I saw V (fs-verity) set.
    I didn't notice any relevant differences to the working system.
  • File Capabilities as XATTR attached to the files.
    A process's access rights are checked by the kernel against caps assigned to a file. File caps are stored in an encoded form. getcap can decipher it to a human readable form. They are stored in an extended attribute named security.capability.
    On my data partition I've not a single security.capability, though.
    What I have and where the value looks a bit like an encoded cap are attributes like:
    user.inode_cache=0szRUAAAAAAAA=
    user.inode_code_cache=0szhUAAAAAAAA=
    user.inode... is only attached to every app directory in /data/data and /data/user/0, nowhere else. I don't know what it is. The sequence of characters is different for every directory and different to the working system.
    Other interesting stuff:
    user.serial="0" attached to /data/data, /data/misc_ce/0, /data/system_ce/0, /data/system_de/0, /data/user/0, /data/user_de/0
    user.extdbsessionid0 and user.uuid attached to com.google.android.providers.media.module/databases/external.db in /data/data and /data/user/0
    user.extdbnextrowid0 and user.extdbsessionid0 attached to /data/media/0
    All the IDs are different to the working system.
  • MAC, Mandatory Access Control of SELinux, checks processes and file access based on central policies in /system/etc/selinux.
    The file context is attached as XATTR. To see with getfattr or simpler with ls -Z.
    cat /proc/kmsg | grep avc: displays SELinux log messages. These are routed to dmesg, and as far as I read, to logcat as well.
    cat /sys/fs/pstore/console-ramoops-0 | grep avc: supposedly displays messages from the previous boot.
    In my logs I have seen extremely few avc: messages. And none related to the error messages/crashes in the first post. Although setting the correct SELinux file context helped against the 'permission denied' error messages.
    There are a lot of differences in the file contexts to the working system. So I started out to correct individual folders and files e.g. with
    setfattr -n security.selinux -v u:object_r:app_data_file:s0:c153,c256,c512,c768 com.oneplus.calculator
    I figured out that I get the same result by using restorecon. It is used to correct wrong contexts. It restores the default context of files and directories based on the central SELinux policies.
    As of the documentation restorecon should actually work recursively with the -R parameter, but it did not. A construct with 'find' does the job:
    find com.oneplus.calculator -exec restorecon -v {} ;
    With that the permission denied errors no longer occur.
  • On top of all this we have the manifest-based permission control of Android apps in the Java framework. Stuff like ACCESS_FINE_LOCATION.

So in the end, setting the correct SELinux file context helped against the permission denied errors in my original post.
I'm still investigating this. Until now, I have not been so bold as to run restorecon over the entire data partition.

Best Regards,
Zweikeks

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .