3 votes

Comment update_engine valide-t-il une image de mise à jour différentielle avec dm-verity activé ?

Je travaille avec Android 8, le démarrage vérifié d'Android avec dm-verity, et les mises à jour A/B différentielles et transparentes par bloc. D'après ce que j'ai compris, le moteur de mise à jour d'Android effectue certaines validations de l'image de mise à jour reçue avant de procéder à l'écriture des partitions cibles. A ma connaissance, le moteur de mise à jour vérifie si la mise à jour différentielle peut être installée sur les partitions actuelles. Comment cette vérification est-elle effectuée ?

Je peux imaginer deux possibilités, mais je n'ai pas trouvé de documentation faisant autorité pour l'une ou l'autre de ces hypothèses :

  1. Le paquet de mise à jour différentielle contient un hachage linéaire de la partition source. Sur le périphérique, update_enigne calcule un hachage SHA-256 de la partition entière sur laquelle la mise à jour différentielle doit être appliquée. Il compare cette valeur avec celle fournie dans le cadre du paquet de mise à jour et ne poursuit que si les deux valeurs concordent.
  2. Le paquet de mise à jour différentielle contient le hash racine dm-verity de l'arbre de Merkle utilisé pour la validation par bloc avec dm-verity. Le moteur de mise à jour compare ce hachage racine cible avec celui fourni sur le dispositif dans la structure vbmeta. Ce n'est que si les deux correspondent qu'il procède à l'installation de la mise à jour.

L'une ou l'autre de ces hypothèses est-elle correcte, ou est-ce que je rate quelque chose ? De même, comment le moteur de mise à jour valide-t-il les partitions cibles une fois qu'elles ont été écrites ? Via un hachage linéaire, ou en utilisant le hachage Root ? Ou autrement ?

3voto

Irfan Latif Points 16863

L'une ou l'autre de ces hypothèses est-elle correcte ?

Je n'ai pas encore expérimenté le dispositif A/B, mais ce que je comprends de la documentation officielle et du code source, c'est que c'est les deux. Le hachage SHA-256 de la partition cible est comparé à celui reçu du serveur de mise à jour. Et après le redémarrage dm-verity est effectuée.

De La vie d'une mise à jour A/B :

"5. Les partitions entières sont relues et vérifiées par rapport au hachage attendu."

De plus, l'implémenteur peut mettre des post-installation des contrôles. Et :

_"Après le redémarrage, update_verifier déclenche le contrôle d'intégrité en utilisant dm-verity " .
...
"Après que la vérification soit terminée, update_verifier marque le démarrage réussi."_

.

Android update_engine effectue certaines validations de l'image de mise à jour reçue avant de procéder à l'écriture des partitions cibles

Les mises à jour A/B diffèrent des anciennes mises à jour non A/B basées sur la récupération. Dans ce dernier cas, le paquet de mise à jour est vérifié deux fois contre les clés publiques dans /system/etc/security/otacerts.zip (démarrage normal) et /res/keys (démarrage de récupération). En cas de OTAs basées sur des blocs dm-verity est un contrôle supplémentaire. Mais les mises à jour A/B prennent en charge mises à jour de streaming :

_" Les mises à jour peuvent être diffusées en continu sur les appareils A/B, ce qui supprime la nécessité de télécharger le paquet avant de l'installer. La diffusion en continu signifie qu'il n'est pas nécessaire que l'utilisateur dispose d'un espace libre suffisant pour stocker le paquet de mise à jour sur son ordinateur. /data o /cache
...
update_engine mettra à jour les blocs bruts sur la partition actuellement inutilisée en diffusant le paquet de mise à jour."_

Il n'est donc pas toujours possible de vérifier l'intégrité de l'ensemble du paquet de mise à jour (charge utile) avant le flashage. Au lieu de cela, l'intégrité du paquet de mise à jour est vérifiée après la mise à jour. Si quelque chose ne va pas, l'ancien emplacement de la partition reste intact comme solution de repli, tandis que l'emplacement mis à jour est marqué. non amorçable jusqu'à la prochaine mise à jour.

.

Est-ce que cela signifie que update_engine calcule un hachage linéaire complet SHA-256 de toutes les partitions sources qu'il est censé mettre à jour ?

"Lors des mises à jour incrémentales ou delta, les données binaires du slot actuel sont utilisées pour générer les données du nouveau slot". . Mais update_engine calcule les hachages de tous les partitions cibles après leur mise à jour. De code source :

"Cette action va hacher toutes les partitions du slot cible impliqué dans la mise à jour. Les hachages sont ensuite vérifiés par rapport à ceux de la base de données de l'utilisateur. InstallPlan . Si le hachage de la cible ne correspond pas, l'action échoue."

.

dm-verity n'effectue pas une vérification exhaustive à chaque démarrage, car cela prendrait beaucoup trop de temps. C'est pourquoi je suppose que update_verifier En revanche, la vérification exhaustive est effectuée lors d'un redémarrage après une installation réussie.

D'après les détails trouvés dans Implémentation du dm-verity Le hachage de chaque bloc de 4k est pré-calculé et ajouté à la fin de l'enregistrement. system.img (ou vendor.img ) en dm-verity table (métabloc ; légèrement différents détails dans le cas d'AVB) qui est signé par la clé privée de l'OEM. La clé publique est enregistrée dans le système du noyau. Porte-clés (sur les périphériques A/B) que le noyau utilise pour vérifier l'intégrité de la table de vérification à chaque démarrage.

"Une façon de vérifier un dispositif de bloc est de hacher directement son contenu et de le comparer à une valeur stockée. Cependant, la vérification d'un bloc entier peut prendre beaucoup de temps et consommer une grande partie de l'énergie du dispositif.
...
Au lieu de cela, dm-verity vérifie les blocs individuellement et uniquement lors de l'accès à chacun d'eux. Lorsqu'il est lu en mémoire, le bloc est haché en parallèle. Le hachage est ensuite vérifié dans l'arbre. Et puisque la lecture du bloc est une opération si coûteuse, la latence introduite par cette vérification au niveau du bloc est comparativement minime.
...
Si la vérification échoue, le dispositif génère une erreur d'E/S indiquant que le bloc ne peut pas être lu."

update_verifier lit une liste de blocs au prochain redémarrage. L'absence d'erreur d'E/S signifie que le nouveau system.img est signé par une clé authentique et le slot mis à jour est marqué comme réussi.

pour une très petite mise à jour différentielle, seuls les blocs qui ont changé sont vérifiés. Pour une mise à jour complète, tous les blocs sont relus. Cette hypothèse est-elle correcte ?

La documentation dit :

_" update_verifier ne lira que les blocs listés dans /data/ota_package/care_map.txt qui est inclus dans un forfait OTA A/B"._

Il ne lira pas les autres blocs, qu'ils soient mis à jour ou non.

0 votes

L'image vbmeta est-elle également mise à jour avec les nouveaux hashs de la racine lorsque l'OTA est appliqué ?

androidalle.com

AndroidAlle est une communauté de androiders où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X