public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
* [PATCH] i386 TLS_INIT_TP might produce bogus asm changing stack pointer.
@ 2014-08-26  8:27 Mark Wielaard
  2014-08-26  8:34 ` Florian Weimer
  0 siblings, 1 reply; 8+ messages in thread
From: Mark Wielaard @ 2014-08-26  8:27 UTC (permalink / raw)
  To: libc-alpha; +Cc: Siddhesh Poyarekar, Florian Weimer, Mark Wielaard

TLS_INIT_TP in sysdeps/i386/nptl/tls.h uses some hand written asm to
generate a set_thread_area that might result in exchanging ebx and esp
around the syscall causing introspection tools like valgrind to loose
track of the user stack. Just use INTERNAL_SYSCALL which makes sure
esp isn't changed arbitrarily.

Before the patch the code would generate:

mov    $0xf3,%eax
movl   $0xfffff,0x8(%esp)
movl   $0x51,0xc(%esp)
xchg   %esp,%ebx
int    $0x80
xchg   %esp,%ebx

Using INTERNAL_SYSCALL instead will generate:

movl   $0xfffff,0x8(%esp)
movl   $0x51,0xc(%esp)
xchg   %ecx,%ebx
mov    $0xf3,%eax
int    $0x80
xchg   %ecx,%ebx

Thanks to Florian Weimer for analysing why the original code generated
the bogus esp usage:

  _segdescr.desc happens to be at the top of the stack, so its address
  is in %esp.  The asm statement says that %3 is an input, so its value
  will not change, and GCC can use %esp as the input register for the
  expression &_segdescr.desc.  But the constraints do not fully describe
  the asm statement because the %3 register is actually modified, albeit
  only temporarily.

https://bugzilla.redhat.com/show_bug.cgi?id=1133134

	* sysdeps/i386/nptl/tls.h (TLS_INIT_TP): Use INTERNAL_SYSCALL
	to call set_thread_area instead of hand written asm.
---
 ChangeLog               | 5 +++++
 sysdeps/i386/nptl/tls.h | 8 ++------
 2 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/sysdeps/i386/nptl/tls.h b/sysdeps/i386/nptl/tls.h
index ac9c9a2..052ea64 100644
--- a/sysdeps/i386/nptl/tls.h
+++ b/sysdeps/i386/nptl/tls.h
@@ -231,12 +231,8 @@ tls_fill_user_desc (union user_desc_init *desc,
      tls_fill_user_desc (&_segdescr, -1, _thrdescr);			      \
 									      \
      /* Install the TLS.  */						      \
-     asm volatile (TLS_LOAD_EBX						      \
-		   "int $0x80\n\t"					      \
-		   TLS_LOAD_EBX						      \
-		   : "=a" (_result), "=m" (_segdescr.desc.entry_number)	      \
-		   : "0" (__NR_set_thread_area),			      \
-		     TLS_EBX_ARG (&_segdescr.desc), "m" (_segdescr.desc));    \
+     INTERNAL_SYSCALL_DECL (err);					      \
+     _result = INTERNAL_SYSCALL (set_thread_area, err, 1, &_segdescr.desc);   \
 									      \
      if (_result == 0)							      \
        /* We know the index in the GDT, now load the segment register.	      \
-- 
1.9.3

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2014-08-28  8:21 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-08-26  8:27 [PATCH] i386 TLS_INIT_TP might produce bogus asm changing stack pointer Mark Wielaard
2014-08-26  8:34 ` Florian Weimer
2014-08-26 12:27   ` Mark Wielaard
2014-08-26 21:29     ` Roland McGrath
2014-08-27 15:12       ` Mark Wielaard
2014-08-27 16:58         ` Roland McGrath
2014-08-27 23:01           ` Allan McRae
2014-08-28  8:21             ` Florian Weimer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).