diff --git a/app/src/main/java/com/topjohnwu/magisk/core/tasks/MagiskInstaller.kt b/app/src/main/java/com/topjohnwu/magisk/core/tasks/MagiskInstaller.kt index b7f1d4a23..882ab9968 100644 --- a/app/src/main/java/com/topjohnwu/magisk/core/tasks/MagiskInstaller.kt +++ b/app/src/main/java/com/topjohnwu/magisk/core/tasks/MagiskInstaller.kt @@ -20,13 +20,11 @@ import com.topjohnwu.magisk.core.isRunningAsStub import com.topjohnwu.magisk.core.ktx.copyAndClose import com.topjohnwu.magisk.core.ktx.reboot import com.topjohnwu.magisk.core.ktx.toast -import com.topjohnwu.magisk.core.ktx.withStreams import com.topjohnwu.magisk.core.ktx.writeTo import com.topjohnwu.magisk.core.utils.MediaStoreUtils import com.topjohnwu.magisk.core.utils.MediaStoreUtils.inputStream import com.topjohnwu.magisk.core.utils.MediaStoreUtils.outputStream import com.topjohnwu.magisk.core.utils.RootUtils -import com.topjohnwu.magisk.signing.SignBoot import com.topjohnwu.superuser.Shell import com.topjohnwu.superuser.ShellUtils import com.topjohnwu.superuser.internal.NOPList @@ -481,22 +479,6 @@ abstract class MagiskInstallImpl protected constructor( } private fun patchBoot(): Boolean { - var isSigned = false - if (!srcBoot.isCharacter) { - try { - srcBoot.newInputStream().use { - if (SignBoot.verifySignature(it, null)) { - isSigned = true - console.add("- Boot image is signed with AVB 1.0") - } - } - } catch (e: IOException) { - console.add("! Unable to check signature") - Timber.e(e) - return false - } - } - val newBoot = installDir.getChildFile("new-boot.img") if (!useRootDir) { // Create output files before hand @@ -511,31 +493,11 @@ abstract class MagiskInstallImpl protected constructor( "PATCHVBMETAFLAG=${Config.patchVbmeta} " + "RECOVERYMODE=${Config.recovery} " + "SYSTEM_ROOT=${Info.isSAR} " + - "sh boot_patch.sh $srcBoot") + "sh boot_patch.sh $srcBoot", + "./magiskboot cleanup", + "cd /") - if (!cmds.sh().isSuccess) - return false - - val job = shell.newJob().add("./magiskboot cleanup", "cd /") - - if (isSigned) { - console.add("- Signing boot image with verity keys") - val signed = File.createTempFile("signed", ".img", context.cacheDir) - try { - val src = newBoot.newInputStream().buffered() - val out = signed.outputStream().buffered() - withStreams(src, out) { _, _ -> - SignBoot.doSignature(null, null, src, out, "/boot") - } - } catch (e: IOException) { - console.add("! Unable to sign image") - Timber.e(e) - return false - } - job.add("cat $signed > $newBoot", "rm -f $signed") - } - job.exec() - return true + return cmds.sh().isSuccess } private fun flashBoot() = "direct_install $installDir $srcBoot".sh().isSuccess diff --git a/app/src/main/java/com/topjohnwu/magisk/signing/CryptoUtils.java b/app/src/main/java/com/topjohnwu/magisk/signing/CryptoUtils.java deleted file mode 100644 index 0edecc0a2..000000000 --- a/app/src/main/java/com/topjohnwu/magisk/signing/CryptoUtils.java +++ /dev/null @@ -1,115 +0,0 @@ -package com.topjohnwu.magisk.signing; - -import org.bouncycastle.asn1.ASN1InputStream; -import org.bouncycastle.asn1.ASN1ObjectIdentifier; -import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; -import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; -import org.bouncycastle.asn1.x509.AlgorithmIdentifier; -import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.security.GeneralSecurityException; -import java.security.Key; -import java.security.KeyFactory; -import java.security.PrivateKey; -import java.security.PublicKey; -import java.security.cert.CertificateFactory; -import java.security.cert.X509Certificate; -import java.security.spec.ECPrivateKeySpec; -import java.security.spec.ECPublicKeySpec; -import java.security.spec.InvalidKeySpecException; -import java.security.spec.PKCS8EncodedKeySpec; -import java.util.HashMap; -import java.util.Map; - -public class CryptoUtils { - - static final Map ID_TO_ALG; - static final Map ALG_TO_ID; - - static { - ID_TO_ALG = new HashMap<>(); - ALG_TO_ID = new HashMap<>(); - ID_TO_ALG.put(X9ObjectIdentifiers.ecdsa_with_SHA256.getId(), "SHA256withECDSA"); - ID_TO_ALG.put(X9ObjectIdentifiers.ecdsa_with_SHA384.getId(), "SHA384withECDSA"); - ID_TO_ALG.put(X9ObjectIdentifiers.ecdsa_with_SHA512.getId(), "SHA512withECDSA"); - ID_TO_ALG.put(PKCSObjectIdentifiers.sha1WithRSAEncryption.getId(), "SHA1withRSA"); - ID_TO_ALG.put(PKCSObjectIdentifiers.sha256WithRSAEncryption.getId(), "SHA256withRSA"); - ID_TO_ALG.put(PKCSObjectIdentifiers.sha512WithRSAEncryption.getId(), "SHA512withRSA"); - ALG_TO_ID.put("SHA256withECDSA", X9ObjectIdentifiers.ecdsa_with_SHA256.getId()); - ALG_TO_ID.put("SHA384withECDSA", X9ObjectIdentifiers.ecdsa_with_SHA384.getId()); - ALG_TO_ID.put("SHA512withECDSA", X9ObjectIdentifiers.ecdsa_with_SHA512.getId()); - ALG_TO_ID.put("SHA1withRSA", PKCSObjectIdentifiers.sha1WithRSAEncryption.getId()); - ALG_TO_ID.put("SHA256withRSA", PKCSObjectIdentifiers.sha256WithRSAEncryption.getId()); - ALG_TO_ID.put("SHA512withRSA", PKCSObjectIdentifiers.sha512WithRSAEncryption.getId()); - } - - static String getSignatureAlgorithm(Key key) throws Exception { - if ("EC".equals(key.getAlgorithm())) { - int curveSize; - KeyFactory factory = KeyFactory.getInstance("EC"); - if (key instanceof PublicKey) { - ECPublicKeySpec spec = factory.getKeySpec(key, ECPublicKeySpec.class); - curveSize = spec.getParams().getCurve().getField().getFieldSize(); - } else if (key instanceof PrivateKey) { - ECPrivateKeySpec spec = factory.getKeySpec(key, ECPrivateKeySpec.class); - curveSize = spec.getParams().getCurve().getField().getFieldSize(); - } else { - throw new InvalidKeySpecException(); - } - if (curveSize <= 256) { - return "SHA256withECDSA"; - } else if (curveSize <= 384) { - return "SHA384withECDSA"; - } else { - return "SHA512withECDSA"; - } - } else if ("RSA".equals(key.getAlgorithm())) { - return "SHA256withRSA"; - } else { - throw new IllegalArgumentException("Unsupported key type " + key.getAlgorithm()); - } - } - - static AlgorithmIdentifier getSignatureAlgorithmIdentifier(Key key) throws Exception { - String id = ALG_TO_ID.get(getSignatureAlgorithm(key)); - if (id == null) { - throw new IllegalArgumentException("Unsupported key type " + key.getAlgorithm()); - } - return new AlgorithmIdentifier(new ASN1ObjectIdentifier(id)); - } - - public static X509Certificate readCertificate(InputStream input) - throws IOException, GeneralSecurityException { - try { - CertificateFactory cf = CertificateFactory.getInstance("X.509"); - return (X509Certificate) cf.generateCertificate(input); - } finally { - input.close(); - } - } - - /** Read a PKCS#8 format private key. */ - public static PrivateKey readPrivateKey(InputStream input) - throws IOException, GeneralSecurityException { - try { - ByteArrayStream buf = new ByteArrayStream(); - buf.readFrom(input); - byte[] bytes = buf.toByteArray(); - /* Check to see if this is in an EncryptedPrivateKeyInfo structure. */ - PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(bytes); - /* - * Now it's in a PKCS#8 PrivateKeyInfo structure. Read its Algorithm - * OID and use that to construct a KeyFactory. - */ - ASN1InputStream bIn = new ASN1InputStream(new ByteArrayInputStream(spec.getEncoded())); - PrivateKeyInfo pki = PrivateKeyInfo.getInstance(bIn.readObject()); - String algOid = pki.getPrivateKeyAlgorithm().getAlgorithm().getId(); - return KeyFactory.getInstance(algOid).generatePrivate(spec); - } finally { - input.close(); - } - } -} diff --git a/app/src/main/java/com/topjohnwu/magisk/signing/SignBoot.java b/app/src/main/java/com/topjohnwu/magisk/signing/SignBoot.java deleted file mode 100644 index ee4c2dceb..000000000 --- a/app/src/main/java/com/topjohnwu/magisk/signing/SignBoot.java +++ /dev/null @@ -1,382 +0,0 @@ -package com.topjohnwu.magisk.signing; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import org.bouncycastle.asn1.ASN1Encodable; -import org.bouncycastle.asn1.ASN1EncodableVector; -import org.bouncycastle.asn1.ASN1InputStream; -import org.bouncycastle.asn1.ASN1Integer; -import org.bouncycastle.asn1.ASN1Object; -import org.bouncycastle.asn1.ASN1ObjectIdentifier; -import org.bouncycastle.asn1.ASN1Primitive; -import org.bouncycastle.asn1.ASN1Sequence; -import org.bouncycastle.asn1.DEROctetString; -import org.bouncycastle.asn1.DERPrintableString; -import org.bouncycastle.asn1.DERSequence; -import org.bouncycastle.asn1.x509.AlgorithmIdentifier; - -import java.io.ByteArrayInputStream; -import java.io.FileInputStream; -import java.io.FilterInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.security.PrivateKey; -import java.security.PublicKey; -import java.security.Signature; -import java.security.cert.CertificateEncodingException; -import java.security.cert.CertificateFactory; -import java.security.cert.X509Certificate; -import java.util.Arrays; - -public class SignBoot { - - private static final int BOOT_IMAGE_HEADER_V1_RECOVERY_DTBO_SIZE_OFFSET = 1632; - private static final int BOOT_IMAGE_HEADER_V2_DTB_SIZE_OFFSET = 1648; - - // Arbitrary maximum header version value; when greater assume the field is dt/extra size - private static final int BOOT_IMAGE_HEADER_VERSION_MAXIMUM = 8; - - // Maximum header size byte value to read (currently the bootimg minimum page size) - private static final int BOOT_IMAGE_HEADER_SIZE_MAXIMUM = 2048; - - private static class PushBackRWStream extends FilterInputStream { - private OutputStream out; - private int pos = 0; - private byte[] backBuf; - - PushBackRWStream(InputStream in, OutputStream o) { - super(in); - out = o; - } - - @Override - public int read() throws IOException { - int b; - if (backBuf != null && backBuf.length > pos) { - b = backBuf[pos++]; - } else { - b = super.read(); - out.write(b); - } - return b; - } - - @Override - public int read(byte[] bytes, int off, int len) throws IOException { - int read = 0; - if (backBuf != null && backBuf.length > pos) { - read = Math.min(len, backBuf.length - pos); - System.arraycopy(backBuf, pos, bytes, off, read); - pos += read; - off += read; - len -= read; - } - if (len > 0) { - int ar = super.read(bytes, off, len); - read += ar; - out.write(bytes, off, ar); - } - return read; - } - - void unread(byte[] buf) { - backBuf = buf; - } - } - - private static int fullRead(InputStream in, byte[] b) throws IOException { - return fullRead(in, b, 0, b.length); - } - - private static int fullRead(InputStream in, byte[] b, int off, int len) throws IOException { - int n = 0; - while (n < len) { - int count = in.read(b, off + n, len - n); - if (count <= 0) - break; - n += count; - } - return n; - } - - public static boolean doSignature( - @Nullable X509Certificate cert, @Nullable PrivateKey key, - @NonNull InputStream imgIn, @NonNull OutputStream imgOut, @NonNull String target - ) { - try { - PushBackRWStream in = new PushBackRWStream(imgIn, imgOut); - byte[] hdr = new byte[BOOT_IMAGE_HEADER_SIZE_MAXIMUM]; - // First read the header - fullRead(in, hdr); - int signableSize = getSignableImageSize(hdr); - // Unread header - in.unread(hdr); - BootSignature bootsig = new BootSignature(target, signableSize); - if (cert == null) { - cert = CryptoUtils.readCertificate( - new ByteArrayInputStream(KeyData.verityCert())); - } - bootsig.setCertificate(cert); - if (key == null) { - key = CryptoUtils.readPrivateKey( - new ByteArrayInputStream(KeyData.verityKey())); - } - byte[] sig = bootsig.sign(key, in, signableSize); - bootsig.setSignature(sig, CryptoUtils.getSignatureAlgorithmIdentifier(key)); - byte[] encoded_bootsig = bootsig.getEncoded(); - imgOut.write(encoded_bootsig); - imgOut.flush(); - return true; - } catch (Exception e) { - e.printStackTrace(); - return false; - } - } - - public static boolean verifySignature(InputStream imgIn, X509Certificate cert) { - try { - // Read the header for size - byte[] hdr = new byte[BOOT_IMAGE_HEADER_SIZE_MAXIMUM]; - if (fullRead(imgIn, hdr) != hdr.length) { - System.err.println("Unable to read image header"); - return false; - } - int signableSize = getSignableImageSize(hdr); - - // Read the rest of the image - byte[] rawImg = Arrays.copyOf(hdr, signableSize); - int remain = signableSize - hdr.length; - if (fullRead(imgIn, rawImg, hdr.length, remain) != remain) { - System.err.println("Unable to read image"); - return false; - } - - // Read footer, which contains the signature - byte[] signature = new byte[4096]; - if (imgIn.read(signature) == -1 || Arrays.equals(signature, new byte [signature.length])) { - System.err.println("Invalid image: not signed"); - return false; - } - - BootSignature bootsig = new BootSignature(signature); - if (cert != null) { - bootsig.setCertificate(cert); - } - if (bootsig.verify(rawImg, signableSize)) { - System.err.println("Signature is VALID"); - return true; - } else { - System.err.println("Signature is INVALID"); - } - } catch (Exception e) { - e.printStackTrace(); - return false; - } - return false; - } - - public static int getSignableImageSize(byte[] data) throws Exception { - if (!Arrays.equals(Arrays.copyOfRange(data, 0, 8), - "ANDROID!".getBytes("US-ASCII"))) { - throw new IllegalArgumentException("Invalid image header: missing magic"); - } - ByteBuffer image = ByteBuffer.wrap(data); - image.order(ByteOrder.LITTLE_ENDIAN); - image.getLong(); // magic - int kernelSize = image.getInt(); - image.getInt(); // kernel_addr - int ramdskSize = image.getInt(); - image.getInt(); // ramdisk_addr - int secondSize = image.getInt(); - image.getLong(); // second_addr + tags_addr - int pageSize = image.getInt(); - if (pageSize >= 0x02000000) { - throw new IllegalArgumentException("Invalid image header: PXA header detected"); - } - int length = pageSize // include the page aligned image header - + ((kernelSize + pageSize - 1) / pageSize) * pageSize - + ((ramdskSize + pageSize - 1) / pageSize) * pageSize - + ((secondSize + pageSize - 1) / pageSize) * pageSize; - int headerVersion = image.getInt(); // boot image header version or dt/extra size - if (headerVersion > 0 && headerVersion < BOOT_IMAGE_HEADER_VERSION_MAXIMUM) { - image.position(BOOT_IMAGE_HEADER_V1_RECOVERY_DTBO_SIZE_OFFSET); - int recoveryDtboLength = image.getInt(); - length += ((recoveryDtboLength + pageSize - 1) / pageSize) * pageSize; - image.getLong(); // recovery_dtbo address - int headerSize = image.getInt(); - if (headerVersion == 2) { - image.position(BOOT_IMAGE_HEADER_V2_DTB_SIZE_OFFSET); - int dtbLength = image.getInt(); - length += ((dtbLength + pageSize - 1) / pageSize) * pageSize; - image.getLong(); // dtb address - } - if (image.position() != headerSize) { - throw new IllegalArgumentException("Invalid image header: invalid header length"); - } - } else { - // headerVersion is 0 or actually dt/extra size in this case - length += ((headerVersion + pageSize - 1) / pageSize) * pageSize; - } - length = ((length + pageSize - 1) / pageSize) * pageSize; - if (length <= 0) { - throw new IllegalArgumentException("Invalid image header: invalid length"); - } - return length; - } - - static class BootSignature extends ASN1Object { - private ASN1Integer formatVersion; - private ASN1Encodable certificate; - private AlgorithmIdentifier algId; - private DERPrintableString target; - private ASN1Integer length; - private DEROctetString signature; - private PublicKey publicKey; - private static final int FORMAT_VERSION = 1; - - /** - * Initializes the object for signing an image file - * @param target Target name, included in the signed data - * @param length Length of the image, included in the signed data - */ - public BootSignature(String target, int length) { - this.formatVersion = new ASN1Integer(FORMAT_VERSION); - this.target = new DERPrintableString(target); - this.length = new ASN1Integer(length); - } - - /** - * Initializes the object for verifying a signed image file - * @param signature Signature footer - */ - public BootSignature(byte[] signature) throws Exception { - ASN1InputStream stream = new ASN1InputStream(signature); - ASN1Sequence sequence = (ASN1Sequence) stream.readObject(); - formatVersion = (ASN1Integer) sequence.getObjectAt(0); - if (formatVersion.getValue().intValue() != FORMAT_VERSION) { - throw new IllegalArgumentException("Unsupported format version"); - } - certificate = sequence.getObjectAt(1); - byte[] encoded = ((ASN1Object) certificate).getEncoded(); - ByteArrayInputStream bis = new ByteArrayInputStream(encoded); - CertificateFactory cf = CertificateFactory.getInstance("X.509"); - X509Certificate c = (X509Certificate) cf.generateCertificate(bis); - publicKey = c.getPublicKey(); - ASN1Sequence algId = (ASN1Sequence) sequence.getObjectAt(2); - this.algId = new AlgorithmIdentifier((ASN1ObjectIdentifier) algId.getObjectAt(0)); - ASN1Sequence attrs = (ASN1Sequence) sequence.getObjectAt(3); - target = (DERPrintableString) attrs.getObjectAt(0); - length = (ASN1Integer) attrs.getObjectAt(1); - this.signature = (DEROctetString) sequence.getObjectAt(4); - } - - public ASN1Object getAuthenticatedAttributes() { - ASN1EncodableVector attrs = new ASN1EncodableVector(); - attrs.add(target); - attrs.add(length); - return new DERSequence(attrs); - } - - public byte[] getEncodedAuthenticatedAttributes() throws IOException { - return getAuthenticatedAttributes().getEncoded(); - } - - public void setSignature(byte[] sig, AlgorithmIdentifier algId) { - this.algId = algId; - signature = new DEROctetString(sig); - } - - public void setCertificate(X509Certificate cert) - throws CertificateEncodingException, IOException { - ASN1InputStream s = new ASN1InputStream(cert.getEncoded()); - certificate = s.readObject(); - publicKey = cert.getPublicKey(); - } - - public byte[] sign(PrivateKey key, InputStream is, int len) throws Exception { - Signature signer = Signature.getInstance(CryptoUtils.getSignatureAlgorithm(key)); - signer.initSign(key); - int read; - byte buffer[] = new byte[4096]; - while ((read = is.read(buffer, 0, Math.min(len, buffer.length))) > 0) { - signer.update(buffer, 0, read); - len -= read; - } - signer.update(getEncodedAuthenticatedAttributes()); - return signer.sign(); - } - - public boolean verify(byte[] image, int length) throws Exception { - if (this.length.getValue().intValue() != length) { - throw new IllegalArgumentException("Invalid image length"); - } - String algName = CryptoUtils.ID_TO_ALG.get(algId.getAlgorithm().getId()); - if (algName == null) { - throw new IllegalArgumentException("Unsupported algorithm " + algId.getAlgorithm()); - } - Signature verifier = Signature.getInstance(algName); - verifier.initVerify(publicKey); - verifier.update(image, 0, length); - verifier.update(getEncodedAuthenticatedAttributes()); - return verifier.verify(signature.getOctets()); - } - - @Override - public ASN1Primitive toASN1Primitive() { - ASN1EncodableVector v = new ASN1EncodableVector(); - v.add(formatVersion); - v.add(certificate); - v.add(algId); - v.add(getAuthenticatedAttributes()); - v.add(signature); - return new DERSequence(v); - } - - } - - public static void main(String[] args) throws Exception { - if (args.length > 0 && "-verify".equals(args[0])) { - X509Certificate cert = null; - if (args.length >= 2) { - // args[1] is the path to a public key certificate - cert = CryptoUtils.readCertificate(new FileInputStream(args[1])); - } - boolean signed = SignBoot.verifySignature(System.in, cert); - System.exit(signed ? 0 : 1); - } else if (args.length > 0 && "-sign".equals(args[0])) { - X509Certificate cert = null; - PrivateKey key = null; - String name = "/boot"; - - if (args.length >= 3) { - cert = CryptoUtils.readCertificate(new FileInputStream(args[1])); - key = CryptoUtils.readPrivateKey(new FileInputStream(args[2])); - } - if (args.length == 2) { - name = args[1]; - } else if (args.length >= 4) { - name = args[3]; - } - - boolean result = SignBoot.doSignature(cert, key, System.in, System.out, name); - System.exit(result ? 0 : 1); - } else { - System.err.println( - "BootSigner [args]\n" + - "Input from stdin, output to stdout\n" + - "\n" + - "Actions:\n" + - " -verify [x509.pem]\n" + - " verify image. cert is optional.\n" + - " -sign [x509.pem] [pk8] [name]\n" + - " sign image. name and the cert/key pair are optional.\n" + - " name should be either /boot (default) or /recovery.\n" - ); - } - } - -} diff --git a/buildSrc/src/main/java/Codegen.kt b/buildSrc/src/main/java/Codegen.kt index 61847fa90..a95d8d9e2 100644 --- a/buildSrc/src/main/java/Codegen.kt +++ b/buildSrc/src/main/java/Codegen.kt @@ -64,19 +64,6 @@ private fun PrintStream.byteField(name: String, bytes: ByteArray) { println("}") } -fun genKeyData(keysDir: File, outSrc: File) { - outSrc.parentFile.mkdirs() - PrintStream(outSrc).use { - it.println("package com.topjohnwu.magisk.signing;") - it.println("public final class KeyData {") - - it.byteField("verityCert", File(keysDir, "verity.x509.pem").readBytes()) - it.byteField("verityKey", File(keysDir, "verity.pk8").readBytes()) - - it.println("}") - } -} - @CacheableTask abstract class ManifestUpdater: DefaultTask() { @get:Input diff --git a/buildSrc/src/main/java/Setup.kt b/buildSrc/src/main/java/Setup.kt index 2debd70fa..af1a9ab7e 100644 --- a/buildSrc/src/main/java/Setup.kt +++ b/buildSrc/src/main/java/Setup.kt @@ -305,19 +305,6 @@ fun Project.setupApp() { } } mergeAssetsProvider.configure { dependsOn(syncAssets) } - - val keysDir = rootProject.file("tools/keys") - val outSrcDir = File(buildDir, "generated/source/keydata/$name") - val outSrc = File(outSrcDir, "com/topjohnwu/magisk/signing/KeyData.java") - - val genSrcTask = tasks.register("generate${variantCapped}KeyData") { - inputs.dir(keysDir) - outputs.file(outSrc) - doLast { - genKeyData(keysDir, outSrc) - } - } - registerJavaGeneratingTask(genSrcTask, outSrcDir) } } diff --git a/scripts/addon.d.sh b/scripts/addon.d.sh index 3c2392186..28617ed0a 100644 --- a/scripts/addon.d.sh +++ b/scripts/addon.d.sh @@ -109,7 +109,6 @@ main() { ui_print "- Device platform: $ABI" remove_system_su - find_magisk_apk install_magisk # Cleanups diff --git a/scripts/flash_script.sh b/scripts/flash_script.sh index e1cddcd62..77a074c5f 100644 --- a/scripts/flash_script.sh +++ b/scripts/flash_script.sh @@ -11,7 +11,6 @@ umask 022 OUTFD=$2 -APK="$3" COMMONDIR=$INSTALLER/assets CHROMEDIR=$INSTALLER/assets/chromeos diff --git a/scripts/uninstaller.sh b/scripts/uninstaller.sh index aa8780164..6be8173ac 100644 --- a/scripts/uninstaller.sh +++ b/scripts/uninstaller.sh @@ -11,7 +11,6 @@ umask 022 OUTFD=$2 -APK="$3" COMMONDIR=$INSTALLER/assets CHROMEDIR=$INSTALLER/assets/chromeos diff --git a/scripts/util_functions.sh b/scripts/util_functions.sh index 1ef3b26aa..72f210fa6 100644 --- a/scripts/util_functions.sh +++ b/scripts/util_functions.sh @@ -185,7 +185,7 @@ recovery_actions() { recovery_cleanup() { local DIR ui_print "- Unmounting partitions" - (umount_apex + ( if [ ! -d /postinstall/tmp ]; then umount -l /system umount -l /system_root @@ -199,7 +199,8 @@ recovery_cleanup() { mv -f ${DIR}_link $DIR fi done - umount -l /dev/random) 2>/dev/null + umount -l /dev/random + ) 2>/dev/null [ -z $OLD_LD_LIB ] || export LD_LIBRARY_PATH=$OLD_LD_LIB [ -z $OLD_LD_PRE ] || export LD_PRELOAD=$OLD_LD_PRE [ -z $OLD_LD_CFG ] || export LD_CONFIG_FILE=$OLD_LD_CFG @@ -306,92 +307,7 @@ mount_partitions() { SYSTEM_ROOT=false grep ' / ' /proc/mounts | grep -qv 'rootfs' || grep -q ' /system_root ' /proc/mounts && SYSTEM_ROOT=true fi - # /vendor is used only on some older devices for recovery AVBv1 signing so is not critical if fails - [ -L /system/vendor ] && mount_name vendor$SLOT /vendor '-o ro' $SYSTEM_ROOT && ui_print "- Device is system-as-root" - - # Allow /system/bin commands (dalvikvm) on Android 10+ in recovery - $BOOTMODE || mount_apex -} - -# loop_setup , sets LOOPDEV -loop_setup() { - unset LOOPDEV - local LOOP - local MINORX=1 - [ -e /dev/block/loop1 ] && MINORX=$(stat -Lc '%T' /dev/block/loop1) - local NUM=0 - while [ $NUM -lt 64 ]; do - LOOP=/dev/block/loop$NUM - [ -e $LOOP ] || mknod $LOOP b 7 $((NUM * MINORX)) - if losetup $LOOP "$1" 2>/dev/null; then - LOOPDEV=$LOOP - break - fi - NUM=$((NUM + 1)) - done -} - -mount_apex() { - $BOOTMODE || [ ! -d /system/apex ] && return - local APEX DEST - setup_mntpoint /apex - mount -t tmpfs tmpfs /apex -o mode=755 - local PATTERN='s/.*"name":[^"]*"\([^"]*\).*/\1/p' - for APEX in /system/apex/*; do - if [ -f $APEX ]; then - # handle CAPEX APKs, extract actual APEX APK first - unzip -qo $APEX original_apex -d /apex - [ -f /apex/original_apex ] && APEX=/apex/original_apex # unzip doesn't do return codes - # APEX APKs, extract and loop mount - unzip -qo $APEX apex_payload.img -d /apex - DEST=$(unzip -qp $APEX apex_manifest.pb | strings | head -n 1 | tr -dc '[:alnum:].-_\n') - [ -z $DEST ] && DEST=$(unzip -qp $APEX apex_manifest.json | sed -n $PATTERN) - [ -z $DEST ] && continue - DEST=/apex/$DEST - mkdir -p $DEST - loop_setup /apex/apex_payload.img - if [ ! -z $LOOPDEV ]; then - ui_print "- Mounting $DEST" - mount -t ext4 -o ro,noatime $LOOPDEV $DEST - fi - rm -f /apex/original_apex /apex/apex_payload.img - elif [ -d $APEX ]; then - # APEX folders, bind mount directory - if [ -f $APEX/apex_manifest.json ]; then - DEST=/apex/$(sed -n $PATTERN $APEX/apex_manifest.json) - elif [ -f $APEX/apex_manifest.pb ]; then - DEST=/apex/$(strings $APEX/apex_manifest.pb | head -n 1 | tr -dc '[:alnum:].-_\n') - else - continue - fi - mkdir -p $DEST - ui_print "- Mounting $DEST" - mount -o bind $APEX $DEST - fi - done - export ANDROID_RUNTIME_ROOT=/apex/com.android.runtime - export ANDROID_TZDATA_ROOT=/apex/com.android.tzdata - export ANDROID_ART_ROOT=/apex/com.android.art - export ANDROID_I18N_ROOT=/apex/com.android.i18n - local APEXJARS=$(find /apex -name '*.jar' | sort | tr '\n' ':') - local FWK=/system/framework - export BOOTCLASSPATH=${APEXJARS}\ -$FWK/framework.jar:$FWK/ext.jar:$FWK/telephony-common.jar:\ -$FWK/voip-common.jar:$FWK/ims-common.jar:$FWK/telephony-ext.jar -} - -umount_apex() { - [ -d /apex ] || return - umount -l /apex - for loop in /dev/block/loop*; do - losetup -d $loop 2>/dev/null - done - unset ANDROID_RUNTIME_ROOT - unset ANDROID_TZDATA_ROOT - unset ANDROID_ART_ROOT - unset ANDROID_I18N_ROOT - unset BOOTCLASSPATH } # After calling this method, the following variables will be set: @@ -452,16 +368,11 @@ find_boot_image() { } flash_image() { + local CMD1 case "$1" in *.gz) CMD1="gzip -d < '$1' 2>/dev/null";; *) CMD1="cat '$1'";; esac - if $BOOTSIGNED; then - CMD2="$BOOTSIGNER -sign" - ui_print "- Sign image with verity keys" - else - CMD2="cat -" - fi if [ -b "$2" ]; then local img_sz=$(stat -c '%s' "$1") local blk_sz=$(blockdev --getsize64 "$2") @@ -469,13 +380,13 @@ flash_image() { blockdev --setrw "$2" local blk_ro=$(blockdev --getro "$2") [ "$blk_ro" -eq 1 ] && return 2 - eval "$CMD1" | eval "$CMD2" | cat - /dev/zero > "$2" 2>/dev/null + eval "$CMD1" | cat - /dev/zero > "$2" 2>/dev/null elif [ -c "$2" ]; then flash_eraseall "$2" >&2 - eval "$CMD1" | eval "$CMD2" | nandwrite -p "$2" - >&2 + eval "$CMD1" | nandwrite -p "$2" - >&2 else ui_print "- Not block or char device, storing image" - eval "$CMD1" | eval "$CMD2" > "$2" 2>/dev/null + eval "$CMD1" > "$2" 2>/dev/null fi return 0 } @@ -484,11 +395,6 @@ flash_image() { install_magisk() { cd $MAGISKBIN - if [ ! -c $BOOTIMAGE ]; then - eval $BOOTSIGNER -verify < $BOOTIMAGE && BOOTSIGNED=true - $BOOTSIGNED && ui_print "- Boot image is signed with AVB 1.0" - fi - # Source the boot patcher SOURCEDMODE=true . ./boot_patch.sh "$BOOTIMAGE" @@ -596,19 +502,6 @@ check_data() { $DATA_DE && set_nvbase "/data/adb" } -find_magisk_apk() { - local DBAPK - [ -z $APK ] && APK=/data/app/com.topjohnwu.magisk*/base.apk - [ -f $APK ] || APK=/data/app/*/com.topjohnwu.magisk*/base.apk - if [ ! -f $APK ]; then - DBAPK=$(magisk --sqlite "SELECT value FROM strings WHERE key='requester'" 2>/dev/null | cut -d= -f2) - [ -z $DBAPK ] && DBAPK=$(strings $NVBASE/magisk.db | grep -oE 'requester..*' | cut -c10-) - [ -z $DBAPK ] || APK=/data/user_de/0/$DBAPK/dyn/current.apk - [ -f $APK ] || [ -z $DBAPK ] || APK=/data/data/$DBAPK/dyn/current.apk - fi - [ -f $APK ] || ui_print "! Unable to detect Magisk app APK for BootSigner" -} - run_migrations() { local LOCSHA1 local TARGET @@ -830,8 +723,3 @@ install_module() { TMPDIR=/dev/tmp set_nvbase "/data/adb" - -# Bootsigner related stuff -BOOTSIGNERCLASS=com.topjohnwu.magisk.signing.SignBoot -BOOTSIGNER='/system/bin/dalvikvm -Xnoimage-dex2oat -cp $APK $BOOTSIGNERCLASS' -BOOTSIGNED=false