From: Jason Wessel <jason.wessel@windriver.com>
To: lkml <linux-kernel@vger.kernel.org>, stable@kernel.org
Subject: [PATCH] i386 - Fix regression, endless loop in ptrace singlestep over an int80
Date: Mon, 02 Jul 2007 15:53:44 -0500 [thread overview]
Message-ID: <468965D8.7020405@windriver.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 692 bytes --]
Attached is a patch with a complete test case to fix the regression
introduced by the commit: 635cf99a80f4ebee59d70eb64bb85ce829e4591f.
This patch is against kernel 2.6.21 but the fix is applicable to 2.6.21
and up. Prior to the commit that introduced the regression the ltp
ptrace tests would complete correctly. I augmented the test case from
the original patch header to include the problem case that shows up in
the lpt tests.
The brief summary is that the the TIF_SINGLESTEP state needs to be
altered on the exit path and not the entry path to a syscall, else it
can loop forever on the same instruction right after the syscall is
executed in certain cases.
Thanks,
Jason.
[-- Attachment #2: ptrace_int80_loop_fix.patch --]
[-- Type: text/plain, Size: 2871 bytes --]
ptrace_int80_loop_fix.patch
[PATCH] i386: fix infinite loop with singlestep int80 syscalls
The commit 635cf99a80f4ebee59d70eb64bb85ce829e4591f introduced a
regression. Executing a ptrace single step after certain int80
accesses will infinitely loop and never advance the PC.
The TIF_SINGLESTEP check should be done on the return from the syscall
and not before it.
The new test case is below:
/* Test whether singlestep through an int80 syscall works.
*/
#define _GNU_SOURCE
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ptrace.h>
#include <sys/wait.h>
#include <sys/mman.h>
#include <asm/user.h>
#include <string.h>
static int child, status;
static struct user_regs_struct regs;
static void do_child()
{
char str[80] = "child: int80 test\n";
ptrace(PTRACE_TRACEME, 0, 0, 0);
kill(getpid(), SIGUSR1);
write(fileno(stdout),str,strlen(str));
asm ("int $0x80" : : "a" (20)); /* getpid */
}
static void do_parent()
{
unsigned long eip, expected = 0;
again:
waitpid(child, &status, 0);
if (WIFEXITED(status) || WIFSIGNALED(status))
return;
if (WIFSTOPPED(status)) {
ptrace(PTRACE_GETREGS, child, 0, ®s);
eip = regs.eip;
if (expected)
fprintf(stderr, "child stop @ %08lx, expected %08lx %s\n",
eip, expected,
eip == expected ? "" : " <== ERROR");
if (*(unsigned short *)eip == 0x80cd) {
fprintf(stderr, "int 0x80 at %08x\n", (unsigned int)eip);
expected = eip + 2;
} else
expected = 0;
ptrace(PTRACE_SINGLESTEP, child, NULL, NULL);
}
goto again;
}
int main(int argc, char * const argv[])
{
child = fork();
if (child)
do_parent();
else
do_child();
return 0;
}
Signed-off-by: Jason Wessel <jason.wessel@windriver.com>
---
arch/i386/kernel/entry.S | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
Index: linux-2.6.21-standard/arch/i386/kernel/entry.S
===================================================================
--- linux-2.6.21-standard.orig/arch/i386/kernel/entry.S
+++ linux-2.6.21-standard/arch/i386/kernel/entry.S
@@ -371,10 +371,6 @@ ENTRY(system_call)
CFI_ADJUST_CFA_OFFSET 4
SAVE_ALL
GET_THREAD_INFO(%ebp)
- testl $TF_MASK,PT_EFLAGS(%esp)
- jz no_singlestep
- orl $_TIF_SINGLESTEP,TI_flags(%ebp)
-no_singlestep:
# system call tracing in operation / emulation
/* Note, _TIF_SECCOMP is bit number 8, and so it needs testw and not testb */
testw $(_TIF_SYSCALL_EMU|_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT),TI_flags(%ebp)
@@ -389,6 +385,10 @@ syscall_exit:
# setting need_resched or sigpending
# between sampling and the iret
TRACE_IRQS_OFF
+ testl $TF_MASK,PT_EFLAGS(%esp) # If tracing set singlestep flag on exit
+ jz no_singlestep
+ orl $_TIF_SINGLESTEP,TI_flags(%ebp)
+no_singlestep:
movl TI_flags(%ebp), %ecx
testw $_TIF_ALLWORK_MASK, %cx # current->work
jne syscall_exit_work
next reply other threads:[~2007-07-02 20:54 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-07-02 20:53 Jason Wessel [this message]
2007-07-02 21:07 ` [PATCH] i386 - Fix regression, endless loop in ptrace singlestep over an int80 Jeremy Fitzhardinge
2007-07-02 22:03 ` Chuck Ebbert
2007-07-02 22:20 ` Jason Wessel
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=468965D8.7020405@windriver.com \
--to=jason.wessel@windriver.com \
--cc=linux-kernel@vger.kernel.org \
--cc=stable@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.