| 551 | } |
| 552 | |
| 553 | static void host_state_free(host_state_t *host) { |
| 554 | if (!host_http_stop_join_free(host)) { |
| 555 | /* The retained server or one of its callbacks can still borrow every |
| 556 | * dependency below. Process containment is the only safe teardown. */ |
| 557 | host_force_terminate("http_cleanup"); |
| 558 | } |
| 559 | if (host->application) { |
| 560 | if (!cbm_daemon_application_free(host->application)) { |
| 561 | /* The application still owns work or a borrowed callback context. |
| 562 | * Freeing any dependency below would turn the retained application |
| 563 | * into UAF. The daemon is the ultimate containment boundary. */ |
| 564 | host_cleanup_force_terminate("application_cleanup"); |
| 565 | } |
| 566 | host->application = NULL; |
| 567 | } |
| 568 | cbm_watcher_free(host->watcher); |
| 569 | host->watcher = NULL; |
| 570 | cbm_store_close(host->watch_store); |
| 571 | host->watch_store = NULL; |
| 572 | cbm_config_close(host->runtime_config); |
| 573 | host->runtime_config = NULL; |
| 574 | if (host->project_locks) { |
| 575 | host_cleanup_release_until_complete(host_project_lock_manager_free_once, |
| 576 | &host->project_locks, "project_lock_manager_cleanup"); |
| 577 | } |
| 578 | cbm_secure_zero(host->ui_readiness_secret, sizeof(host->ui_readiness_secret)); |
| 579 | } |
| 580 | |
| 581 | static bool host_state_prepare(host_state_t *host, const cbm_daemon_ipc_endpoint_t *endpoint) { |
| 582 | host->http_ops = &g_host_http_default_ops; |
no test coverage detected