
A Mac-alkalmazásod megkapja a mikrofon-hozzáférést — aztán minden indításkor elfelejti
A GeekBye mikrofonengedélyt kért, megadtad, és működött. A következő indításnál: eltűnt. És az alkalmazás egyáltalán meg sem jelent a Rendszerbeállítások → Mikrofon alatt. A bűnös egy macOS biztonsági funkció volt, amely csendben egy eltűnő elérési útról futtatta az alkalmazást — íme a diagnózis és az egyetlen kérdéssel megoldó javítás.
Íme egy hiba, amitől kételkedni kezdesz a saját szemedben. Telepíted a GeekBye-t, mikrofon-hozzáférést kér, rákattintasz az Allow gombra, és az átírás működik. Remek. Kilépsz, másnap reggel újranyitod — és megint mikrofon-hozzáférést kér. Elmész megnézni a Rendszerbeállítások → Adatvédelem és biztonság → Mikrofon menüt, hogy kézzel javítsd, és a GeekBye nincs is a listán. Nem letiltva. Nem engedélyezve. Egyszerűen hiányzik, mintha sosem kérte volna.
Minden egyes darab helyesnek tűnt. A kérés valódi volt. Az engedély abban a pillanatban működött. Az alkalmazás megfelelően alá volt írva és notarizálva, a helyes használati szövegekkel. És az engedély mégis elpárolgott minden indításkor. A GeekBye v2.0.6 megjavította — és a kiváltó ok az egyik legalattomosabb dolog, amit a macOS a védelmed érdekében tesz.
A funkció, amely önmaga elől rejtette az alkalmazást
A bűnös a macOS App Translocation, egy Gatekeeper biztonsági funkció. Amikor letöltesz egy alkalmazást, és közvetlenül a DMG-ből vagy a ~/Downloads mappádból futtatod — bárhonnan, ahol még „karanténban" van —, a macOS valójában nem onnan futtatja, ahol látod. Átlátszóan átmásolja egy véletlenszerű, csak olvasható elérési útra, mélyen a /private/var/folders/.../AppTranslocation/… alá, és azt a másolatot futtatja. Jó védelem: megakadályozza, hogy egy rosszindulatú letöltés a mellette lévő fájlokat manipulálja.
De itt az ütközés. A macOS engedélyrendszere (a TCC — az, amelyik nyomon követi, ki használhatja a mikrofonod, kamerád, képernyőd) az alkalmazást az elérési útja és kódidentitása alapján azonosítja. Amikor az alkalmazás transzlokált, ez az elérési út véletlenszerű és ideiglenes. Így amikor mikrofon-hozzáférést adsz, a macOS engedelmesen rögzíti a megadást — egy olyan elérési úthoz, amely a következő indításkor nem fog létezni. Újranyitod az alkalmazást, a macOS egy másik véletlenszerű elérési útra transzlokálja, olyan alkalmazást lát, amelyről semmilyen feljegyzése nincs, és újra kérdez. És mivel az a fantom elérési út sosem stabil hely, az alkalmazás sosem szerez állandó sort a Rendszerbeállítások → Mikrofon alatt.
Az alkalmazás egy szellemnek adott engedélyt.
Ezért is történt, hogy csak néhány ember találkozott vele. Ha a GeekBye példányod már az /Applications mappában lakott — mert odahúztad, vagy mert automatikus frissítéssel oda került —, nincs karantén, nincs transzlokáció, stabil elérési út, és minden tökéletesen megmarad. A hiba láthatatlan volt számunkra és bárki számára, aki túl volt az első telepítésen, pontosan az a fajta hiba, amely a legtovább túléli.
A javítás: adj az alkalmazásnak igazi otthont
Mivel az egész probléma egy instabil elérési út, a javítás az, hogy az alkalmazást egy stabilra tesszük. A v2.0.6 észleli, amikor a GeekBye transzlokáltan fut (vagy egyszerűen az /Applications mappán kívülről fut), és egykattintásos „Move to Applications" lehetőséget kínál — a macOS áthelyezési hívásával, amely bemásolja a bundle-t az /Applications mappába, és onnan indítja újra. Ettől a ponttól kezdve az alkalmazásnak rögzített identitása van: a mikrofonengedély megmarad, a képernyőfelvétel megmarad, és a GeekBye végre megjelenik a Rendszerbeállításokban, ahol számítasz rá.
A kérés udvarias ezzel kapcsolatban. Felkínálja a Move to Applications, a Not Now és a Don't Ask Again lehetőséget — és megjegyzi az utolsó választást, így az alkalmazás sosem zaklat olyasvalakit, akinek szándékos oka van máshonnan futtatni. Annak eldöntése, hogy egyáltalán megjelenítse-e a kérést, kis, tiszta függvényekbe van izolálva (transzlokált-e ez a build? az /Applications mappán kívül van? elnyomta-e a felhasználó?), így a logikát unit-tesztelni lehet anélkül, hogy valódi notarizált buildet kellene elindítani egy valódi karanténba helyezett köteten.
Ugyanez a kiadás magát az engedélyélményt is leegyszerűsítette. A GeekBye korábban egy egyedi, testreszabott, alkalmazáson belüli engedélyablakot dobott fel — néhány száz sornyi UI, amely valamit próbált reprodukálni, amit az operációs rendszer már jól csinál. A v2.0.6 törölte ezt, és a natív macOS engedélykérésre támaszkodott, amelyet egy csendes, nem blokkoló szalag támogat, amely csak akkor jelenik meg, amikor egy szükséges engedély valóban hiányzik. Kevesebb kód, és olyan viselkedés, amelyet a felhasználók már felismernek, mert minden más Mac-alkalmazás ugyanígy működik.
A rész, amire a legbüszkébb vagyok: bebizonyítottuk, mielőtt elhittük
Könnyű lett volna megtippelni a transzlokációt, és kiadni egy javítást. Ehelyett a kiadás először egy indítási diagnosztikát hozott: indításkor a GeekBye most jelenti a saját futtatható fájljának elérési útját, és hogy transzlokált-e, hogy az /Applications mappán belül van-e, valamint a mikrofon- és képernyőengedélyek aktuális állapotát. Ez a telemetria egy hihető elméletet megerősítetté tett — a produkciós adatok megmutatták, hogy az érintett munkamenetek valóban az /Applications mappán kívüli transzlokált elérési utakról futottak, pontosan a jóslat szerint.
Ez a sorrend számít. A „megjelenik a kérés, de az engedély nem marad meg" mögött több lehetséges magyarázat áll — aláírási probléma, hiányzó használati szöveg, entitlement-gond, TCC-adatbázis furcsaság. Kizártuk az API-szintű okokat (a kérés útja bizonyíthatóan helyes volt), majd hagytuk, hogy a valós adatok az identitás/elérési út rétegre mutassanak, ahelyett, hogy egy reménykedő javítást adtunk volna ki, és reménykedtünk volna, hogy a támogatási jegyek elapadnak.
Három dolog, amit ez a hiba tanít
- Egy engedély, amely kér, de nem marad meg, identitás-probléma, nem API-probléma. Ha a kérés kódja helyes, és az engedély mégis eltűnik, hagyd abba a kérés újraírását. Kérdezd meg, milyen elérési úthoz és kódidentitáshoz köti az operációs rendszer a megadást — és hogy ez az identitás stabil-e az indítások között.
- Add ki a diagnosztikát a javítással együtt (vagy előtte). Néhány mező — honnan futok, mi az engedélyeim állapota — egy megalapozott találgatást igazolt kiváltó okká változtatott, és pontosan megmondta, mely felhasználók érintettek. Műszerezd fel a határt, amelyre gyanakszol, mielőtt megfoltoznád.
- A fejlesztők elől rejtőző hibák azok, amelyek a „rossz" környezetben futnak. A miénk minden fejlesztőgépen az
/Applicationsmappában lakott, így a hiba szerkezetileg láthatatlan volt számunkra, miközben az első telepítésű felhasználókat sújtotta. Amikor egy bejelentés nem reprodukálható, az első kérdés az, hogy mi különbözik abban, ahol fut, nem az, hogy téved-e a felhasználó.
A GeekBye v2.0.6 az áthelyezési kérést és a diagnosztikát együtt adta ki. A tágabb megbízhatósági ívről, amelybe ez illeszkedik, lásd mit igényel valójában egy 2-es verzió (v2.0.0) és miért a rossz monitort rögzíti a képernyőfelvétel (v2.0.10) — egy másik hiba, amely csak egy adott környezetben bukkant fel. A szomszédos, apró részletekről szóló kiadásért lásd nyugodt szoftver: a villódzásjavítás és a válaszmód-chip (v2.0.3 + v2.0.5).