x86/CET: Renumber ARCH_CET_LEGACY_BITMAP to 0x3006

Message ID 20181120142214.20783-1-hjl.tools@gmail.com
State New
Headers show
Series
  • x86/CET: Renumber ARCH_CET_LEGACY_BITMAP to 0x3006
Related show

Commit Message

H.J. Lu Nov. 20, 2018, 2:22 p.m.
The current CET kernel:

https://github.com/yyu168/linux_cet

changed legacy region bitmap allocation from kernel to user space and
renumbered the prctl number from 0x3005 to 0x3006.  This patch updates
glibc with:

/* Enable legacy region bitmap with unsigned long long *addr:
     address: addr[0].
     size: addr[1].
 */
 # define ARCH_CET_LEGACY_BITMAP	0x3006

	* sysdeps/unix/sysv/linux/x86/dl-cet.h
	(dl_cet_allocate_legacy_bitmap ): Removed.
	(dl_cet_enable_legacy_bitmap): New.
	* sysdeps/unix/sysv/linux/x86/include/asm/prctl.h
	(ARCH_CET_LEGACY_BITMAP): Renumbered to 0x3006.
	* sysdeps/x86/dl-cet.c (dl_cet_check): Mmap legacy bitmap.
	Call dl_cet_enable_legacy_bitmap instead of
	dl_cet_allocate_legacy_bitmap.
---
 sysdeps/unix/sysv/linux/x86/dl-cet.h          | 17 +++++-------
 .../unix/sysv/linux/x86/include/asm/prctl.h   |  4 +--
 sysdeps/x86/dl-cet.c                          | 27 ++++++++++++++++---
 3 files changed, 32 insertions(+), 16 deletions(-)

-- 
2.19.1

Comments

Florian Weimer Nov. 20, 2018, 4:07 p.m. | #1
* H. J. Lu:

> The current CET kernel:

>

> https://github.com/yyu168/linux_cet

>

> changed legacy region bitmap allocation from kernel to user space and

> renumbered the prctl number from 0x3005 to 0x3006.  This patch updates

> glibc with:

>

> /* Enable legacy region bitmap with unsigned long long *addr:

>      address: addr[0].

>      size: addr[1].

>  */

>  # define ARCH_CET_LEGACY_BITMAP	0x3006


The patch looks okay in general, but I suggest to wait until this is
actually merged into an upstream kernel, so that we don't have to change
the number again.

> +		  /* Allocate and enable legacy bitmap.  */

> +		  size_t legacy_bitmap_size

> +		    = ((uintptr_t) __libc_stack_end

> +		       / GLRO(dl_pagesize) / 8);

> +		  void *legacy_bitmap_addr

> +		    = __mmap (NULL, legacy_bitmap_size,

> +			      PROT_READ | PROT_WRITE,

> +			      MAP_ANON | MAP_PRIVATE | MAP_NORESERVE,

> +			      -1, 0);

> +		  if (legacy_bitmap_addr == MAP_FAILED)

> +		    {

> +		      if (program)

> +			_dl_fatal_printf ("%s: mmap legacy bitmap failed\n",

> +					  l->l_name);

> +		      else

> +			_dl_signal_error (EINVAL, l->l_name, "dlopen",

> +					  N_("mmap legacy bitmap failed"));


Maybe you can log the size of the mapping attempt?  That could be useful
to diagnose failures.

Thanks,
Florian
H.J. Lu Nov. 21, 2018, 10:37 p.m. | #2
On Tue, Nov 20, 2018 at 8:07 AM Florian Weimer <fweimer@redhat.com> wrote:
>

> * H. J. Lu:

>

> > The current CET kernel:

> >

> > https://github.com/yyu168/linux_cet

> >

> > changed legacy region bitmap allocation from kernel to user space and

> > renumbered the prctl number from 0x3005 to 0x3006.  This patch updates

> > glibc with:

> >

> > /* Enable legacy region bitmap with unsigned long long *addr:

> >      address: addr[0].

> >      size: addr[1].

> >  */

> >  # define ARCH_CET_LEGACY_BITMAP      0x3006

>

> The patch looks okay in general, but I suggest to wait until this is

> actually merged into an upstream kernel, so that we don't have to change

> the number again.


Sure.

> > +               /* Allocate and enable legacy bitmap.  */

> > +               size_t legacy_bitmap_size

> > +                 = ((uintptr_t) __libc_stack_end

> > +                    / GLRO(dl_pagesize) / 8);

> > +               void *legacy_bitmap_addr

> > +                 = __mmap (NULL, legacy_bitmap_size,

> > +                           PROT_READ | PROT_WRITE,

> > +                           MAP_ANON | MAP_PRIVATE | MAP_NORESERVE,

> > +                           -1, 0);

> > +               if (legacy_bitmap_addr == MAP_FAILED)

> > +                 {

> > +                   if (program)

> > +                     _dl_fatal_printf ("%s: mmap legacy bitmap failed\n",

> > +                                       l->l_name);

> > +                   else

> > +                     _dl_signal_error (EINVAL, l->l_name, "dlopen",

> > +                                       N_("mmap legacy bitmap failed"));

>

> Maybe you can log the size of the mapping attempt?  That could be useful

> to diagnose failures.


It isn't easy since  _dl_signal_error only takes strings.

-- 
H.J.
Florian Weimer Nov. 21, 2018, 11:02 p.m. | #3
* H. J. Lu:

>> Maybe you can log the size of the mapping attempt?  That could be useful

>> to diagnose failures.

>

> It isn't easy since  _dl_signal_error only takes strings.


Ah.  We have _dl_exception_create_format and _dl_signal_exception for
that; this functionality is split across two function.

Thanks,
Florian
H.J. Lu Nov. 22, 2018, 5:40 p.m. | #4
On Wed, Nov 21, 2018 at 3:02 PM Florian Weimer <fweimer@redhat.com> wrote:
>

> * H. J. Lu:

>

> >> Maybe you can log the size of the mapping attempt?  That could be useful

> >> to diagnose failures.

> >

> > It isn't easy since  _dl_signal_error only takes strings.

>

> Ah.  We have _dl_exception_create_format and _dl_signal_exception for

> that; this functionality is split across two function.

>


Here is the updated patch, which depends on

https://sourceware.org/ml/libc-alpha/2018-11/msg00596.html

to add support for %x, %lx and %Zx to _dl_exception_create_format.

-- 
H.J.
From d7f6e11594bd094ea719a6c452600748561a56c3 Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Wed, 31 Oct 2018 13:59:29 -0700
Subject: [PATCH] x86/CET: Renumber ARCH_CET_LEGACY_BITMAP to 0x3006

The current CET kernel:

https://github.com/yyu168/linux_cet

changed legacy region bitmap allocation from kernel to user space and
renumbered the prctl number from 0x3005 to 0x3006.  This patch updates
glibc with:

/* Enable legacy region bitmap with unsigned long long *addr:
     address: addr[0].
     size: addr[1].
 */
 # define ARCH_CET_LEGACY_BITMAP	0x3006

	* sysdeps/unix/sysv/linux/x86/dl-cet.h
	(dl_cet_allocate_legacy_bitmap ): Removed.
	(dl_cet_enable_legacy_bitmap): New.
	* sysdeps/unix/sysv/linux/x86/include/asm/prctl.h
	(ARCH_CET_LEGACY_BITMAP): Renumbered to 0x3006.
	* sysdeps/x86/dl-cet.c (dl_cet_check): Mmap legacy bitmap.
	Call dl_cet_enable_legacy_bitmap instead of
	dl_cet_allocate_legacy_bitmap.
---
 sysdeps/unix/sysv/linux/x86/dl-cet.h          | 17 ++++-------
 .../unix/sysv/linux/x86/include/asm/prctl.h   |  4 +--
 sysdeps/x86/dl-cet.c                          | 29 +++++++++++++++++--
 3 files changed, 34 insertions(+), 16 deletions(-)

diff --git a/sysdeps/unix/sysv/linux/x86/dl-cet.h b/sysdeps/unix/sysv/linux/x86/dl-cet.h
index 3fbcfebed5..4da8d165dc 100644
--- a/sysdeps/unix/sysv/linux/x86/dl-cet.h
+++ b/sysdeps/unix/sysv/linux/x86/dl-cet.h
@@ -19,24 +19,19 @@
 #include <asm/prctl.h>
 
 static inline int __attribute__ ((always_inline))
-dl_cet_allocate_legacy_bitmap (unsigned long *legacy_bitmap)
+dl_cet_enable_legacy_bitmap (unsigned long *legacy_bitmap)
 {
   /* Allocate legacy bitmap.  */
   INTERNAL_SYSCALL_DECL (err);
 #ifdef __LP64__
-  return (int) INTERNAL_SYSCALL (arch_prctl, err, 2,
-				 ARCH_CET_LEGACY_BITMAP, legacy_bitmap);
+  unsigned long *legacy_bitmap_u64 = legacy_bitmap;
 #else
   unsigned long long legacy_bitmap_u64[2];
-  int res = INTERNAL_SYSCALL (arch_prctl, err, 2,
-			      ARCH_CET_LEGACY_BITMAP, legacy_bitmap_u64);
-  if (res == 0)
-    {
-      legacy_bitmap[0] = legacy_bitmap_u64[0];
-      legacy_bitmap[1] = legacy_bitmap_u64[1];
-    }
-  return res;
+  legacy_bitmap_u64[0] = legacy_bitmap[0];
+  legacy_bitmap_u64[1] = legacy_bitmap[1];
 #endif
+  return (int) INTERNAL_SYSCALL (arch_prctl, err, 2,
+				 ARCH_CET_LEGACY_BITMAP, legacy_bitmap_u64);
 }
 
 static inline int __attribute__ ((always_inline))
diff --git a/sysdeps/unix/sysv/linux/x86/include/asm/prctl.h b/sysdeps/unix/sysv/linux/x86/include/asm/prctl.h
index f67f3299b9..94196aa768 100644
--- a/sysdeps/unix/sysv/linux/x86/include/asm/prctl.h
+++ b/sysdeps/unix/sysv/linux/x86/include/asm/prctl.h
@@ -24,9 +24,9 @@
      OUT: allocated shadow stack address: *addr.
  */
 # define ARCH_CET_ALLOC_SHSTK	0x3004
-/* Return legacy region bitmap info in unsigned long long *addr:
+/* Enable legacy region bitmap with unsigned long long *addr:
      address: addr[0].
      size: addr[1].
  */
-# define ARCH_CET_LEGACY_BITMAP	0x3005
+# define ARCH_CET_LEGACY_BITMAP	0x3006
 #endif /* ARCH_CET_STATUS */
diff --git a/sysdeps/x86/dl-cet.c b/sysdeps/x86/dl-cet.c
index 78f36bcf53..b43387f6b4 100644
--- a/sysdeps/x86/dl-cet.c
+++ b/sysdeps/x86/dl-cet.c
@@ -202,13 +202,36 @@ mprotect_failure:
 					  N_("mprotect legacy bitmap failed"));
 		    }
 		}
-	      else
+	      else if (!GL(dl_x86_legacy_bitmap)[0])
 		{
-		  /* Allocate legacy bitmap.  */
-		  int res = dl_cet_allocate_legacy_bitmap
+		  /* Allocate and enable legacy bitmap.  */
+		  size_t legacy_bitmap_size
+		    = ((uintptr_t) __libc_stack_end
+		       / GLRO(dl_pagesize) / 8);
+		  void *legacy_bitmap_addr
+		    = __mmap (NULL, legacy_bitmap_size,
+			      PROT_READ | PROT_WRITE,
+			      MAP_ANON | MAP_PRIVATE | MAP_NORESERVE,
+			      -1, 0);
+		  if (legacy_bitmap_addr == MAP_FAILED)
+		    {
+		      struct dl_exception exception;
+		      /* NB: We cannot translate the message.  */
+		      _dl_exception_create_format
+			(&exception, DSO_FILENAME (l->l_name),
+			 "mmap size 0x%Zx failed", legacy_bitmap_size);
+		      _dl_signal_cexception
+			(errno, &exception, N_("legacy bitmap error"));
+		      _dl_exception_free (&exception);
+		    }
+		  GL(dl_x86_legacy_bitmap)[0]
+		    = (uintptr_t) legacy_bitmap_addr;
+		  GL(dl_x86_legacy_bitmap)[1] = legacy_bitmap_size;
+		  int res = dl_cet_enable_legacy_bitmap
 		    (GL(dl_x86_legacy_bitmap));
 		  if (res != 0)
 		    {
+		      __munmap (legacy_bitmap_addr, legacy_bitmap_size);
 		      if (program)
 			_dl_fatal_printf ("%s: legacy bitmap isn't available\n",
 					  l->l_name);
Florian Weimer Nov. 23, 2018, 2:14 p.m. | #5
* H. J. Lu:

> +		      _dl_exception_create_format

> +			(&exception, DSO_FILENAME (l->l_name),

> +			 "mmap size 0x%Zx failed", legacy_bitmap_size);

> +		      _dl_signal_cexception


I think you should mark the string as translateable and say that it's
for the legacy bitmap.

Thanks,
Florian
H.J. Lu Nov. 23, 2018, 4:18 p.m. | #6
On Fri, Nov 23, 2018 at 6:14 AM Florian Weimer <fweimer@redhat.com> wrote:
>

> * H. J. Lu:

>

> > +                   _dl_exception_create_format

> > +                     (&exception, DSO_FILENAME (l->l_name),

> > +                      "mmap size 0x%Zx failed", legacy_bitmap_size);

> > +                   _dl_signal_cexception

>

> I think you should mark the string as translateable and say that it's

> for the legacy bitmap.

>


Like this?

-- 
H.J.
From d7223b8e323efe7d468c1007da76932601caa217 Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Wed, 31 Oct 2018 13:59:29 -0700
Subject: [PATCH] x86/CET: Renumber ARCH_CET_LEGACY_BITMAP to 0x3006

The current CET kernel:

https://github.com/yyu168/linux_cet

changed legacy region bitmap allocation from kernel to user space and
renumbered the prctl number from 0x3005 to 0x3006.  This patch updates
glibc with:

/* Enable legacy region bitmap with unsigned long long *addr:
     address: addr[0].
     size: addr[1].
 */
 # define ARCH_CET_LEGACY_BITMAP	0x3006

	* sysdeps/unix/sysv/linux/x86/dl-cet.h
	(dl_cet_allocate_legacy_bitmap ): Removed.
	(dl_cet_enable_legacy_bitmap): New.
	* sysdeps/unix/sysv/linux/x86/include/asm/prctl.h
	(ARCH_CET_LEGACY_BITMAP): Renumbered to 0x3006.
	* sysdeps/x86/dl-cet.c (dl_cet_check): Mmap legacy bitmap.
	Call dl_cet_enable_legacy_bitmap instead of
	dl_cet_allocate_legacy_bitmap.
---
 sysdeps/unix/sysv/linux/x86/dl-cet.h          | 17 ++++-------
 .../unix/sysv/linux/x86/include/asm/prctl.h   |  4 +--
 sysdeps/x86/dl-cet.c                          | 29 +++++++++++++++++--
 3 files changed, 34 insertions(+), 16 deletions(-)

diff --git a/sysdeps/unix/sysv/linux/x86/dl-cet.h b/sysdeps/unix/sysv/linux/x86/dl-cet.h
index 3fbcfebed5..4da8d165dc 100644
--- a/sysdeps/unix/sysv/linux/x86/dl-cet.h
+++ b/sysdeps/unix/sysv/linux/x86/dl-cet.h
@@ -19,24 +19,19 @@
 #include <asm/prctl.h>
 
 static inline int __attribute__ ((always_inline))
-dl_cet_allocate_legacy_bitmap (unsigned long *legacy_bitmap)
+dl_cet_enable_legacy_bitmap (unsigned long *legacy_bitmap)
 {
   /* Allocate legacy bitmap.  */
   INTERNAL_SYSCALL_DECL (err);
 #ifdef __LP64__
-  return (int) INTERNAL_SYSCALL (arch_prctl, err, 2,
-				 ARCH_CET_LEGACY_BITMAP, legacy_bitmap);
+  unsigned long *legacy_bitmap_u64 = legacy_bitmap;
 #else
   unsigned long long legacy_bitmap_u64[2];
-  int res = INTERNAL_SYSCALL (arch_prctl, err, 2,
-			      ARCH_CET_LEGACY_BITMAP, legacy_bitmap_u64);
-  if (res == 0)
-    {
-      legacy_bitmap[0] = legacy_bitmap_u64[0];
-      legacy_bitmap[1] = legacy_bitmap_u64[1];
-    }
-  return res;
+  legacy_bitmap_u64[0] = legacy_bitmap[0];
+  legacy_bitmap_u64[1] = legacy_bitmap[1];
 #endif
+  return (int) INTERNAL_SYSCALL (arch_prctl, err, 2,
+				 ARCH_CET_LEGACY_BITMAP, legacy_bitmap_u64);
 }
 
 static inline int __attribute__ ((always_inline))
diff --git a/sysdeps/unix/sysv/linux/x86/include/asm/prctl.h b/sysdeps/unix/sysv/linux/x86/include/asm/prctl.h
index f67f3299b9..94196aa768 100644
--- a/sysdeps/unix/sysv/linux/x86/include/asm/prctl.h
+++ b/sysdeps/unix/sysv/linux/x86/include/asm/prctl.h
@@ -24,9 +24,9 @@
      OUT: allocated shadow stack address: *addr.
  */
 # define ARCH_CET_ALLOC_SHSTK	0x3004
-/* Return legacy region bitmap info in unsigned long long *addr:
+/* Enable legacy region bitmap with unsigned long long *addr:
      address: addr[0].
      size: addr[1].
  */
-# define ARCH_CET_LEGACY_BITMAP	0x3005
+# define ARCH_CET_LEGACY_BITMAP	0x3006
 #endif /* ARCH_CET_STATUS */
diff --git a/sysdeps/x86/dl-cet.c b/sysdeps/x86/dl-cet.c
index 78f36bcf53..408e7e89d4 100644
--- a/sysdeps/x86/dl-cet.c
+++ b/sysdeps/x86/dl-cet.c
@@ -202,13 +202,36 @@ mprotect_failure:
 					  N_("mprotect legacy bitmap failed"));
 		    }
 		}
-	      else
+	      else if (!GL(dl_x86_legacy_bitmap)[0])
 		{
-		  /* Allocate legacy bitmap.  */
-		  int res = dl_cet_allocate_legacy_bitmap
+		  /* Allocate and enable legacy bitmap.  */
+		  size_t legacy_bitmap_size
+		    = ((uintptr_t) __libc_stack_end
+		       / GLRO(dl_pagesize) / 8);
+		  void *legacy_bitmap_addr
+		    = __mmap (NULL, legacy_bitmap_size,
+			      PROT_READ | PROT_WRITE,
+			      MAP_ANON | MAP_PRIVATE | MAP_NORESERVE,
+			      -1, 0);
+		  if (legacy_bitmap_addr == MAP_FAILED)
+		    {
+		      struct dl_exception exception;
+		      _dl_exception_create_format
+			(&exception, DSO_FILENAME (l->l_name),
+			 N_("mmap size 0x%zx for legacy bitmap failed"),
+			 legacy_bitmap_size);
+		      _dl_signal_cexception
+			(errno, &exception, N_("legacy bitmap error"));
+		      _dl_exception_free (&exception);
+		    }
+		  GL(dl_x86_legacy_bitmap)[0]
+		    = (uintptr_t) legacy_bitmap_addr;
+		  GL(dl_x86_legacy_bitmap)[1] = legacy_bitmap_size;
+		  int res = dl_cet_enable_legacy_bitmap
 		    (GL(dl_x86_legacy_bitmap));
 		  if (res != 0)
 		    {
+		      __munmap (legacy_bitmap_addr, legacy_bitmap_size);
 		      if (program)
 			_dl_fatal_printf ("%s: legacy bitmap isn't available\n",
 					  l->l_name);
Florian Weimer Dec. 11, 2018, 11:33 a.m. | #7
* H. J. Lu:

> On Fri, Nov 23, 2018 at 6:14 AM Florian Weimer <fweimer@redhat.com> wrote:

>>

>> * H. J. Lu:

>>

>> > +                   _dl_exception_create_format

>> > +                     (&exception, DSO_FILENAME (l->l_name),

>> > +                      "mmap size 0x%Zx failed", legacy_bitmap_size);

>> > +                   _dl_signal_cexception

>>

>> I think you should mark the string as translateable and say that it's

>> for the legacy bitmap.

>

> Like this?


Yes, but please wait with committing until the kernel part has been
merged into mainline at least.

Thanks,
Florian

Patch

diff --git a/sysdeps/unix/sysv/linux/x86/dl-cet.h b/sysdeps/unix/sysv/linux/x86/dl-cet.h
index 3fbcfebed5..4da8d165dc 100644
--- a/sysdeps/unix/sysv/linux/x86/dl-cet.h
+++ b/sysdeps/unix/sysv/linux/x86/dl-cet.h
@@ -19,24 +19,19 @@ 
 #include <asm/prctl.h>
 
 static inline int __attribute__ ((always_inline))
-dl_cet_allocate_legacy_bitmap (unsigned long *legacy_bitmap)
+dl_cet_enable_legacy_bitmap (unsigned long *legacy_bitmap)
 {
   /* Allocate legacy bitmap.  */
   INTERNAL_SYSCALL_DECL (err);
 #ifdef __LP64__
-  return (int) INTERNAL_SYSCALL (arch_prctl, err, 2,
-				 ARCH_CET_LEGACY_BITMAP, legacy_bitmap);
+  unsigned long *legacy_bitmap_u64 = legacy_bitmap;
 #else
   unsigned long long legacy_bitmap_u64[2];
-  int res = INTERNAL_SYSCALL (arch_prctl, err, 2,
-			      ARCH_CET_LEGACY_BITMAP, legacy_bitmap_u64);
-  if (res == 0)
-    {
-      legacy_bitmap[0] = legacy_bitmap_u64[0];
-      legacy_bitmap[1] = legacy_bitmap_u64[1];
-    }
-  return res;
+  legacy_bitmap_u64[0] = legacy_bitmap[0];
+  legacy_bitmap_u64[1] = legacy_bitmap[1];
 #endif
+  return (int) INTERNAL_SYSCALL (arch_prctl, err, 2,
+				 ARCH_CET_LEGACY_BITMAP, legacy_bitmap_u64);
 }
 
 static inline int __attribute__ ((always_inline))
diff --git a/sysdeps/unix/sysv/linux/x86/include/asm/prctl.h b/sysdeps/unix/sysv/linux/x86/include/asm/prctl.h
index f67f3299b9..94196aa768 100644
--- a/sysdeps/unix/sysv/linux/x86/include/asm/prctl.h
+++ b/sysdeps/unix/sysv/linux/x86/include/asm/prctl.h
@@ -24,9 +24,9 @@ 
      OUT: allocated shadow stack address: *addr.
  */
 # define ARCH_CET_ALLOC_SHSTK	0x3004
-/* Return legacy region bitmap info in unsigned long long *addr:
+/* Enable legacy region bitmap with unsigned long long *addr:
      address: addr[0].
      size: addr[1].
  */
-# define ARCH_CET_LEGACY_BITMAP	0x3005
+# define ARCH_CET_LEGACY_BITMAP	0x3006
 #endif /* ARCH_CET_STATUS */
diff --git a/sysdeps/x86/dl-cet.c b/sysdeps/x86/dl-cet.c
index 78f36bcf53..983caa0018 100644
--- a/sysdeps/x86/dl-cet.c
+++ b/sysdeps/x86/dl-cet.c
@@ -202,13 +202,34 @@  mprotect_failure:
 					  N_("mprotect legacy bitmap failed"));
 		    }
 		}
-	      else
+	      else if (!GL(dl_x86_legacy_bitmap)[0])
 		{
-		  /* Allocate legacy bitmap.  */
-		  int res = dl_cet_allocate_legacy_bitmap
+		  /* Allocate and enable legacy bitmap.  */
+		  size_t legacy_bitmap_size
+		    = ((uintptr_t) __libc_stack_end
+		       / GLRO(dl_pagesize) / 8);
+		  void *legacy_bitmap_addr
+		    = __mmap (NULL, legacy_bitmap_size,
+			      PROT_READ | PROT_WRITE,
+			      MAP_ANON | MAP_PRIVATE | MAP_NORESERVE,
+			      -1, 0);
+		  if (legacy_bitmap_addr == MAP_FAILED)
+		    {
+		      if (program)
+			_dl_fatal_printf ("%s: mmap legacy bitmap failed\n",
+					  l->l_name);
+		      else
+			_dl_signal_error (EINVAL, l->l_name, "dlopen",
+					  N_("mmap legacy bitmap failed"));
+		    }
+		  GL(dl_x86_legacy_bitmap)[0]
+		    = (uintptr_t) legacy_bitmap_addr;
+		  GL(dl_x86_legacy_bitmap)[1] = legacy_bitmap_size;
+		  int res = dl_cet_enable_legacy_bitmap
 		    (GL(dl_x86_legacy_bitmap));
 		  if (res != 0)
 		    {
+		      __munmap (legacy_bitmap_addr, legacy_bitmap_size);
 		      if (program)
 			_dl_fatal_printf ("%s: legacy bitmap isn't available\n",
 					  l->l_name);