[oss] [Lab 03][Task 4] volatile keyword

Alex Teaca ionutalex.teaca at gmail.com
Wed Oct 29 14:50:03 EET 2014


Hi LucianC,

I am perfectly agree with your clarifications and managed to reproduce your
example on my 32 bits system by changing SLEEP_GOT_OFFSET and
SLEEP_LOADED_ADDR accordingly with the values where the got sleep starts.
I perfectly understand what is happening there and I think would be more
clearly (just as an addition) if we see the assembly code compiled with o3
in the both scenarios:

- without the volatile qualifier

 80485df:       81 7a 18 80 b0 1c 00   cmp    DWORD PTR [edx+0x18],0x1cb080
 80485e6:       74 08                         je     80485f0 <main+0x100>
 80485e8:       eb fe                          jmp    80485e8 <main+0xf8>
(*)
 80485ea:       8d b6 00 00 00 00       lea    esi,[esi+0x0]
 80485f0:       c7 44 24 04 fa 87 04    mov    DWORD PTR [esp+0x4],0x80487fa
 80485f7:       08

the compiler compares just once *(got_start+SLEEP_GOT_OFFSET) from memory
with the SLEEP_LOADED_ADDR assuming
that *(got_start+SLEEP_GOT_OFFSET) in memory will never by updated and then
it remains in while (1) (*).

- with the volatile qualifier
 80485e8:       8b 02                         mov    eax,DWORD PTR [edx]
 80485ea:       3d 80 b0 1c 00           cmp    eax,0x1cb080
 80485ef:       75 f7                          jne    80485e8 <main+0xf8>
the compiler compares in each loop with the value from memory.

Thanks for your clarifications, and for the example of why is needed to use
the volarile qualifier in relation with the GOT.

Alex

On Tue, Oct 28, 2014 at 10:11 PM, Lucian Cojocar <cojocar at rosedu.org> wrote:

> On 10/28/2014 01:43 PM, Lucian Mogosanu wrote:
> > On Tue, Oct 28, 2014 at 02:22:57PM +0200, Alex Teaca wrote:
> >> Hello,
> >>
> >> I see in get_got routine that the plt_ptr, got_min and got_max
> >> variables are marked with the volatile keyword.
> >> What is its purpose, is there a danger  for these variables
> >> to be modified, and the compiler don't see it ?
> >
> > Not sure about got_min and got_max, but plt_ptr *must* be volatile. What
> the
> > volatile keyword does is it tells the compiler to not make any
> assumptions
> > about the data stored at that particular pointer (e.g. the compiler
> could make
> > the assumption that the value at plt_ptr doesn't change during
> execution, when
> > in fact it does/it may, only this is done transparently by the OS when
> some
> > plt-linked library function gets called).
> >
>
>
> got_{min,max} should not be volatile, error on our side.
>
> The PLT is actually code (trampoline code, but still code), so plt_ptr
> points to code region, no need for volatile keyword here, so another
> error on our side.
>
> The case that Lucian is mentioning relates with the GOT, the GOT is the
> only one that the 'OS' changes during execution, basically, the GOT
> holds the offsets (which are runtime information) of the called symbols.
> For this, we *should have marked* the 'got_start' pointer volatile,
> however, the code still works (even with -O3). Why is that?
>
> Let's look at how got_start is used, after it is computed.
>
> """
> get_got_for_sleep(void)
> {
>         ...
>         memcpy(old_got, got_start, size);
>         sleep(1);
>         memcpy(new_got, got_start, size);
>         ...
> }
>
> """
>
> The call of sleep function is a 'sequence point'[1], meaning that all
> "the side effects of previous evaluations will have been performed".
> Memcopy is not a 'pure'[2] function, meaning that it has side effects.
> So this guarantees that memcpy will be actually called two times, with
> got_start as second parameter. Anyway, this behavior does not need
> advanced explanation.
>
> The second usage of got_start is here:
>
> """
>         *got_sleep = *got_puts;
>         *got_kill = *got_system;
>
>         my_func();
>
> """
> So another sequence point.
>
> But how we can show that volatile can be useful?
>
> Use the code from here[3]. If you computed the offsets correctly and if
> compiled with O3, the code should block when got_start is not volatile
> and it should 'unblock' when got_start is volatile.
>
> P.S. [3]s/'sleep plt'/'sleep ptr'/g
> P.P.S you may want to disable ASLR in order to get the same address of
> sleep function each time the binary is loaded.
> P(3).S Here are some things that might go wrong with volatile[4], even
> at compiler level.
>
> Hope this helps,
> Lucian
>
> [1]http://en.wikipedia.org/wiki/Sequence_point
> [2]http://en.wikipedia.org/wiki/Pure_function
> [3]http://paste.debian.net/129140
> [4]http://www.cs.utah.edu/~regehr/papers/emsoft08-preprint.pdf
>
> LucianC
> _______________________________________________
> http://elf.cs.pub.ro/oss/wiki/resources/mailing-list
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://cursuri.cs.pub.ro/pipermail/oss/attachments/20141029/8192cb03/attachment.html>


More information about the oss mailing list