-->

Android NDK open() device permission denied

2019-01-28 15:49发布

问题:

In a native call, I'm trying to open("/dev/video4", O_RDWR) but I get errno EACCES 13 "permission denied".

If I run the same code* in an executable, on the same Android host, as the same UID of the installed app I'm running above, it works fine. (* minor differences like main() instead of Java_com_test_testOpen())

I've tried chmod 666 /dev/video4 and still get EACCES, which is especially strange.

Why does the same code, on the same host, as the same user, give EACCESS when called via JNI, and success when called as standalone executable?

The test device is rooted and running Cyanogenmod 12.1 (API 22) and I'm targeting >= API 21 (5.0 Lollipop) on rooted devices. Thanks for your help.

回答1:

Since you get an error when running your code from an Android Java application, I would guess that you are missing a permission. It's the camera that you are trying to access, if I am not mistaken, so if you add:

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

to your AndroidManifest.xml, your application should run fine.



回答2:

Since I'm building Cyanogenmod 12.1 (API 22) with other minor hacks I was able to get permissions for /dev/video* in my app by using the following hacks:

  1. For standard Linux permissions, android.permission.CAMERA no longer seems to allow access to /dev/video* even though they're owned by system:camera. Instead, I edited device/samsung/klte-common/rootdir/etc/ueventd.qcom.rc and changed the /dev/video* line to 0666.
  2. For SE Linux permissions, I added the line allow untrusted_app video_device:chr_file rw_file_perms; to external/sepolicy/untrusted_app.te.

After rebuilding and installing the image, my JNI lib is able to access /dev/video* and my client is happy!



回答3:

The answers was not enough for me, so I left one more anwser. open API has more parameter 'mode'.

int open(const char *pathname, int flags, mode_t mode);

check out the link http://man7.org/linux/man-pages/man2/open.2.html

you might need to use 'open' with S_IRWXU option. like

open("/dev/video4", O_RDWR | O_CREAT, S_IRWXU )