forked from rpms/glibc
		
	import UBI glibc-2.28-236.el8_9.12
This commit is contained in:
		
							parent
							
								
									0058656e5f
								
							
						
					
					
						commit
						8eea62074d
					
				
							
								
								
									
										112
									
								
								SOURCES/glibc-RHEL-21519.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										112
									
								
								SOURCES/glibc-RHEL-21519.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,112 @@ | ||||
| commit 849274d48fc59bfa6db3c713c8ced8026b20f3b7 | ||||
| Author: Florian Weimer <fweimer@redhat.com> | ||||
| Date:   Thu Nov 16 19:55:35 2023 +0100 | ||||
| 
 | ||||
|     elf: Fix force_first handling in dlclose (bug 30981) | ||||
|      | ||||
|     The force_first parameter was ineffective because the dlclose'd | ||||
|     object was not necessarily the first in the maps array.  Also | ||||
|     enable force_first handling unconditionally, regardless of namespace. | ||||
|     The initial object in a namespace should be destructed first, too. | ||||
|      | ||||
|     The _dl_sort_maps_dfs function had early returns for relocation | ||||
|     dependency processing which broke force_first handling, too, and | ||||
|     this is fixed in this change as well. | ||||
|      | ||||
|     Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org> | ||||
| 
 | ||||
| diff --git a/elf/dl-close.c b/elf/dl-close.c
 | ||||
| index 22225efb3226c3e1..16a39f5bf17b440f 100644
 | ||||
| --- a/elf/dl-close.c
 | ||||
| +++ b/elf/dl-close.c
 | ||||
| @@ -182,6 +182,16 @@ _dl_close_worker (struct link_map *map, bool force)
 | ||||
|      } | ||||
|    assert (idx == nloaded); | ||||
|   | ||||
| +  /* Put the dlclose'd map first, so that its destructor runs first.
 | ||||
| +     The map variable is NULL after a retry.  */
 | ||||
| +  if (map != NULL)
 | ||||
| +    {
 | ||||
| +      maps[map->l_idx] = maps[0];
 | ||||
| +      maps[map->l_idx]->l_idx = map->l_idx;
 | ||||
| +      maps[0] = map;
 | ||||
| +      maps[0]->l_idx = 0;
 | ||||
| +    }
 | ||||
| +
 | ||||
|    /* Keep track of the lowest index link map we have covered already.  */ | ||||
|    int done_index = -1; | ||||
|    while (++done_index < nloaded) | ||||
| @@ -255,9 +265,10 @@ _dl_close_worker (struct link_map *map, bool force)
 | ||||
|  	  } | ||||
|      } | ||||
|   | ||||
| -  /* Sort the entries.  We can skip looking for the binary itself which is
 | ||||
| -     at the front of the search list for the main namespace.  */
 | ||||
| -  _dl_sort_maps (maps, nloaded, (nsid == LM_ID_BASE), true);
 | ||||
| +  /* Sort the entries.  Unless retrying, the maps[0] object (the
 | ||||
| +     original argument to dlclose) needs to remain first, so that its
 | ||||
| +     destructor runs first.  */
 | ||||
| +  _dl_sort_maps (maps, nloaded, /* force_first */ map != NULL, true);
 | ||||
|   | ||||
|    /* Call all termination functions at once.  */ | ||||
|    bool unload_any = false; | ||||
| @@ -768,7 +779,11 @@ _dl_close_worker (struct link_map *map, bool force)
 | ||||
|    /* Recheck if we need to retry, release the lock.  */ | ||||
|   out: | ||||
|    if (dl_close_state == rerun) | ||||
| -    goto retry;
 | ||||
| +    {
 | ||||
| +      /* The map may have been deallocated.  */
 | ||||
| +      map = NULL;
 | ||||
| +      goto retry;
 | ||||
| +    }
 | ||||
|   | ||||
|    dl_close_state = not_pending; | ||||
|  } | ||||
| diff --git a/elf/dl-sort-maps.c b/elf/dl-sort-maps.c
 | ||||
| index aeb79b40b45054c0..c17ac325eca658ef 100644
 | ||||
| --- a/elf/dl-sort-maps.c
 | ||||
| +++ b/elf/dl-sort-maps.c
 | ||||
| @@ -260,13 +260,12 @@ _dl_sort_maps_dfs (struct link_map **maps, unsigned int nmaps,
 | ||||
|  	     The below memcpy is not needed in the do_reldeps case here, | ||||
|  	     since we wrote back to maps[] during DFS traversal.  */ | ||||
|  	  if (maps_head == maps) | ||||
| -	    return;
 | ||||
| +	    break;
 | ||||
|  	} | ||||
|        assert (maps_head == maps); | ||||
| -      return;
 | ||||
|      } | ||||
| -
 | ||||
| -  memcpy (maps, rpo, sizeof (struct link_map *) * nmaps);
 | ||||
| +  else
 | ||||
| +    memcpy (maps, rpo, sizeof (struct link_map *) * nmaps);
 | ||||
|   | ||||
|    /* Skipping the first object at maps[0] is not valid in general, | ||||
|       since traversing along object dependency-links may "find" that | ||||
| diff --git a/elf/dso-sort-tests-1.def b/elf/dso-sort-tests-1.def
 | ||||
| index 4bf9052db16fb352..cf6453e9eb85ac65 100644
 | ||||
| --- a/elf/dso-sort-tests-1.def
 | ||||
| +++ b/elf/dso-sort-tests-1.def
 | ||||
| @@ -56,14 +56,16 @@ output: b>a>{}<a<b
 | ||||
|  # relocation(dynamic) dependencies. While this is technically unspecified, the | ||||
|  # presumed reasonable practical behavior is for the destructor order to respect | ||||
|  # the static DT_NEEDED links (here this means the a->b->c->d order). | ||||
| -# The older dynamic_sort=1 algorithm does not achieve this, while the DFS-based
 | ||||
| -# dynamic_sort=2 algorithm does, although it is still arguable whether going
 | ||||
| -# beyond spec to do this is the right thing to do.
 | ||||
| +# The older dynamic_sort=1 algorithm originally did not achieve this,
 | ||||
| +# but this was a bug in the way _dl_sort_maps was called from _dl_close_worker,
 | ||||
| +# effectively disabling proper force_first handling.
 | ||||
| +# The new dynamic_sort=2 algorithm shows the effect of the simpler force_first
 | ||||
| +# handling: the a object is simply moved to the front.
 | ||||
|  # The below expected outputs are what the two algorithms currently produce | ||||
|  # respectively, for regression testing purposes. | ||||
|  tst-bz15311: {+a;+e;+f;+g;+d;%d;-d;-g;-f;-e;-a};a->b->c->d;d=>[ba];c=>a;b=>e=>a;c=>f=>b;d=>g=>c | ||||
| -output(glibc.rtld.dynamic_sort=1): {+a[d>c>b>a>];+e[e>];+f[f>];+g[g>];+d[];%d(b(e(a()))a()g(c(a()f(b(e(a()))))));-d[];-g[];-f[];-e[];-a[<a<c<d<g<f<b<e];}
 | ||||
| -output(glibc.rtld.dynamic_sort=2): {+a[d>c>b>a>];+e[e>];+f[f>];+g[g>];+d[];%d(b(e(a()))a()g(c(a()f(b(e(a()))))));-d[];-g[];-f[];-e[];-a[<g<f<a<b<c<d<e];}
 | ||||
| +output(glibc.rtld.dynamic_sort=1): {+a[d>c>b>a>];+e[e>];+f[f>];+g[g>];+d[];%d(b(e(a()))a()g(c(a()f(b(e(a()))))));-d[];-g[];-f[];-e[];-a[<a<b<c<d<g<f<e];}
 | ||||
| +output(glibc.rtld.dynamic_sort=2): {+a[d>c>b>a>];+e[e>];+f[f>];+g[g>];+d[];%d(b(e(a()))a()g(c(a()f(b(e(a()))))));-d[];-g[];-f[];-e[];-a[<a<g<f<b<c<d<e];}
 | ||||
|   | ||||
|  # Test that even in the presence of dependency loops involving dlopen'ed | ||||
|  # object, that object is initialized last (and not unloaded prematurely). | ||||
							
								
								
									
										35
									
								
								SOURCES/glibc-RHEL-21522-1.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								SOURCES/glibc-RHEL-21522-1.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,35 @@ | ||||
| commit b893410be304ddcea0bd43f537a13e8b18d37cf2 | ||||
| Author: Florian Weimer <fweimer@redhat.com> | ||||
| Date:   Mon Nov 27 11:28:07 2023 +0100 | ||||
| 
 | ||||
|     elf: In _dl_relocate_object, skip processing if object is relocated | ||||
|      | ||||
|     This is just a minor optimization.  It also makes it more obvious that | ||||
|     _dl_relocate_object can be called multiple times. | ||||
|      | ||||
|     Reviewed-by: Carlos O'Donell <carlos@redhat.com> | ||||
| 
 | ||||
| diff --git a/elf/dl-reloc.c b/elf/dl-reloc.c
 | ||||
| index 7a84b1fa8c3a7fdd..a80a54fb013adab5 100644
 | ||||
| --- a/elf/dl-reloc.c
 | ||||
| +++ b/elf/dl-reloc.c
 | ||||
| @@ -165,6 +165,9 @@ void
 | ||||
|  _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[], | ||||
|  		     int reloc_mode, int consider_profiling) | ||||
|  { | ||||
| +  if (l->l_relocated)
 | ||||
| +    return;
 | ||||
| +
 | ||||
|    struct textrels | ||||
|    { | ||||
|      caddr_t start; | ||||
| @@ -202,9 +205,6 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
 | ||||
|  # define consider_symbind 0 | ||||
|  #endif | ||||
|   | ||||
| -  if (l->l_relocated)
 | ||||
| -    return;
 | ||||
| -
 | ||||
|    /* If DT_BIND_NOW is set relocate all references in this object.  We | ||||
|       do not do this if we are profiling, of course.  */ | ||||
|    // XXX Correct for auditing? | ||||
							
								
								
									
										121
									
								
								SOURCES/glibc-RHEL-21522-2.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										121
									
								
								SOURCES/glibc-RHEL-21522-2.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,121 @@ | ||||
| commit a74c2e1cbc8673dd7e97aae2f2705392e2ccc3f6 | ||||
| Author: Florian Weimer <fweimer@redhat.com> | ||||
| Date:   Mon Nov 27 11:28:10 2023 +0100 | ||||
| 
 | ||||
|     elf: Introduce the _dl_open_relocate_one_object function | ||||
|      | ||||
|     It is extracted from dl_open_worker_begin. | ||||
|      | ||||
|     Reviewed-by: Carlos O'Donell <carlos@redhat.com> | ||||
| 
 | ||||
| diff --git a/elf/dl-open.c b/elf/dl-open.c
 | ||||
| index e82e53ff8b38fa11..1505fdb73088dcdb 100644
 | ||||
| --- a/elf/dl-open.c
 | ||||
| +++ b/elf/dl-open.c
 | ||||
| @@ -466,6 +466,50 @@ activate_nodelete (struct link_map *new)
 | ||||
|        } | ||||
|  } | ||||
|   | ||||
| +/* Relocate the object L.  *RELOCATION_IN_PROGRESS controls whether
 | ||||
| +   the debugger is notified of the start of relocation processing.  */
 | ||||
| +static void
 | ||||
| +_dl_open_relocate_one_object (struct dl_open_args *args, struct r_debug *r,
 | ||||
| +			      struct link_map *l, int reloc_mode,
 | ||||
| +			      bool *relocation_in_progress)
 | ||||
| +{
 | ||||
| +  if (l->l_real->l_relocated)
 | ||||
| +    return;
 | ||||
| +
 | ||||
| +  if (!*relocation_in_progress)
 | ||||
| +    {
 | ||||
| +      /* Notify the debugger that relocations are about to happen.  */
 | ||||
| +      LIBC_PROBE (reloc_start, 2, args->nsid, r);
 | ||||
| +      *relocation_in_progress = true;
 | ||||
| +    }
 | ||||
| +
 | ||||
| +#ifdef SHARED
 | ||||
| +  if (__glibc_unlikely (GLRO(dl_profile) != NULL))
 | ||||
| +    {
 | ||||
| +      /* If this here is the shared object which we want to profile
 | ||||
| +	 make sure the profile is started.  We can find out whether
 | ||||
| +	 this is necessary or not by observing the `_dl_profile_map'
 | ||||
| +	 variable.  If it was NULL but is not NULL afterwards we must
 | ||||
| +	 start the profiling.  */
 | ||||
| +      struct link_map *old_profile_map = GL(dl_profile_map);
 | ||||
| +
 | ||||
| +      _dl_relocate_object (l, l->l_scope, reloc_mode | RTLD_LAZY, 1);
 | ||||
| +
 | ||||
| +      if (old_profile_map == NULL && GL(dl_profile_map) != NULL)
 | ||||
| +	{
 | ||||
| +	  /* We must prepare the profiling.  */
 | ||||
| +	  _dl_start_profile ();
 | ||||
| +
 | ||||
| +	  /* Prevent unloading the object.  */
 | ||||
| +	  GL(dl_profile_map)->l_nodelete_active = true;
 | ||||
| +	}
 | ||||
| +    }
 | ||||
| +  else
 | ||||
| +#endif
 | ||||
| +    _dl_relocate_object (l, l->l_scope, reloc_mode, 0);
 | ||||
| +}
 | ||||
| +
 | ||||
| +
 | ||||
|  /* struct dl_init_args and call_dl_init are used to call _dl_init with | ||||
|     exception handling disabled.  */ | ||||
|  struct dl_init_args | ||||
| @@ -638,7 +682,7 @@ dl_open_worker_begin (void *a)
 | ||||
|      } | ||||
|    while (l != NULL); | ||||
|   | ||||
| -  int relocation_in_progress = 0;
 | ||||
| +  bool relocation_in_progress = false;
 | ||||
|   | ||||
|    /* Perform relocation.  This can trigger lazy binding in IFUNC | ||||
|       resolvers.  For NODELETE mappings, these dependencies are not | ||||
| @@ -649,44 +693,8 @@ dl_open_worker_begin (void *a)
 | ||||
|       are undefined anyway, so this is not a problem.  */ | ||||
|   | ||||
|    for (unsigned int i = last; i-- > first; ) | ||||
| -    {
 | ||||
| -      l = new->l_initfini[i];
 | ||||
| -
 | ||||
| -      if (l->l_real->l_relocated)
 | ||||
| -	continue;
 | ||||
| -
 | ||||
| -      if (! relocation_in_progress)
 | ||||
| -	{
 | ||||
| -	  /* Notify the debugger that relocations are about to happen.  */
 | ||||
| -	  LIBC_PROBE (reloc_start, 2, args->nsid, r);
 | ||||
| -	  relocation_in_progress = 1;
 | ||||
| -	}
 | ||||
| -
 | ||||
| -#ifdef SHARED
 | ||||
| -      if (__glibc_unlikely (GLRO(dl_profile) != NULL))
 | ||||
| -	{
 | ||||
| -	  /* If this here is the shared object which we want to profile
 | ||||
| -	     make sure the profile is started.  We can find out whether
 | ||||
| -	     this is necessary or not by observing the `_dl_profile_map'
 | ||||
| -	     variable.  If it was NULL but is not NULL afterwards we must
 | ||||
| -	     start the profiling.  */
 | ||||
| -	  struct link_map *old_profile_map = GL(dl_profile_map);
 | ||||
| -
 | ||||
| -	  _dl_relocate_object (l, l->l_scope, reloc_mode | RTLD_LAZY, 1);
 | ||||
| -
 | ||||
| -	  if (old_profile_map == NULL && GL(dl_profile_map) != NULL)
 | ||||
| -	    {
 | ||||
| -	      /* We must prepare the profiling.  */
 | ||||
| -	      _dl_start_profile ();
 | ||||
| -
 | ||||
| -	      /* Prevent unloading the object.  */
 | ||||
| -	      GL(dl_profile_map)->l_nodelete_active = true;
 | ||||
| -	    }
 | ||||
| -	}
 | ||||
| -      else
 | ||||
| -#endif
 | ||||
| -	_dl_relocate_object (l, l->l_scope, reloc_mode, 0);
 | ||||
| -    }
 | ||||
| +    _dl_open_relocate_one_object (args, r, new->l_initfini[i], reloc_mode,
 | ||||
| +				  &relocation_in_progress);
 | ||||
|   | ||||
|    /* This only performs the memory allocations.  The actual update of | ||||
|       the scopes happens below, after failure is impossible.  */ | ||||
							
								
								
									
										223
									
								
								SOURCES/glibc-RHEL-21522-3.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										223
									
								
								SOURCES/glibc-RHEL-21522-3.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,223 @@ | ||||
| commit 78ca44da0160a0b442f0ca1f253e3360f044b2ec | ||||
| Author: Florian Weimer <fweimer@redhat.com> | ||||
| Date:   Mon Nov 27 11:28:13 2023 +0100 | ||||
| 
 | ||||
|     elf: Relocate libc.so early during startup and dlmopen (bug 31083) | ||||
|      | ||||
|     This makes it more likely that objects without dependencies can | ||||
|     use IFUNC resolvers in libc.so. | ||||
|      | ||||
|     Reviewed-by: Carlos O'Donell <carlos@redhat.com> | ||||
| 
 | ||||
| Conflicts: | ||||
| 	elf/Makefile | ||||
| 	  (differences in test backports) | ||||
| 	elf/rtld.c | ||||
| 	  (removal of prelink support upstream) | ||||
| 
 | ||||
| diff --git a/elf/Makefile b/elf/Makefile
 | ||||
| index 634c3113227d64a6..6f0f36cdfe3961e8 100644
 | ||||
| --- a/elf/Makefile
 | ||||
| +++ b/elf/Makefile
 | ||||
| @@ -386,6 +386,8 @@ tests += \
 | ||||
|    tst-nodelete2 \ | ||||
|    tst-nodelete-dlclose \ | ||||
|    tst-nodelete-opened \ | ||||
| +  tst-nodeps1 \
 | ||||
| +  tst-nodeps2 \
 | ||||
|    tst-noload \ | ||||
|    tst-null-argv \ | ||||
|    tst-relsort1 \ | ||||
| @@ -740,6 +742,8 @@ modules-names = \
 | ||||
|    tst-nodelete-dlclose-dso \ | ||||
|    tst-nodelete-dlclose-plugin \ | ||||
|    tst-nodelete-opened-lib \ | ||||
| +  tst-nodeps1-mod \
 | ||||
| +  tst-nodeps2-mod \
 | ||||
|    tst-null-argv-lib \ | ||||
|    tst-relsort1mod1 \ | ||||
|    tst-relsort1mod2 \ | ||||
| @@ -886,8 +890,13 @@ modules-execstack-yes = tst-execstack-mod
 | ||||
|  extra-test-objs += $(addsuffix .os,$(strip $(modules-names))) | ||||
|   | ||||
|  # filtmod1.so has a special rule | ||||
| -modules-names-nobuild := filtmod1 \
 | ||||
| -			 tst-audit24bmod1 tst-audit24bmod2
 | ||||
| +modules-names-nobuild += \
 | ||||
| +  filtmod1 \
 | ||||
| +  tst-audit24bmod1 \
 | ||||
| +  tst-audit24bmod2 \
 | ||||
| +  tst-nodeps1-mod \
 | ||||
| +  tst-nodeps2-mod \
 | ||||
| +  # modules-names-nobuild
 | ||||
|   | ||||
|  tests += $(tests-static) | ||||
|   | ||||
| @@ -2697,3 +2706,19 @@ $(objpfx)tst-dlmopen-twice: $(libdl)
 | ||||
|  $(objpfx)tst-dlmopen-twice.out: \ | ||||
|    $(objpfx)tst-dlmopen-twice-mod1.so \ | ||||
|    $(objpfx)tst-dlmopen-twice-mod2.so | ||||
| +
 | ||||
| +# The object tst-nodeps1-mod.so has no explicit dependencies on libc.so.
 | ||||
| +$(objpfx)tst-nodeps1-mod.so: $(objpfx)tst-nodeps1-mod.os
 | ||||
| +	$(LINK.o) -nostartfiles -nostdlib -shared -o $@ $^
 | ||||
| +tst-nodeps1.so-no-z-defs = yes
 | ||||
| +# Link libc.so before the test module with the IFUNC resolver reference.
 | ||||
| +LDFLAGS-tst-nodeps1 = $(common-objpfx)libc.so $(objpfx)tst-nodeps1-mod.so
 | ||||
| +$(objpfx)tst-nodeps1: $(objpfx)tst-nodeps1-mod.so
 | ||||
| +# Reuse the tst-nodeps1 module.  Link libc.so before the test module
 | ||||
| +# with the IFUNC resolver reference.
 | ||||
| +$(objpfx)tst-nodeps2-mod.so: $(common-objpfx)libc.so \
 | ||||
| +  $(objpfx)tst-nodeps1-mod.so $(objpfx)tst-nodeps2-mod.os
 | ||||
| +	$(LINK.o) -Wl,--no-as-needed -nostartfiles -nostdlib -shared -o $@ $^
 | ||||
| +$(objpfx)tst-nodeps2: $(libdl)
 | ||||
| +$(objpfx)tst-nodeps2.out: \
 | ||||
| +  $(objpfx)tst-nodeps1-mod.so $(objpfx)tst-nodeps2-mod.so
 | ||||
| diff --git a/elf/dl-open.c b/elf/dl-open.c
 | ||||
| index 1505fdb73088dcdb..6508b0ea545440b8 100644
 | ||||
| --- a/elf/dl-open.c
 | ||||
| +++ b/elf/dl-open.c
 | ||||
| @@ -692,6 +692,17 @@ dl_open_worker_begin (void *a)
 | ||||
|       them.  However, such relocation dependencies in IFUNC resolvers | ||||
|       are undefined anyway, so this is not a problem.  */ | ||||
|   | ||||
| +  /* Ensure that libc is relocated first.  This helps with the
 | ||||
| +     execution of IFUNC resolvers in libc, and matters only to newly
 | ||||
| +     created dlmopen namespaces.  Do not do this for static dlopen
 | ||||
| +     because libc has relocations against ld.so, which may not have
 | ||||
| +     been relocated at this point.  */
 | ||||
| +#ifdef SHARED
 | ||||
| +  if (GL(dl_ns)[args->nsid].libc_map != NULL)
 | ||||
| +    _dl_open_relocate_one_object (args, r, GL(dl_ns)[args->nsid].libc_map,
 | ||||
| +				  reloc_mode, &relocation_in_progress);
 | ||||
| +#endif
 | ||||
| +
 | ||||
|    for (unsigned int i = last; i-- > first; ) | ||||
|      _dl_open_relocate_one_object (args, r, new->l_initfini[i], reloc_mode, | ||||
|  				  &relocation_in_progress); | ||||
| diff --git a/elf/rtld.c b/elf/rtld.c
 | ||||
| index cd2cc4024a3581c2..502d2a1c58505d88 100644
 | ||||
| --- a/elf/rtld.c
 | ||||
| +++ b/elf/rtld.c
 | ||||
| @@ -2414,11 +2414,17 @@ ERROR: '%s': cannot process note segment.\n", _dl_argv[0]);
 | ||||
|  	 objects.  We do not re-relocate the dynamic linker itself in this | ||||
|  	 loop because that could result in the GOT entries for functions we | ||||
|  	 call being changed, and that would break us.  It is safe to relocate | ||||
| -	 the dynamic linker out of order because it has no copy relocs (we
 | ||||
| -	 know that because it is self-contained).  */
 | ||||
| +	 the dynamic linker out of order because it has no copy relocations.
 | ||||
| +	 Likewise for libc, which is relocated early to ensure that IFUNC
 | ||||
| +	 resolvers in libc work.  */
 | ||||
|   | ||||
|        int consider_profiling = GLRO(dl_profile) != NULL; | ||||
|   | ||||
| +      if (GL(dl_ns)[LM_ID_BASE].libc_map != NULL)
 | ||||
| +	_dl_relocate_object (GL(dl_ns)[LM_ID_BASE].libc_map,
 | ||||
| +			     GL(dl_ns)[LM_ID_BASE].libc_map->l_scope,
 | ||||
| +			     GLRO(dl_lazy) ? RTLD_LAZY : 0, consider_profiling);
 | ||||
| +
 | ||||
|        /* If we are profiling we also must do lazy reloaction.  */ | ||||
|        GLRO(dl_lazy) |= consider_profiling; | ||||
|   | ||||
| diff --git a/elf/tst-nodeps1-mod.c b/elf/tst-nodeps1-mod.c
 | ||||
| new file mode 100644 | ||||
| index 0000000000000000..45c8e3c631251a89
 | ||||
| --- /dev/null
 | ||||
| +++ b/elf/tst-nodeps1-mod.c
 | ||||
| @@ -0,0 +1,25 @@
 | ||||
| +/* Test module with no libc.so dependency and string function references.
 | ||||
| +   Copyright (C) 2023 Free Software Foundation, Inc.
 | ||||
| +   This file is part of the GNU C Library.
 | ||||
| +
 | ||||
| +   The GNU C Library is free software; you can redistribute it and/or
 | ||||
| +   modify it under the terms of the GNU Lesser General Public
 | ||||
| +   License as published by the Free Software Foundation; either
 | ||||
| +   version 2.1 of the License, or (at your option) any later version.
 | ||||
| +
 | ||||
| +   The GNU C Library is distributed in the hope that it will be useful,
 | ||||
| +   but WITHOUT ANY WARRANTY; without even the implied warranty of
 | ||||
| +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | ||||
| +   Lesser General Public License for more details.
 | ||||
| +
 | ||||
| +   You should have received a copy of the GNU Lesser General Public
 | ||||
| +   License along with the GNU C Library; if not, see
 | ||||
| +   <https://www.gnu.org/licenses/>.  */
 | ||||
| +
 | ||||
| +#include <string.h>
 | ||||
| +
 | ||||
| +/* Some references to libc symbols which are likely to have IFUNC
 | ||||
| +   resolvers.  If they do not, this module does not exercise bug 31083.  */
 | ||||
| +void *memcpy_pointer = memcpy;
 | ||||
| +void *memmove_pointer = memmove;
 | ||||
| +void *memset_pointer = memset;
 | ||||
| diff --git a/elf/tst-nodeps1.c b/elf/tst-nodeps1.c
 | ||||
| new file mode 100644 | ||||
| index 0000000000000000..1a8bde36cdb71446
 | ||||
| --- /dev/null
 | ||||
| +++ b/elf/tst-nodeps1.c
 | ||||
| @@ -0,0 +1,23 @@
 | ||||
| +/* Test initially loaded module with implicit libc.so dependency (bug 31083).
 | ||||
| +   Copyright (C) 2023 Free Software Foundation, Inc.
 | ||||
| +   This file is part of the GNU C Library.
 | ||||
| +
 | ||||
| +   The GNU C Library is free software; you can redistribute it and/or
 | ||||
| +   modify it under the terms of the GNU Lesser General Public
 | ||||
| +   License as published by the Free Software Foundation; either
 | ||||
| +   version 2.1 of the License, or (at your option) any later version.
 | ||||
| +
 | ||||
| +   The GNU C Library is distributed in the hope that it will be useful,
 | ||||
| +   but WITHOUT ANY WARRANTY; without even the implied warranty of
 | ||||
| +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | ||||
| +   Lesser General Public License for more details.
 | ||||
| +
 | ||||
| +   You should have received a copy of the GNU Lesser General Public
 | ||||
| +   License along with the GNU C Library; if not, see
 | ||||
| +   <https://www.gnu.org/licenses/>.  */
 | ||||
| +
 | ||||
| +/* Testing happens before main.  */
 | ||||
| +int
 | ||||
| +main (void)
 | ||||
| +{
 | ||||
| +}
 | ||||
| diff --git a/elf/tst-nodeps2-mod.c b/elf/tst-nodeps2-mod.c
 | ||||
| new file mode 100644 | ||||
| index 0000000000000000..4913feee9b56e0e1
 | ||||
| --- /dev/null
 | ||||
| +++ b/elf/tst-nodeps2-mod.c
 | ||||
| @@ -0,0 +1 @@
 | ||||
| +/* Empty test module which depends on tst-nodeps1-mod.so.  */
 | ||||
| diff --git a/elf/tst-nodeps2.c b/elf/tst-nodeps2.c
 | ||||
| new file mode 100644 | ||||
| index 0000000000000000..0bdc8eeb8cba3a99
 | ||||
| --- /dev/null
 | ||||
| +++ b/elf/tst-nodeps2.c
 | ||||
| @@ -0,0 +1,29 @@
 | ||||
| +/* Test dlmopen with implicit libc.so dependency (bug 31083).
 | ||||
| +   Copyright (C) 2023 Free Software Foundation, Inc.
 | ||||
| +   This file is part of the GNU C Library.
 | ||||
| +
 | ||||
| +   The GNU C Library is free software; you can redistribute it and/or
 | ||||
| +   modify it under the terms of the GNU Lesser General Public
 | ||||
| +   License as published by the Free Software Foundation; either
 | ||||
| +   version 2.1 of the License, or (at your option) any later version.
 | ||||
| +
 | ||||
| +   The GNU C Library is distributed in the hope that it will be useful,
 | ||||
| +   but WITHOUT ANY WARRANTY; without even the implied warranty of
 | ||||
| +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | ||||
| +   Lesser General Public License for more details.
 | ||||
| +
 | ||||
| +   You should have received a copy of the GNU Lesser General Public
 | ||||
| +   License along with the GNU C Library; if not, see
 | ||||
| +   <https://www.gnu.org/licenses/>.  */
 | ||||
| +
 | ||||
| +#include <support/xdlfcn.h>
 | ||||
| +
 | ||||
| +static int
 | ||||
| +do_test (void)
 | ||||
| +{
 | ||||
| +  void *handle = xdlmopen (LM_ID_NEWLM, "tst-nodeps2-mod.so", RTLD_NOW);
 | ||||
| +  xdlclose (handle);
 | ||||
| +  return 0;
 | ||||
| +}
 | ||||
| +
 | ||||
| +#include <support/test-driver.c>
 | ||||
							
								
								
									
										41
									
								
								SOURCES/glibc-RHEL-21522-4.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								SOURCES/glibc-RHEL-21522-4.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,41 @@ | ||||
| commit b3bee76c5f59498b9c189608f0a3132e2013fa1a | ||||
| Author: Florian Weimer <fweimer@redhat.com> | ||||
| Date:   Fri Dec 8 09:51:34 2023 +0100 | ||||
| 
 | ||||
|     elf: Initialize GLRO(dl_lazy) before relocating libc in dynamic startup | ||||
| 
 | ||||
|     GLRO(dl_lazy) is used to set the parameters for the early | ||||
|     _dl_relocate_object call, so the consider_profiling setting has to | ||||
|     be applied before the call. | ||||
| 
 | ||||
|     Fixes commit 78ca44da0160a0b442f0ca1f253e3360f044b2ec ("elf: Relocate | ||||
|     libc.so early during startup and dlmopen (bug 31083)"). | ||||
| 
 | ||||
|     Reviewed-by: Carlos O'Donell <carlos@redhat.com> | ||||
| 
 | ||||
| Conflicts: | ||||
| 	elf/rtld.c | ||||
| 	  (removal of prelink support upstream) | ||||
| 
 | ||||
| diff --git a/elf/rtld.c b/elf/rtld.c
 | ||||
| index 502d2a1c58505d88..4f317a2a874e6af7 100644
 | ||||
| --- a/elf/rtld.c
 | ||||
| +++ b/elf/rtld.c
 | ||||
| @@ -2420,14 +2420,14 @@ ERROR: '%s': cannot process note segment.\n", _dl_argv[0]);
 | ||||
|   | ||||
|        int consider_profiling = GLRO(dl_profile) != NULL; | ||||
|   | ||||
| +      /* If we are profiling we also must do lazy reloaction.  */
 | ||||
| +      GLRO(dl_lazy) |= consider_profiling;
 | ||||
| +
 | ||||
|        if (GL(dl_ns)[LM_ID_BASE].libc_map != NULL) | ||||
|  	_dl_relocate_object (GL(dl_ns)[LM_ID_BASE].libc_map, | ||||
|  			     GL(dl_ns)[LM_ID_BASE].libc_map->l_scope, | ||||
|  			     GLRO(dl_lazy) ? RTLD_LAZY : 0, consider_profiling); | ||||
|   | ||||
| -      /* If we are profiling we also must do lazy reloaction.  */
 | ||||
| -      GLRO(dl_lazy) |= consider_profiling;
 | ||||
| -
 | ||||
|        RTLD_TIMING_VAR (start); | ||||
|        rtld_timer_start (&start); | ||||
|        unsigned i = main_map->l_searchlist.r_nlist; | ||||
							
								
								
									
										83
									
								
								SOURCES/glibc-RHEL-22441.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										83
									
								
								SOURCES/glibc-RHEL-22441.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,83 @@ | ||||
| commit c00b984fcd53f679ca2dafcd1aee2c89836e6e73 | ||||
| Author: Florian Weimer <fweimer@redhat.com> | ||||
| Date:   Tue Aug 29 08:28:31 2023 +0200 | ||||
| 
 | ||||
|     nscd: Skip unusable entries in first pass in prune_cache (bug 30800) | ||||
|      | ||||
|     Previously, if an entry was marked unusable for any reason, but had | ||||
|     not timed out yet, the assert would trigger. | ||||
|      | ||||
|     One way to get into such state is if a data change is detected during | ||||
|     re-validation of an entry.  This causes the entry to be marked as not | ||||
|     usable.  If exits nscd soon after that, then the clock jumps | ||||
|     backwards, and nscd restarted, the cache re-validation run after | ||||
|     startup triggers the removed assert. | ||||
|      | ||||
|     The change is more complicated than just the removal of the assert | ||||
|     because entries marked as not usable should be garbage-collected in | ||||
|     the second pass.  To make this happen, it is necessary to update some | ||||
|     book-keeping data. | ||||
|      | ||||
|     Reviewed-by: DJ Delorie <dj@redhat.com> | ||||
| 
 | ||||
| diff --git a/nscd/cache.c b/nscd/cache.c
 | ||||
| index efe4214d953edb30..2fd3f78ebb567bbe 100644
 | ||||
| --- a/nscd/cache.c
 | ||||
| +++ b/nscd/cache.c
 | ||||
| @@ -371,8 +371,11 @@ prune_cache (struct database_dyn *table, time_t now, int fd)
 | ||||
|  		       serv2str[runp->type], str, dh->timeout); | ||||
|  	    } | ||||
|   | ||||
| -	  /* Check whether the entry timed out.  */
 | ||||
| -	  if (dh->timeout < now)
 | ||||
| +	  /* Check whether the entry timed out.  Timed out entries
 | ||||
| +	     will be revalidated.  For unusable records, it is still
 | ||||
| +	     necessary to record that the bucket needs to be scanned
 | ||||
| +	     again below.  */
 | ||||
| +	  if (dh->timeout < now || !dh->usable)
 | ||||
|  	    { | ||||
|  	      /* This hash bucket could contain entries which need to | ||||
|  		 be looked at.  */ | ||||
| @@ -384,7 +387,7 @@ prune_cache (struct database_dyn *table, time_t now, int fd)
 | ||||
|  	      /* We only have to look at the data of the first entries | ||||
|  		 since the count information is kept in the data part | ||||
|  		 which is shared.  */ | ||||
| -	      if (runp->first)
 | ||||
| +	      if (runp->first && dh->usable)
 | ||||
|  		{ | ||||
|   | ||||
|  		  /* At this point there are two choices: we reload the | ||||
| @@ -400,9 +403,6 @@ prune_cache (struct database_dyn *table, time_t now, int fd)
 | ||||
|  		    { | ||||
|  		      /* Remove the value.  */ | ||||
|  		      dh->usable = false; | ||||
| -
 | ||||
| -		      /* We definitely have some garbage entries now.  */
 | ||||
| -		      any = true;
 | ||||
|  		    } | ||||
|  		  else | ||||
|  		    { | ||||
| @@ -414,18 +414,15 @@ prune_cache (struct database_dyn *table, time_t now, int fd)
 | ||||
|   | ||||
|  		      time_t timeout = readdfcts[runp->type] (table, runp, dh); | ||||
|  		      next_timeout = MIN (next_timeout, timeout); | ||||
| -
 | ||||
| -		      /* If the entry has been replaced, we might need
 | ||||
| -			 cleanup.  */
 | ||||
| -		      any |= !dh->usable;
 | ||||
|  		    } | ||||
|  		} | ||||
| +
 | ||||
| +	      /* If the entry has been replaced, we might need cleanup.  */
 | ||||
| +	      any |= !dh->usable;
 | ||||
|  	    } | ||||
|  	  else | ||||
| -	    {
 | ||||
| -	      assert (dh->usable);
 | ||||
| -	      next_timeout = MIN (next_timeout, dh->timeout);
 | ||||
| -	    }
 | ||||
| +	    /* Entry has not timed out and is usable.  */
 | ||||
| +	    next_timeout = MIN (next_timeout, dh->timeout);
 | ||||
|   | ||||
|  	  run = runp->next; | ||||
|  	} | ||||
							
								
								
									
										237
									
								
								SOURCES/glibc-RHEL-22846.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										237
									
								
								SOURCES/glibc-RHEL-22846.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,237 @@ | ||||
| commit d0f07f7df8d9758c838674b70144ac73bcbd1634 | ||||
| Author: Florian Weimer <fweimer@redhat.com> | ||||
| Date:   Tue May 30 13:25:50 2023 +0200 | ||||
| 
 | ||||
|     elf: Make more functions available for binding during dlclose (bug 30425) | ||||
|      | ||||
|     Previously, after destructors for a DSO have been invoked, ld.so refused | ||||
|     to bind against that DSO in all cases.  Relax this restriction somewhat | ||||
|     if the referencing object is itself a DSO that is being unloaded.  This | ||||
|     assumes that the symbol reference is not going to be stored anywhere. | ||||
|      | ||||
|     The situation in the test case can arise fairly easily with C++ and | ||||
|     objects that are built with different optimization levels and therefore | ||||
|     define different functions with vague linkage. | ||||
|      | ||||
|     Reviewed-by: Carlos O'Donell <carlos@redhat.com> | ||||
| 
 | ||||
| Conflicts: | ||||
| 	elf/Makefile | ||||
| 	  (usual test differences, link test with -ldl) | ||||
| 
 | ||||
| diff --git a/elf/Makefile b/elf/Makefile
 | ||||
| index 6f0f36cdfe3961e8..ebf46a297d241d8f 100644
 | ||||
| --- a/elf/Makefile
 | ||||
| +++ b/elf/Makefile
 | ||||
| @@ -362,6 +362,7 @@ tests += \
 | ||||
|    tst-big-note \ | ||||
|    tst-debug1 \ | ||||
|    tst-deep1 \ | ||||
| +  tst-dlclose-lazy \
 | ||||
|    tst-dlmodcount \ | ||||
|    tst-dlmopen1 \ | ||||
|    tst-dlmopen3 \ | ||||
| @@ -711,6 +712,8 @@ modules-names = \
 | ||||
|    tst-deep1mod2 \ | ||||
|    tst-deep1mod3 \ | ||||
|    tst-dlmopen1mod \ | ||||
| +  tst-dlclose-lazy-mod1 \
 | ||||
| +  tst-dlclose-lazy-mod2 \
 | ||||
|    tst-dlmopen-dlerror-mod \ | ||||
|    tst-dlmopen-gethostbyname-mod \ | ||||
|    tst-dlmopen-twice-mod1 \ | ||||
| @@ -2707,6 +2710,12 @@ $(objpfx)tst-dlmopen-twice.out: \
 | ||||
|    $(objpfx)tst-dlmopen-twice-mod1.so \ | ||||
|    $(objpfx)tst-dlmopen-twice-mod2.so | ||||
|   | ||||
| +LDFLAGS-tst-dlclose-lazy-mod1.so = -Wl,-z,lazy,--no-as-needed
 | ||||
| +$(objpfx)tst-dlclose-lazy-mod1.so: $(objpfx)tst-dlclose-lazy-mod2.so
 | ||||
| +$(objpfx)tst-dlclose-lazy: $(libdl)
 | ||||
| +$(objpfx)tst-dlclose-lazy.out: \
 | ||||
| +  $(objpfx)tst-dlclose-lazy-mod1.so $(objpfx)tst-dlclose-lazy-mod2.so
 | ||||
| +
 | ||||
|  # The object tst-nodeps1-mod.so has no explicit dependencies on libc.so. | ||||
|  $(objpfx)tst-nodeps1-mod.so: $(objpfx)tst-nodeps1-mod.os | ||||
|  	$(LINK.o) -nostartfiles -nostdlib -shared -o $@ $^ | ||||
| diff --git a/elf/dl-lookup.c b/elf/dl-lookup.c
 | ||||
| index 47acd134600b44b5..9e8f14b8483f5eba 100644
 | ||||
| --- a/elf/dl-lookup.c
 | ||||
| +++ b/elf/dl-lookup.c
 | ||||
| @@ -380,8 +380,25 @@ do_lookup_x (const char *undef_name, uint_fast32_t new_hash,
 | ||||
|        if ((type_class & ELF_RTYPE_CLASS_COPY) && map->l_type == lt_executable) | ||||
|  	continue; | ||||
|   | ||||
| -      /* Do not look into objects which are going to be removed.  */
 | ||||
| -      if (map->l_removed)
 | ||||
| +      /* Do not look into objects which are going to be removed,
 | ||||
| +	 except when the referencing object itself is being removed.
 | ||||
| +
 | ||||
| +	 The second part covers the situation when an object lazily
 | ||||
| +	 binds to another object while running its destructor, but the
 | ||||
| +	 destructor of the other object has already run, so that
 | ||||
| +	 dlclose has set l_removed.  It may not always be obvious how
 | ||||
| +	 to avoid such a scenario to programmers creating DSOs,
 | ||||
| +	 particularly if C++ vague linkage is involved and triggers
 | ||||
| +	 symbol interposition.
 | ||||
| +
 | ||||
| +	 Accepting these to-be-removed objects makes the lazy and
 | ||||
| +	 BIND_NOW cases more similar.  (With BIND_NOW, the symbol is
 | ||||
| +	 resolved early, before the destructor call, so the issue does
 | ||||
| +	 not arise.).  Behavior matches the constructor scenario: the
 | ||||
| +	 implementation allows binding to symbols of objects whose
 | ||||
| +	 constructors have not run.  In fact, not doing this would be
 | ||||
| +	 mostly incompatible with symbol interposition.  */
 | ||||
| +      if (map->l_removed && !(undef_map != NULL && undef_map->l_removed))
 | ||||
|  	continue; | ||||
|   | ||||
|        /* Print some debugging info if wanted.  */ | ||||
| diff --git a/elf/tst-dlclose-lazy-mod1.c b/elf/tst-dlclose-lazy-mod1.c
 | ||||
| new file mode 100644 | ||||
| index 0000000000000000..8439dc1925cc8b41
 | ||||
| --- /dev/null
 | ||||
| +++ b/elf/tst-dlclose-lazy-mod1.c
 | ||||
| @@ -0,0 +1,36 @@
 | ||||
| +/* Lazy binding during dlclose.  Directly loaded module.
 | ||||
| +   Copyright (C) 2023 Free Software Foundation, Inc.
 | ||||
| +   This file is part of the GNU C Library.
 | ||||
| +
 | ||||
| +   The GNU C Library is free software; you can redistribute it and/or
 | ||||
| +   modify it under the terms of the GNU Lesser General Public
 | ||||
| +   License as published by the Free Software Foundation; either
 | ||||
| +   version 2.1 of the License, or (at your option) any later version.
 | ||||
| +
 | ||||
| +   The GNU C Library is distributed in the hope that it will be useful,
 | ||||
| +   but WITHOUT ANY WARRANTY; without even the implied warranty of
 | ||||
| +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | ||||
| +   Lesser General Public License for more details.
 | ||||
| +
 | ||||
| +   You should have received a copy of the GNU Lesser General Public
 | ||||
| +   License along with the GNU C Library; if not, see
 | ||||
| +   <https://www.gnu.org/licenses/>.  */
 | ||||
| +
 | ||||
| +/* This function is called from exported_function below.  It is only
 | ||||
| +   defined in this module.  The weak attribute mimics how G++
 | ||||
| +   implements vague linkage for C++.  */
 | ||||
| +void __attribute__ ((weak))
 | ||||
| +lazily_bound_exported_function (void)
 | ||||
| +{
 | ||||
| +}
 | ||||
| +
 | ||||
| +/* Called from tst-dlclose-lazy-mod2.so.  */
 | ||||
| +void
 | ||||
| +exported_function (int call_it)
 | ||||
| +{
 | ||||
| +  if (call_it)
 | ||||
| +    /* Previous to the fix this would crash when called during dlclose
 | ||||
| +       since symbols from the DSO were no longer available for binding
 | ||||
| +       (bug 30425) after the DSO started being closed by dlclose.  */
 | ||||
| +    lazily_bound_exported_function ();
 | ||||
| +}
 | ||||
| diff --git a/elf/tst-dlclose-lazy-mod2.c b/elf/tst-dlclose-lazy-mod2.c
 | ||||
| new file mode 100644 | ||||
| index 0000000000000000..767f69ffdb23a685
 | ||||
| --- /dev/null
 | ||||
| +++ b/elf/tst-dlclose-lazy-mod2.c
 | ||||
| @@ -0,0 +1,49 @@
 | ||||
| +/* Lazy binding during dlclose.  Indirectly loaded module.
 | ||||
| +   Copyright (C) 2023 Free Software Foundation, Inc.
 | ||||
| +   This file is part of the GNU C Library.
 | ||||
| +
 | ||||
| +   The GNU C Library is free software; you can redistribute it and/or
 | ||||
| +   modify it under the terms of the GNU Lesser General Public
 | ||||
| +   License as published by the Free Software Foundation; either
 | ||||
| +   version 2.1 of the License, or (at your option) any later version.
 | ||||
| +
 | ||||
| +   The GNU C Library is distributed in the hope that it will be useful,
 | ||||
| +   but WITHOUT ANY WARRANTY; without even the implied warranty of
 | ||||
| +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | ||||
| +   Lesser General Public License for more details.
 | ||||
| +
 | ||||
| +   You should have received a copy of the GNU Lesser General Public
 | ||||
| +   License along with the GNU C Library; if not, see
 | ||||
| +   <https://www.gnu.org/licenses/>.  */
 | ||||
| +
 | ||||
| +#include <stdio.h>
 | ||||
| +#include <stdlib.h>
 | ||||
| +
 | ||||
| +void
 | ||||
| +exported_function (int ignored)
 | ||||
| +{
 | ||||
| +  /* This function is interposed from tst-dlclose-lazy-mod1.so and
 | ||||
| +     thus never called.  */
 | ||||
| +  abort ();
 | ||||
| +}
 | ||||
| +
 | ||||
| +static void __attribute__ ((constructor))
 | ||||
| +init (void)
 | ||||
| +{
 | ||||
| +  puts ("info: tst-dlclose-lazy-mod2.so constructor called");
 | ||||
| +
 | ||||
| +  /* Trigger lazy binding to the definition in
 | ||||
| +     tst-dlclose-lazy-mod1.so, but not for
 | ||||
| +     lazily_bound_exported_function in that module.  */
 | ||||
| +  exported_function (0);
 | ||||
| +}
 | ||||
| +
 | ||||
| +static void __attribute__ ((destructor))
 | ||||
| +fini (void)
 | ||||
| +{
 | ||||
| +  puts ("info: tst-dlclose-lazy-mod2.so destructor called");
 | ||||
| +
 | ||||
| +  /* Trigger the lazily_bound_exported_function call in
 | ||||
| +     exported_function in tst-dlclose-lazy-mod1.so.  */
 | ||||
| +  exported_function (1);
 | ||||
| +}
 | ||||
| diff --git a/elf/tst-dlclose-lazy.c b/elf/tst-dlclose-lazy.c
 | ||||
| new file mode 100644 | ||||
| index 0000000000000000..976a6bb6f64fa981
 | ||||
| --- /dev/null
 | ||||
| +++ b/elf/tst-dlclose-lazy.c
 | ||||
| @@ -0,0 +1,47 @@
 | ||||
| +/* Test lazy binding during dlclose (bug 30425).
 | ||||
| +   Copyright (C) 2023 Free Software Foundation, Inc.
 | ||||
| +   This file is part of the GNU C Library.
 | ||||
| +
 | ||||
| +   The GNU C Library is free software; you can redistribute it and/or
 | ||||
| +   modify it under the terms of the GNU Lesser General Public
 | ||||
| +   License as published by the Free Software Foundation; either
 | ||||
| +   version 2.1 of the License, or (at your option) any later version.
 | ||||
| +
 | ||||
| +   The GNU C Library is distributed in the hope that it will be useful,
 | ||||
| +   but WITHOUT ANY WARRANTY; without even the implied warranty of
 | ||||
| +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | ||||
| +   Lesser General Public License for more details.
 | ||||
| +
 | ||||
| +   You should have received a copy of the GNU Lesser General Public
 | ||||
| +   License along with the GNU C Library; if not, see
 | ||||
| +   <https://www.gnu.org/licenses/>.  */
 | ||||
| +
 | ||||
| +/* This test re-creates a situation that can arise naturally for C++
 | ||||
| +   applications due to the use of vague linkage and differences in the
 | ||||
| +   set of compiler-emitted functions.  A function in
 | ||||
| +   tst-dlclose-lazy-mod1.so (exported_function) interposes a function
 | ||||
| +   in tst-dlclose-lazy-mod2.so.  This function is called from the
 | ||||
| +   destructor in tst-dlclose-lazy-mod2.so, after the destructor for
 | ||||
| +   tst-dlclose-lazy-mod1.so has already completed.  Prior to the fix
 | ||||
| +   for bug 30425, this would lead to a lazy binding failure in
 | ||||
| +   tst-dlclose-lazy-mod1.so because dlclose had already marked the DSO
 | ||||
| +   as unavailable for binding (by setting l_removed).  */
 | ||||
| +
 | ||||
| +#include <dlfcn.h>
 | ||||
| +#include <support/xdlfcn.h>
 | ||||
| +#include <support/check.h>
 | ||||
| +
 | ||||
| +int
 | ||||
| +main (void)
 | ||||
| +{
 | ||||
| +  /* Load tst-dlclose-lazy-mod1.so, indirectly loading
 | ||||
| +     tst-dlclose-lazy-mod2.so.  */
 | ||||
| +  void *handle = xdlopen ("tst-dlclose-lazy-mod1.so", RTLD_GLOBAL | RTLD_LAZY);
 | ||||
| +
 | ||||
| +  /* Invoke the destructor of tst-dlclose-lazy-mod2.so, which calls
 | ||||
| +     into tst-dlclose-lazy-mod1.so after its destructor has been
 | ||||
| +     called.  */
 | ||||
| +  xdlclose (handle);
 | ||||
| +
 | ||||
| +  return 0;
 | ||||
| +}
 | ||||
							
								
								
									
										27
									
								
								SOURCES/glibc-RHEL-22847.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								SOURCES/glibc-RHEL-22847.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,27 @@ | ||||
| commit ecc7c3deb9f347649c2078fcc0f94d4cedf92d60 | ||||
| Author: Florian Weimer <fweimer@redhat.com> | ||||
| Date:   Tue Jan 2 14:36:17 2024 +0100 | ||||
| 
 | ||||
|     libio: Check remaining buffer size in _IO_wdo_write (bug 31183) | ||||
|      | ||||
|     The multibyte character needs to fit into the remaining buffer space, | ||||
|     not the already-written buffer space.  Without the fix, we were never | ||||
|     moving the write pointer from the start of the buffer, always using | ||||
|     the single-character fallback buffer. | ||||
|      | ||||
|     Fixes commit 04b76b5aa8b2d1d19066e42dd1 ("Don't error out writing | ||||
|     a multibyte character to an unbuffered stream (bug 17522)"). | ||||
| 
 | ||||
| diff --git a/libio/wfileops.c b/libio/wfileops.c
 | ||||
| index d3deb34ba058ca39..6a6421f8880f9356 100644
 | ||||
| --- a/libio/wfileops.c
 | ||||
| +++ b/libio/wfileops.c
 | ||||
| @@ -57,7 +57,7 @@ _IO_wdo_write (FILE *fp, const wchar_t *data, size_t to_do)
 | ||||
|  	  char mb_buf[MB_LEN_MAX]; | ||||
|  	  char *write_base, *write_ptr, *buf_end; | ||||
|   | ||||
| -	  if (fp->_IO_write_ptr - fp->_IO_write_base < sizeof (mb_buf))
 | ||||
| +	  if (fp->_IO_buf_end - fp->_IO_write_ptr < sizeof (mb_buf))
 | ||||
|  	    { | ||||
|  	      /* Make sure we have room for at least one multibyte | ||||
|  		 character.  */ | ||||
| @ -132,7 +132,7 @@ end \ | ||||
| Summary: The GNU libc libraries | ||||
| Name: glibc | ||||
| Version: %{glibcversion} | ||||
| Release: %{glibcrelease}.7 | ||||
| Release: %{glibcrelease}.12 | ||||
| 
 | ||||
| # In general, GPLv2+ is used by programs, LGPLv2+ is used for | ||||
| # libraries. | ||||
| @ -1053,6 +1053,14 @@ Patch865: glibc-RHEL-2435.patch | ||||
| Patch866: glibc-RHEL-2435-2.patch | ||||
| Patch867: glibc-RHEL-2423.patch | ||||
| Patch868: glibc-RHEL-3036.patch | ||||
| Patch869: glibc-RHEL-21522-1.patch | ||||
| Patch870: glibc-RHEL-21522-2.patch | ||||
| Patch871: glibc-RHEL-21522-3.patch | ||||
| Patch872: glibc-RHEL-21522-4.patch | ||||
| Patch873: glibc-RHEL-21519.patch | ||||
| Patch874: glibc-RHEL-22441.patch | ||||
| Patch875: glibc-RHEL-22846.patch | ||||
| Patch876: glibc-RHEL-22847.patch | ||||
| 
 | ||||
| ############################################################################## | ||||
| # Continued list of core "glibc" package information: | ||||
| @ -2883,6 +2891,21 @@ fi | ||||
| %files -f compat-libpthread-nonshared.filelist -n compat-libpthread-nonshared | ||||
| 
 | ||||
| %changelog | ||||
| * Mon Jan 29 2024 Florian Weimer <fweimer@redhat.com> - 2.28-236.12 | ||||
| - Re-enable output buffering for wide stdio streams (RHEL-22847) | ||||
| 
 | ||||
| * Mon Jan 29 2024 Florian Weimer <fweimer@redhat.com> - 2.28-236.11 | ||||
| - Avoid lazy binding failures during dlclose (RHEL-22846) | ||||
| 
 | ||||
| * Fri Jan 26 2024 Florian Weimer <fweimer@redhat.com> - 2.28-236.10 | ||||
| - nscd: Skip unusable entries in first pass in prune_cache (RHEL-22441) | ||||
| 
 | ||||
| * Fri Jan 26 2024 Florian Weimer <fweimer@redhat.com> - 2.28-236.9 | ||||
| - Fix force-first handling in dlclose (RHEL-21519) | ||||
| 
 | ||||
| * Fri Jan 26 2024 Florian Weimer <fweimer@redhat.com> - 2.28-236.8 | ||||
| - Improve compatibility between underlinking and IFUNC resolvers (RHEL-21522) | ||||
| 
 | ||||
| * Wed Sep 20 2023 Siddhesh Poyarekar <siddhesh@redhat.com> - 2.28-236.7 | ||||
| - CVE-2023-4911 glibc: buffer overflow in ld.so leading to privilege escalation (RHEL-3036) | ||||
| 
 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user