-
I am Dave (Jing) Tian, an Associate Professor in the Department of Computer Science at Purdue University working on system security. My research involves embedded systems, operating systems, trusted and confidential computing, and hardware security. All opinions are my own.
Shoot me:
root@davejingtian.org Categories
Tags
- ABNF
- agile
- AI/ML
- Alcatel-Lucent
- android
- arp
- asn1c
- assembly
- bash
- ber
- bison
- BNF
- build
- C
- CentOS
- CIS122
- Coverity
- crypto
- csv
- cuda
- DCA
- ddclient
- debugfs
- DH
- Diffie-Hellman
- drd
- drig
- elixir
- fedora
- fedup
- flex
- fsck
- gcc
- gdb
- GFW
- git
- github
- gnome
- gprof
- gpu
- guitar
- gumstix
- helgrind
- intel
- itevad
- Java
- jmgsim
- JVM
- kenai
- kernel
- kill
- ksh
- kvm
- ld
- Linux
- list
- netbeans
- netlink
- nvidia
- OS
- overo
- Python
- relay
- security
- selinux
- sgx
- socket
- ssh
- Ubuntu
- UO
- USB
- valgrind
- x86
- x86_64
- yocto
Blog Stats
- 275,740 hits
-

All blogs on this website are licensed under a Creative Commons Attribution 4.0 International License.
RedHat 6 – Porting code to RH6
We are moving our product’s OS from RedHat 5 to 6, as well as new version of ‘gcc’ (4.X) along with RH6. To port the existing code to RH6 with new compiler, there might be a lot of things we need to care. This post gives a brief summary for the issue during our trial and hopefully would be updated timely. May it help:)
1. C++ header file include
#include <iostream.h> -> #include <iostream>
#include <typeinfo.h> -> #include <typeinfo>
#include <list.h> -> #include <list>
#include “poll.h” -> #include <poll.h>
#include “fcntl.h” -> #include <fcntl.h>
a. All the standard C++ header file need to omit “.h”;
b. Standard C header file could have both format:
#include <stdio.h> OR
#include <cstdio>
NOT #include “stdio.h”
2. SCTP library
libsctp.a -> -lsctp
RH 6 does not support static lib of SCTP. Should be dynamically linked.
3. SCTP struct/API
sctp_adaption_layer_event -> sctp_adaptation_layer_event
SCTP_ADAPTION_INDICATION -> SCTP_ADAPTATION_INDICATION
sctp_connectx(int, sockaddr*, int) -> sctp_connectx(int, sockaddr*, int, sctp_assoc_t*)
a. Member name updated in structure sctp_event_subscribe
b. Member name updated in enum sctp_sn_type
c. New argument updated in function sctp_connectx
4. Linux Kernel API
extern struct net_device *dev_get_by_name( const char *name) ->
extern struct net_devide *dev_get_by_name( struct net *net, const char *name)
shellcode 1 – comments for the doc “The Basics of Shellcoding”
Recently been doing some stuffs on Shellcode. After a while wandering in the net, I found the doc “The Basics of Shellcoding” by Angelo Rosiello may be the very concise introduction to start with shellcoding, especially for the newbie like myself – baby step. However, though with brief and clear description in this doc, I feel frustrated when I was trying to do it myself. Stack manipulation with string and system call is expected in the doc (part C below); while assembly code my here is C lib call and string in .rodata (part B below). Detailed workaround to get the opcode in part C is listed below. On the other hand, to implement shellcode, we really need to put everything we need in the stack and use system call directly, as address of .rodata and C lib function call would be dynamically changed per each binary.
/* A: Original C source code in the doc */
/home/daveti/shellcode: cat rosiello.c
#include <stdio.h>
int main()
{
write( 0, “WWW.ROSIELLO.ORG”, 16);
exit(0);
}
/* B: Objdump for the binary of the code above */
080481d0 <main>:
#include <stdio.h>
int main()
{
80481d0: 55 push %ebp
80481d1: 89 e5 mov %esp,%ebp
80481d3: 83 ec 08 sub $0x8,%esp
80481d6: 83 e4 f0 and $0xfffffff0,%esp
80481d9: b8 00 00 00 00 mov $0x0,%eax
80481de: 29 c4 sub %eax,%esp
write( 0, “WWW.ROSIELLO.ORG”, 16);
80481e0: 83 ec 04 sub $0x4,%esp
80481e3: 6a 10 push $0x10
80481e5: 68 68 f7 08 08 push $0x808f768
80481ea: 6a 00 push $0x0
80481ec: e8 8f 5a 00 00 call 804dc80 <__libc_write>
80481f1: 83 c4 10 add $0x10,%esp
exit(0);
80481f4: 83 ec 0c sub $0xc,%esp
80481f7: 6a 00 push $0x0
80481f9: e8 16 04 00 00 call 8048614 <exit>
80481fe: 90 nop
80481ff: 90 nop
/* C: Assembly code for shellcode expected in the doc */
xor %eax,%eax
xor %ebx,%ebx
xor %edx,%edx
push %eax
push $0x47524f2e
push $0x4f4c4c45
push $0x49534f52
push $0x2e575757
mov %esp,%ecx
mov $0x10,%dl
mov $0x4,%al
int $0x80
xor %eax,%eax
xor %ebx,%ebx
mov $0x1,%al
int $0x80
/* D: Shellcode in the doc */
/home/daveti/shellcode: cat rosiello_shellcode.c
#include <stdio.h>
char shellcode[]=
“x31xc0x31xdbx31xd2x50x68x2ex4f”
“x52x47x68x45x4cx4cx4fx68x52x4f”
“x53x49x68x57x57x57x2ex89xe1xb2”
“x10xb0x04xcdx80x31xc0x31xdbxb0”
“x01xcdx80”;
int main()
{
void (*routine)();
/* daveti: gcc 4.X would report error! */
(long) routine = &shellcode;
printf(“Size: %d bytesn”, sizeof(shellcode));
routine();
return 0;
}
/* E: Run the shellcode in the doc */
/home/daveti/shellcode: ./rosiello_shellcode
Size: 44 bytes
WWW.ROSIELLO.ORG/home/daveti/shellcode: gcc -v
Reading specs from /usr/lib/gcc-lib/i386-redhat-linux/3.2.2/specs
Configured with: ../configure –prefix=/usr –mandir=/usr/share/man –infodir=/usr/share/info –enable-shared –enable-threads=posix –disable-checking –with-system-zlib –enable-__cxa_atexit –host=i386-redhat-linux
Thread model: posix
gcc version 3.2.2 20030222 (Red Hat Linux 3.2.2-5)
/home/daveti/shellcode: uname -a
Linux lssxlinux1.ih.lucent.com 2.6.32-042stab044.11 #1 SMP Wed Dec 14 16:02:00 MSK 2011 i686
/* F: gcc -S rosiello.c */
/home/daveti/shellcode: cat rosiello.s
.file “rosiello.c”
.section .rodata
.LC0:
.string “WWW.ROSIELLO.ORG”
.text
.globl main
.type main,@function
main:
pushl %ebp
movl %esp, %ebp
subl $8, %esp
andl $-16, %esp
movl $0, %eax
subl %eax, %esp
subl $4, %esp
pushl $16
pushl $.LC0
pushl $0
call write
addl $16, %esp
subl $12, %esp
pushl $0
call exit
.Lfe1:
.size main,.Lfe1-main
.ident “GCC: (GNU) 3.2.2 20030222 (Red Hat Linux 3.2.2-5)”
/* G: Modify rosiello.s to rosiello_daveti.c with desired assembly in C */
/home/daveti/shellcode: cat rosiello_daveti.s
.file “rosiello_daveti.c”
.section .rodata
.text
.globl main
.type main,@function
main:
pushl %ebp
movl %esp, %ebp
subl $8, %esp
andl $-16, %esp
movl $0, %eax
subl %eax, %esp
xor %eax, %eax
xor %ebx, %ebx
xor %edx, %edx
push %eax
push $0x47524f2e
push $0x4f4c4c45
push $0x49534f52
push $0x2e575757
mov %esp, %ecx
mov $0x10, %dl
mov $0x4, %al
int $0x80
xor %eax, %eax
xor %ebx, %ebx
mov $0x1, %al
int $0x80
.Lfe1:
.size main,.Lfe1-main
.ident “GCC: (GNU) 3.2.2 20030222 (Red Hat Linux 3.2.2-5)”
/* H: gcc -o rosiello_daveti rosiello_daveti.s – make sure our change work */
/home/daveti/shellcode: ./rosiello_daveti
WWW.ROSIELLO.ORG/home/daveti/shellcode:
/* I: Objdump to get the opcode instead of gdb */
080482f4 <main>:
80482f4: 55 push %ebp
80482f5: 89 e5 mov %esp,%ebp
80482f7: 83 ec 08 sub $0x8,%esp
80482fa: 83 e4 f0 and $0xfffffff0,%esp
80482fd: b8 00 00 00 00 mov $0x0,%eax
8048302: 29 c4 sub %eax,%esp
8048304: 31 c0 xor %eax,%eax
8048306: 31 db xor %ebx,%ebx
8048308: 31 d2 xor %edx,%edx
804830a: 50 push %eax
804830b: 68 2e 4f 52 47 push $0x47524f2e
8048310: 68 45 4c 4c 4f push $0x4f4c4c45
8048315: 68 52 4f 53 49 push $0x49534f52
804831a: 68 57 57 57 2e push $0x2e575757
804831f: 89 e1 mov %esp,%ecx
8048321: b2 10 mov $0x10,%dl
8048323: b0 04 mov $0x4,%al
8048325: cd 80 int $0x80
8048327: 31 c0 xor %eax,%eax
8048329: 31 db xor %ebx,%ebx
804832b: b0 01 mov $0x1,%al
804832d: cd 80 int $0x80
804832f: 90 nop
/* J: Finally we have got the workable opcode in the doc:) */
side effect of “++” in C – compiler implemenation with assembly
This post shows a common known side effect of “++” operator in C programming because of different compiler implementation. Assembly code from PowerPC and x86 with gcc is provide to show the key difference and the reason why for this side effect. Detailed comments may not be completely correct. However, should be easy to get the point:)
/* sideEffect1.c */
#include <stdio.h>
int main()
{
int n = 0;
printf(“n1 = %d, n2 = %dn”, n++, n++);
return 0;
}
/* PowerPC */
/loads/umts6/cpsb/montavista/M8cge4.0_drop090305/montavista/cge/devkit/ppc/7xx/bin/ppc_7xx-gcc -v
Reading specs from /loads/umts6/cpsb/montavista/M8cge4.0_drop090305/montavista/cge/devkit/ppc/7xx/bin/../lib/gcc/powerpc-montavista-linux/3.4.3/specs
Configured with: ../configure –host=i686-pc-linux-gnu –target=powerpc-montavista-linux –prefix=/opt/montavista/foundation/devkit/ppc/7xx –exec-prefix=/opt/montavista/foundation/devkit/ppc/7xx –bindir=/opt/montavista/foundation/devkit/ppc/7xx/bin –sbindir=/opt/montavista/foundation/devkit/ppc/7xx/sbin –sysconfdir=/opt/montavista/foundation/devkit/ppc/7xx/etc –datadir=/opt/montavista/foundation/devkit/ppc/7xx/share –includedir=/opt/montavista/foundation/devkit/ppc/7xx/include –libdir=/opt/montavista/foundation/devkit/ppc/7xx/lib –libexecdir=/opt/montavista/foundation/devkit/ppc/7xx/libexec –localstatedir=/opt/montavista/foundation/devkit/ppc/7xx/var –sharedstatedir=/opt/montavista/foundation/devkit/ppc/7xx/share –mandir=/opt/montavista/foundation/devkit/ppc/7xx/man –infodir=/opt/montavista/foundation/devkit/ppc/7xx/info –build=i686-pc-linux-gnu –program-transform-name=s,^,ppc_7xx-, –enable-cross –with-sysroot=/opt/montavista/foundation/devkit/ppc/7xx/target !
–enable-shared –enable-languages=c,c++ –enable-__cxa_atexit –enable-threads=posix –disable-multilib –with-gxx-include-dir=${prefix}/lib/gcc/powerpc-montavista-linux/3.4.3/../../../../target/usr/include/c++/3.4.3 –with-numa-policy=no –with-cpu=750 –libexecdir=/opt/montavista/foundation/devkit/ppc/7xx/lib
Thread model: posix
gcc version 3.4.3 (MontaVista 3.4.3-25.0.145.0801204 2008-06-04)
<dv111-s01c10h0:lss>/export/home/lss:
# uname -a
Linux dv111-s01c10h0 2.6.10_mvlcge401-katana #2403 Fri Jan 20 10:25:01 CST 2012 ppc
<dv111-s01c10h0:lss>/export/home/lss:
# ./sideEffect1
n1 = 0, n2 = 1
<dv111-s01c10h0:lss>/export/home/lss:
1000028c <main>:
#include <stdio.h>
int main()
{
1000028c: 94 21 ff e0 stwu r1,-32(r1) /* store stack pointer to r1-32 and update r1=r1-32 */
10000290: 7c 08 02 a6 mflr r0 /* get link register – set up the stack frame */
10000294: 93 e1 00 1c stw r31,28(r1) /* store nonvolatile r31 to 28(r1) */
10000298: 90 01 00 24 stw r0,36(r1) /* store old link register to 36(r1) */
1000029c: 7c 3f 0b 78 mr r31,r1 /* move stack pointer to r31 */
int n = 0;
100002a0: 38 00 00 00 li r0,0 /* load 0 to r0 */
100002a4: 90 1f 00 08 stw r0,8(r31) /* store r0(0) to 8(r31)=8(r1), (n=0, 8(r31))*/
printf(“n1 = %d, n2 = %dn”, n++, n++);
100002a8: 81 3f 00 08 lwz r9,8(r31) /* load 8(r31) to r9 */
100002ac: 7d 20 4b 78 mr r0,r9 /* move r9 to r0(0) */
100002b0: 39 29 00 01 addi r9,r9,1 /* r9=r9+1, (n++, r9(1)) */
100002b4: 91 3f 00 08 stw r9,8(r31) /* store r9 to 8(r31), (n=1, 8(r31)) */
100002b8: 81 3f 00 08 lwz r9,8(r31) /* load 8(r31) to r9(1) again */
100002bc: 7d 2b 4b 78 mr r11,r9 /* move r9 to r11(1) */
100002c0: 39 29 00 01 addi r9,r9,1 /* r9=r9+1, (n++, r9(2)) */
100002c4: 91 3f 00 08 stw r9,8(r31) /* store r9 to 8(r31), (n=2, 8(r31)) */
100002c8: 3d 20 10 05 lis r9,4101 /* load 4101 to r9 */
100002cc: 38 69 4c ac addi r3,r9,19628 /* r3=r9+19628=4101+19628=23729 – first parameter */
100002d0: 7c 04 03 78 mr r4,r0 /* move r0 to r4(0) – second parameter */
100002d4: 7d 65 5b 78 mr r5,r11 /* move r11 to r5(1) – third parameter */
100002d8: 4c c6 31 82 crclr 4*cr1+eq /* clear the control register */
100002dc: 48 00 0b 59 bl 10000e34 <_IO_printf> /* printf(“…”, 0, 1); */
return 0;
100002e0: 38 00 00 00 li r0,0 /* load 0 to r0(0) */
}
100002e4: 7c 03 03 78 mr r3,r0 /* move r0 to r3(0) */
100002e8: 81 61 00 00 lwz r11,0(r1) /* load saved link register (in printf) to r11 */
100002ec: 80 0b 00 04 lwz r0,4(r11) /* load next link register (saved in main) to r0 */
100002f0: 7c 08 03 a6 mtlr r0 /* set link register to r0 – recover link register */
100002f4: 83 eb ff fc lwz r31,-4(r11) /* load -4(r11) (original saved in 28(r1)) back to nonvolatile r31 */
100002f8: 7d 61 5b 78 mr r1,r11 /* move saved link register to stack pointer */
100002fc: 4e 80 00 20 blr /* exit */
/* x86 */
/home/daveti/Ctest/sideEffect/x86: uname -a
Linux lssxlinux1.ih.lucent.com 2.6.32-042stab044.11 #1 SMP Wed Dec 14 16:02:00 MSK 2011 i686
/home/daveti/Ctest/sideEffect/x86: gcc -v
Reading specs from /usr/lib/gcc-lib/i386-redhat-linux/3.2.2/specs
Configured with: ../configure –prefix=/usr –mandir=/usr/share/man –infodir=/usr/share/info –enable-shared –enable-threads=posix –disable-checking –with-system-zlib –enable-__cxa_atexit –host=i386-redhat-linux
Thread model: posix
gcc version 3.2.2 20030222 (Red Hat Linux 3.2.2-5)
/home/daveti/Ctest/sideEffect/x86: ./sideEffect1
n1 = 1, n2 = 0
/home/daveti/Ctest/sideEffect/x86:
080481d0 <main>:
#include <stdio.h>
int main()
{
80481d0: 55 push %ebp
80481d1: 89 e5 mov %esp,%ebp /* save and update ebp */
80481d3: 83 ec 08 sub $0x8,%esp /* ‘grow’ 8 bytes in the stack */
80481d6: 83 e4 f0 and $0xfffffff0,%esp /* 16-byte alignment for the stack */
80481d9: b8 00 00 00 00 mov $0x0,%eax
80481de: 29 c4 sub %eax,%esp
int n = 0;
80481e0: c7 45 fc 00 00 00 00 movl $0x0,0xfffffffc(%ebp) /* n=0, -4(%ebp) */
printf(“n1 = %d, n2 = %dn”, n++, n++);
80481e7: 83 ec 04 sub $0x4,%esp /* ‘grow’ 4 bytes in the stack */
80481ea: 8b 45 fc mov 0xfffffffc(%ebp),%eax
80481ed: 50 push %eax /* push n=0 – last parameter */
80481ee: 8d 45 fc lea 0xfffffffc(%ebp),%eax
80481f1: ff 00 incl (%eax) /* n++; (n=1)*/
80481f3: 8b 45 fc mov 0xfffffffc(%ebp),%eax
80481f6: 50 push %eax /* push n=1 – second parameter */
80481f7: 8d 45 fc lea 0xfffffffc(%ebp),%eax
80481fa: ff 00 incl (%eax) /* n++; (n=2) */
80481fc: 68 c8 f7 08 08 push $0x808f7c8 /* push “format string” – first paramter */
8048201: e8 b2 06 00 00 call 80488b8 <_IO_printf> /* printf(“…”, 1, 0); */
8048206: 83 c4 10 add $0x10,%esp /* ‘degrow’ 16 bytes in the stack */
return 0;
8048209: b8 00 00 00 00 mov $0x0,%eax
}
804820e: c9 leave
804820f: c3 ret
Intel x86 32-bit assembly – function call & stack frame
This post is originally written for a basic view on function call and stack frame in Intel x86 32-bit assembly code. EBP and ESP are the focus. A stack layout pic with dynamic register changes is also down there. May it help:)
/home/daveti/Ctest: cat assemblyTry.c
#include <stdio.h>
int myFunc( int a)
{
int b;
b = a + 1;
return b;
}
int main()
{
int stackInt1 = 0xffff;
int stackInt2 = 0;
stackInt2 = myFunc( stackInt1);
return stackInt2;
}
========================================
/home/daveti/Ctest: gcc -o assemblyTry -ggdb -static assemblyTry.c
/home/daveti/Ctest: objdump -S -C -d -g -T -t -x -f assemblyTry > assemblyTry.objdump
/home/daveti/Ctest: vi assemblyTry.objdump
080481d0 <myFunc>:
#include <stdio.h>
int myFunc( int a)
{
80481d0: 55 push %ebp
80481d1: 89 e5 mov %esp,%ebp /* save ebp and update ebp */
80481d3: 83 ec 04 sub $0x4,%esp /* ‘grow’ 4 bytes in the stack for b */
int b;
b = a + 1;
80481d6: 8b 45 08 mov 0x8(%ebp),%eax /* pass stackInt1=+8(%ebp) to eax */
80481d9: 40 inc %eax /* eax++ */
80481da: 89 45 fc mov %eax,0xfffffffc(%ebp) /* pass stackInt1+1 to b=-4(%ebp) */
return b;
80481dd: 8b 45 fc mov 0xfffffffc(%ebp),%eax /* return code for myFunc */
}
80481e0: c9 leave /* mov %ebp,%esp; pop %ebp; – destory the stack frame before return from this func
ion call and set the ebp with the old ebp saved in the (top of) stack to restore the caller function’s stack */
80481e1: c3 ret /* return to the caller function */
080481e2 <main>:
int main()
{
80481e2: 55 push %ebp
80481e3: 89 e5 mov %esp,%ebp /* save ebp and update ebp with new esp */
80481e5: 83 ec 08 sub $0x8,%esp /* ‘grow’ 8 bytes in the stack for stackInt1 and stackInt2 */
80481e8: 83 e4 f0 and $0xfffffff0,%esp /* 4-byte alignment for esp */
80481eb: b8 00 00 00 00 mov $0x0,%eax
80481f0: 29 c4 sub %eax,%esp
int stackInt1 = 0xffff;
80481f2: c7 45 fc ff ff 00 00 movl $0xffff,0xfffffffc(%ebp) /* pass 0xffff to stackInt1; 0xfffffffc(%ebp)=-4(%ebp) */
int stackInt2 = 0;
80481f9: c7 45 f8 00 00 00 00 movl $0x0,0xfffffff8(%ebp) /* pass 0x0 to stackInt2; 0xfffffff8(%ebp)=-8(%ebp) */
stackInt2 = myFunc( stackInt1);
8048200: 83 ec 0c sub $0xc,%esp /* ‘grow 12 bytes in the stack for myFunc */
8048203: ff 75 fc pushl 0xfffffffc(%ebp) /* push stackInt1 (last parameter) into stack as (last) parameter of myFunc */
8048206: e8 c5 ff ff ff call 80481d0 <myFunc>
804820b: 83 c4 10 add $0x10,%esp /* ‘degrow’ 16 bytes in the stack */
804820e: 89 45 f8 mov %eax,0xfffffff8(%ebp) /* pass return value b from eax to stackInt2 */
return stackInt2;
8048211: 8b 45 f8 mov 0xfffffff8(%ebp),%eax /* return code for main */
}
8048214: c9 leave /* destroy the stack frame of main */
8048215: c3 ret /* return */
8048216: 90 nop
8048217: 90 nop
Posted in Programming, Stuff about Compiler
Tagged assembly, EBP, ESP, gdb, objdump, stack, x86
1 Comment
Print unsigned long long – SegV in C
This post shows a potential bug in printing unsigned long long, which cost David, Leo and me a few days for debugging. One product got segv on cPSB lab – a platform based on MontaVista Linux and PowerPC CPU. Back trace showed that the segv fired in C lib function ‘snprintf’. As PowerPC’s assembly is not easy to read, we tried to reproduce this issue on x86 based system and succeeded. Below is the C source of the issued code and the x86 assembly code. Enjoy:)
/* Issued C source */
/home/daveti/Ctest: cat longlong.c
#include <stdio.h>
int main( void)
{
char tmpbuf[ 50];
unsigned long long count = 0;
strcpy( tmpbuf, “daveti”);
printf( “%dt%sn”, count, tmpbuf);
return 0;
}
/* Build the source */
/home/daveti/Ctest: gcc -o longlong -g2 -static longlong.c
/* Run the binary */
/home/daveti/Ctest: ./longlong
0 (null)
/* Get the assembly code */
/home/daveti/Ctest: objdump -S -C -d -g -T -t -x -f longlong > longlong.objdump
objdump: longlong: not a dynamic object
objdump: longlong: no recognized debugging information
/* Check the x86 assembly code */
080481d0 <main>:
#include <stdio.h>
int main( void)
{
80481d0: 55 push %ebp // save base pointer
80481d1: 89 e5 mov %esp,%ebp // update base pointer with currentl stack pointer
80481d3: 83 ec 58 sub $0x58,%esp // ‘grow’ 88 bytes in the stack
80481d6: 83 e4 f0 and $0xfffffff0,%esp // 4-byte alignment for stack pointer: ‘grow’ stack again – make sure stack pointe
r would NOT be like 0xXXXXXXX(odd number)
80481d9: b8 00 00 00 00 mov $0x0,%eax
80481de: 29 c4 sub %eax,%esp
char tmpbuf[ 50];
unsigned long long count = 0;
80481e0: c7 45 b0 00 00 00 00 movl $0x0,0xffffffb0(%ebp) // init low-4 bytes of count with zero
80481e7: c7 45 b4 00 00 00 00 movl $0x0,0xffffffb4(%ebp) // init high-4 bytes of count with zero
strcpy( tmpbuf, “daveti”);
80481ee: 83 ec 08 sub $0x8,%esp // ‘grow’ 8 bytes in the stack
80481f1: 68 e8 f7 08 08 push $0x808f7e8 // push address of “daveti”
80481f6: 8d 45 b8 lea 0xffffffb8(%ebp),%eax
80481f9: 50 push %eax // push address of tmpbuf
80481fa: e8 65 57 00 00 call 804d964 <strcpy>
80481ff: 83 c4 10 add $0x10,%esp // ‘degrow’ 16 bytes in the stack after calling strcpy
printf( “%dt%sn”, count, tmpbuf);
8048202: 8d 45 b8 lea 0xffffffb8(%ebp),%eax
8048205: 50 push %eax // push address of tmpbuf
8048206: ff 75 b4 pushl 0xffffffb4(%ebp) // push high-4 bytes of count
8048209: ff 75 b0 pushl 0xffffffb0(%ebp) // push low-4 bytes of count
804820c: 68 ef f7 08 08 push $0x808f7ef // push address of “%dt%sn”
8048211: e8 b2 06 00 00 call 80488c8 <_IO_printf> // BUG: then the first 3 parameters of printf would be “%dt%sn”, low-4 bytes of
count, high-4 bytes of count because “%d” only accepts 320-bit value – tmpbuf would never be called.
8048216: 83 c4 10 add $0x10,%esp
return 0;
8048219: b8 00 00 00 00 mov $0x0,%eax // return value 0
}
804821e: c9 leave
804821f: c3 ret
/* Fixed example with ‘count’=0xffffffff */
/home/daveti/Ctest: cat longlong2.c
#include <stdio.h>
int main( void)
{
char tmpbuf[ 50];
unsigned long long count = 0xffffffff;
strcpy( tmpbuf, “daveti”);
printf( “%llut%sn”, count, tmpbuf);
return 0;
}
/* Run the binary */
/home/daveti/Ctest: ./longlong2
4294967295 daveti
/* Check the x86 assembly code */
080481d0 <main>:
#include <stdio.h>
int main( void)
{
80481d0: 55 push %ebp
80481d1: 89 e5 mov %esp,%ebp
80481d3: 83 ec 58 sub $0x58,%esp
80481d6: 83 e4 f0 and $0xfffffff0,%esp
80481d9: b8 00 00 00 00 mov $0x0,%eax
80481de: 29 c4 sub %eax,%esp
char tmpbuf[ 50];
unsigned long long count = 0xffffffff;
80481e0: c7 45 b0 ff ff ff ff movl $0xffffffff,0xffffffb0(%ebp) // init low-4 byte of count with 0xffffffff
80481e7: c7 45 b4 00 00 00 00 movl $0x0,0xffffffb4(%ebp) // init high-4 byte of count with zero
strcpy( tmpbuf, “daveti”);
80481ee: 83 ec 08 sub $0x8,%esp
80481f1: 68 e8 f7 08 08 push $0x808f7e8
80481f6: 8d 45 b8 lea 0xffffffb8(%ebp),%eax
80481f9: 50 push %eax
80481fa: e8 65 57 00 00 call 804d964 <strcpy>
80481ff: 83 c4 10 add $0x10,%esp
printf( “%llut%sn”, count, tmpbuf);
8048202: 8d 45 b8 lea 0xffffffb8(%ebp),%eax
8048205: 50 push %eax
8048206: ff 75 b4 pushl 0xffffffb4(%ebp)
8048209: ff 75 b0 pushl 0xffffffb0(%ebp)
804820c: 68 ef f7 08 08 push $0x808f7ef
8048211: e8 b2 06 00 00 call 80488c8 <_IO_printf> // Then the 3 parameters of printf would be “%llut%sn”, count, tmpbuf be
cause “%llu” would instruct printf to get the 64-bit long value – tmpbuf would be finally passed then.
8048216: 83 c4 10 add $0x10,%esp
return 0;
8048219: b8 00 00 00 00 mov $0x0,%eax
}
804821e: c9 leave
804821f: c3 ret
Another format string to print unsigned long long may be “%I64u” besides “%llu”. However, based on David and my’s trial, it seems that either “%I64u” working or “%llu” or both depends on the compiler and CPU arch (32/64 bit, x86/PowerPC/Sparc). If our inspection is true, then we should avoid using unsigned long long in C programming – do we really need that so big number. On the other hand, let us get back to the original SegV happened on PowerPC. Though PowerPC uses registers to pass parameters of function calls instead of stack, the same case like x86 above could be imagined: when count is 0xffffffff and “%d%s” is format string, x86 (little endian) would take low-4 byte of count – 0xffffffff as the input for “%d” and high-4 byte of count – 0x00000000 as the input of “%s”, which is the same output as above. PowerPC (big endian), on the other hand, does it in the opposite way, which is passing the high-4 byte of count – 0x00000000 as the input for “%d” and low-4 bytes of count – 0xffffffff as the input of “%s”. Then as long as the count is not zero, the code is trying to access the memory at 0xcount, which may cause the SegV here.
After the discussion for the bug above, apparently this issue belongs to static code analysis scope. More over, Coverity does have a parse warning checker called “PRINTF_ARGS_MISMATCH” to catch this kind of issue. However, this checker focuses on the mismatch too much – each “%d” with unsigned long parameter would be reported, which is indeed not a secure coding but not so fatal as the bug above. When developer is frustrated by the tons of reports from this checker, it is acceptable that even fatal bug would be ignored. Then for Coverity, I would suggest to detail each checker to do one thing and only one thing or rank the severity level under this checker.
Moving forward, I am thinking if there is a kind of meta language or model to describe different kind of defect to make static code analysis much more flex and accurate. More over, users should feel easy to write the model for their certain cases…
Posted in Programming, Static Code Analysis, Stuff about Compiler
Tagged Coverity, longlong, printf, segv
3 Comments
Let’s play guitar – video with the Band:)
The Band (Alcatel-Lucent R&D Qingdao Band) recently got some shows both for wireless and wireline departments. Below comes a pic of me and 2 videos of the band. Enjoy:)
(pic took by Maggie Mai for the 2nd Wireless Pace Day, Hotel Sophia, Qingdao, Nov 2011)
Im_yours_the_Band (Download ‘I’m yours’ covered by Jason Mraz)
(‘I’m yours’ – video’d by Tim Ren for Wireline department, Qingdao R&D TR1, Dec 2011)
Hotel_California_the_Band (Download ‘Hotel California’ covered by the Eagles)
(‘Hotel California’ – video’d by Tim Ren for Wireline department, Qingdao R&D TR1, Dec 2011)
Uninit structure member – Uninit checking and static code analysis
A recent software bug caused a serious data damage in our customer’s side, which is using an uninit sturcture member. This post gives a practical comparison between kinds of static code analysis tools for this specific bug among popular commerical tools and open source tools. This post does NOT try to tell which tool is better but only for information. On the other hand, this ‘stupid’ bug may be a good start to begin with real static code analysis…
/* daveti_uninit1.c - BUG */ typedef struct s { int a; int b; }S; int test(S *y) { y->b=0; return 0; /* member a has never been used or init'd */ } int main() { int w=0; S x; int ret; ret=test(&x); /* pass the address of structure x to function test */ w=x.a; /* now use the uninit structure member a */ return 0; } /* daveti_uninit2.c - BUG */ typedef struct s { int a; int b; }S; int test(S *y, int k) { if (k==0) { y->b=0; y->a=0; /* y.a is only init'd when k is 0 */ return 0; } if (k==1) { y->b=0; return 0; /* y.a has never been used or init'd */ } return 0; } int main() { int w=0; S x; int ret; ret=test(&x, 1); /* pass the address of structure x to function test */ w=x.a; /* use the uninit structure member a */ return 0; } /* daveti_uninit3.c - GOOD */ typedef struct s { int a; int b; }S; int test(S *y, int k) { if (k==0) { y->b=0; y->a=0; return 0; } else { y->b=0; y->a=1; return 0; } } int main() { int w=0; S x; int ret; ret=test(&x, 1); /* pass the address of structure x to function test */ w=x.a; return 0; }
| Tools / daveti_uninitX.c | daveti_uninit1.c (bug) | daveti_uninit2.c (bug) | daveti_uninit3.c (good) |
| gcc –Wall (4.1.2) | No | No | No |
| Klocwork Insight 9.2 | Yes | No | N/A |
| Coverity 5.5.1 | Yes | Yes | No |
| CppCheck 1.47 | No | No | No |
| Splint 3.1.1 | Warning when passing x to func | Warning when passing x to func | Warning when passing x to func |
| Uno 2.13 | No | No | No |
For this speical case, well, Coverity explains the reason why it is the top 1 in static code analysis in commercial products. However, as the bug has been reported to Klocwork, it should have no problem in future release. Meanwhile, as gcc is a pure compiler which apparently does not focus on code analysis, it may not be a surprise to get such a result; CppCheck/Splint/Uno, on the other hand, show nothing to help because of internal limitation. Another 2 open source tools maybe worth a try are mygcc and saturn. If you have any thoughts, please leave me a commemt:)
Posted in Static Code Analysis
Tagged Coverity, cppcheck, gcc, Klocwork, splint, Static Code Analysis, uninit, uno
Leave a comment
kill all – killing all the process of certain user under Solaris
This is a quick post on kill based on the trial and discussion when David, Daniel and myself were trying to kill all the abnormal process of Daniel under a Solaris 8 Ultra-80 server. The most tough thing was the evil father would fork his evil child, who would fork his own evil son very soon, and then evil’s evil’s evil’s…into a never-gonna-stop evil forking recursion, which would exhaust the resource of this machine. Currently, only item 1 could counterstrike the recursive evil forking case mentioned above. Though some other traditional SHELL ways are listed as well, none of them would work for this case but only for static case.
1.
kill -9 -1
2.
kill `ps -fu user_name | awk ‘NR != 1 {print $2}’`
3.
pkill -U user_name
4.
killall process_name (Linux)
5.
kill -9 `ps -ef | grep process_name | grep -v grep | awk ‘{print $2}’`
Guitar – My new personal designed Telecaster “daveti”, Orange and Song “Near Side”
Aha, after almost 1 month’s wating, I’ve got my ‘Green’ now – a personal designed Telecaster guitar with my personal logo “daveti” on the head. ‘Green’ right now is my 3rd guitar after ‘White”(Squier Strat) and ‘Black'(Jackson). The other new member of my ‘family’ is ‘Orange’ – Crush 20LDX sound box. Below are some pics of my ‘family’, as well as a cover version of a folk song from Lifeng Zhong (钟立风-在路旁). Enjoy:)
Pics from left to right, row by row, are 'Green', 'Green's "daveti" logo, 'Orange' and the 'Family'. Name: Near side of the road Originated: Lifeng Zhong Tune: A Date: Oct 27, 2011 Rhythm: daveti Vocal: daveti Solo: daveti Synthesize: daveti Equipment: Telecaster "daveti", Orange Crush 20LDX, Internal mac of ThinkPad T61 Software: Java Sound Demo, Winamp 5.2 Tab: A-Cm-D-A, A-Cm-D-E Try this cover version of folk song...[audio:http://daveti.blog.com/files/2011/10/Rhythm_Vocal_20111027.mp3|titles=Rhythm_Vocal_20111027]









