Hi, On Wed, Jun 28, 2023 at 06:08:35PM +0300, Maxim Dounin wrote: > Hello! > > On Wed, Jun 28, 2023 at 04:45:16PM +0400, Roman Arutyunyan wrote: > > > On Sat, Jun 24, 2023 at 05:06:46AM +0300, Maxim Dounin wrote: > > > Hello! > > > > > > On Fri, Jun 23, 2023 at 07:55:47PM +0400, Sergey Kandaurov wrote: > > > > > > > # HG changeset patch > > > > # User Sergey Kandaurov <pluk...@nginx.com> > > > > # Date 1687535739 -14400 > > > > # Fri Jun 23 19:55:39 2023 +0400 > > > > # Node ID 34a8e1a4161542896c11c4a5c60d6a6fe1931e3d > > > > # Parent c681f4906d838ac45b517fada4c4274ade03fd3c > > > > Core: fixed environment on exit better. > > > > > > > > The fix in 6822:c045b4926b2c to replace environment allocations from a > > > > pool > > > > was incomplete, such that it left pool owned allocations for variables > > > > set > > > > with values using the "env" directive. Another consumer of this > > > > interface > > > > is the QUIC BPF helper that uses the environment variable > > > > NGINX_BPF_MAPS. > > > > The fix is to re-allocate variables with malloc, to avoid use after > > > > free. > > > > If memory allocation failed, the only option is to expel from > > > > environment. > > > > > > > > The observed symptoms are similar to described in 6822:c045b4926b2c, > > > > that > > > > is a segmentation fault on worker process exit from atexit() handler > > > > seen > > > > with 3rd party modules or if nginx was built with lcov profiling. > > > > > > > > diff --git a/src/core/nginx.c b/src/core/nginx.c > > > > --- a/src/core/nginx.c > > > > +++ b/src/core/nginx.c > > > > @@ -631,17 +631,48 @@ ngx_cleanup_environment(void *data) > > > > { > > > > char **env = data; > > > > > > > > - if (environ == env) { > > > > + char *p, **penv; > > > > + size_t size; > > > > + ngx_uint_t i, n; > > > > > > > > - /* > > > > - * if the environment is still used, as it happens on exit, > > > > - * the only option is to leak it > > > > - */ > > > > - > > > > + if (environ != env) { > > > > + ngx_free(env); > > > > return; > > > > } > > > > > > Note: if we assume that the environment can be arbitrary modified, > > > I don't think it's enough. For example, a setenv() call can > > > replace environ with something different, so this code will free > > > env and exit, but pool-allocated variables will be still > > > referenced by the new environ. > > > > Another problem is if setenv() was called, environ may have been > > reallocated with realloc() which may result in double-free in this function, > > even with current code. > > I don't think that realloc() is allowed here. At least BSD libc > does not try to do this and only use realloc() on it's internal > storage, and glibc does the same.
You're right. I see, glibc only realloc()'ates what it allocated itself. stdlib/setenv.c: /* If this variable is not a null pointer we allocated the current environment. */ static char **last_environ; [..] -- Roman Arutyunyan _______________________________________________ nginx-devel mailing list nginx-devel@nginx.org https://mailman.nginx.org/mailman/listinfo/nginx-devel