Steven
Steven6 min læsning

Din Mac-app får adgang til mikrofonen — og glemmer det så hver gang du åbner den

GeekBye bad om mikrofontilladelse, du gav den, og det virkede. Næste gang du åbnede appen: væk. Og appen dukkede aldrig op i Systemindstillinger → Mikrofon overhovedet. Skurken var en macOS-sikkerhedsfunktion, der stille og roligt kørte appen fra en sti, som forsvinder — her er diagnosen og den ét-klik-løsning.

macOS
Tilladelser
Udvikling
GeekBye-udgivelser
Din Mac-app får adgang til mikrofonen — og glemmer det så hver gang du åbner den

Her er en fejl, der får dig til at tvivle på dine egne øjne. Du installerer GeekBye, den beder om adgang til mikrofonen, du klikker Allow, og transskriptionen virker. Fint. Du lukker den, åbner den igen næste morgen — og den beder om mikrofonadgang igen. Du går ind for at tjekke Systemindstillinger → Anonymitet og sikkerhed → Mikrofon for at rette det manuelt, og GeekBye er ikke engang på listen. Ikke nægtet. Ikke tilladt. Bare fraværende, som om den aldrig havde spurgt.

Hver enkelt brik så korrekt ud. Prompten var ægte. Tilladelsen virkede i øjeblikket. Appen var korrekt signeret og notariseret med de rigtige brugsstrenge. Og alligevel fordampede tilladelsen ved hver opstart. GeekBye v2.0.6 rettede den — og den underliggende årsag er en af de mest snigende ting, macOS gør for at beskytte dig.

Funktionen, der skjulte appen for sig selv

Skurken er macOS App Translocation, en Gatekeeper-sikkerhedsfunktion. Når du henter en app og kører den direkte fra DMG'en eller fra din ~/Downloads-mappe — et hvilket som helst sted, hvor den stadig er i "karantæne" — kører macOS den faktisk ikke fra det sted, du ser den. Den kopierer den gennemsigtigt til en tilfældig, skrivebeskyttet sti dybt under /private/var/folders/.../AppTranslocation/… og kører den kopi. Det er et godt forsvar: det forhindrer en ondsindet download i at manipulere med filer ved siden af sig selv.

Men her er konflikten. macOS' tilladelsessystem (TCC — det, der holder styr på, hvem der må bruge din mikrofon, dit kamera og din skærm) identificerer en app ud fra dens sti og kodeidentitet. Når appen er translokeret, er den sti tilfældig og midlertidig. Så når du giver mikrofonadgang, registrerer macOS pligtskyldigt tilladelsen — mod en sti, der ikke findes næste gang appen åbnes. Åbn appen igen, macOS translokerer den til en anden tilfældig sti, ser en app, den ikke har nogen oplysninger om, og spørger igen. Og fordi den spøgelsessti aldrig er en stabil placering, får appen aldrig en permanent række i Systemindstillinger → Mikrofon.

Appen gav tilladelse til et spøgelse.

Det er også derfor, kun nogle folk ramte den. Hvis din kopi af GeekBye allerede lå i /Applications — fordi du trak den derhen, eller fordi den kom derhen via automatisk opdatering — er der ingen karantæne, ingen translokation, en stabil sti, og alt bevares perfekt. Fejlen var usynlig for os og for alle, der var forbi deres første installation, hvilket er præcis den slags fejl, der overlever længst.

Løsningen: giv appen et rigtigt hjem

Da hele problemet er en ustabil sti, er løsningen at få appen over på en stabil en. v2.0.6 registrerer, når GeekBye kører translokeret (eller bare kører uden for /Applications) og tilbyder et ét-klik "Move to Applications" (flyt til Programmer) — ved hjælp af det macOS-relokeringskald, der kopierer bundtet ind i /Applications og genstarter det derfra. Fra det tidspunkt har appen en fast identitet: mikrofontilladelsen bliver hængende, skærmoptagelse bliver hængende, og GeekBye dukker endelig op i Systemindstillinger, hvor du ville forvente det.

Prompten er høflig omkring det. Den tilbyder Move to Applications (flyt til Programmer), Not Now (ikke nu) og Don't Ask Again (spørg ikke igen) — og den husker det sidste valg, så appen aldrig plager nogen, der har en bevidst grund til at køre den fra et andet sted. Beslutningen om, hvorvidt prompten overhovedet skal vises, er isoleret i små, rene funktioner (er dette build translokeret? er det uden for /Applications? har brugeren undertrykt det?), så logikken kan enhedstestes uden at skulle starte et rigtigt notariseret build på et rigtigt karantæne-volumen.

Den samme udgivelse forenklede også selve tilladelsesoplevelsen. GeekBye plejede at åbne et brugerdefineret, specialbygget tilladelsesvindue inde i appen — nogle få hundrede linjer UI, der forsøgte at gengive noget, operativsystemet allerede gør godt. v2.0.6 slettede det og lænede sig op ad den native macOS-tilladelsesprompt, understøttet af en stille, ikke-blokerende banner, der kun vises, når en påkrævet tilladelse faktisk mangler. Mindre kode, og en adfærd brugerne allerede genkender, fordi alle andre Mac-apps fungerer på samme måde.

Den del, jeg er mest stolt af: vi beviste det, før vi troede på det

Det havde været nemt at gætte translokation og sende en rettelse. I stedet sendte udgivelsen en opstartsdiagnostik først: ved opstart rapporterer GeekBye nu sin egen sti til den eksekverbare fil og hvorvidt den er translokeret, hvorvidt den er inde i /Applications, samt den aktuelle status for mikrofon- og skærmtilladelser. Den telemetri gjorde en plausibel teori til en bekræftet: produktionsdata viste, at de berørte sessioner faktisk kørte fra translokerede stier uden for /Applications, præcis som forudsagt.

Den rækkefølge betyder noget. "Prompten dukker op, men tilladelsen bliver ikke hængende" har flere mulige forklaringer — et signeringsproblem, en manglende brugsstreng, et entitlement-problem, en finurlighed i TCC-databasen. Vi udelukkede årsagerne på API-niveau (anmodningsstien var påviseligt korrekt) og lod så virkelige data pege på identitets-/stilaget i stedet for at sende en håbefuld rettelse og håbe, at supporthenvendelserne stoppede.

Tre ting denne fejl lærer

  1. En tilladelse, der prompter, men ikke bliver hængende, er et identitets_problem, ikke et _API-problem. Hvis anmodningskoden er korrekt, og tilladelsen alligevel forsvinder, så hold op med at omskrive anmodningen. Spørg, hvilken sti og kodeidentitet operativsystemet binder tilladelsen til — og hvorvidt den identitet er stabil på tværs af opstarter.
  2. Send diagnostikken med (eller før) rettelsen. Nogle få felter — hvor kører jeg fra, hvad er min tilladelsesstatus — forvandlede et kvalificeret gæt til en verificeret rodårsag og fortalte os præcis, hvilke brugere der var berørt. Instrumentér den grænse, du har mistanke om, før du lapper den.
  3. De fejl, der skjuler sig for udviklerne, er dem, der kører i det "forkerte" miljø. Vores boede i /Applications på hver eneste udviklermaskine, så fejlen var strukturelt usynlig for os, mens den ramte førstegangsbrugere. Når en fejlrapport ikke kan reproduceres, er det første spørgsmål hvad er anderledes ved det sted, den kører, ikke tager brugeren fejl.

GeekBye v2.0.6 sendte relokeringsprompten og diagnostikken sammen. For den bredere pålidelighedsbue, som dette indgår i, se hvad en version 2 faktisk kræver (v2.0.0) og hvorfor skærmoptagelse fanger den forkerte skærm (v2.0.10) — endnu en fejl, der kun dukkede op i et specifikt miljø. For den detaljeorienterede udgivelse ved siden af, rolig software: flimmer-rettelsen og svar-tilstands-chippen (v2.0.3 + v2.0.5).

Relaterede artikler

Én CSS-variabel, fem review-runder og en Swift-værktøjskæde, der løj
Steven
Steven7 min læsning

Én CSS-variabel, fem review-runder og en Swift-værktøjskæde, der løj

GeekBye v2.0.7 gjorde hele overlay-laget justerbart gennemsigtigt — hvilket lyder som en CSS-ændring på én linje og på ingen måde var det. Den egentlige historie er, hvad code review fangede: to flader, der nægtede at fade, en optagelseslinje, der så forkert ud ved samme opacitet, og en kompileret binær, der vippede 672 bytes frem og tilbage, fordi vores egen dokumentation fortalte en reviewer den forkerte Swift-version.

Udvikling
Design
Build
Rolig software: at dræbe en flimrende kontakt og lære chatten at sige, hvilken tilstand den er i
Steven
Steven6 min læsning

Rolig software: at dræbe en flimrende kontakt og lære chatten at sige, hvilken tilstand den er i

To små GeekBye-udgivelser, ingen overskriftsfunktioner — bare en indstillingskontakt, der holdt op med at flimre, og en chatassistent, der endelig fortæller, om den svarede i mødetilstand eller kodningstilstand. Så meget koster "rolig software" i virkeligheden, én detalje ad gangen.

Produkt
Design
Udvikling
Anatomien bag at levere software til perfektion: hvordan kodegennemgang fangede det, testene ikke kunne
Steven
Steven6 min læsning

Anatomien bag at levere software til perfektion: hvordan kodegennemgang fangede det, testene ikke kunne

Gennem hele GeekBye v2-serien sker det samme igen og igen: en rettelse består hver eneste test på udviklerens maskine, og så beviser kodegennemgangen, at den ville være fejlet for næsten alle andre. Dette er arbejdsgangen bag ni udgivelser — gennemgangsporten, rettelse-først-fangsterne og test-før-levering-disciplinen, der forvandler "det virker for mig" til "det virker".

Ingeniørarbejde
Proces
Kodegennemgang