• After 15+ years, we've made a big change: Android Forums is now Early Bird Club. Learn more here.

Apps /cache/recovery/command: open failed: EACCESS (permission denied) - missing permission after update

KraZbi

Lurker
Hi everyone,

I already searched in the Internet an answer to my problem, but unfortunately I have not found a solution for my issue. I even wrote in this case on the official forum (groups.google.com/forum/#!forum/android-developers), Unfortunately, the moderators could not cope with this problem. Below I describe the problem, hoping that someone had a similar problem and knows the solution.

I made an application that works fine on Android 4.1, which is why I reject the problems associated with the lack of "something".
For now, it seems that in newer versions of android is a bug, because after updating to Android 4.3+ (API 18+) my app shows the message:
/cache/recovery/command: open failed: EACCESS (permission denied)
My application is an system application, so the file '*.apk' was put in directory '/system/app/'
together with a suitable file access permissions (chmod), so that the 'context.getApplicationInfo().flags & ApplicationInfo.FLAG_SYSTEM' is equal 1.

Because the application uses the method 'RecoverySystem.installPackage(...)' I added permissions:
<uses-permission android:name="android.permission.ACCESS_CACHE_FILESYSTEM" />
<uses-permission android:name="android.permission.REBOOT" />
<uses-permission android:name="android.permission.DELETE_CACHE_FILES" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
More than the required minimum, because among others my application uses the method 'RecoverySystem.verifyPackage(...)'
Also, this method had problems after updating to Android 4.3+, but these problems have been solved after adding one of (or all) permissions:
<uses-permission android:name="android.permission.WRITE_MEDIA_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
NOTE:
For testing I added to manifest file also all the possible permissions that are available, but this does not solve the problem.


Once again, I would like to emphasize that the application works correctly until an update to android 4.3+.
After the update there is an error with the message:
/cache/recovery/command: open failed: EACCESS (permission denied)
This error occurs when call the method 'RecoverySystem.installPackage(...)'.
('FileWriter command = new FileWriter(COMMAND_FILE);' where 'COMMAND_FILE' == '/cache/recovery/command')

I'm not sure, but I think that one of the possible reasons may be bug in the 'bootable/recovery/recovery.c', but I can not find any confirmation.


If anyone can help, I'd be grateful.


P.S. To avoid mess in the Internet, do not post with texts like "use Google", "already it was - I've seen it somewhere - but can not remember where", "I have the same problem / also not working for me", and other posts which do not help solve the problem.
 
Hey KraZbi,

I'm thinking that it's possible your issues were due to multi-user support added and resulting changes in Android 4.2 and above. It's entirely possible you had access to the /cache filesystem prior to 4.2, but things (system behavior and permissions) have clearly changed since then.

I'm guessing that you're trying to communicate with either the currently installed stock or custom recovery via the /cache/recovery/command file and am pretty sure that the only way you'll be able to read/access/update that file is to have root access and manipulate that file indirectly (since the filesystem API will continue to give you the EACCESS errors when trying to open/read/write that particular filesystem and subordinate files).

The only way I can envision this working would be for your app to request root (su) permissions on a rooted device and manipulate the /cache/recovery/command file via shell (su) commands. It's kludgey, but it works.

Lemme know if you have other information about your app and code you are trying to use (your provided a lot of good info, but details on what exactly you're trying to accomplish would be helpful) or have questions about the above.

Cheers!
 
Hey scary alien,

The only way I can envision this working would be for your app to request root (su) permissions on a rooted device and manipulate the /cache/recovery/command file via shell (su) commands. It's kludgey, but it works.
I'd rather not use this solution via shell

Lemme know if you have other information about your app and code you are trying to use (your provided a lot of good info, but details on what exactly you're trying to accomplish would be helpful) or have questions about the above.
I would like to execute successfully (as it did before the upgrade android) the following command:
Code:
File cachedFile = new File(getApplicationContext().getCacheDir().getAbsolutePath(), "package.zip");
RecoverySystem.installPackage(getApplicationContext(), cachedFile);
P.S. changing the permissive/enforced mode didn't help
 
KraZbi,

See this post over on stackoverflow.com:

Android development RecoverySystem.installPackage() cannot write to /cache/recovery/command permission denied - Stack Overflow

It sounds identical to what you are experiencing and appears that the poster didn't properly get his app installed in /system/app. Here's the update information to his solution:

UPDATE:

Well, it looks like I figured it out. The permissions were right after all. Everything was right.

When I was setting up the app as a system app by moving the apk file to /system/app I hadn't put all the permissions in yet. When I ran the latest code on my device, it installed it in /data/app and recognized it as an update to the system app. Because of that, only the permissions of the original system app were recognized.

After I re-set up my latest code to run from /system/app directly, it worked.

Now the only issue I have is that when it reboots it doesn't install the image and I end up with a dead green robot with an exclamation mark. I'll keep investigating.

I hope this post helps anyone with the same issue. I'll be happy to answer any questions as well.

Hope that helps!

-SA
 
Meh! :( :banghead:

I wrote a small test app and ran it on my 4.2.2 Samsung Galaxy Nexus and it worked just fine.

I installed the same app on my 4.4.2 Nexus 5 and did/do indeed get the EACCES (Permission denied) error:

04-28 22:56:12.030: V/sa.testPackageInstall(3674): onCreate(): started
04-28 22:56:12.030: V/sa.testPackageInstall(3674): onCreate(): about to call RecoverySystem.installPackage
04-28 22:56:12.030: W/RecoverySystem(3674): !!! REBOOTING TO INSTALL /data/data/sa.testpackageinstall/cache/package.zip !!!
04-28 22:56:12.030: W/System.err(3674): java.io.FileNotFoundException: /cache/recovery/command: open failed: EACCES (Permission denied)
04-28 22:56:12.040: W/System.err(3674): at libcore.io.IoBridge.open(IoBridge.java:409)
04-28 22:56:12.040: W/System.err(3674): at java.io.FileOutputStream.<init>(FileOutputStream.java:88)
04-28 22:56:12.040: W/System.err(3674): at java.io.FileOutputStream.<init>(FileOutputStream.java:73)
04-28 22:56:12.040: W/System.err(3674): at java.io.FileWriter.<init>(FileWriter.java:42)
04-28 22:56:12.040: W/System.err(3674): at android.os.RecoverySystem.bootCommand(RecoverySystem.java:389)
04-28 22:56:12.040: W/System.err(3674): at android.os.RecoverySystem.installPackage(RecoverySystem.java:337)
04-28 22:56:12.040: W/System.err(3674): at sa.testpackageinstall.MainActivity.onCreate(MainActivity.java:23)

So, yes, something certainly changed in the RecoverySystem.java's bootCommand function's ability to write to the /cache/recovery/command file as it did earlier versions of Android (at least we know that Android 4.2.2 still allowed this functionality).

:confused: :confused: :confused:
 
I was having same problem, but solved it.
If you firmware is 4.3+ then,
You should add android:sharedUserId="com.google.uid.shared" in you apps manifest, and push your app to system/app.
For this you can root your device
But after adding this, your will not get installed, as during installation verifySignaturesLP method from PackageManagerService will return false as your app isn't signed with google signatures, so you have to make changes in that method to check you apps package and return true there.
 
@shirish_herwade Thanks for reply.

after adding android:sharedUserId="com.google.uid.shared" to my apps manifest (AndroidManifest.xml), an error occurred:

Installation error: INSTALL_FAILED_SHARED_USER_INCOMPATIBLE
Please check logcat output for more details.
Launch canceled!


LogCat
Package com.example.test has no signatures that match those in shared user com.google.uid.shared; ignoring!

and/or

Package com.example.test has no signatures that match those in shared user android.uid.system; ignoring!
You wrote:
shirish_herwade said:
..as your app isn't signed with google signatures..

but after sign application, using files *.pk8 and *.x509.pem, which can be found under build/target/product/security in the pulbic sdk.

Code:
java -jar SignApk.jar platform.x509.pem platform.pk8   Application.apk Application_signed.apk
and/or
Code:
java -jar SignApk.jar shared.x509.pem shared.pk8   Application.apk Application_signed.apk
the error still occurs.

When I push my app to system/app (and reboot) the application is not visible in apps.
 
Back
Top Bottom