Message ID | 20231028195559.390407-2-adhemerval.zanella@linaro.org |
---|---|
State | New |
Headers | show |
Series | Add a tunable to decorate anonymous memory maps | expand |
LGTM Reviewed-by: DJ Delorie <dj@redhat.com> Adhemerval Zanella <adhemerval.zanella@linaro.org> writes: > diff --git a/include/sys/prctl.h b/include/sys/prctl.h > > # ifndef _ISOMAC > > +# ifndef PR_SET_VMA > +# define PR_SET_VMA 0x53564d41 > +# define PR_SET_VMA_ANON_NAME 0 > +# endif > + These match the kernel includes on rawhide, so OK. > diff --git a/sysdeps/generic/setvmaname.h b/sysdeps/generic/setvmaname.h > new file mode 100644 > index 0000000000..2824587e9f > --- /dev/null > +++ b/sysdeps/generic/setvmaname.h > @@ -0,0 +1,27 @@ > +/* Utilities functions to name memory mappings. > + 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/>. */ > + > +#ifndef __SETVMANAME_H > +#define __SETVMANAME_H > + > +static inline > +void __set_vma_name (void *start, size_t len, const char *name) > +{ > +} > + > +#endif Ok. > diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile > index 063719bae6..250df6f455 100644 > --- a/sysdeps/unix/sysv/linux/Makefile > +++ b/sysdeps/unix/sysv/linux/Makefile > @@ -97,6 +97,7 @@ sysdep_routines += \ > readahead \ > setfsgid \ > setfsuid \ > + setvmaname \ > signalfd \ > splice \ > sysctl \ Ok. > diff --git a/sysdeps/unix/sysv/linux/setvmaname.c b/sysdeps/unix/sysv/linux/setvmaname.c > new file mode 100644 > index 0000000000..9960ab5917 > --- /dev/null > +++ b/sysdeps/unix/sysv/linux/setvmaname.c > @@ -0,0 +1,44 @@ > +/* Utilities functions to name memory mappings. > + 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 <ldsodefs.h> > +#include <setvmaname.h> > +#include <sys/prctl.h> > +#include <sysdep.h> Ok. > +/* If PR_SET_VMA_ANON_NAME is not supported by the kernel, prctl returns > + EINVAL. However, it also returns the same error for invalid argument. > + Since it is an internal-only API, it assumes well formatted input: > + aligned START, with (START, START+LEN) being a valid memory range, > + and NAME with a limit of 80 characters without invalid one ("\\`$[]"). */ > + > +void > +__set_vma_name (void *start, size_t len, const char *name) > +{ > + static int prctl_supported = 1; > + if (atomic_load_relaxed (&prctl_supported) == 0) > + return; > + > + int r = INTERNAL_SYSCALL_CALL (prctl, PR_SET_VMA, PR_SET_VMA_ANON_NAME, > + start, len, name); > + if (r == 0 || r != -EINVAL) > + return; I'll point out that this logic is redundant, but I like that it conveys more meaning this way :-) Ok. > + atomic_store_relaxed (&prctl_supported, 0); > + return; > +} Ok. > diff --git a/sysdeps/unix/sysv/linux/setvmaname.h b/sysdeps/unix/sysv/linux/setvmaname.h > new file mode 100644 > index 0000000000..eaa7a7a32e > --- /dev/null > +++ b/sysdeps/unix/sysv/linux/setvmaname.h > @@ -0,0 +1,36 @@ > +/* Utilities functions to name memory mappings. > + 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/>. */ > + > +#ifndef __SETVMANAME_H > +#define __SETVMANAME_H > + > +/* Set the NAME to the anonymous memory map START with size of LEN. > + It assumes well-formatted input. */ > +#if IS_IN(libc) || IS_IN(rtld) > +void __set_vma_name (void *start, size_t len, const char *name) > + attribute_hidden; > +#else > +#include <sys/prctl.h> > + > +static inline void __set_vma_name (void *start, size_t len, const char *name) > +{ > + prctl (PR_SET_VMA, PR_SET_VMA_ANON_NAME, start, len, name); > +} > +#endif > + > +#endif Ok.
diff --git a/include/sys/prctl.h b/include/sys/prctl.h index d33f3a290e..8e8e05b07c 100644 --- a/include/sys/prctl.h +++ b/include/sys/prctl.h @@ -3,6 +3,11 @@ # ifndef _ISOMAC +# ifndef PR_SET_VMA +# define PR_SET_VMA 0x53564d41 +# define PR_SET_VMA_ANON_NAME 0 +# endif + extern int __prctl (int __option, ...); libc_hidden_proto (__prctl) diff --git a/sysdeps/generic/setvmaname.h b/sysdeps/generic/setvmaname.h new file mode 100644 index 0000000000..2824587e9f --- /dev/null +++ b/sysdeps/generic/setvmaname.h @@ -0,0 +1,27 @@ +/* Utilities functions to name memory mappings. + 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/>. */ + +#ifndef __SETVMANAME_H +#define __SETVMANAME_H + +static inline +void __set_vma_name (void *start, size_t len, const char *name) +{ +} + +#endif diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile index 063719bae6..250df6f455 100644 --- a/sysdeps/unix/sysv/linux/Makefile +++ b/sysdeps/unix/sysv/linux/Makefile @@ -97,6 +97,7 @@ sysdep_routines += \ readahead \ setfsgid \ setfsuid \ + setvmaname \ signalfd \ splice \ sysctl \ diff --git a/sysdeps/unix/sysv/linux/setvmaname.c b/sysdeps/unix/sysv/linux/setvmaname.c new file mode 100644 index 0000000000..9960ab5917 --- /dev/null +++ b/sysdeps/unix/sysv/linux/setvmaname.c @@ -0,0 +1,44 @@ +/* Utilities functions to name memory mappings. + 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 <ldsodefs.h> +#include <setvmaname.h> +#include <sys/prctl.h> +#include <sysdep.h> + +/* If PR_SET_VMA_ANON_NAME is not supported by the kernel, prctl returns + EINVAL. However, it also returns the same error for invalid argument. + Since it is an internal-only API, it assumes well formatted input: + aligned START, with (START, START+LEN) being a valid memory range, + and NAME with a limit of 80 characters without invalid one ("\\`$[]"). */ + +void +__set_vma_name (void *start, size_t len, const char *name) +{ + static int prctl_supported = 1; + if (atomic_load_relaxed (&prctl_supported) == 0) + return; + + int r = INTERNAL_SYSCALL_CALL (prctl, PR_SET_VMA, PR_SET_VMA_ANON_NAME, + start, len, name); + if (r == 0 || r != -EINVAL) + return; + + atomic_store_relaxed (&prctl_supported, 0); + return; +} diff --git a/sysdeps/unix/sysv/linux/setvmaname.h b/sysdeps/unix/sysv/linux/setvmaname.h new file mode 100644 index 0000000000..eaa7a7a32e --- /dev/null +++ b/sysdeps/unix/sysv/linux/setvmaname.h @@ -0,0 +1,36 @@ +/* Utilities functions to name memory mappings. + 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/>. */ + +#ifndef __SETVMANAME_H +#define __SETVMANAME_H + +/* Set the NAME to the anonymous memory map START with size of LEN. + It assumes well-formatted input. */ +#if IS_IN(libc) || IS_IN(rtld) +void __set_vma_name (void *start, size_t len, const char *name) + attribute_hidden; +#else +#include <sys/prctl.h> + +static inline void __set_vma_name (void *start, size_t len, const char *name) +{ + prctl (PR_SET_VMA, PR_SET_VMA_ANON_NAME, start, len, name); +} +#endif + +#endif