[PATCH] support: add check_mem_access

Adhemerval Zanella Netto adhemerval.zanella@linaro.org
Tue Sep 9 15:16:10 GMT 2025



On 09/09/25 11:23, Yury Khrustalev wrote:
> Add check_mem_access(addr) function to check if memory at addr can
> be written or read returning false if memory is not accessible.
> ---
> base-commit: 5c522d7a58

I think you seeing a build failure:


ld: build/support/libsupport_nonshared.a(support_mem_access.oS): in function `__sigsegv_handler':
support/support_mem_access.c:10:(.text+0x4c): undefined reference to `__longjmp_chk'

because libsupport is built with _ISOMAC and there is a wrong attribute_hidden
for __longjmp_chk. This makes libsupport_noshared.a binding the a hidden
symbol.  We have the libc_hidden_proto/libc_hidden_def to avoid such issues.

This should fix it:

diff --git a/include/setjmp.h b/include/setjmp.h
index d2353be71b..4997d0d7d2 100644
--- a/include/setjmp.h
+++ b/include/setjmp.h
@@ -12,7 +12,7 @@ extern void ____longjmp_chk (__jmp_buf __env, int __val)
      __attribute__ ((__noreturn__)) attribute_hidden;

 extern void __longjmp_chk (sigjmp_buf env, int val)
-         __attribute__ ((noreturn)) attribute_hidden;
+         __attribute__ ((noreturn));
 /* The redirection in the installed header does not work with
    libc_hidden_proto.  */
 #define longjmp __longjmp_chk

> ---
>  nptl/tst-guard1.c            |  7 ++++---
>  support/Makefile             |  1 +
>  support/check_mem_access.h   | 12 ++++++++++++
>  support/support_mem_access.c | 33 +++++++++++++++++++++++++++++++++
>  4 files changed, 50 insertions(+), 3 deletions(-)
>  create mode 100644 support/check_mem_access.h
>  create mode 100644 support/support_mem_access.c
> 
> diff --git a/nptl/tst-guard1.c b/nptl/tst-guard1.c
> index e3e06df0fc..3a3e9c5c75 100644
> --- a/nptl/tst-guard1.c
> +++ b/nptl/tst-guard1.c
> @@ -26,6 +26,7 @@
>  #include <support/xsignal.h>
>  #include <support/xthread.h>
>  #include <support/xunistd.h>
> +#include <support/check_mem_access.h>
>  #include <sys/mman.h>
>  #include <stdlib.h>
>  
> @@ -185,9 +186,9 @@ tf (void *closure)
>      }
>  
>    /* Ensure we can access the stack area.  */
> -  TEST_COMPARE (try_read_buf (s.stack), true);
> -  TEST_COMPARE (try_read_buf (&s.stack[s.stacksize / 2]), true);
> -  TEST_COMPARE (try_read_buf (&s.stack[s.stacksize - 1]), true);
> +  TEST_COMPARE (check_mem_access (s.stack, false), true);
> +  TEST_COMPARE (check_mem_access (&s.stack[s.stacksize / 2], false), true);
> +  TEST_COMPARE (check_mem_access (&s.stack[s.stacksize - 1], false), true);
>  
>    /* Check if accessing the guard area results in SIGSEGV.  */
>    if (s.guardsize > 0)
> diff --git a/support/Makefile b/support/Makefile
> index f67f38130a..f0a1e1ca44 100644
> --- a/support/Makefile
> +++ b/support/Makefile
> @@ -66,6 +66,7 @@ libsupport-routines = \
>    support_format_netent \
>    support_fuse \
>    support_isolate_in_subprocess \
> +  support_mem_access \
>    support_mutex_pi_monotonic \
>    support_need_proc \
>    support_open_and_compare_file_bytes \
> diff --git a/support/check_mem_access.h b/support/check_mem_access.h
> new file mode 100644
> index 0000000000..cd5ea07c9e
> --- /dev/null
> +++ b/support/check_mem_access.h
> @@ -0,0 +1,12 @@
> +#ifndef SUPPORT_CHECK_MEM_ACCESS_H
> +#define SUPPORT_CHECK_MEM_ACCESS_H
> +
> +#include <sys/cdefs.h>
> +
> +__BEGIN_DECLS
> +
> +bool check_mem_access (const void *addr, bool write);
> +
> +__END_DECLS
> +
> +#endif // SUPPORT_CHECK_MEM_ACCESS_H
> diff --git a/support/support_mem_access.c b/support/support_mem_access.c
> new file mode 100644
> index 0000000000..5a11a476a2
> --- /dev/null
> +++ b/support/support_mem_access.c
> @@ -0,0 +1,33 @@
> +
> +#include <setjmp.h>
> +#include <signal.h>
> +
> +static sigjmp_buf sigsegv_jmp_buf;
> +
> +static void
> +__sigsegv_handler (int signum)
> +{
> +  siglongjmp (sigsegv_jmp_buf, signum);
> +}
> +
> +bool check_mem_access (const void *addr, bool write)
> +{
> +  static bool handler_set_up;
> +  if (!handler_set_up)
> +    {
> +      signal (SIGSEGV, __sigsegv_handler);
> +      handler_set_up = true;
> +    }
> +  int r = sigsetjmp (sigsegv_jmp_buf, 0);
> +  if (r == 0)
> +    {
> +      if (write)
> +        *(volatile char *)addr = 'x';
> +      else
> +        *(volatile char *)addr;
> +      return false;
> +    }
> +  if (r == SIGSEGV)
> +    return true;
> +  return false;
> +}



More information about the Libc-alpha mailing list