From e718a7c03cf1962cd1e4a4ebd79e6dc800d67aa2 Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Mon, 31 Jul 2017 23:21:59 -0500 Subject: [PATCH] RootShell: Use the application cache dir as TMPDIR Signed-off-by: Jason A. Donenfeld --- .../java/com/wireguard/android/ProfileService.java | 8 +++++--- .../main/java/com/wireguard/android/RootShell.java | 14 +++++++++++--- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/com/wireguard/android/ProfileService.java b/app/src/main/java/com/wireguard/android/ProfileService.java index d5c882db..93d2049f 100644 --- a/app/src/main/java/com/wireguard/android/ProfileService.java +++ b/app/src/main/java/com/wireguard/android/ProfileService.java @@ -29,6 +29,7 @@ public class ProfileService extends Service { private final IBinder binder = new ProfileServiceBinder(); private final ObservableList profiles = new ObservableArrayList<>(); + private RootShell rootShell; @Override public IBinder onBind(Intent intent) { @@ -37,6 +38,7 @@ public class ProfileService extends Service { @Override public void onCreate() { + rootShell = new RootShell(this); new ProfileLoader().execute(getFilesDir().listFiles(new FilenameFilter() { @Override public boolean accept(File dir, String name) { @@ -94,7 +96,7 @@ public class ProfileService extends Service { protected Boolean doInBackground(Void... voids) { Log.i(TAG, "Running wg-quick up for profile " + profile.getName()); final File configFile = new File(getFilesDir(), profile.getName() + ".conf"); - return RootShell.run(null, "wg-quick up '" + configFile.getPath() + "'") == 0; + return rootShell.run(null, "wg-quick up '" + configFile.getPath() + "'") == 0; } @Override @@ -117,7 +119,7 @@ public class ProfileService extends Service { protected Boolean doInBackground(Void... voids) { Log.i(TAG, "Running wg-quick down for profile " + profile.getName()); final File configFile = new File(getFilesDir(), profile.getName() + ".conf"); - return RootShell.run(null, "wg-quick down '" + configFile.getPath() + "'") == 0; + return rootShell.run(null, "wg-quick down '" + configFile.getPath() + "'") == 0; } @Override @@ -134,7 +136,7 @@ public class ProfileService extends Service { final List interfaceNames = new LinkedList<>(); final List loadedProfiles = new LinkedList<>(); final String command = "wg show interfaces"; - if (RootShell.run(interfaceNames, command) == 0 && interfaceNames.size() == 1) { + if (rootShell.run(interfaceNames, command) == 0 && interfaceNames.size() == 1) { // wg puts all interface names on the same line. Split them into separate elements. final String nameList = interfaceNames.get(0); Collections.addAll(interfaceNames, nameList.split(" ")); diff --git a/app/src/main/java/com/wireguard/android/RootShell.java b/app/src/main/java/com/wireguard/android/RootShell.java index b80a1b41..096ff046 100644 --- a/app/src/main/java/com/wireguard/android/RootShell.java +++ b/app/src/main/java/com/wireguard/android/RootShell.java @@ -1,5 +1,6 @@ package com.wireguard.android; +import android.content.Context; import android.util.Log; import java.io.BufferedReader; @@ -19,9 +20,16 @@ class RootShell { * Setup commands that are run at the beginning of each root shell. The trap command ensures * access to the return value of the last command, since su itself always exits with 0. */ - private static final String SETUP = "export TMPDIR=/data/local/tmp\ntrap 'echo $?' EXIT\n"; + private static final String SETUP = "export TMPDIR=%s\ntrap 'echo $?' EXIT\n"; private static final String TAG = "RootShell"; + private final byte setupCommands[]; + + RootShell(Context context) { + final String tmpdir = context.getCacheDir().getPath(); + setupCommands = String.format(SETUP, tmpdir).getBytes(StandardCharsets.UTF_8); + } + /** * Run a series of commands in a root shell. These commands are all sent to the same shell * process, so they can be considered a shell script. @@ -31,7 +39,7 @@ class RootShell { * @param commands One or more commands to run as root (each element is a separate line). * @return The exit value of the last command run, or -1 if there was an internal error. */ - static int run(List output, String... commands) { + int run(List output, String... commands) { if (commands.length < 1) throw new IndexOutOfBoundsException("At least one command must be supplied"); int exitValue = -1; @@ -39,7 +47,7 @@ class RootShell { final ProcessBuilder builder = new ProcessBuilder().redirectErrorStream(true); final Process process = builder.command("su").start(); final OutputStream stdin = process.getOutputStream(); - stdin.write(SETUP.getBytes(StandardCharsets.UTF_8)); + stdin.write(setupCommands); for (String command : commands) stdin.write(command.concat("\n").getBytes(StandardCharsets.UTF_8)); stdin.close();