php / php/php-src

Consider not calling dlclose() for extensions

Offen
#16,202 2 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

Feature Status: Needs Triage
Vorherrschende Sprache
C
Sterne
40.4k
Forks
8.1k
Ø Merge
2 T. 13 Std.
Gemergte PRs (30 T.)
96

Beschreibung

Description

PHP calls dlclose on extension as part of tearing down the runtime. However, dlclose can be really finicky; while I would hope extensions handle it fine (being that they are expected to be loaded and unloaded), the libraries that extensions often depend on often do not, and those can get unloaded as part of collecting garbage by the dynamic linker. If there are any dangling references to things in the unloaded memory, things can be catastrophic.

For example, one issue I've had was with the gnupg extension. It loads libgpg-error as a transitive dependency, and that sets up an atexit handler for clean up. But if the gnupg PHP extension gets unloaded by PHP, the dynamic linker can claim libgpg-error (since it wasn't referenced elsewhere), remove it from memory, and now the dangling atexit handler is all nulls. I have a patch inbound for libgpg-error, but it's one such example.

The problems with dlclose seem known; it was the cause of an OpenSSH exploit a year ago. Platform behaviour with dlclose also seems unpredictable; some platforms have specific criteria that will make them decide to close a library or not, which can be confusing. musl notably turns dlclose into a no-op considering the issues that dlclose brings in.

PHP already has a ZEND_DONT_UNLOAD_MODULES variable used for debugging contexts, since dlclose can confuse i.e. Valgrind. I suspect the main reason to unload modules is embedded SAPIs like i.e. the Apache module, if PHP gets unloaded and reloaded instead of the host going down with it. However, I'm not familiar enough with the embedded SAPIs outside of CLI/CGI to say how common this is.

(This might require an RFC.)

Beitragsleitfaden

Beitragsleitfaden öffnen

Erste Schritte

  1. Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
  3. Forke das Repository und arbeite in einem Branch.
  4. Öffne einen Pull Request, der die Issue-Nummer nennt.

Rechercherichtung

Es ist keine Datei und kein Test angegeben. Beginne damit, den Teardown-Pfad der Runtime-Erweiterungen rund um dlclose nachzuverfolgen und zu prüfen, wie ZEND_DONT_UNLOAD_MODULES und eingebettete SAPIs das Entladen beeinflussen. Ermittle die Anforderungen an Plattform und Lebenszyklus und kläre anschließend, ob ein RFC erforderlich ist; als abgeschlossen gilt die Einigung auf die Entladestrategie und die Kompatibilitätsanforderungen.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
c, php
Bereich
backend
Issue-Typ
Feature
Schwierigkeit
5/5
Geschätzter Aufwand
Über eine Woche
Aktivitätsstatus
Veraltet
Klarheit
Muss geklärt werden
Anfängerfreundlichkeit
25/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.