[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [RFC PATCH] test-c-stack2.sh: skip if the platform sent SIGILL on an
From: |
Ivan Zakharyaschev |
Subject: |
Re: [RFC PATCH] test-c-stack2.sh: skip if the platform sent SIGILL on an invalid address. |
Date: |
Fri, 28 Dec 2018 17:23:09 +0300 (MSK) |
User-agent: |
Alpine 2.20 (LFD 67 2015-01-07) |
Hi Bruno,
On Thu, 20 Dec 2018, Bruno Haible wrote:
> > + # E2K (elbrus) systems send SIGILL on an access to an invalid
> > address.
>
> This is a bug in the system. Access of an invalid address ought to produce a
> SIGSEGV or SIGBUS.
>
> 'elbrus' is not an important OS so far, for which it would be worth adding
> workarounds in the gnulib source.
> Is it still in development? -> If so, please fix that bug.
> Or is it a museum system? -> If so, just bear with the test failure.
Of these descriptions, "system in development" is the one which suits
Linux/E2k better. The port to E2K (MCST Elbrus general purpose hardware
architecture) is quite mature, but not yet released publicly.
As for the SIGILL peculiarity, it has a reason in the Elbrus architecture.
AFAIU, a different protection mechanism comes into play here. It is based
on tagging values/memory: if an attempt is made to use a value in a way
which contradicts its tag, then the "illegal operand" condition arises.
Namely, a "load" instruction can expect a certain tag, and then there can
be a mismatch between the assumptions of the code and the actual value
and its tag.
And it's not a segmentation fault.
(This must be just a simple case of the use of tagging in this
architecture, whereas--AFAIK--MCST has been developing some smarter
protection modes to make use of tags to track the array bounds along with
pointers and for other things. The smarter modes are probably not enabled
by default in the compiler. Now, I could google up a 2018 report on such
recent work by searching for "elbrus" "e2k" "SIGILL", in Russian.)
But wait, while writing this explanation, I seem to have come to see a way
how the code in test-c-stack.c:
++*argv[argc]; /* Intentionally dereference NULL. */
could be rewritten to cause the intended SIGSEGV and not SIGILL like now:
$ ./test-c-stack 1; echo $?
Illegal instruction
132
$
The tags that are seen and checked by a "load" instruction must have been
stored before. So, if we now think about storing values to memory, we see
that when storing a value, one is not checking the tag, but rather writing
it initially. So (at least in the simple protection mode), there can be no
SIGILL when writing.
And I've tested running test-c-stack with this code instead:
*argv[argc] = 175; /* Intentionally dereference NULL. */
and it indeed causes a SIGSEGV:
$ ./test-c-stack 1; echo $?
test-c-stack: stack overflow
77
$
and with libsigsegv:
$ ./test-c-stack 1; echo $?
test-c-stack: program error
Aborted
134
$ ./test-c-stack2.sh; echo $?
0
$
So, now I suggest a patch that replaces the reading-and-then-writing a
value at this place with just writing a value. (A complete patch is
attached.) This way we don't need a workaround in the test for the
Linux/E2K platform, and the test shouldn't have got worse.
There is a possibility to follow the "first-writing" part by a
"then-reading" part, but this doesn't seem to be essential. At least, on
E2K and probably most other architectures it would never come to it. (But
that way the new code would be closer to the old code in the involved
operations, and who knows, there might be some architecture where one
needs to read to cause a fault.)
--
Best regards,
Ivan
gnulib-0.1.2305-test-c-stack-e2k.patch
Description: Text Data