[PATCH] Core: added realpath() checking when testing PID files

Maxim Dounin mdounin at mdounin.ru
Wed May 8 01:13:55 UTC 2024


# HG changeset patch
# User Maxim Dounin <mdounin at mdounin.ru>
# Date 1715130825 -10800
#      Wed May 08 04:13:45 2024 +0300
# Node ID 72cfccd6d587eb0b0e8f8c3c85e6bcecdc246cfe
# Parent  b1bf4da2220d8c5321cbc8a7c873c61129b66a05
Core: added realpath() checking when testing PID files.

This ensures that if the PID file path is changed, yet resolves to the
same file via symbolic links, trying to recreate the PID file won't
remove it.  In particular, this resolves issues as observed on Linux
systems with "/var/run/nginx.pid" changed to "/run/nginx.pid".

diff --git a/src/core/ngx_cycle.c b/src/core/ngx_cycle.c
--- a/src/core/ngx_cycle.c
+++ b/src/core/ngx_cycle.c
@@ -13,6 +13,8 @@
 static void ngx_destroy_cycle_pools(ngx_conf_t *conf);
 static ngx_int_t ngx_init_zone_pool(ngx_cycle_t *cycle,
     ngx_shm_zone_t *shm_zone);
+static ngx_int_t ngx_pidfile_changed(ngx_str_t *name1, ngx_str_t *name2,
+    ngx_log_t *log);
 static ngx_int_t ngx_test_lockfile(u_char *file, ngx_log_t *log);
 static void ngx_clean_old_cycles(ngx_event_t *ev);
 static void ngx_shutdown_timer_handler(ngx_event_t *ev);
@@ -332,9 +334,9 @@ ngx_init_cycle(ngx_cycle_t *old_cycle)
 
         old_ccf = (ngx_core_conf_t *) ngx_get_conf(old_cycle->conf_ctx,
                                                    ngx_core_module);
-        if (ccf->pid.len != old_ccf->pid.len
-            || ngx_strcmp(ccf->pid.data, old_ccf->pid.data) != 0)
-        {
+
+        if (ngx_pidfile_changed(&ccf->pid, &old_ccf->pid, log)) {
+
             /* new pid file name */
 
             if (ngx_create_pidfile(&ccf->pid, log) != NGX_OK) {
@@ -1087,6 +1089,54 @@ ngx_delete_pidfile(ngx_cycle_t *cycle)
 }
 
 
+static ngx_int_t
+ngx_pidfile_changed(ngx_str_t *name1, ngx_str_t *name2, ngx_log_t *log)
+{
+    u_char     *real1, *real2;
+    ngx_int_t   rc;
+
+    if (name1->len == name2->len
+        && ngx_strcmp(name1->data, name2->data) == 0)
+    {
+        return 0;
+    }
+
+    rc = 1;
+    real1 = NULL;
+    real2 = NULL;
+
+    real1 = ngx_realpath(name1->data, NULL);
+
+    if (real1 == NULL) {
+        ngx_log_debug1(NGX_LOG_DEBUG_CORE, log, ngx_errno,
+                       ngx_realpath_n " \"%s\" failed", name1->data);
+        goto done;
+    }
+
+    real2 = ngx_realpath(name2->data, NULL);
+
+    if (real2 == NULL) {
+        ngx_log_debug1(NGX_LOG_DEBUG_CORE, log, ngx_errno,
+                       ngx_realpath_n " \"%s\" failed", name2->data);
+        goto done;
+    }
+
+    rc = ngx_strcmp(real1, real2);
+
+done:
+
+    if (real1 && real1 != name1->data) {
+        ngx_free(real1);
+    }
+
+    if (real2 && real2 != name2->data) {
+        ngx_free(real2);
+    }
+
+    return rc;
+}
+
+
 ngx_int_t
 ngx_signal_process(ngx_cycle_t *cycle, char *sig)
 {




More information about the nginx-devel mailing list