John Sperbeck
ecb101aed8
powerpc/mm: Fix SEGV on mapped region to return SEGV_ACCERR
The recent refactoring of the powerpc page fault handler in commit
c3350602e876 ("powerpc/mm: Make bad_area* helper functions") caused
access to protected memory regions to indicate SEGV_MAPERR instead of
the traditional SEGV_ACCERR in the si_code field of a user-space
signal handler. This can confuse debug libraries that temporarily
change the protection of memory regions, and expect to use SEGV_ACCERR
as an indication to restore access to a region.
This commit restores the previous behavior. The following program
exhibits the issue:
$ ./repro read || echo "FAILED"
$ ./repro write || echo "FAILED"
$ ./repro exec || echo "FAILED"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <sys/mman.h>
#include <assert.h>
static void segv_handler(int n, siginfo_t *info, void *arg) {
_exit(info->si_code == SEGV_ACCERR ? 0 : 1);
}
int main(int argc, char **argv)
{
void *p = NULL;
struct sigaction act = {
.sa_sigaction = segv_handler,
.sa_flags = SA_SIGINFO,
};
assert(argc == 2);
p = mmap(NULL, getpagesize(),
(strcmp(argv[1], "write") == 0) ? PROT_READ : 0,
MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
assert(p != MAP_FAILED);
assert(sigaction(SIGSEGV, &act, NULL) == 0);
if (strcmp(argv[1], "read") == 0)
printf("%c", *(unsigned char *)p);
else if (strcmp(argv[1], "write") == 0)
*(unsigned char *)p = 0;
else if (strcmp(argv[1], "exec") == 0)
((void (*)(void))p)();
return 1; /* failed to generate SEGV */
}
Fixes: c3350602e876 ("powerpc/mm: Make bad_area* helper functions")
Cc: stable@vger.kernel.org # v4.14+
Signed-off-by: John Sperbeck <jsperbeck@google.com>
Acked-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
[mpe: Add commit references in change log]
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
2018-01-02 21:12:33 +11:00
..
2017-08-15 22:55:54 +10:00
2016-12-24 11:46:01 -08:00
2013-07-01 11:10:36 +10:00
2017-02-15 20:02:39 +11:00
2017-06-05 19:59:03 +10:00
2017-11-06 16:48:14 +11:00
2017-11-06 16:48:14 +11:00
2018-01-02 21:12:33 +11:00
2016-12-24 11:46:01 -08:00
2016-11-29 23:59:40 +11:00
2016-11-29 23:59:40 +11:00
2017-09-01 16:42:45 +10:00
2017-11-23 23:10:14 +11:00
2017-11-06 16:48:13 +11:00
2017-11-02 11:10:55 +01:00
2016-07-21 18:59:09 +10:00
2017-11-02 11:10:55 +01:00
2017-11-02 11:10:55 +01:00
2017-11-16 12:47:46 -08:00
2017-11-15 18:21:04 -08:00
2017-08-16 14:56:12 +10:00
2017-11-06 16:48:15 +11:00
2017-02-14 17:18:29 +11:00
2017-11-16 12:47:46 -08:00
2017-08-10 23:32:12 +10:00
2017-11-13 23:35:43 +11:00
2017-11-16 12:47:46 -08:00
2014-07-28 14:10:26 +10:00
2017-04-28 20:19:37 +10:00
2017-03-31 23:09:47 +11:00
2017-09-28 17:09:16 +10:00
2017-08-10 23:32:12 +10:00
2017-11-16 12:47:46 -08:00
2017-10-04 22:15:30 +11:00
2017-11-16 12:47:46 -08:00
2016-05-01 18:32:48 +10:00
2017-08-17 23:31:52 +10:00
2017-08-23 22:27:45 +10:00
2017-11-12 23:25:48 +11:00
2017-02-17 22:16:25 +11:00
2016-03-11 17:18:02 -06:00
2017-11-13 23:35:43 +11:00
2017-06-21 16:18:33 +10:00
2017-11-20 19:28:25 +11:00
2017-07-27 13:05:50 +10:00
2016-08-01 11:15:13 +10:00
2017-08-23 22:27:45 +10:00
2016-03-01 19:27:20 +11:00
2017-08-10 23:32:12 +10:00
2017-04-11 07:46:04 +10:00
2017-11-10 21:33:35 +11:00
2017-11-02 11:10:55 +01:00
2017-11-02 11:10:55 +01:00