gioser

sergio/takana

> Una distribución Linux construida con un laboratorio funcional y hermético en el > sótano, y una terminal mutable, clásica y anárquica en el piso de arriba — diseñada > desde el suelo para que una IA programadora entienda, modifique y co…

TOML 1471Shell 173Rust 105Markdown 943545 Definiciones

⎇ 534014c3ec69daea789a1d0523e1d00a69c6ed65 tandas/staged-2026-06-26/0210-dirmngr-hkp-avoid-potential-race-condition-when-some-host-die.patch 284 líneas · 9.2 KB Historia crudo

Etapa G: fuel-5 — recarga la cola del VPS (parado 14h sin producir) 08fdec3bb · sergio ·

1note: combination of previous 0210+0220
2--
3From: Daniel Kahn Gillmor <dkg@fifthhorseman.net>
4Date: Sat, 29 Oct 2016 01:25:05 -0400
5Subject: dirmngr: hkp: Avoid potential race condition when some hosts die.
6
7* dirmngr/ks-engine-hkp.c (select_random_host): Use atomic pass
8through the host table instead of risking out-of-bounds write.
9
10--
11
12Multiple threads may write to hosttable[x]->dead while
13select_random_host() is running.  For example, a housekeeping thread
14might clear the ->dead bit on some entries, or another connection to
15dirmngr might manually mark a host as alive.
16
17If one or more hosts are resurrected between the two loops over a
18given table in select_random_host(), then the allocation of tbl might
19not be large enough, resulting in a write past the end of tbl on the
20second loop.
21
22This change collapses the two loops into a single loop to avoid this
23discrepancy: each host's "dead" bit is now only checked once.
24
25As Werner points out, this isn't currently strictly necessary, since
26npth will not switch threads unless a blocking system call is made,
27and no blocking system call is made in these two loops.
28
29However, in a subsequent change in this series, we will call a
30function in this loop, and that function may sometimes write(2), or
31call other functions, which may themselves block.  Keeping this as a
32single-pass loop avoids the need to keep track of what might block and
33what might not.
34
35Signed-off-by: Daniel Kahn Gillmor <dkg@fifthhorseman.net>
36---
37 dirmngr/ks-engine-hkp.c | 23 ++++++++++-------------
38 1 file changed, 10 insertions(+), 13 deletions(-)
39
40Patch-Source: https://sources.debian.org/data/main/g/gnupg2/2.2.27-2/debian/patches/dirmngr-idling/dirmngr-hkp-Avoid-potential-race-condition-when-some.patch
41
42From: Daniel Kahn Gillmor <dkg@fifthhorseman.net>
43Date: Sat, 29 Oct 2016 02:00:50 -0400
44Subject: dirmngr: Avoid need for hkp housekeeping.
45
46* dirmngr/ks-engine-hkp.c (host_is_alive): New function.  Test whether
47host is alive and resurrects it if it has been dead long enough.
48(select_random_host, map_host, ks_hkp_mark_host): Use host_is_alive
49instead of testing hostinfo_t->dead directly.
50(ks_hkp_housekeeping): Remove function, no longer needed.
51* dirmngr/dirmngr.c (housekeeping_thread): Remove call to
52ks_hkp_housekeeping.
53
54--
55
56Rather than resurrecting hosts upon scheduled resurrection times, test
57whether hosts should be resurrected as they're inspected for being
58dead.  This removes the need for explicit housekeeping, and makes host
59resurrections happen "just in time", rather than being clustered on
60HOUSEKEEPING_INTERVAL seconds.
61
62According to 392e068e9f143d41f6350345619543cbcd47380f,
63dns_stuff_housekeeping only works on Windows, so it also isn't
64necessary in debian, but it remains in place for now.
65
66Signed-off-by: Daniel Kahn Gillmor <dkg@fifthhorseman.net>
67---
68 dirmngr/dirmngr.c       |  3 ---
69 dirmngr/dirmngr.h       |  1 -
70 dirmngr/ks-engine-hkp.c | 72 ++++++++++++++++++++++++-------------------------
71 3 files changed, 35 insertions(+), 41 deletions(-)
72
73Patch-Source: https://sources.debian.org/data/main/g/gnupg2/2.2.27-2/debian/patches/dirmngr-idling/dirmngr-Avoid-need-for-hkp-housekeeping.patch
74
75diff --git a/dirmngr/dirmngr.c b/dirmngr/dirmngr.c
76index 977e7dd..5017c3f 100644
77--- a/dirmngr/dirmngr.c
78+++ b/dirmngr/dirmngr.c
79@@ -2085,7 +2085,6 @@ housekeeping_thread (void *arg)
80   dirmngr_init_default_ctrl (&ctrlbuf);
81 
82   dns_stuff_housekeeping ();
83-  ks_hkp_housekeeping (curtime);
84   if (network_activity_seen)
85     {
86       network_activity_seen = 0;
87diff --git a/dirmngr/ks-engine-hkp.c b/dirmngr/ks-engine-hkp.c
88index 5292da8..690b37d 100644
89--- a/dirmngr/ks-engine-hkp.c
90+++ b/dirmngr/ks-engine-hkp.c
91@@ -221,6 +221,24 @@ host_in_pool_p (hostinfo_t hi, int tblidx)
92   return 0;
93 }
94 
95+static int
96+host_is_alive (hostinfo_t hi, time_t curtime)
97+{
98+  if (!hi)
99+    return 0;
100+  if (!hi->dead)
101+    return 1;
102+  if (!hi->died_at)
103+    return 0; /* manually marked dead */
104+  if (hi->died_at + RESURRECT_INTERVAL <= curtime
105+      || hi->died_at > curtime)
106+    {
107+      hi->dead = 0;
108+      log_info ("resurrected host '%s'", hi->name);
109+      return 1;
110+    }
111+  return 0;
112+}
113 
114 /* Select a random host.  Consult HI->pool which indices into the global
115    hosttable.  Returns index into HI->pool or -1 if no host could be
116@@ -228,32 +246,32 @@ host_in_pool_p (hostinfo_t hi, int tblidx)
117 static int
118 select_random_host (hostinfo_t hi)
119 {
120-  int *tbl;
121-  size_t tblsize;
122+  int *tbl = NULL;
123+  size_t tblsize = 0;
124   int pidx, idx;
125+  time_t curtime;
126+
127+  curtime = gnupg_get_time ();
128 
129   /* CHECKTHIS();  See */
130   /*                 https://sources.debian.org/patches/gnupg2/2.2.20-1/dirmngr-idling/dirmngr-hkp-Avoid-potential-race-condition-when-some.patch/ */
131 
132   /* We create a new table so that we randomly select only from
133      currently alive hosts.  */
134-  for (idx = 0, tblsize = 0;
135+  for (idx = 0;
136        idx < hi->pool_len && (pidx = hi->pool[idx]) != -1;
137        idx++)
138-    if (hosttable[pidx] && !hosttable[pidx]->dead)
139-      tblsize++;
140+    if (hosttable[pidx] && host_is_alive (hosttable[pidx], curtime))
141+      {
142+        tblsize++;
143+        tbl = xtryrealloc(tbl, tblsize * sizeof *tbl);
144+        if (!tbl)
145+          return -1; /* memory allocation failed! */
146+        tbl[tblsize-1] = pidx;
147+      }
148   if (!tblsize)
149     return -1; /* No hosts.  */
150 
151-  tbl = xtrymalloc (tblsize * sizeof *tbl);
152-  if (!tbl)
153-    return -1;
154-  for (idx = 0, tblsize = 0;
155-       idx < hi->pool_len && (pidx = hi->pool[idx]) != -1;
156-       idx++)
157-    if (hosttable[pidx] && !hosttable[pidx]->dead)
158-      tbl[tblsize++] = pidx;
159-
160   if (tblsize == 1)  /* Save a get_uint_nonce.  */
161     pidx = tbl[0];
162   else
163@@ -471,6 +489,7 @@ map_host (ctrl_t ctrl, const char *name, const char *srvtag, int force_reselect,
164   int is_pool;
165   int new_hosts = 0;
166   char *cname;
167+  time_t curtime;
168 
169   *r_host = NULL;
170   if (r_httpflags)
171@@ -510,6 +529,7 @@ map_host (ctrl_t ctrl, const char *name, const char *srvtag, int force_reselect,
172     }
173   else
174     hi = hosttable[idx];
175+  curtime = gnupg_get_time ();
176 
177   is_pool = hi->pool != NULL;
178 
179@@ -616,7 +636,7 @@ map_host (ctrl_t ctrl, const char *name, const char *srvtag, int force_reselect,
180       if (force_reselect)
181         hi->poolidx = -1;
182       else if (hi->poolidx >= 0 && hi->poolidx < hosttable_size
183-               && hosttable[hi->poolidx] && hosttable[hi->poolidx]->dead)
184+               && hosttable[hi->poolidx] && !host_is_alive (hosttable[hi->poolidx], curtime))
185         hi->poolidx = -1;
186 
187       /* Select a host if needed.  */
188@@ -675,7 +695,7 @@ map_host (ctrl_t ctrl, const char *name, const char *srvtag, int force_reselect,
189         return gpg_error_from_syserror ();
190     }
191 
192-  if (hi->dead)
193+  if (!host_is_alive (hi, curtime))
194     {
195       log_error ("host '%s' marked as dead\n", hi->name);
196       if (r_httphost)
197@@ -781,7 +801,8 @@ ks_hkp_mark_host (ctrl_t ctrl, const char *name, int alive)
198 {
199   gpg_error_t err = 0;
200   hostinfo_t hi, hi2;
201-  int idx, idx2, idx3, n;
202+  int idx, idx2, idx3, n, is_alive;
203+  time_t curtime;
204 
205   if (!name || !*name || !strcmp (name, "localhost"))
206     return 0;
207@@ -796,13 +817,15 @@ ks_hkp_mark_host (ctrl_t ctrl, const char *name, int alive)
208       goto leave;
209     }
210 
211+  curtime = gnupg_get_time ();
212   hi = hosttable[idx];
213-  if (alive && hi->dead)
214+  is_alive = host_is_alive (hi, curtime);
215+  if (alive && !is_alive)
216     {
217       hi->dead = 0;
218       err = ks_printf_help (ctrl, "marking '%s' as alive", name);
219     }
220-  else if (!alive && !hi->dead)
221+  else if (!alive && is_alive)
222     {
223       hi->dead = 1;
224       hi->died_at = 0; /* Manually set dead.  */
225@@ -836,14 +859,15 @@ ks_hkp_mark_host (ctrl_t ctrl, const char *name, int alive)
226 
227           hi2 = hosttable[n];
228           if (!hi2)
229-            ;
230-          else if (alive && hi2->dead)
231+            continue;
232+          is_alive = host_is_alive (hi2, curtime);
233+          if (alive && !is_alive)
234             {
235               hi2->dead = 0;
236               err = ks_printf_help (ctrl, "marking '%s' as alive",
237                                     hi2->name);
238             }
239-          else if (!alive && !hi2->dead)
240+          else if (!alive && is_alive)
241             {
242               hi2->dead = 1;
243               hi2->died_at = 0; /* Manually set dead. */
244@@ -1149,40 +1173,6 @@ ks_hkp_resolve (ctrl_t ctrl, parsed_uri_t uri)
245 }
246 
247 
248-/* Housekeeping function called from the housekeeping thread.  It is
249-   used to mark dead hosts alive so that they may be tried again after
250-   some time.  */
251-void
252-ks_hkp_housekeeping (time_t curtime)
253-{
254-  int idx;
255-  hostinfo_t hi;
256-
257-  if (npth_mutex_lock (&hosttable_lock))
258-    log_fatal ("failed to acquire mutex\n");
259-
260-  for (idx=0; idx < hosttable_size; idx++)
261-    {
262-      hi = hosttable[idx];
263-      if (!hi)
264-        continue;
265-      if (!hi->dead)
266-        continue;
267-      if (!hi->died_at)
268-        continue; /* Do not resurrect manually shot hosts.  */
269-      if (hi->died_at + RESURRECT_INTERVAL <= curtime
270-          || hi->died_at > curtime)
271-        {
272-          hi->dead = 0;
273-          log_info ("resurrected host '%s'", hi->name);
274-        }
275-    }
276-
277-  if (npth_mutex_unlock (&hosttable_lock))
278-    log_fatal ("failed to release mutex\n");
279-}
280-
281-
282 /* Reload (SIGHUP) action for this module.  We mark all host alive
283  * even those which have been manually shot.  */
284 void