I have met a weird problem on a Samsung Galaxy Note 2, running Android 4.3, with an origin-forgetton rooted rom.
- getenforce returns "Permissive", so selinux is Permissive.
- cat /proc/self/status returns CapBnd/CapEff/CapPrm ffffffffffffffff after su, so all the capabilities are granted.
- su is from chainfire's SuperSU.
The syndrome is, any executable under /data calling execve() fails with EACCES.
To demonstrate, the following is carried out after su. Static compile the following program into a static linked binary, say execve.
# gcc -static execve.c -o execve
/* execve.c */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int
main(int argc, char *argv[])
{
char *newargv[] = { NULL, "hello", "world", NULL };
char *newenviron[] = { NULL };
if (argc != 2) {
fprintf(stderr, "Usage: %s <file-to-exec>\n", argv[0]);
exit(EXIT_FAILURE);
}
newargv[0] = argv[1];
execve(argv[1], newargv, newenviron);
perror("execve"); /* execve() only returns on error */
exit(EXIT_FAILURE);
}
Running "execve /system/bin/ls" should be equivalent to "ls hello world".
But if execve is put under any subdirectory of /data, "execve /system/bin/ls" results in "Permission Denied".
- If execve is put into any of /, /system, /cache, /mnt/obb. execve() works.
- Remounting /data with exactly the same mount options as /cache does not help.
Symlinking a subdirectory from /cache into /data containing execve works.
ln -s /cache/test /data/test #/data/test/execve works
And in reverse, execve does not work
ln -s /cache/test1 /data/test1 #/cache/test1/execve Permission Denied
Bind mount /data to /bind. /bind/execve works, but /data/execve does not.
mount -o bind /data /bind
Conclusion: There seems to be soming preventing any executables under /data from calling execve() syscall. The mechanism has nothing to do with the filesystem attributes, and symlink is dereferenced before the mechanism is applied.
Question: What mechanism in Android could give this strange behavior?
Aucun commentaire:
Enregistrer un commentaire