Beagleboard application root privileges with Runtime.getRuntime().exec()

1980 views
Skip to first unread message

matt...@live.com

unread,
Jul 23, 2013, 10:09:43 AM7/23/13
to row...@googlegroups.com
I'm running JB 4.1.2 on  a BeagleBoard-xM but i can't run any root command using Runtime.getRuntime().exec().
I've tried anything but i got:

java.io.IOException: Error running exec(). Command: [echo] Working Directory: null Environment: null

With original /system/xbin/su command, or at least

Permission Denied or no output replacing original "su" command with a custom one (taken from SuperSu or SuperUser application, ARM build).

I've also tried to change "su" command group and permission and running application as a system app.
I've tried any command like "sh -c" "su -c" or libsuperuser (from chainfire) or also using a custom JNI lib that invoke system("su...");
Nothing change, no luck.

su command only works by terminal or through adb shell.

I need to run some echo command to use board leds from my application, how can solve it?

Thanks

nikolay...@gmail.com

unread,
Jul 23, 2013, 11:33:36 PM7/23/13
to row...@googlegroups.com, matt...@live.com


On Tuesday, July 23, 2013 11:09:43 PM UTC+9, matt...@live.com wrote:

su command only works by terminal or through adb shell.



Exactly. It checks if you are the shell user and exits if you are not. 
SuperUser.apk and friends use a white list in a DB instead and you 
have to authorize each app via the UI to get su access.  

Nikolay Elenkov

unread,
Jul 24, 2013, 3:27:05 AM7/24/13
to matt...@live.com, row...@googlegroups.com
Replying back to list.

On Wed, Jul 24, 2013 at 4:19 PM, <matt...@live.com> wrote:
> Ok, very interesting.
> I can't use full SuperUser.apk or similar because i don't have a fully UI
> access on my board.
> But i can still use the modified su command from SuperUser and manually
> enter my app in whitelist using a boot script.

It's typically in the app directory. You can use a OSS superuser app like
this one and modify it accordingly and or pre-populate the DB at
install time.

https://github.com/koush/Superuser

However, if you don't have a UI, it might be easier to take the su.c from
AOSP (system/extras/su/su.c) and modify it to fit your needs. Check
for a specific UID or group (wheel or whaterver). Cf the current
implementation:

myuid = getuid();
if (myuid != AID_ROOT && myuid != AID_SHELL) {
fprintf(stderr,"su: uid %d not allowed to su\n", myuid);
return 1;
}

matt...@live.com

unread,
Jul 24, 2013, 11:29:22 AM7/24/13
to row...@googlegroups.com, matt...@live.com
Solved!
Thanks.

matt...@live.com

unread,
Jul 25, 2013, 4:30:51 AM7/25/13
to row...@googlegroups.com, matt...@live.com
I still have a problem:
I've commented out multiple if and now I'm able to execute commands.

Now the problem is that I haven't the right permission to write to /sys/class/gpio/export and others, becase i'm not root.
If I execute "id" from my java app i got "uid=10019(u0_a19) gid=10019(u0_a19) groups=1015(sdcard_rw),1023(media_rw),1028(sdcard_r),3003(inet)".

I've also try to modify the su command adding:

seteuid(0);
setresgid(0,0,0);
setresuid(0,0,0);
setgroups(0, NULL);

Like in Superuser su executable, bot nothing changes.
How can I solve?

Thanks

nikolay...@gmail.com

unread,
Jul 26, 2013, 4:11:47 AM7/26/13
to row...@googlegroups.com, matt...@live.com


On Thursday, July 25, 2013 5:30:51 PM UTC+9, matt...@live.com wrote:
I still have a problem:
I've commented out multiple if and now I'm able to execute commands.

Now the problem is that I haven't the right permission to write to /sys/class/gpio/export and others, becase i'm not root.

... 


How can I solve?


Change the permission of the file in init.rc. You are probably not getting 
a proper root shell via su if you are getting permission denied though. 

 

matt...@live.com

unread,
Jul 26, 2013, 7:18:18 AM7/26/13
to row...@googlegroups.com, matt...@live.com
Changing /sys/class/gpio/export permission via init.rc is a workaroud (and it works) but I need to get a proper ROOT shell in my app, with uid=0(root) gid=0(root)

matt...@live.com

unread,
Aug 5, 2013, 6:30:40 AM8/5/13
to row...@googlegroups.com, matt...@live.com
Finally solved!

The problem was that setgid(0) and setuid(0) calls into su.c fails.

The solution is add "chmod 7777 /sytem/xbin/su" in init.rc

preyas...@gmail.com

unread,
Aug 23, 2013, 12:06:23 PM8/23/13
to row...@googlegroups.com, matt...@live.com
I'm facing a similar issue to exec a shell command with root permissions. I compiled su.c and used the following code to execute the shell command in my app. It fails with java.io.IOException: write failed: EPIPE (Broken pipe). Here is the Java code. Any ideas?

public static void RunAsRoot(String[] cmds) {
        Process p;
        try {       
            p = Runtime.getRuntime().exec("/system/bin/su");
            OutputStream os = p.getOutputStream();
            DataOutputStream dos = new DataOutputStream(p.getOutputStream());
            for (String tmpCmd : cmds) {
                dos.writeBytes(tmpCmd + "\n");
            }
            dos.writeBytes("exit\n");
            dos.flush();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }.

matt...@live.com

unread,
Aug 23, 2013, 12:26:45 PM8/23/13
to row...@googlegroups.com, matt...@live.com
Try this:


private class RootShell {
        public String execute(String command) {
            String[] str = new String[1];
            str[0] = command;
            return execute(str);
        }

        public String execute(String[] commands) {
            return execute(commands, true);
        }

        public String execute(String[] commands, boolean errorStream) {
            DataOutputStream dos = null;
            DataInputStream dis = null;
            DataInputStream des = null;
            Process process = null;

            try {
                process = Runtime.getRuntime().exec("su -c sh");
            } catch (IOException io) {
            }
            dos = new DataOutputStream(process.getOutputStream());
            dis = new DataInputStream(process.getInputStream());
            if (errorStream)
                des = new DataInputStream(process.getErrorStream());
            try {
                String result = "";
                for (String single : commands) {
                    dos.writeBytes(single + "\n");
                    dos.flush();

                }
                dos.writeBytes("exit\n");
                dos.flush();
                process.waitFor();
                while (dis.available() > 0)
                    result += dis.readLine() + "\n";
                if (errorStream) {
                    while (des.available() > 0)
                        result += des.readLine() + "\n";
                }
                dis.close();
                dos.close();
                if (errorStream)
                    des.close();
                return result;
            } catch (Exception e) {
                return e.getMessage();
            }
        }
    }

preyas...@gmail.com

unread,
Aug 23, 2013, 12:46:51 PM8/23/13
to row...@googlegroups.com, matt...@live.com
Thanks. I realized that the su daemon wasn't running, when I run it the Superuser.apk pop showed up when root permission were requested. What needed to pre-populate to Superuser db with my application credentials. I'm building an app for a custom product and I don't want to show the root permissions dialog to user.

-Preyas

matt...@live.com

unread,
Aug 23, 2013, 12:57:41 PM8/23/13
to row...@googlegroups.com, matt...@live.com
If you compile by yourself a su binary with setgid(0) and setuid(0) calls you don't need to user Superuser or a pre-populated db. The su binary that comes with Superuser only give you root permission (setgid(0) and setuid(0)) if your app is in the databases, if you made su binary by yourself you don't need it.
Remember to set 7777 privileges to su.

preyas...@gmail.com

unread,
Aug 23, 2013, 1:59:45 PM8/23/13
to row...@googlegroups.com, matt...@live.com
The code hangs when I set the uid/gid to 0 in su.c code

int main(int argc, char *argv[]) {
    setgid(0);
    setuid(0);

    // start up in daemon mode if prompted
    if (argc == 2 && strcmp(argv[1], "--daemon") == 0) {
        return run_daemon();
    }
.....

matt...@live.com

unread,
Aug 23, 2013, 7:24:40 PM8/23/13
to row...@googlegroups.com, matt...@live.com
Try this su.c:

static int permissionDenied()
{
        printf("su: permission denied\n");
        return 1;
}

static int executionFailure(char *context)
{
        fprintf(stderr, "su: %s. Error:%s\n", context, strerror(errno));
        return -errno;

}

int main(int argc, char *argv[])
{
        if(setgid(0) || setuid(0))
                return permissionDenied();
          
        char *exec_args[argc + 1];
        exec_args[argc] = NULL;
        exec_args[0] = "sh";
        int i;
        for (i = 1; i < argc; i++)
        {
                exec_args[i] = argv[i];
        }
        execv("/system/bin/sh", exec_args);
        return executionFailure("sh");
}

preyas...@gmail.com

unread,
Aug 24, 2013, 5:59:50 AM8/24/13
to row...@googlegroups.com, matt...@live.com
that worked. Thanks.

-Preyas

jmarti...@gmail.com

unread,
Oct 28, 2013, 8:34:15 PM10/28/13
to row...@googlegroups.com, matt...@live.com
Hello,  i hope you could help me out, how do i  compile the binary, and is it necesary the superuser app? Because i'm developing on beagleboard xm adn i don't really know if i have to add this, the problem is that with the binary su preinstalled, i can't give acces to my app to run an specific command. So i hope you please help me. It would be nice.

matt...@live.com

unread,
Oct 29, 2013, 4:35:12 AM10/29/13
to row...@googlegroups.com, matt...@live.com
You don't need superuser app, only su binary from post above.
You can compile using rowboat guide for xm: http://code.google.com/p/rowboat/wiki/JellybeanOnBeagleboard_WithSGX

Here is my precompiled one: http://www.sendspace.com/file/albduk
Use
adb push su /system/xbin/su
adb shell chmod 7777 /system/xbin/su

malcolm....@gmail.com

unread,
Aug 8, 2014, 1:57:36 AM8/8/14
to row...@googlegroups.com, matt...@live.com
Hi,

Sorry to revive such an old thread, but am facing the same problem and looking for your precompiled su. The link to sendspace has expired. Is it possible to share again somewhere?

Cheers
Malcolm 
Reply all
Reply to author
Forward
0 new messages