OSEC

Neohapsis is currently accepting applications for employment. For more information, please visit our website www.neohapsis.com or email hr@neohapsis.com
 
From: Jirka Kosina (jikos_at_jikos.cz)
Date: Thu Nov 14 2002 - 12:29:24 CST

  • Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]

    On Wed, 13 Nov 2002, Christophe Devine wrote:

    > > Regarding this issue: is it 80x86 or specifically 80386 designed ?
    > > Been trying it on AMD Duron, AMD Athlon MP, Intel i586 - just segfaults :(
    > Yep; the first version of the DoS I posted on bugtraq was defective and
    > worked only under special conditions (inside gdb for example).
    > However this updated version works much better:
    > At the beginning I thought only kernels <= 2.4.18 were affected; but it
    > appeared that both kernels 2.4.19 and 2.4.20-rc1 are vulnerable as well.
    > The flaw seems to be related to the kernel's handling of the nested task
    > (NT) flag inside a lcall7.

    Reposting mail from Linus to linux-kernel mailing list.

    == cut here ==

    >From torvaldstransmeta.com Thu Nov 14 19:27:17 2002
    Date: Thu, 14 Nov 2002 10:12:53 -0800 (PST)
    From: Linus Torvalds transmeta.com>
    Subject: Re: FW: i386 Linux kernel DoS
    
    
    Ok, the reason for this one is that we don't really emulate a
    trap/interrupt gate correctly when taking a lcall. We _do_ set up the
    stack to be identical, but a real trap/interrupt will also clear TF and NT
    in EFLAGS on entry to the kernel (_after_ having saved the value off), and
    our emulation code didn't do that.
    
    So when we returned with an "iret", we had NT set in EFLAGS, causing the
    iret to do all the wrong things.
    
    This is my 2.5.x fix, I suspect it applies as-is to 2.4.x too. I don't
    think anything has changed here in a long time.
    
    Does anybody see anything else we're missing from the emulation path?
    
    (Or path_s_, as I noticed after fixing the bug once already ;^p. We should
    probably try to do this all as common code rather than having two separate
    paths for lcall 0x7 and lcall 0x27 - the code is identical apart from one
    little constant.. This looks like the minimal patch, though.)
    
                    Linus
    
    -----
    # The following is the BitKeeper ChangeSet Log
    # --------------------------------------------
    # 02/11/14      torvaldshome.transmeta.com     1.848
    # Fix impressive call gate misuse DoS reported on bugtraq.
    # --------------------------------------------
    # 02/11/14      torvaldshome.transmeta.com     1.849
    # Duh. Fix the other lcall entry point too.
    # --------------------------------------------
    #
    diff -Nru a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S
    --- a/arch/i386/kernel/entry.S  Thu Nov 14 09:59:08 2002
    +++ b/arch/i386/kernel/entry.S  Thu Nov 14 09:59:08 2002
     -66,7 +66,9 
     OLDSS          = 0x38
    
     CF_MASK                = 0x00000001
    +TF_MASK                = 0x00000100
     IF_MASK                = 0x00000200
    +DF_MASK                = 0x00000400
     NT_MASK                = 0x00004000
     VM_MASK                = 0x00020000
    
     -134,6 +136,17 
            movl %eax,EFLAGS(%esp)  #
            movl %edx,EIP(%esp)     # Now we move them to their "normal" places
            movl %ecx,CS(%esp)      #
    +
    +       #
    +       # Call gates don't clear TF and NT in eflags like
    +       # traps do, so we need to do it ourselves.
    +       # %eax already contains eflags (but it may have
    +       # DF set, clear that also)
    +       #
    +       andl $~(DF_MASK | TF_MASK | NT_MASK),%eax
    +       pushl %eax
    +       popfl
    +
            movl %esp, %ebx
            pushl %ebx
            andl $-8192, %ebx       # GET_THREAD_INFO
     -156,6 +169,17 
            movl %eax,EFLAGS(%esp)  #
            movl %edx,EIP(%esp)     # Now we move them to their "normal" places
            movl %ecx,CS(%esp)      #
    +
    +       #
    +       # Call gates don't clear TF and NT in eflags like
    +       # traps do, so we need to do it ourselves.
    +       # %eax already contains eflags (but it may have
    +       # DF set, clear that also)
    +       #
    +       andl $~(DF_MASK | TF_MASK | NT_MASK),%eax
    +       pushl %eax
    +       popfl
    +
            movl %esp, %ebx
            pushl %ebx
            andl $-8192, %ebx       # GET_THREAD_INFO
    
    == cut here ==
    
    --
    JiKos.