mirror of
https://github.com/topjohnwu/Magisk.git
synced 2024-11-24 18:45:28 +00:00
Update the method to handle global su db
This commit is contained in:
parent
b05d2d3a2d
commit
3f55be9676
@ -119,7 +119,7 @@ public class MagiskManager extends Shell.ContainerApp {
|
|||||||
} catch (PackageManager.NameNotFoundException ignored) { /* Expected */ }
|
} catch (PackageManager.NameNotFoundException ignored) { /* Expected */ }
|
||||||
}
|
}
|
||||||
|
|
||||||
suDB = SuDatabaseHelper.getSuDB(false);
|
suDB = SuDatabaseHelper.getInstance(this);
|
||||||
repoDB = new RepoDatabaseHelper(this);
|
repoDB = new RepoDatabaseHelper(this);
|
||||||
defaultLocale = Locale.getDefault();
|
defaultLocale = Locale.getDefault();
|
||||||
setLocale();
|
setLocale();
|
||||||
@ -219,11 +219,6 @@ public class MagiskManager extends Shell.ContainerApp {
|
|||||||
ret = Shell.Sync.su("echo \"$BOOTIMAGE\"");
|
ret = Shell.Sync.su("echo \"$BOOTIMAGE\"");
|
||||||
if (Utils.isValidShellResponse(ret))
|
if (Utils.isValidShellResponse(ret))
|
||||||
bootBlock = ret.get(0);
|
bootBlock = ret.get(0);
|
||||||
|
|
||||||
if (suDB != null && !SuDatabaseHelper.verified) {
|
|
||||||
suDB.close();
|
|
||||||
suDB = SuDatabaseHelper.getSuDB(true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void getDefaultInstallFlags() {
|
public void getDefaultInstallFlags() {
|
||||||
|
@ -4,13 +4,13 @@ import android.app.Activity;
|
|||||||
import android.app.ProgressDialog;
|
import android.app.ProgressDialog;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import com.topjohnwu.utils.JarMap;
|
|
||||||
import com.topjohnwu.magisk.MagiskManager;
|
import com.topjohnwu.magisk.MagiskManager;
|
||||||
import com.topjohnwu.magisk.R;
|
import com.topjohnwu.magisk.R;
|
||||||
import com.topjohnwu.magisk.utils.Const;
|
import com.topjohnwu.magisk.utils.Const;
|
||||||
import com.topjohnwu.magisk.utils.Utils;
|
import com.topjohnwu.magisk.utils.Utils;
|
||||||
import com.topjohnwu.magisk.utils.ZipUtils;
|
import com.topjohnwu.magisk.utils.ZipUtils;
|
||||||
import com.topjohnwu.superuser.Shell;
|
import com.topjohnwu.superuser.Shell;
|
||||||
|
import com.topjohnwu.utils.JarMap;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
|
@ -7,7 +7,6 @@ import android.os.Build;
|
|||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
import com.topjohnwu.utils.SignBoot;
|
|
||||||
import com.topjohnwu.magisk.FlashActivity;
|
import com.topjohnwu.magisk.FlashActivity;
|
||||||
import com.topjohnwu.magisk.MagiskManager;
|
import com.topjohnwu.magisk.MagiskManager;
|
||||||
import com.topjohnwu.magisk.container.TarEntry;
|
import com.topjohnwu.magisk.container.TarEntry;
|
||||||
@ -15,6 +14,7 @@ import com.topjohnwu.magisk.utils.Const;
|
|||||||
import com.topjohnwu.magisk.utils.Utils;
|
import com.topjohnwu.magisk.utils.Utils;
|
||||||
import com.topjohnwu.magisk.utils.ZipUtils;
|
import com.topjohnwu.magisk.utils.ZipUtils;
|
||||||
import com.topjohnwu.superuser.Shell;
|
import com.topjohnwu.superuser.Shell;
|
||||||
|
import com.topjohnwu.utils.SignBoot;
|
||||||
|
|
||||||
import org.kamranzafar.jtar.TarInputStream;
|
import org.kamranzafar.jtar.TarInputStream;
|
||||||
import org.kamranzafar.jtar.TarOutputStream;
|
import org.kamranzafar.jtar.TarOutputStream;
|
||||||
|
@ -5,8 +5,8 @@ import android.content.Context;
|
|||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
import android.database.sqlite.SQLiteDatabase;
|
import android.database.sqlite.SQLiteDatabase;
|
||||||
import android.database.sqlite.SQLiteOpenHelper;
|
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
|
import android.os.Process;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
@ -25,142 +25,99 @@ import java.util.Collections;
|
|||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class SuDatabaseHelper extends SQLiteOpenHelper {
|
public class SuDatabaseHelper {
|
||||||
|
|
||||||
public static final String DB_NAME = "su.db";
|
|
||||||
public static boolean verified = false;
|
|
||||||
|
|
||||||
private static final int DATABASE_VER = 5;
|
private static final int DATABASE_VER = 5;
|
||||||
private static final String POLICY_TABLE = "policies";
|
private static final String POLICY_TABLE = "policies";
|
||||||
private static final String LOG_TABLE = "logs";
|
private static final String LOG_TABLE = "logs";
|
||||||
private static final String SETTINGS_TABLE = "settings";
|
private static final String SETTINGS_TABLE = "settings";
|
||||||
private static final String STRINGS_TABLE = "strings";
|
private static final String STRINGS_TABLE = "strings";
|
||||||
private static final File GLOBAL_DB = new File("/data/adb/magisk.db");
|
|
||||||
|
|
||||||
private Context mContext;
|
|
||||||
private PackageManager pm;
|
private PackageManager pm;
|
||||||
private SQLiteDatabase mDb;
|
private SQLiteDatabase mDb;
|
||||||
|
|
||||||
private static void unmntDB() {
|
public static SuDatabaseHelper getInstance(MagiskManager mm) {
|
||||||
Shell.Sync.su(Utils.fmt("umount -l /data/user*/*/%s/*/*.db", MagiskManager.get().getPackageName()));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Context initDB(boolean verify) {
|
|
||||||
Context context, de = null;
|
|
||||||
MagiskManager ce = MagiskManager.get();
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
|
||||||
de = ce.createDeviceProtectedStorageContext();
|
|
||||||
File ceDB = Utils.getDB(ce, DB_NAME);
|
|
||||||
if (ceDB.exists()) {
|
|
||||||
context = ce;
|
|
||||||
} else {
|
|
||||||
context = de;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
context = ce;
|
|
||||||
}
|
|
||||||
|
|
||||||
File db = Utils.getDB(context, DB_NAME);
|
|
||||||
if (!verify) {
|
|
||||||
if (db.exists() && db.length() == 0) {
|
|
||||||
ce.loadMagiskInfo();
|
|
||||||
// Continue verification
|
|
||||||
} else {
|
|
||||||
return context;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Encryption storage
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
|
||||||
if (ce.magiskVersionCode < 1410) {
|
|
||||||
if (context == de) {
|
|
||||||
unmntDB();
|
|
||||||
ce.moveDatabaseFrom(de, DB_NAME);
|
|
||||||
context = ce;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (context == ce) {
|
|
||||||
unmntDB();
|
|
||||||
de.moveDatabaseFrom(ce, DB_NAME);
|
|
||||||
context = de;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Context might be updated
|
|
||||||
db = Utils.getDB(context, DB_NAME);
|
|
||||||
|
|
||||||
if (!Shell.rootAccess())
|
|
||||||
return context;
|
|
||||||
|
|
||||||
// Verify the global db matches the local with the same inode
|
|
||||||
if (ce.magiskVersionCode >= 1450 && ce.magiskVersionCode < 1460) {
|
|
||||||
// v14.5 global su db
|
|
||||||
File OLD_GLOBAL_DB = new File(context.getFilesDir().getParentFile().getParentFile(), "magisk.db");
|
|
||||||
verified = TextUtils.equals(Utils.checkInode(OLD_GLOBAL_DB), Utils.checkInode(db));
|
|
||||||
if (!verified) {
|
|
||||||
context.deleteDatabase(DB_NAME);
|
|
||||||
db.getParentFile().mkdirs();
|
|
||||||
Shell.Sync.su(Utils.fmt("magisk --clone-attr %s %s; chmod 600 %s; ln %s %s",
|
|
||||||
context.getFilesDir(), OLD_GLOBAL_DB, OLD_GLOBAL_DB, OLD_GLOBAL_DB, db));
|
|
||||||
verified = TextUtils.equals(Utils.checkInode(OLD_GLOBAL_DB), Utils.checkInode(db));
|
|
||||||
}
|
|
||||||
} else if (ce.magiskVersionCode >= 1464) {
|
|
||||||
// New global su db
|
|
||||||
Shell.Sync.su(Utils.fmt("mkdir %s 2>/dev/null; chmod 700 %s", GLOBAL_DB.getParent(), GLOBAL_DB.getParent()));
|
|
||||||
if (!Utils.itemExist(GLOBAL_DB)) {
|
|
||||||
context.openOrCreateDatabase(DB_NAME, 0, null).close();
|
|
||||||
Shell.Sync.su(Utils.fmt("cp -af %s %s; rm -f %s*", db, GLOBAL_DB, db));
|
|
||||||
}
|
|
||||||
verified = TextUtils.equals(Utils.checkInode(GLOBAL_DB), Utils.checkInode(db));
|
|
||||||
if (!verified) {
|
|
||||||
context.deleteDatabase(DB_NAME);
|
|
||||||
Utils.javaCreateFile(db);
|
|
||||||
Shell.Sync.su(Utils.fmt(
|
|
||||||
"chown 0.0 %s; chmod 666 %s; chcon u:object_r:su_file:s0 %s;" +
|
|
||||||
"mount -o bind %s %s",
|
|
||||||
GLOBAL_DB, GLOBAL_DB, GLOBAL_DB, GLOBAL_DB, db));
|
|
||||||
verified = TextUtils.equals(Utils.checkInode(GLOBAL_DB), Utils.checkInode(db));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return context;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static SuDatabaseHelper getSuDB(boolean verify) {
|
|
||||||
try {
|
try {
|
||||||
return new SuDatabaseHelper(initDB(verify));
|
return new SuDatabaseHelper(mm);
|
||||||
} catch(Exception e) {
|
} catch (Exception e) {
|
||||||
// Try to catch runtime exceptions and remove all db for retry
|
// Let's cleanup and try again
|
||||||
unmntDB();
|
cleanup();
|
||||||
Shell.Sync.su(Utils.fmt("rm -rf /data/user*/*/magisk.db /data/adb/magisk.db /data/user*/*/%s/databases",
|
return new SuDatabaseHelper(mm);
|
||||||
MagiskManager.get().getPackageName()));
|
|
||||||
e.printStackTrace();
|
|
||||||
return new SuDatabaseHelper(initDB(false));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private SuDatabaseHelper(Context context) {
|
public static void cleanup() {
|
||||||
super(context, DB_NAME, null, DATABASE_VER);
|
Shell.Sync.su(
|
||||||
mContext = context;
|
"umount -l /data/user*/*/*/databases/su.db /sbin/.core/db-*/magisk.db",
|
||||||
pm = context.getPackageManager();
|
"rm -rf /sbin/.core/db-*");
|
||||||
mDb = getWritableDatabase();
|
}
|
||||||
cleanup();
|
|
||||||
|
|
||||||
if (context.getPackageName().equals(Const.ORIG_PKG_NAME)) {
|
private SuDatabaseHelper(MagiskManager mm) {
|
||||||
String pkg = getStrings(Const.Key.SU_REQUESTER, null);
|
pm = mm.getPackageManager();
|
||||||
if (pkg != null) {
|
mDb = openDatabase(mm);
|
||||||
Utils.uninstallPkg(pkg);
|
clearOutdated();
|
||||||
setStrings(Const.Key.SU_REQUESTER, null);
|
}
|
||||||
|
|
||||||
|
private SQLiteDatabase openDatabase(MagiskManager mm) {
|
||||||
|
SQLiteDatabase db = null;
|
||||||
|
String GLOBAL_DB = "/data/adb/magisk.db";
|
||||||
|
File dbFile = new File(Utils.fmt("/sbin/.core/db-%s/magisk.db", mm.getPackageName()));
|
||||||
|
Context de = Build.VERSION.SDK_INT >= Build.VERSION_CODES.N
|
||||||
|
? mm.createDeviceProtectedStorageContext() : mm;
|
||||||
|
if (!dbFile.exists()) {
|
||||||
|
if (!Shell.rootAccess()) {
|
||||||
|
// We don't want the app to crash, create a db and return
|
||||||
|
return mm.openOrCreateDatabase("su.db", Context.MODE_PRIVATE, null);
|
||||||
|
}
|
||||||
|
mm.loadMagiskInfo();
|
||||||
|
// Cleanup
|
||||||
|
cleanup();
|
||||||
|
if (mm.magiskVersionCode < 1410) {
|
||||||
|
// Super old legacy mode
|
||||||
|
db = mm.openOrCreateDatabase("su.db", Context.MODE_PRIVATE, null);
|
||||||
|
} else if (mm.magiskVersionCode < 1450) {
|
||||||
|
// Legacy mode with FBE aware
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||||
|
de.moveDatabaseFrom(mm, "su.db");
|
||||||
|
}
|
||||||
|
db = de.openOrCreateDatabase("su.db", Context.MODE_PRIVATE, null);
|
||||||
|
} else {
|
||||||
|
mm.deleteDatabase("su.db");
|
||||||
|
de.deleteDatabase("su.db");
|
||||||
|
if (mm.magiskVersionCode < 1460) {
|
||||||
|
// v14.5 global DB location
|
||||||
|
GLOBAL_DB = new File(de.getFilesDir().getParentFile().getParentFile(),
|
||||||
|
"magisk.db").getPath();
|
||||||
|
// We need some additional policies on old versions
|
||||||
|
Shell.Sync.su("magiskpolicy --live 'create su_file' 'allow * su_file file *'");
|
||||||
|
}
|
||||||
|
// Touch global DB and setup db in tmpfs
|
||||||
|
Shell.Sync.su(Utils.fmt("touch %s; mkdir -p %s; touch %s; touch %s-journal;" +
|
||||||
|
"mount -o bind %s %s;" +
|
||||||
|
"chcon u:object_r:su_file:s0 %s/*; chown %d.%d %s;" +
|
||||||
|
"chmod 666 %s/*; chmod 700 %s;",
|
||||||
|
GLOBAL_DB, dbFile.getParent(), dbFile, dbFile,
|
||||||
|
GLOBAL_DB, dbFile,
|
||||||
|
dbFile.getParent(), Process.myUid(), Process.myUid(), dbFile.getParent(),
|
||||||
|
dbFile.getParent(), dbFile.getParent()
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (db == null) {
|
||||||
|
// Not using legacy mode, open the mounted global DB
|
||||||
|
db = SQLiteDatabase.openOrCreateDatabase(dbFile, null);
|
||||||
|
}
|
||||||
|
int version = db.getVersion();
|
||||||
|
if (version < DATABASE_VER) {
|
||||||
|
onUpgrade(db, version);
|
||||||
|
} else if (version > DATABASE_VER) {
|
||||||
|
onDowngrade(db);
|
||||||
|
}
|
||||||
|
db.setVersion(DATABASE_VER);
|
||||||
|
return db;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public void onUpgrade(SQLiteDatabase db, int oldVersion) {
|
||||||
public void onCreate(SQLiteDatabase db) {
|
|
||||||
onUpgrade(db, 0, DATABASE_VER);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
|
|
||||||
try {
|
try {
|
||||||
if (oldVersion == 0) {
|
if (oldVersion == 0) {
|
||||||
createTables(db);
|
createTables(db);
|
||||||
@ -196,23 +153,18 @@ public class SuDatabaseHelper extends SQLiteOpenHelper {
|
|||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
onDowngrade(db, DATABASE_VER, 0);
|
onDowngrade(db);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
// Remove everything, we do not support downgrade
|
||||||
public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
|
public void onDowngrade(SQLiteDatabase db) {
|
||||||
MagiskManager.toast(R.string.su_db_corrupt, Toast.LENGTH_LONG);
|
MagiskManager.toast(R.string.su_db_corrupt, Toast.LENGTH_LONG);
|
||||||
// Remove everything, we do not support downgrade
|
|
||||||
db.execSQL("DROP TABLE IF EXISTS " + POLICY_TABLE);
|
db.execSQL("DROP TABLE IF EXISTS " + POLICY_TABLE);
|
||||||
db.execSQL("DROP TABLE IF EXISTS " + LOG_TABLE);
|
db.execSQL("DROP TABLE IF EXISTS " + LOG_TABLE);
|
||||||
db.execSQL("DROP TABLE IF EXISTS " + SETTINGS_TABLE);
|
db.execSQL("DROP TABLE IF EXISTS " + SETTINGS_TABLE);
|
||||||
db.execSQL("DROP TABLE IF EXISTS " + STRINGS_TABLE);
|
db.execSQL("DROP TABLE IF EXISTS " + STRINGS_TABLE);
|
||||||
onUpgrade(db, 0, DATABASE_VER);
|
onUpgrade(db, 0);
|
||||||
}
|
|
||||||
|
|
||||||
public File getDbFile() {
|
|
||||||
return mContext.getDatabasePath(DB_NAME);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createTables(SQLiteDatabase db) {
|
private void createTables(SQLiteDatabase db) {
|
||||||
@ -235,7 +187,7 @@ public class SuDatabaseHelper extends SQLiteOpenHelper {
|
|||||||
"(key TEXT, value INT, PRIMARY KEY(key))");
|
"(key TEXT, value INT, PRIMARY KEY(key))");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void cleanup() {
|
public void clearOutdated() {
|
||||||
// Clear outdated policies
|
// Clear outdated policies
|
||||||
mDb.delete(POLICY_TABLE, Utils.fmt("until > 0 AND until < %d", System.currentTimeMillis() / 1000), null);
|
mDb.delete(POLICY_TABLE, Utils.fmt("until > 0 AND until < %d", System.currentTimeMillis() / 1000), null);
|
||||||
// Clear outdated logs
|
// Clear outdated logs
|
||||||
|
@ -68,7 +68,7 @@ public class RequestActivity extends Activity {
|
|||||||
|
|
||||||
pm = getPackageManager();
|
pm = getPackageManager();
|
||||||
mm = Utils.getMagiskManager(this);
|
mm = Utils.getMagiskManager(this);
|
||||||
mm.suDB.cleanup();
|
mm.suDB.clearOutdated();
|
||||||
|
|
||||||
Intent intent = getIntent();
|
Intent intent = getIntent();
|
||||||
socketPath = intent.getStringExtra("socket");
|
socketPath = intent.getStringExtra("socket");
|
||||||
|
@ -28,6 +28,7 @@ import com.topjohnwu.magisk.MagiskManager;
|
|||||||
import com.topjohnwu.magisk.R;
|
import com.topjohnwu.magisk.R;
|
||||||
import com.topjohnwu.magisk.SplashActivity;
|
import com.topjohnwu.magisk.SplashActivity;
|
||||||
import com.topjohnwu.magisk.components.SnackbarMaker;
|
import com.topjohnwu.magisk.components.SnackbarMaker;
|
||||||
|
import com.topjohnwu.magisk.database.SuDatabaseHelper;
|
||||||
import com.topjohnwu.magisk.receivers.DownloadReceiver;
|
import com.topjohnwu.magisk.receivers.DownloadReceiver;
|
||||||
import com.topjohnwu.superuser.Shell;
|
import com.topjohnwu.superuser.Shell;
|
||||||
|
|
||||||
@ -80,7 +81,8 @@ public class Utils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void uninstallPkg(String pkg) {
|
public static void uninstallPkg(String pkg) {
|
||||||
Shell.Sync.su(fmt("umount -l /data/user*/*/%s/*/*.db 2>/dev/null; pm uninstall %s", pkg, pkg));
|
SuDatabaseHelper.cleanup();
|
||||||
|
Shell.Sync.su("pm uninstall " + pkg);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void dlAndReceive(Context context, DownloadReceiver receiver, String link, String filename) {
|
public static void dlAndReceive(Context context, DownloadReceiver receiver, String link, String filename) {
|
||||||
|
Loading…
Reference in New Issue
Block a user