Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 18 Jul 2004 23:07:46 GMT
From:      Qing Li <qing.li@bluecoat.com>
To:        freebsd-gnats-submit@FreeBSD.org
Subject:   i386/69257: in_cksum_hdr is non-functional without -O compiler flag
Message-ID:  <200407182307.i6IN7k2V063441@www.freebsd.org>
Resent-Message-ID: <200407182310.i6INAAC4019230@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         69257
>Category:       i386
>Synopsis:       in_cksum_hdr is non-functional without -O compiler flag
>Confidential:   no
>Severity:       critical
>Priority:       high
>Responsible:    freebsd-i386
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Sun Jul 18 23:10:10 GMT 2004
>Closed-Date:
>Last-Modified:
>Originator:     Qing Li
>Release:        5.2.1
>Organization:
Blue Coat Systems, Inc.
>Environment:
FreeBSD heavygear.bluecoat.com 5.2.1-RELEASE FreeBSD 5.2.1-RELEASE #0: Tue Jun8 20:16:31 GMT 2004    root@heavygear.bluecoat.com:/usr/src/sys/i386/compile/QING i386

>Description:
The "in_cksum_hdr" function does not work when compiled without any optimization flags on i386. 

	The original inline __asm code was written as

#define ADD(n)	__asm __volatile ("addl %1, %0" : "+r" (sum) : \
    "g" (((const u_int32_t *)ip)[n]))
#define ADDC(n)	__asm __volatile ("adcl %1, %0" : "+r" (sum) : \
    "g" (((const u_int32_t *)ip)[n]))

      ADD(0)
      ADDC(4)
      ADDC(8)  etc.

The C code assumes that the carry bit is always kept from the
previous operation. However, the pointer indexing requires another
add operation, here is the gcc generated code

#1    3784 2ef0 0310     addl (%eax), %edx
      3786 2ef2 8955FC   movl	%edx, -4(%ebp)
      3787 2ef5 8B4508 	 movl	8(%ebp), %eax
#2    3788 2ef8 83C004   addl	$4, %eax
      3789 2efb 8B55FC 	 movl	-4(%ebp), %edx
#3    3791 2efe 1310 	 adcl (%eax), %edx

The bug is, the carry bit from #1 is tromped over by the
"addl" operation on line #2, so the "adcl" on #3 has no effect
because the carry bit is cleard by #2. The result is checksum
failure on received packets.

>How-To-Repeat:
Compile any file that calls the in_cksum_hdr function, such as
ip_input.c, without any optimization flags. 
>Fix:
      
>Release-Note:
>Audit-Trail:
>Unformatted:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200407182307.i6IN7k2V063441>