By default, an ADB shell session drops into an unprivileged user context (uid=2000(shell)). To gain full administrative control over the scooter’s Android head unit, we can elevate our privileges to root (uid=0) using a patched su binary.
How It Works
Section titled “How It Works”The Ola S1 Pro operating system already contains a stock su binary. However, invoking it immediately prompts for an authentication password:
:/ $ suplease input password:The password is wrong. Please input it again:su: Authentication failed: Operation not permittedThe authentication password is stored as an encrypted hash and cannot be easily guessed or cracked. To bypass this restriction, we mount a patched su binary that skips password validation and grants an immediate root shell to the calling process.
Option A: Automatic Setup (Recommended)
Section titled “Option A: Automatic Setup (Recommended)”Run the setup-su command with s1util.py to automate the entire installation:
python s1util.py setup-su --host <scooter-ip>This automated command handles pushing the patched binary, mounting a writable tmpfs volume, configuring SUID permissions, and applying the required SELinux context in a single step.
Option B: Manual Setup
Section titled “Option B: Manual Setup”Follow these steps to manually upload and configure the patched su binary.
-
Download Patched su Binary:
Download the pre-patched binary to your local machine:
-
Push Binary to Scooter:
Upload the downloaded
sufile to the staging directory/data/local/tmp/on the scooter:Terminal window python s1util.py push --host <scooter-ip> su /data/local/tmp/su -
Open gRPC Root Shell:
Open an interactive root shell session via the gRPC diagnostics interface:
Terminal window python s1util.py shell --host "<scooter-ip>"You should be greeted by the gRPC root shell prompt:
root@ola:# -
Mount and Configure su:
Execute the following sequence of commands one by one in the gRPC shell:
Terminal window root@ola:# mkdir -p /mnt/runtimeroot@ola:# mount -t tmpfs -o mode=755 tmpfs /mnt/runtimeroot@ola:# cp /data/local/tmp/su /mnt/runtime/suroot@ola:# chown root:root /mnt/runtime/suroot@ola:# chmod 4755 /mnt/runtime/suroot@ola:# chcon u:object_r:shell_data_file:s0 /mnt/runtime/su
What These Commands Do
Section titled “What These Commands Do”mkdir -p /mnt/runtime: Creates a mount point directory within/mnt.mount -t tmpfs -o mode=755 tmpfs /mnt/runtime: Mounts an in-memorytmpfsfilesystem with read and execute permissions (755), ensuring binaries can be executed without filesystem restrictions.cp /data/local/tmp/su /mnt/runtime/su: Copies the stagedsubinary into the newly mounted filesystem.chown root:root /mnt/runtime/su: Sets the owner and group of the binary toroot.chmod 4755 /mnt/runtime/su: Enables the SUID (Set User ID) permission bit (4755). This allows unprivileged processes (like the ADB shell) to execute the binary while inheriting fullrootprivileges.chcon u:object_r:shell_data_file:s0 /mnt/runtime/su: Sets the SELinux security context toshell_data_fileso the ADB shell domain has permission to invoke it without being blocked by Android’s security policies.
Using Root Through ADB
Section titled “Using Root Through ADB”Done! You now have a working su binary.
Open a standard ADB shell:
adb shellInteractive Root Shell
Section titled “Interactive Root Shell”Invoke /mnt/runtime/su from your shell session to drop into a root prompt:
/mnt/runtime/suCheck your identity:
root@ola:/ # iduid=0(root) gid=0(root) groups=0(root),1004(input),1007(log),1011(adb),1015(sdcard_rw),1028(sdcard_r),1078(ext_data_rw),1079(ext_obb_rw),3001(net_bt_admin),3002(net_bt),3003(inet),3006(net_bw_stats),3009(readproc),3011(uhid),3012(readtracefs) context=u:r:shell:s0Running Inline Commands
Section titled “Running Inline Commands”You can also run one-off root commands directly using the -c flag without opening an interactive shell session:
/mnt/runtime/su -c idExpected output:
uid=0(root) gid=0(root) groups=0(root),1004(input),1007(log),1011(adb),1015(sdcard_rw),1028(sdcard_r),1078(ext_data_rw),1079(ext_obb_rw),3001(net_bt_admin),3002(net_bt),3003(inet),3006(net_bw_stats),3009(readproc),3011(uhid),3012(readtracefs) context=u:r:shell:s0Reverting su Setup
Section titled “Reverting su Setup”If you want to revert your scooter to its original state and undo the changes made by setup-su, run the revert-su command with s1util.py:
python s1util.py revert-su --host <scooter-ip>This unmounts /mnt/runtime and cleans up the temporary files, restoring the stock su configuration.