diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index b2eb58890..6fcb0576d 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -24,6 +24,7 @@ # Snet extention -keepclassmembers class com.topjohnwu.magisk.utils.ISafetyNetHelper { *; } +-keepclassmembers class com.topjohnwu.magisk.utils.BootSigner { *; } # Fast Android Networking Library -dontwarn okhttp3.** diff --git a/app/src/full/AndroidManifest.xml b/app/src/full/AndroidManifest.xml index b33046493..b8dd6e416 100644 --- a/app/src/full/AndroidManifest.xml +++ b/app/src/full/AndroidManifest.xml @@ -53,15 +53,6 @@ android:taskAffinity="internal.superuser" android:theme="@style/SuRequest" /> - - - - diff --git a/app/src/full/java/com/topjohnwu/magisk/Const.java b/app/src/full/java/com/topjohnwu/magisk/Const.java index 0e76c8a5e..13e871b6a 100644 --- a/app/src/full/java/com/topjohnwu/magisk/Const.java +++ b/app/src/full/java/com/topjohnwu/magisk/Const.java @@ -10,7 +10,6 @@ import java.util.List; public class Const { public static final String DEBUG_TAG = "MagiskManager"; - public static final String MAGISKHIDE_PROP = "persist.magisk.hide"; // APK content public static final String ANDROID_MANIFEST = "AndroidManifest.xml"; @@ -47,11 +46,7 @@ public class Const { public static final int USER_ID = Process.myUid() / 100000; public static final class MAGISK_VER { - public static final int SEPOL_REFACTOR = 1640; - public static final int FIX_ENV = 1650; - public static final int DBVER_SIX = 17000; - public static final int CMDLINE_DB = 17305; - public static final int HIDE_STATUS = 17315; + /* Currently no backwards compatibility needed */ } public static class ID { diff --git a/app/src/full/java/com/topjohnwu/magisk/Data.java b/app/src/full/java/com/topjohnwu/magisk/Data.java index 0f2d1485d..ecdb47c4f 100644 --- a/app/src/full/java/com/topjohnwu/magisk/Data.java +++ b/app/src/full/java/com/topjohnwu/magisk/Data.java @@ -83,12 +83,7 @@ public class Data { try { magiskVersionString = ShellUtils.fastCmd("magisk -v").split(":")[0]; magiskVersionCode = Integer.parseInt(ShellUtils.fastCmd("magisk -V")); - if (magiskVersionCode >= Const.MAGISK_VER.HIDE_STATUS) { - magiskHide = Shell.su("magiskhide --status").exec().isSuccess(); - } else { - String s = ShellUtils.fastCmd(("resetprop -p ") + Const.MAGISKHIDE_PROP); - magiskHide = s.isEmpty() || Integer.parseInt(s) != 0; - } + magiskHide = Shell.su("magiskhide --status").exec().isSuccess(); } catch (NumberFormatException ignored) {} } diff --git a/app/src/full/java/com/topjohnwu/magisk/FlashActivity.java b/app/src/full/java/com/topjohnwu/magisk/FlashActivity.java index e3fd4fbea..0911572ea 100644 --- a/app/src/full/java/com/topjohnwu/magisk/FlashActivity.java +++ b/app/src/full/java/com/topjohnwu/magisk/FlashActivity.java @@ -15,7 +15,6 @@ import android.widget.Toast; import com.topjohnwu.magisk.asyncs.FlashZip; import com.topjohnwu.magisk.asyncs.InstallMagisk; import com.topjohnwu.magisk.components.BaseActivity; -import com.topjohnwu.magisk.utils.RootUtils; import com.topjohnwu.magisk.utils.Utils; import com.topjohnwu.superuser.CallbackList; import com.topjohnwu.superuser.Shell; @@ -160,7 +159,7 @@ public class FlashActivity extends BaseActivity { protected void onPostExecute(Integer result) { if (result == 1) { Data.mainHandler.postDelayed(() -> - RootUtils.uninstallPkg(getActivity().getPackageName()), 3000); + Shell.su("pm uninstall " + getActivity().getPackageName()).exec(), 3000); } else { super.onPostExecute(result); } diff --git a/app/src/full/java/com/topjohnwu/magisk/MagiskManager.java b/app/src/full/java/com/topjohnwu/magisk/MagiskManager.java index 74ed5c9f3..6cf8c9d6c 100644 --- a/app/src/full/java/com/topjohnwu/magisk/MagiskManager.java +++ b/app/src/full/java/com/topjohnwu/magisk/MagiskManager.java @@ -20,8 +20,8 @@ public class MagiskManager extends ContainerApp { // Global resources public SharedPreferences prefs; - public MagiskDB mDB; public RepoDatabaseHelper repoDB; + public MagiskDB mDB; public MagiskManager() { Data.weakApp = new WeakReference<>(this); @@ -37,8 +37,8 @@ public class MagiskManager extends ContainerApp { Shell.Config.setTimeout(2); prefs = PreferenceManager.getDefaultSharedPreferences(this); - mDB = MagiskDB.getInstance(); repoDB = new RepoDatabaseHelper(this); + mDB = new MagiskDB(this); LocaleManager.setLocale(this); Data.loadConfig(); diff --git a/app/src/full/java/com/topjohnwu/magisk/SplashActivity.java b/app/src/full/java/com/topjohnwu/magisk/SplashActivity.java index 8ea1adb26..43a97a608 100644 --- a/app/src/full/java/com/topjohnwu/magisk/SplashActivity.java +++ b/app/src/full/java/com/topjohnwu/magisk/SplashActivity.java @@ -12,7 +12,6 @@ import com.topjohnwu.magisk.components.Notifications; import com.topjohnwu.magisk.receivers.ShortcutReceiver; import com.topjohnwu.magisk.utils.Download; import com.topjohnwu.magisk.utils.LocaleManager; -import com.topjohnwu.magisk.utils.RootUtils; import com.topjohnwu.magisk.utils.Utils; import com.topjohnwu.superuser.Shell; @@ -31,7 +30,7 @@ public class SplashActivity extends BaseActivity { try { // We are the manager, remove com.topjohnwu.magisk as it could be malware getPackageManager().getApplicationInfo(BuildConfig.APPLICATION_ID, 0); - RootUtils.uninstallPkg(BuildConfig.APPLICATION_ID); + Shell.su("pm uninstall " + BuildConfig.APPLICATION_ID).submit(); } catch (PackageManager.NameNotFoundException ignored) {} } diff --git a/app/src/full/java/com/topjohnwu/magisk/SuRequestActivity.java b/app/src/full/java/com/topjohnwu/magisk/SuRequestActivity.java index 9db9ad34d..ed28b0987 100644 --- a/app/src/full/java/com/topjohnwu/magisk/SuRequestActivity.java +++ b/app/src/full/java/com/topjohnwu/magisk/SuRequestActivity.java @@ -3,10 +3,8 @@ package com.topjohnwu.magisk; import android.content.Intent; import android.content.pm.PackageManager; import android.hardware.fingerprint.FingerprintManager; -import android.net.LocalSocketAddress; import android.os.Bundle; import android.os.CountDownTimer; -import android.os.FileObserver; import android.text.TextUtils; import android.view.View; import android.view.Window; @@ -43,48 +41,6 @@ public class SuRequestActivity extends BaseActivity { private CountDownTimer timer; private FingerprintHelper fingerprintHelper; - class SuConnectorV1 extends SuConnector { - - SuConnectorV1(String name) throws IOException { - super(name); - } - - @Override - public void connect(String name) throws IOException { - socket.connect(new LocalSocketAddress(name, LocalSocketAddress.Namespace.FILESYSTEM)); - new FileObserver(name) { - @Override - public void onEvent(int fileEvent, String path) { - if (fileEvent == FileObserver.DELETE_SELF) { - finish(); - } - } - }.startWatching(); - } - - @Override - public void onResponse() throws IOException { - out.write((policy.policy == Policy.ALLOW ? "socket:ALLOW" : "socket:DENY").getBytes()); - } - } - - class SuConnectorV2 extends SuConnector { - - SuConnectorV2(String name) throws IOException { - super(name); - } - - @Override - public void connect(String name) throws IOException { - socket.connect(new LocalSocketAddress(name, LocalSocketAddress.Namespace.ABSTRACT)); - } - - @Override - public void onResponse() throws IOException { - out.writeInt(policy.policy); - } - } - @Override public int getDarkTheme() { return R.style.SuRequest_Dark; @@ -120,8 +76,12 @@ public class SuRequestActivity extends BaseActivity { Intent intent = getIntent(); try { String socketName = intent.getStringExtra("socket"); - connector = intent.getIntExtra("version", 1) == 1 ? - new SuConnectorV1(socketName) : new SuConnectorV2(socketName); + connector = new SuConnector(socketName) { + @Override + protected void onResponse() throws IOException { + out.writeInt(policy.policy); + } + }; Bundle bundle = connector.readSocketInput(); int uid = Integer.parseInt(bundle.getString("uid")); policy = mm.mDB.getPolicy(uid); diff --git a/app/src/full/java/com/topjohnwu/magisk/asyncs/InstallMagisk.java b/app/src/full/java/com/topjohnwu/magisk/asyncs/InstallMagisk.java index 72c49060f..5939cd741 100644 --- a/app/src/full/java/com/topjohnwu/magisk/asyncs/InstallMagisk.java +++ b/app/src/full/java/com/topjohnwu/magisk/asyncs/InstallMagisk.java @@ -342,18 +342,7 @@ public class InstallMagisk extends ParallelTask { console.add("- Target image: " + mBoot); List abis = Arrays.asList(Build.SUPPORTED_ABIS); - String arch; - - if (Data.remoteMagiskVersionCode >= Const.MAGISK_VER.SEPOL_REFACTOR) { - // 32-bit only - if (abis.contains("x86")) arch = "x86"; - else arch = "arm"; - } else { - if (abis.contains("x86_64")) arch = "x64"; - else if (abis.contains("arm64-v8a")) arch = "arm64"; - else if (abis.contains("x86")) arch = "x86"; - else arch = "arm"; - } + String arch = abis.contains("x86") ? "x86" : "arm"; console.add("- Device platform: " + Build.SUPPORTED_ABIS[0]); diff --git a/app/src/full/java/com/topjohnwu/magisk/database/MagiskDB.java b/app/src/full/java/com/topjohnwu/magisk/database/MagiskDB.java index e443d31c9..3a45ae41f 100644 --- a/app/src/full/java/com/topjohnwu/magisk/database/MagiskDB.java +++ b/app/src/full/java/com/topjohnwu/magisk/database/MagiskDB.java @@ -1,66 +1,197 @@ package com.topjohnwu.magisk.database; +import android.content.ContentValues; +import android.content.Context; +import android.content.pm.PackageManager; +import android.text.TextUtils; + import com.topjohnwu.magisk.Const; import com.topjohnwu.magisk.Data; import com.topjohnwu.magisk.container.Policy; import com.topjohnwu.magisk.container.SuLogEntry; +import com.topjohnwu.magisk.utils.LocaleManager; import com.topjohnwu.magisk.utils.Utils; import com.topjohnwu.superuser.Shell; -import java.io.File; +import java.text.DateFormat; +import java.util.ArrayList; import java.util.Collections; +import java.util.Date; import java.util.List; - -import androidx.annotation.NonNull; +import java.util.Map; public class MagiskDB { - static final String POLICY_TABLE = "policies"; - static final String LOG_TABLE = "logs"; - static final String SETTINGS_TABLE = "settings"; - static final String STRINGS_TABLE = "strings"; - static final File LEGACY_MANAGER_DB = - new File(Utils.fmt("/sbin/.magisk/db-%d/magisk.db", Const.USER_ID)); + private static final String POLICY_TABLE = "policies"; + private static final String LOG_TABLE = "logs"; + private static final String SETTINGS_TABLE = "settings"; + private static final String STRINGS_TABLE = "strings"; - @NonNull - public static MagiskDB getInstance() { - if (LEGACY_MANAGER_DB.canWrite()) { - return MagiskDBLegacy.newInstance(); - } else if (Shell.rootAccess()) { - return Data.magiskVersionCode >= Const.MAGISK_VER.CMDLINE_DB ? - new MagiskDBCmdline() : MagiskDBLegacy.newInstance(); - } else { - return new MagiskDB(); - } + private PackageManager pm; + + public MagiskDB(Context context) { + pm = context.getPackageManager(); } - public void clearOutdated() {} - public void deletePolicy(Policy policy) { deletePolicy(policy.uid); } - public void deletePolicy(String pkg) {} + private List rawSQL(String fmt, Object... args) { + return Shell.su("magisk --sqlite '" + Utils.fmt(fmt, args) + "'").exec().getOut(); + } - public void deletePolicy(int uid) {} + private List SQL(String fmt, Object... args) { + List list = new ArrayList<>(); + for (String raw : rawSQL(fmt, args)) { + ContentValues values = new ContentValues(); + String[] cols = raw.split("\\|"); + for (String col : cols) { + String[] pair = col.split("=", 2); + if (pair.length != 2) + continue; + values.put(pair[0], pair[1]); + } + list.add(values); + } + return list; + } - public Policy getPolicy(int uid) { return null; } + private String toSQL(ContentValues values) { + StringBuilder keys = new StringBuilder(), vals = new StringBuilder(); + keys.append('('); + vals.append("VALUES("); + boolean first = true; + for (Map.Entry entry : values.valueSet()) { + if (!first) { + keys.append(','); + vals.append(','); + } else { + first = false; + } + keys.append(entry.getKey()); + vals.append('"'); + vals.append(entry.getValue()); + vals.append('"'); + } + keys.append(')'); + vals.append(')'); + keys.append(vals); + return keys.toString(); + } - public void updatePolicy(Policy policy) {} + public void clearOutdated() { + rawSQL( + "DELETE FROM %s WHERE until > 0 AND until < %d;" + + "DELETE FROM %s WHERE time < %d", + POLICY_TABLE, System.currentTimeMillis() / 1000, + LOG_TABLE, System.currentTimeMillis() - Data.suLogTimeout * 86400000 + ); + } - public List getPolicyList() { return Collections.emptyList(); } + public void deletePolicy(String pkg) { + rawSQL("DELETE FROM %s WHERE package_name=\"%s\"", POLICY_TABLE, pkg); + } - public List> getLogs() { return Collections.emptyList(); } - public void addLog(SuLogEntry log) {} + public void deletePolicy(int uid) { + rawSQL("DELETE FROM %s WHERE uid=%d", POLICY_TABLE, uid); + } - public void clearLogs() {} - public void setSettings(String key, int value) {} + public Policy getPolicy(int uid) { + List res = + SQL("SELECT * FROM %s WHERE uid=%d", POLICY_TABLE, uid); + if (!res.isEmpty()) { + try { + return new Policy(res.get(0), pm); + } catch (PackageManager.NameNotFoundException e) { + deletePolicy(uid); + } + } + return null; + } - public int getSettings(String key, int defaultValue) { return defaultValue; } - public void setStrings(String key, String value) {} + public void updatePolicy(Policy policy) { + rawSQL("REPLACE INTO %s %s", POLICY_TABLE, toSQL(policy.getContentValues())); + } - public String getStrings(String key, String defaultValue) { return defaultValue; } + + public List getPolicyList() { + List list = new ArrayList<>(); + for (ContentValues values : SQL("SELECT * FROM %s WHERE uid/100000=%d", POLICY_TABLE, Const.USER_ID)) { + try { + list.add(new Policy(values, pm)); + } catch (PackageManager.NameNotFoundException e) { + deletePolicy(values.getAsInteger("uid")); + } + } + Collections.sort(list); + return list; + } + + + public List> getLogs() { + List> ret = new ArrayList<>(); + List list = null; + String dateString = null, newString; + for (ContentValues values : SQL("SELECT * FROM %s ORDER BY time DESC", LOG_TABLE)) { + Date date = new Date(values.getAsLong("time")); + newString = DateFormat.getDateInstance(DateFormat.MEDIUM, LocaleManager.locale).format(date); + if (!TextUtils.equals(dateString, newString)) { + dateString = newString; + list = new ArrayList<>(); + ret.add(list); + } + list.add(new SuLogEntry(values)); + } + return ret; + } + + + public void addLog(SuLogEntry log) { + rawSQL("INSERT INTO %s %s", LOG_TABLE, toSQL(log.getContentValues())); + } + + + public void clearLogs() { + rawSQL("DELETE FROM %s", LOG_TABLE); + } + + + public void setSettings(String key, int value) { + ContentValues data = new ContentValues(); + data.put("key", key); + data.put("value", value); + rawSQL("REPLACE INTO %s %s", SETTINGS_TABLE, toSQL(data)); + } + + + public int getSettings(String key, int defaultValue) { + List res = SQL("SELECT value FROM %s WHERE key=\"%s\"", SETTINGS_TABLE, key); + if (res.isEmpty()) + return defaultValue; + return res.get(0).getAsInteger("value"); + } + + + public void setStrings(String key, String value) { + if (value == null) { + rawSQL("DELETE FROM %s WHERE key=\"%s\"", STRINGS_TABLE, key); + return; + } + ContentValues data = new ContentValues(); + data.put("key", key); + data.put("value", value); + rawSQL("REPLACE INTO %s %s", STRINGS_TABLE, toSQL(data)); + } + + + public String getStrings(String key, String defaultValue) { + List res = SQL("SELECT value FROM %s WHERE key=\"%s\"", STRINGS_TABLE, key); + if (res.isEmpty()) + return defaultValue; + return res.get(0).getAsString("value"); + } } diff --git a/app/src/full/java/com/topjohnwu/magisk/database/MagiskDBCmdline.java b/app/src/full/java/com/topjohnwu/magisk/database/MagiskDBCmdline.java deleted file mode 100644 index e78f198a1..000000000 --- a/app/src/full/java/com/topjohnwu/magisk/database/MagiskDBCmdline.java +++ /dev/null @@ -1,189 +0,0 @@ -package com.topjohnwu.magisk.database; - -import android.content.ContentValues; -import android.content.pm.PackageManager; -import android.text.TextUtils; - -import com.topjohnwu.magisk.Const; -import com.topjohnwu.magisk.Data; -import com.topjohnwu.magisk.container.Policy; -import com.topjohnwu.magisk.container.SuLogEntry; -import com.topjohnwu.magisk.utils.LocaleManager; -import com.topjohnwu.magisk.utils.Utils; -import com.topjohnwu.superuser.Shell; - -import java.text.DateFormat; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Date; -import java.util.List; -import java.util.Map; - -public class MagiskDBCmdline extends MagiskDB { - - private PackageManager pm; - - public MagiskDBCmdline() { - pm = Data.MM().getPackageManager(); - } - - private List rawSQL(String fmt, Object... args) { - return Shell.su("magisk --sqlite '" + Utils.fmt(fmt, args) + "'").exec().getOut(); - } - - private List SQL(String fmt, Object... args) { - List list = new ArrayList<>(); - for (String raw : rawSQL(fmt, args)) { - ContentValues values = new ContentValues(); - String[] cols = raw.split("\\|"); - for (String col : cols) { - String[] pair = col.split("=", 2); - if (pair.length != 2) - continue; - values.put(pair[0], pair[1]); - } - list.add(values); - } - return list; - } - - private String toSQL(ContentValues values) { - StringBuilder keys = new StringBuilder(), vals = new StringBuilder(); - keys.append('('); - vals.append("VALUES("); - boolean first = true; - for (Map.Entry entry : values.valueSet()) { - if (!first) { - keys.append(','); - vals.append(','); - } else { - first = false; - } - keys.append(entry.getKey()); - vals.append('"'); - vals.append(entry.getValue()); - vals.append('"'); - } - keys.append(')'); - vals.append(')'); - keys.append(vals); - return keys.toString(); - } - - @Override - public void clearOutdated() { - rawSQL( - "DELETE FROM %s WHERE until > 0 AND until < %d;" + - "DELETE FROM %s WHERE time < %d", - POLICY_TABLE, System.currentTimeMillis() / 1000, - LOG_TABLE, System.currentTimeMillis() - Data.suLogTimeout * 86400000 - ); - } - - @Override - public void deletePolicy(String pkg) { - rawSQL("DELETE FROM %s WHERE package_name=\"%s\"", POLICY_TABLE, pkg); - } - - @Override - public void deletePolicy(int uid) { - rawSQL("DELETE FROM %s WHERE uid=%d", POLICY_TABLE, uid); - } - - @Override - public Policy getPolicy(int uid) { - List res = - SQL("SELECT * FROM %s WHERE uid=%d", POLICY_TABLE, uid); - if (!res.isEmpty()) { - try { - return new Policy(res.get(0), pm); - } catch (PackageManager.NameNotFoundException e) { - deletePolicy(uid); - } - } - return null; - } - - @Override - public void updatePolicy(Policy policy) { - rawSQL("REPLACE INTO %s %s", POLICY_TABLE, toSQL(policy.getContentValues())); - } - - @Override - public List getPolicyList() { - List list = new ArrayList<>(); - for (ContentValues values : SQL("SELECT * FROM %s WHERE uid/100000=%d", POLICY_TABLE, Const.USER_ID)) { - try { - list.add(new Policy(values, pm)); - } catch (PackageManager.NameNotFoundException e) { - deletePolicy(values.getAsInteger("uid")); - } - } - Collections.sort(list); - return list; - } - - @Override - public List> getLogs() { - List> ret = new ArrayList<>(); - List list = null; - String dateString = null, newString; - for (ContentValues values : SQL("SELECT * FROM %s ORDER BY time DESC", LOG_TABLE)) { - Date date = new Date(values.getAsLong("time")); - newString = DateFormat.getDateInstance(DateFormat.MEDIUM, LocaleManager.locale).format(date); - if (!TextUtils.equals(dateString, newString)) { - dateString = newString; - list = new ArrayList<>(); - ret.add(list); - } - list.add(new SuLogEntry(values)); - } - return ret; - } - - @Override - public void addLog(SuLogEntry log) { - rawSQL("INSERT INTO %s %s", LOG_TABLE, toSQL(log.getContentValues())); - } - - @Override - public void clearLogs() { - rawSQL("DELETE FROM %s", LOG_TABLE); - } - - @Override - public void setSettings(String key, int value) { - ContentValues data = new ContentValues(); - data.put("key", key); - data.put("value", value); - rawSQL("REPLACE INTO %s %s", SETTINGS_TABLE, toSQL(data)); - } - - @Override - public int getSettings(String key, int defaultValue) { - List res = SQL("SELECT value FROM %s WHERE key=\"%s\"", SETTINGS_TABLE, key); - if (res.isEmpty()) - return defaultValue; - return res.get(0).getAsInteger("value"); - } - - @Override - public void setStrings(String key, String value) { - if (value == null) { - rawSQL("DELETE FROM %s WHERE key=\"%s\"", STRINGS_TABLE, key); - return; - } - ContentValues data = new ContentValues(); - data.put("key", key); - data.put("value", value); - rawSQL("REPLACE INTO %s %s", STRINGS_TABLE, toSQL(data)); - } - - @Override - public String getStrings(String key, String defaultValue) { - List res = SQL("SELECT value FROM %s WHERE key=\"%s\"", STRINGS_TABLE, key); - if (res.isEmpty()) - return defaultValue; - return res.get(0).getAsString("value"); - } -} diff --git a/app/src/full/java/com/topjohnwu/magisk/database/MagiskDBLegacy.java b/app/src/full/java/com/topjohnwu/magisk/database/MagiskDBLegacy.java deleted file mode 100644 index 490950eb8..000000000 --- a/app/src/full/java/com/topjohnwu/magisk/database/MagiskDBLegacy.java +++ /dev/null @@ -1,299 +0,0 @@ -package com.topjohnwu.magisk.database; - -import android.content.ContentValues; -import android.content.Context; -import android.content.pm.PackageManager; -import android.database.Cursor; -import android.database.DatabaseUtils; -import android.database.sqlite.SQLiteDatabase; -import android.os.Build; -import android.os.Process; -import android.text.TextUtils; -import android.widget.Toast; - -import com.topjohnwu.magisk.Const; -import com.topjohnwu.magisk.Data; -import com.topjohnwu.magisk.MagiskManager; -import com.topjohnwu.magisk.R; -import com.topjohnwu.magisk.container.Policy; -import com.topjohnwu.magisk.container.SuLogEntry; -import com.topjohnwu.magisk.utils.LocaleManager; -import com.topjohnwu.magisk.utils.Utils; -import com.topjohnwu.superuser.Shell; -import com.topjohnwu.superuser.io.SuFile; - -import java.text.DateFormat; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Date; -import java.util.List; - -public class MagiskDBLegacy extends MagiskDB { - - private static final int DATABASE_VER = 6; - private static final int OLD_DATABASE_VER = 5; - - private PackageManager pm; - private SQLiteDatabase db; - - static MagiskDBLegacy newInstance() { - try { - return new MagiskDBLegacy(); - } catch (Exception e) { - // Let's cleanup everything and try again - Shell.su("db_clean '*'").exec(); - return new MagiskDBLegacy(); - } - } - - private MagiskDBLegacy() { - pm = Data.MM().getPackageManager(); - db = openDatabase(); - db.disableWriteAheadLogging(); - int version = Data.magiskVersionCode >= Const.MAGISK_VER.DBVER_SIX ? DATABASE_VER : OLD_DATABASE_VER; - int curVersion = db.getVersion(); - if (curVersion < version) { - onUpgrade(db, curVersion); - } else if (curVersion > DATABASE_VER) { - /* Higher than we can possibly support */ - onDowngrade(db); - } - db.setVersion(version); - clearOutdated(); - } - - private SQLiteDatabase openDatabase() { - MagiskManager mm = Data.MM(); - Context de = Build.VERSION.SDK_INT >= Build.VERSION_CODES.N - ? mm.createDeviceProtectedStorageContext() : mm; - if (!LEGACY_MANAGER_DB.canWrite()) { - if (!Shell.rootAccess() || Data.magiskVersionCode < 0) { - // We don't want the app to crash, create a db and return - return mm.openOrCreateDatabase("su.db", Context.MODE_PRIVATE, null); - } - // Cleanup - Shell.su("db_clean " + Const.USER_ID).exec(); - // Global database - final SuFile GLOBAL_DB = new SuFile("/data/adb/magisk.db"); - mm.deleteDatabase("su.db"); - de.deleteDatabase("su.db"); - if (Data.magiskVersionCode < Const.MAGISK_VER.SEPOL_REFACTOR) { - // We need some additional policies on old versions - Shell.su("db_sepatch").exec(); - } - if (!GLOBAL_DB.exists()) { - Shell.su("db_init").exec(); - SQLiteDatabase.openOrCreateDatabase(GLOBAL_DB, null).close(); - Shell.su("db_restore").exec(); - } - Shell.su("db_setup " + Process.myUid()).exec(); - } - // Not using legacy mode, open the mounted global DB - return SQLiteDatabase.openOrCreateDatabase(LEGACY_MANAGER_DB, null); - } - - private void onUpgrade(SQLiteDatabase db, int oldVersion) { - if (oldVersion == 0) { - createTables(db); - oldVersion = 3; - } - if (oldVersion == 1) { - // We're dropping column app_name, rename and re-construct table - db.execSQL(Utils.fmt("ALTER TABLE %s RENAME TO %s_old", POLICY_TABLE)); - - // Create the new tables - createTables(db); - - // Migrate old data to new tables - db.execSQL(Utils.fmt("INSERT INTO %s SELECT " + - "uid, package_name, policy, until, logging, notification FROM %s_old", - POLICY_TABLE, POLICY_TABLE)); - db.execSQL(Utils.fmt("DROP TABLE %s_old", POLICY_TABLE)); - - Data.MM().deleteDatabase("sulog.db"); - ++oldVersion; - } - if (oldVersion == 2) { - db.execSQL(Utils.fmt("UPDATE %s SET time=time*1000", LOG_TABLE)); - ++oldVersion; - } - if (oldVersion == 3) { - db.execSQL(Utils.fmt("CREATE TABLE IF NOT EXISTS %s (key TEXT, value TEXT, PRIMARY KEY(key))", STRINGS_TABLE)); - ++oldVersion; - } - if (oldVersion == 4) { - db.execSQL(Utils.fmt("UPDATE %s SET uid=uid%%100000", POLICY_TABLE)); - ++oldVersion; - } - if (oldVersion == 5) { - setSettings(Const.Key.SU_FINGERPRINT, - Data.MM().prefs.getBoolean(Const.Key.SU_FINGERPRINT, false) ? 1 : 0); - ++oldVersion; - } - } - - // Remove everything, we do not support downgrade - private void onDowngrade(SQLiteDatabase db) { - Utils.toast(R.string.su_db_corrupt, Toast.LENGTH_LONG); - db.execSQL("DROP TABLE IF EXISTS " + POLICY_TABLE); - db.execSQL("DROP TABLE IF EXISTS " + LOG_TABLE); - db.execSQL("DROP TABLE IF EXISTS " + SETTINGS_TABLE); - db.execSQL("DROP TABLE IF EXISTS " + STRINGS_TABLE); - onUpgrade(db, 0); - } - - private void createTables(SQLiteDatabase db) { - // Policies - db.execSQL( - "CREATE TABLE IF NOT EXISTS " + POLICY_TABLE + " " + - "(uid INT, package_name TEXT, policy INT, " + - "until INT, logging INT, notification INT, " + - "PRIMARY KEY(uid))"); - - // Logs - db.execSQL( - "CREATE TABLE IF NOT EXISTS " + LOG_TABLE + " " + - "(from_uid INT, package_name TEXT, app_name TEXT, from_pid INT, " + - "to_uid INT, action INT, time INT, command TEXT)"); - - // Settings - db.execSQL( - "CREATE TABLE IF NOT EXISTS " + SETTINGS_TABLE + " " + - "(key TEXT, value INT, PRIMARY KEY(key))"); - } - - @Override - public void clearOutdated() { - // Clear outdated policies - db.delete(POLICY_TABLE, Utils.fmt("until > 0 AND until < %d", System.currentTimeMillis() / 1000), null); - // Clear outdated logs - db.delete(LOG_TABLE, Utils.fmt("time < %d", System.currentTimeMillis() - Data.suLogTimeout * 86400000), null); - } - - @Override - public void deletePolicy(String pkg) { - db.delete(POLICY_TABLE, "package_name=?", new String[] { pkg }); - } - - @Override - public void deletePolicy(int uid) { - db.delete(POLICY_TABLE, Utils.fmt("uid=%d", uid), null); - } - - @Override - public Policy getPolicy(int uid) { - Policy policy = null; - try (Cursor c = db.query(POLICY_TABLE, null, Utils.fmt("uid=%d", uid), null, null, null, null)) { - if (c.moveToNext()) { - ContentValues values = new ContentValues(); - DatabaseUtils.cursorRowToContentValues(c, values); - policy = new Policy(values, pm); - } - } catch (PackageManager.NameNotFoundException e) { - deletePolicy(uid); - return null; - } - return policy; - } - - @Override - public void updatePolicy(Policy policy) { - db.replace(POLICY_TABLE, null, policy.getContentValues()); - } - - @Override - public List getPolicyList() { - try (Cursor c = db.query(POLICY_TABLE, null, Utils.fmt("uid/100000=%d", Const.USER_ID), - null, null, null, null)) { - List ret = new ArrayList<>(c.getCount()); - while (c.moveToNext()) { - try { - ContentValues values = new ContentValues(); - DatabaseUtils.cursorRowToContentValues(c, values); - Policy policy = new Policy(values, pm); - ret.add(policy); - } catch (PackageManager.NameNotFoundException e) { - // The app no longer exist, remove from DB - deletePolicy(c.getInt(c.getColumnIndex("uid"))); - } - } - Collections.sort(ret); - return ret; - } - } - - @Override - public List> getLogs() { - try (Cursor c = db.query(LOG_TABLE, null, Utils.fmt("from_uid/100000=%d", Const.USER_ID), - null, null, null, "time DESC")) { - List> ret = new ArrayList<>(); - List list = null; - String dateString = null, newString; - while (c.moveToNext()) { - Date date = new Date(c.getLong(c.getColumnIndex("time"))); - newString = DateFormat.getDateInstance(DateFormat.MEDIUM, LocaleManager.locale).format(date); - if (!TextUtils.equals(dateString, newString)) { - dateString = newString; - list = new ArrayList<>(); - ret.add(list); - } - ContentValues values = new ContentValues(); - DatabaseUtils.cursorRowToContentValues(c, values); - list.add(new SuLogEntry(values)); - } - return ret; - } - } - - @Override - public void addLog(SuLogEntry log) { - db.insert(LOG_TABLE, null, log.getContentValues()); - } - - @Override - public void clearLogs() { - db.delete(LOG_TABLE, null, null); - } - - @Override - public void setSettings(String key, int value) { - ContentValues data = new ContentValues(); - data.put("key", key); - data.put("value", value); - db.replace(SETTINGS_TABLE, null, data); - } - - @Override - public int getSettings(String key, int defaultValue) { - int value = defaultValue; - try (Cursor c = db.query(SETTINGS_TABLE, null, "key=?",new String[] { key }, null, null, null)) { - if (c.moveToNext()) { - value = c.getInt(c.getColumnIndex("value")); - } - } - return value; - } - - @Override - public void setStrings(String key, String value) { - if (value == null) { - db.delete(STRINGS_TABLE, "key=?", new String[] { key }); - } else { - ContentValues data = new ContentValues(); - data.put("key", key); - data.put("value", value); - db.replace(STRINGS_TABLE, null, data); - } - } - - @Override - public String getStrings(String key, String defaultValue) { - String value = defaultValue; - try (Cursor c = db.query(STRINGS_TABLE, null, "key=?",new String[] { key }, null, null, null)) { - if (c.moveToNext()) { - value = c.getString(c.getColumnIndex("value")); - } - } - return value; - } -} diff --git a/app/src/full/java/com/topjohnwu/magisk/fragments/MagiskFragment.java b/app/src/full/java/com/topjohnwu/magisk/fragments/MagiskFragment.java index 06d789f41..995858d2f 100644 --- a/app/src/full/java/com/topjohnwu/magisk/fragments/MagiskFragment.java +++ b/app/src/full/java/com/topjohnwu/magisk/fragments/MagiskFragment.java @@ -271,8 +271,7 @@ public class MagiskFragment extends BaseFragment if (Data.remoteMagiskVersionCode > Data.magiskVersionCode || Data.remoteManagerVersionCode > BuildConfig.VERSION_CODE) { install(); - } else if (Data.remoteMagiskVersionCode >= Const.MAGISK_VER.FIX_ENV && - !ShellUtils.fastCmdResult("env_check")) { + } else if (!ShellUtils.fastCmdResult("env_check")) { new EnvFixDialog(requireActivity()).show(); } } diff --git a/app/src/full/java/com/topjohnwu/magisk/receivers/GeneralReceiver.java b/app/src/full/java/com/topjohnwu/magisk/receivers/GeneralReceiver.java index d1cbfde46..e861c554b 100644 --- a/app/src/full/java/com/topjohnwu/magisk/receivers/GeneralReceiver.java +++ b/app/src/full/java/com/topjohnwu/magisk/receivers/GeneralReceiver.java @@ -36,12 +36,11 @@ public class GeneralReceiver extends BroadcastReceiver { case "request": Intent i = new Intent(mm, Data.classMap.get(SuRequestActivity.class)) .putExtra("socket", intent.getStringExtra("socket")) - .putExtra("version", 2) .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); mm.startActivity(i); break; case "log": - SuConnector.handleLogs(intent, 2); + SuConnector.handleLogs(intent); break; case "notify": SuConnector.handleNotify(intent); diff --git a/app/src/full/java/com/topjohnwu/magisk/superuser/RequestActivity.java b/app/src/full/java/com/topjohnwu/magisk/superuser/RequestActivity.java deleted file mode 100644 index 3f8a2cbde..000000000 --- a/app/src/full/java/com/topjohnwu/magisk/superuser/RequestActivity.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.topjohnwu.magisk.superuser; - -import android.content.Intent; -import android.os.Bundle; - -import com.topjohnwu.magisk.Data; -import com.topjohnwu.magisk.SuRequestActivity; -import com.topjohnwu.magisk.components.BaseActivity; - -public class RequestActivity extends BaseActivity { - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - Intent intent = new Intent(this, Data.classMap.get(SuRequestActivity.class)) - .putExtra("socket", getIntent().getStringExtra("socket")) - .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - startActivity(intent); - finish(); - } -} diff --git a/app/src/full/java/com/topjohnwu/magisk/superuser/SuReceiver.java b/app/src/full/java/com/topjohnwu/magisk/superuser/SuReceiver.java deleted file mode 100644 index e247c42ec..000000000 --- a/app/src/full/java/com/topjohnwu/magisk/superuser/SuReceiver.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.topjohnwu.magisk.superuser; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; - -import com.topjohnwu.magisk.utils.SuConnector; - -public class SuReceiver extends BroadcastReceiver { - - @Override - public void onReceive(Context context, Intent intent) { - if (intent != null) - SuConnector.handleLogs(intent, 1); - } -} diff --git a/app/src/full/java/com/topjohnwu/magisk/utils/BootSigner.java b/app/src/full/java/com/topjohnwu/magisk/utils/BootSigner.java index a3a37a970..bb150c661 100644 --- a/app/src/full/java/com/topjohnwu/magisk/utils/BootSigner.java +++ b/app/src/full/java/com/topjohnwu/magisk/utils/BootSigner.java @@ -9,7 +9,6 @@ import androidx.annotation.Keep; public class BootSigner { - @Keep public static void main(String[] args) throws Exception { if (args.length > 0 && "-verify".equals(args[0])) { String certPath = ""; diff --git a/app/src/full/java/com/topjohnwu/magisk/utils/RootUtils.java b/app/src/full/java/com/topjohnwu/magisk/utils/RootUtils.java index dbf4e02a3..ac3e52b02 100644 --- a/app/src/full/java/com/topjohnwu/magisk/utils/RootUtils.java +++ b/app/src/full/java/com/topjohnwu/magisk/utils/RootUtils.java @@ -21,10 +21,6 @@ public class RootUtils extends Shell.Initializer { BusyBox.BB_PATH = new File(Const.BUSYBOX_PATH); } - public static void uninstallPkg(String pkg) { - Shell.su("db_clean " + Const.USER_ID, "pm uninstall " + pkg).exec(); - } - public static void rmAndLaunch(String rm, String launch) { Shell.su(Utils.fmt("(rm_launch %d %s %s)&", Const.USER_ID, rm, launch)).exec(); } @@ -33,9 +29,6 @@ public class RootUtils extends Shell.Initializer { public boolean onInit(Context context, @NonNull Shell shell) { Shell.Job job = shell.newJob(); if (shell.isRoot()) { - if (!new SuFile("/sbin/.magisk").exists()) - job.add("ln -s /sbin/.core /sbin/.magisk"); - job.add(context.getResources().openRawResource(R.raw.util_functions)) .add(context.getResources().openRawResource(R.raw.utils)); Const.MAGISK_DISABLE_FILE = new SuFile("/cache/.disable_magisk"); diff --git a/app/src/full/java/com/topjohnwu/magisk/utils/SuConnector.java b/app/src/full/java/com/topjohnwu/magisk/utils/SuConnector.java index 7ca379186..6dac1b811 100644 --- a/app/src/full/java/com/topjohnwu/magisk/utils/SuConnector.java +++ b/app/src/full/java/com/topjohnwu/magisk/utils/SuConnector.java @@ -3,6 +3,7 @@ package com.topjohnwu.magisk.utils; import android.content.Intent; import android.content.pm.PackageManager; import android.net.LocalSocket; +import android.net.LocalSocketAddress; import android.os.Bundle; import android.os.Process; import android.text.TextUtils; @@ -24,12 +25,13 @@ import java.util.Date; public abstract class SuConnector { - protected LocalSocket socket = new LocalSocket(); + private LocalSocket socket; protected DataOutputStream out; protected DataInputStream in; public SuConnector(String name) throws IOException { - connect(name); + socket = new LocalSocket(); + socket.connect(new LocalSocketAddress(name, LocalSocketAddress.Namespace.ABSTRACT)); out = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream())); in = new DataInputStream(new BufferedInputStream(socket.getInputStream())); } @@ -66,11 +68,9 @@ public abstract class SuConnector { } catch (IOException ignored) { } } - public abstract void connect(String name) throws IOException; - protected abstract void onResponse() throws IOException; - public static void handleLogs(Intent intent, int version) { + public static void handleLogs(Intent intent) { int fromUid = intent.getIntExtra("from.uid", -1); if (fromUid < 0) return; @@ -97,24 +97,9 @@ public abstract class SuConnector { notify = policy.notification; } - if (version == 1) { - String action = intent.getStringExtra("action"); - if (action == null) return; - switch (action) { - case "allow": - policy.policy = Policy.ALLOW; - break; - case "deny": - policy.policy = Policy.DENY; - break; - default: - return; - } - } else { - policy.policy = data.getInt("policy", -1); - if (policy.policy < 0) - return; - } + policy.policy = data.getInt("policy", -1); + if (policy.policy < 0) + return; if (notify) handleNotify(policy); diff --git a/app/src/full/res/raw/utils.sh b/app/src/full/res/raw/utils.sh index d5432a21b..c9970257f 100644 --- a/app/src/full/res/raw/utils.sh +++ b/app/src/full/res/raw/utils.sh @@ -1,42 +1,3 @@ -db_sepatch() { - magiskpolicy --live 'create magisk_file' 'attradd magisk_file mlstrustedobject' \ - 'allow * magisk_file file *' 'allow * magisk_file dir *' \ - 'allow magisk_file * filesystem associate' -} - -db_clean() { - local USERID=$1 - local DIR="/sbin/.magisk/db-${USERID}" - umount -l /data/user*/*/*/databases/su.db $DIR $DIR/* - rm -rf $DIR - [ "$USERID" = "*" ] && rm -fv /data/adb/magisk.db* -} - -db_init() { - # Temporary let the folder rw by anyone - chcon u:object_r:magisk_file:s0 /data/adb - chmod 777 /data/adb -} - -db_restore() { - chmod 700 /data/adb - magisk --restorecon -} - -db_setup() { - local USER=$1 - local USERID=$(($USER / 100000)) - local DIR=/sbin/.magisk/db-${USERID} - mkdir -p $DIR - touch $DIR/magisk.db - mount -o bind /data/adb/magisk.db $DIR/magisk.db - rm -f /data/adb/magisk.db-* - chcon u:object_r:magisk_file:s0 $DIR $DIR/* - chmod 700 $DIR - chown $USER.$USER $DIR - chmod 666 $DIR/* -} - env_check() { for file in busybox magisk magiskboot magiskinit util_functions.sh boot_patch.sh; do [ -f /data/adb/magisk/$file ] || return 1