From 0adfb2bff3c39bc98f3f52a7f295f3aef246eb0d Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Thu, 29 Aug 2024 22:48:52 +0200 Subject: [PATCH] vma-prot: New module. * lib/vma-prot.h: New file. * lib/vma-prot.c: New file. * modules/vma-prot: New file. --- ChangeLog | 7 ++++ lib/vma-prot.c | 86 ++++++++++++++++++++++++++++++++++++++++++++++++ lib/vma-prot.h | 50 ++++++++++++++++++++++++++++ modules/vma-prot | 24 ++++++++++++++ 4 files changed, 167 insertions(+) create mode 100644 lib/vma-prot.c create mode 100644 lib/vma-prot.h create mode 100644 modules/vma-prot diff --git a/ChangeLog b/ChangeLog index 922aba9e8b..709509e07a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2024-08-29 Bruno Haible + + vma-prot: New module. + * lib/vma-prot.h: New file. + * lib/vma-prot.c: New file. + * modules/vma-prot: New file. + 2024-08-29 Bruno Haible vma-iter: Relicense under GPLv2+. diff --git a/lib/vma-prot.c b/lib/vma-prot.c new file mode 100644 index 0000000000..ebf9699a61 --- /dev/null +++ b/lib/vma-prot.c @@ -0,0 +1,86 @@ +/* Determine the protection of a virtual memory area. + Copyright (C) 2024 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 2 of the License, + or (at your option) any later version. + + This file 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* Written by Bruno Haible , 2024. */ + +#include + +/* Specification. */ +#include "vma-prot.h" + +#include + +struct locals +{ + /* The common protections seen so far. */ + unsigned int prot_so_far; + /* The remaining address interval. + remaining_start <= remaining_end-1. */ + uintptr_t remaining_start; + uintptr_t remaining_end; +}; + +static int +callback (void *data, uintptr_t start, uintptr_t end, unsigned int flags) +{ + struct locals *l = (struct locals *) data; + + if (start > l->remaining_start) + { + /* The interval [remaining_start, min (remaining_end, start)) is + unmapped. */ + l->prot_so_far = 0; + return 1; + } + if (end - 1 < l->remaining_start) + /* The interval [start,end) lies before [remaining_start,remaining_end). */ + return 0; + /* Here start <= remaining_start <= remaining_end-1 + and remaining_start <= end-1, + hence start <= remaining_start <= min (end-1, remaining_end-1). + So, the two intervals intersect. */ + l->prot_so_far &= flags; + if (l->prot_so_far == 0) + return 1; + if (l->remaining_end - 1 <= end - 1) + /* Done. */ + return 1; + /* Trim the remaining address interval. */ + l->remaining_start = end; + return 0; +} + +int +get_vma_prot (void *start, size_t size) +{ + uintptr_t start_address = (uintptr_t) start; + + struct locals l; + l.prot_so_far = VMA_PROT_READ | VMA_PROT_WRITE | VMA_PROT_EXECUTE; + l.remaining_start = start_address; + l.remaining_end = start_address + size; + + if (l.remaining_end < l.remaining_start) + /* Invalid arguments. */ + return -1; + + if (l.remaining_end > l.remaining_start) + { + if (vma_iterate (callback, &l) < 0) + return -1; + } + return l.prot_so_far; +} diff --git a/lib/vma-prot.h b/lib/vma-prot.h new file mode 100644 index 0000000000..aa99048ffe --- /dev/null +++ b/lib/vma-prot.h @@ -0,0 +1,50 @@ +/* Determine the protection of a virtual memory area. + Copyright (C) 2024 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 2 of the License, + or (at your option) any later version. + + This file 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* Written by Bruno Haible , 2024. */ + +#ifndef _VMA_PROT_H +#define _VMA_PROT_H + +/* Get size_t. */ +#include + +/* Get VMA_PROT_READ, VMA_PROT_WRITE, VMA_PROT_EXECUTE. */ +#include "vma-iter.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Returns the declared permissions available on the memory area that + starts at START and is SIZE bytes long, as a combination of the bit masks + VMA_PROT_READ, VMA_PROT_WRITE, VMA_PROT_EXECUTE. + Note: The effective permissions may be larger. For example, some hardware + allows execute permission anywhere where read permission is present. + Returns -1 if it cannot be determined. + + Note: This function is expensive. If possible, an application should find + faster alternatives for memory areas that it has allocated itself, such as + through malloc(), mmap(), or shmat(). */ +extern int get_vma_prot (void *start, size_t size); + + +#ifdef __cplusplus +} +#endif + +#endif /* _VMA_PROT_H */ diff --git a/modules/vma-prot b/modules/vma-prot new file mode 100644 index 0000000000..5ff9277535 --- /dev/null +++ b/modules/vma-prot @@ -0,0 +1,24 @@ +Description: +Determine the protection of a virtual memory area. + +Files: +lib/vma-prot.h +lib/vma-prot.c + +Depends-on: +stdint +vma-iter + +configure.ac: + +Makefile.am: +lib_SOURCES += vma-prot.c + +Include: +"vma-prot.h" + +License: +GPLv2+ + +Maintainer: +all -- 2.39.5