Subject: Re: Hooray!
To: David Brownlee <abs@NetBSD.org>
From: Rhialto <rhialto@falu.nl>
List: port-vax
Date: 05/03/2007 01:17:19
Indeed it was late at the time of my previous research, but now it is a
bit less late.

On Wed 02 May 2007 at 00:24:36 +0100, David Brownlee wrote:
> 	Just nfs export the src dir and mount it by hand before
> 	running gdb :)

Of course, I blame the hour for not thinking of that. (I'll use the same
excuse for the rest ;-)

> 	Some random thoughts:
> 	 - Presumably printf of sizeof sblk.buf, sizeof sblk, and
> 	   SBLOCKSIZE all indicate the same value?

Yes, and SBLOCK_UFS1 too (but that is a coincidence).

SBLOCKSIZE=8192, sizeof(sblk)=8192, sizeof(sblk.buf)=8192, SBLOCK_UFS1=8192

> 	 - Does adding char pad[1024]; between sblk and fs hide
> 	   the problem?

Apparently not.

> 	 - Could there be an issue with pread() on VAX.  Could try
> 	   replacing the pread() with an lseek() and read()

I did that next. Strangely enough it makes no difference?

Breakpoint 1, fixsb (prog=0x420e0 "/sbin/fsck_ffs", disk=0x3e4c8 "sd0", 
    ptn=97 'a', 270560, 255176, 97) installation      x
    at /vol1/rhialto/cvs/src/distrib/utils/sysinst/arch/vax/../../disks.c:605
605             struct fs *fs = &sblk.fs;
(gdb) n
607             memset(pad, '*', sizeof(pad));
(gdb) 
609             fprintf(stderr, "SBLOCKSIZE=%ld, sizeof(sblk)=%ld, sizeof(sblk.buf)=%ld, SBLOCK_UFS1=%ld\n", SBLOCKSIZE, sizeof(sblk), sizeof(sblk.buf), SBLOCK_UFS1);
(gdb) n
SBLOCKSIZE=8192, sizeof(sblk)=8192, sizeof(sblk.buf)=8192, SBLOCK_UFS1=8192
611             snprintf(sblk.buf, sizeof(sblk.buf), "/dev/r%s%c",
(gdb) 
613             fd = open(sblk.buf, O_RDONLY);
(gdb) 
614             if (fd == -1)
(gdb) print fs
$8 = (struct fs *) 0x7fffca28
(gdb) n
621             lseek(fd, SBLOCK_UFS1, SEEK_SET);
(gdb) print fs
$9 = (struct fs *) 0x7fffca28
(gdb) n
622             rval = read(fd, sblk.buf, sizeof sblk.buf);
(gdb) print fs
$10 = (struct fs *) 0x7fffca28
(gdb) n
624             close(fd);
(gdb) print fs
$11 = (struct fs *) 0x0
(gdb) 

So I put the pad[] array on the other side of sblk and now we see proof of
buffer overflow:

    char pad[8192];
    union {
	struct fs fs;
	char buf[SBLOCKSIZE];
    } sblk;
    struct fs *fs = &sblk.fs;


Breakpoint 1, fixsb (prog=0x420e0 "/sbin/fsck_ffs", disk=0x3e4c8 "sd0", 
    ptn=97 'a', 270560, 255176, 97) installation      x
    at /vol1/rhialto/cvs/src/distrib/utils/sysinst/arch/vax/../../disks.c:605
605             struct fs *fs = &sblk.fs;
(gdb) n
607             memset(pad, '*', sizeof(pad));
(gdb) 
609             fprintf(stderr, "SBLOCKSIZE=%ld, sizeof(sblk)=%ld, sizeof(sblk.buf)=%ld, SBLOCK_UFS1=%ld\n", SBLOCKSIZE, sizeof(sblk), sizeof(sblk.buf), SBLOCK_UFS1);
(gdb) 
SBLOCKSIZE=8192, sizeof(sblk)=8192, sizeof(sblk.buf)=8192, SBLOCK_UFS1=8192
611             snprintf(sblk.buf, sizeof(sblk.buf), "/dev/r%s%c",
(gdb) 
613             fd = open(sblk.buf, O_RDONLY);
(gdb) print pad
$1 = '*' <repeats 8192 times>
(gdb) print fs
$2 = (struct fs *) 0x7fffaa28
(gdb) n
614             if (fd == -1)
(gdb) 
621             lseek(fd, SBLOCK_UFS1, SEEK_SET);
(gdb) 
622             rval = read(fd, sblk.buf, sizeof sblk.buf);
(gdb) print fs pad
A syntax error in expression, near `pad'.
(gdb) print fs, pad
$3 = '*' <repeats 8192 times>
(gdb) print fs     
$4 = (struct fs *) 0x7fffaa28
(gdb) n
624             close(fd);
(gdb) print fs
$5 = (struct fs *) 0x7fffaa28
(gdb) print pad
$6 = '\0' <repeats 1496 times>, '*' <repeats 6696 times>
(gdb) 

So read(2) reads 1496 extra 0 bytes?!? That seems sooo unlikely...
Lots more would break if this were always so. And the generated code for
fixsb() looks ok... (I realised that the clrf is likely because a file
position is a 64-bit argument, although a clrl would seem to be more
logical)

(gdb) disas fixsb
Dump of assembler code for function fixsb:
0x0001c0c2 <fixsb+2>:   movab 0xffffbfe8(sp),sp
0x0001c0c7 <fixsb+7>:   movl 0xc(ap),r0
0x0001c0cb <fixsb+11>:  movb r0,0xffffbfec(fp)
0x0001c0d0 <fixsb+16>:  movab 0xffffbff0(fp),0xfffffff8(fp)
0x0001c0d6 <fixsb+22>:  movzwl $0x2000,-(sp)
0x0001c0db <fixsb+27>:  pushl $0x2a
0x0001c0dd <fixsb+29>:  movab 0xffffdff0(fp),r0
0x0001c0e2 <fixsb+34>:  pushl r0
0x0001c0e4 <fixsb+36>:  calls $0x3,*0x38ec4 <_GLOBAL_OFFSET_TABLE_+480> memset
0x0001c0eb <fixsb+43>:  movab *0x39054 <_GLOBAL_OFFSET_TABLE_+880>,r0
0x0001c0f2 <fixsb+50>:  movab 0xb0(r0),r0
0x0001c0f7 <fixsb+55>:  movzwl $0x2000,-(sp)
0x0001c0fc <fixsb+60>:  movzwl $0x2000,-(sp)
0x0001c101 <fixsb+65>:  movzwl $0x2000,-(sp)
0x0001c106 <fixsb+70>:  movzwl $0x2000,-(sp)
0x0001c10b <fixsb+75>:  pushab 0x27f62 <_fini+22474>
0x0001c111 <fixsb+81>:  pushl r0
0x0001c113 <fixsb+83>:  calls $0x6,*0x38e0c <_GLOBAL_OFFSET_TABLE_+296> fprintf
0x0001c11a <fixsb+90>:  cmpb 0xffffbfec(fp),$0x20
0x0001c11f <fixsb+95>:  beql 0x1c12a <fixsb+106>
0x0001c121 <fixsb+97>:  cvtbl 0xffffbfec(fp),0xffffbfe8(fp)
0x0001c128 <fixsb+104>: brb 0x1c12e <fixsb+110>
0x0001c12a <fixsb+106>: clrf 0xffffbfe8(fp)

0x0001c12e <fixsb+110>: pushl 0xffffbfe8(fp)
0x0001c132 <fixsb+114>: pushl 0x8(ap)
0x0001c135 <fixsb+117>: pushab 0x27fab <_fini+22547>
0x0001c13b <fixsb+123>: movzwl $0x2000,-(sp)
0x0001c140 <fixsb+128>: movab 0xffffbff0(fp),r0
0x0001c145 <fixsb+133>: pushl r0
0x0001c147 <fixsb+135>: calls $0x5,*0x38d24 <_GLOBAL_OFFSET_TABLE_+64> snprintf
0x0001c14e <fixsb+142>: clrf -(sp)
0x0001c150 <fixsb+144>: movab 0xffffbff0(fp),r0
0x0001c155 <fixsb+149>: pushl r0
0x0001c157 <fixsb+151>: calls $0x2,*0x38f5c <_GLOBAL_OFFSET_TABLE_+632> open
0x0001c15e <fixsb+158>: movl r0,0xfffffff0(fp)

0x0001c162 <fixsb+162>: cmpl 0xfffffff0(fp),$0xffffffff
0x0001c16a <fixsb+170>: bneq 0x1c16f <fixsb+175>
0x0001c16c <fixsb+172>: brw 0x1c236 <fixsb+374>

0x0001c16f <fixsb+175>: clrf -(sp)
0x0001c171 <fixsb+177>: clrf -(sp)
0x0001c173 <fixsb+179>: movzwl $0x2000,-(sp)
0x0001c178 <fixsb+184>: pushl 0xfffffff0(fp)
0x0001c17b <fixsb+187>: calls $0x4,*0x38dbc <_GLOBAL_OFFSET_TABLE_+216> lseek

0x0001c182 <fixsb+194>: movzwl $0x2000,-(sp)
0x0001c187 <fixsb+199>: movab 0xffffbff0(fp),r0
0x0001c18c <fixsb+204>: pushl r0
0x0001c18e <fixsb+206>: pushl 0xfffffff0(fp)
0x0001c191 <fixsb+209>: calls $0x3,*0x38e58 <_GLOBAL_OFFSET_TABLE_+372> read
0x0001c198 <fixsb+216>: movl r0,0xfffffff4(fp)

0x0001c19c <fixsb+220>: pushl 0xfffffff0(fp)
0x0001c19f <fixsb+223>: calls $0x1,*0x38f9c <_GLOBAL_OFFSET_TABLE_+696> close

0x0001c1a6 <fixsb+230>: cmpl 0xfffffff4(fp),$0x00002000
0x0001c1ae <fixsb+238>: beql 0x1c1b3 <fixsb+243>
0x0001c1b0 <fixsb+240>: brw 0x1c236 <fixsb+374>
0x0001c1b3 <fixsb+243>: movl 0xfffffff8(fp),r0
0x0001c1b7 <fixsb+247>: movl 0x55c(r0),r0
0x0001c1bc <fixsb+252>: cmpl r0,$0x00011954
0x0001c1c3 <fixsb+259>: beql 0x1c1d7 <fixsb+279>
0x0001c1c5 <fixsb+261>: movl 0xfffffff8(fp),r0
0x0001c1c9 <fixsb+265>: movl 0x55c(r0),r0
0x0001c1ce <fixsb+270>: cmpl r0,$0x54190100
0x0001c1d5 <fixsb+277>: bneq 0x1c236 <fixsb+374>
0x0001c1d7 <fixsb+279>: movl 0xfffffff8(fp),r0
0x0001c1db <fixsb+283>: movb 0xd3(r0),r0
0x0001c1e0 <fixsb+288>: tstb r0
0x0001c1e2 <fixsb+290>: blss 0x1c236 <fixsb+374>
0x0001c1e4 <fixsb+292>: movl 0xfffffff8(fp),r0
0x0001c1e8 <fixsb+296>: movl 0x30(r0),r1
0x0001c1ec <fixsb+300>: movl 0xfffffff8(fp),r0
0x0001c1f0 <fixsb+304>: movl 0x35c(r0),r0
0x0001c1f5 <fixsb+309>: cmpl r1,r0
0x0001c1f8 <fixsb+312>: bneq 0x1c236 <fixsb+374>
0x0001c1fa <fixsb+314>: cvtbl 0xffffbfec(fp),r0
0x0001c1ff <fixsb+319>: pushl r0
0x0001c201 <fixsb+321>: pushl 0x8(ap)
0x0001c204 <fixsb+324>: pushl 0x4(ap)
0x0001c207 <fixsb+327>: pushab 0x27fb6 <_fini+22558>
0x0001c20d <fixsb+333>: movzbl $0x81,-(sp)
0x0001c211 <fixsb+337>: calls $0x5,0x19374 <run_program>
0x0001c218 <fixsb+344>: cvtbl 0xffffbfec(fp),r0
0x0001c21d <fixsb+349>: pushl r0
0x0001c21f <fixsb+351>: pushl 0x8(ap)
0x0001c222 <fixsb+354>: pushl 0x4(ap)
0x0001c225 <fixsb+357>: pushab 0x27fd2 <_fini+22586>
0x0001c22b <fixsb+363>: movzbl $0x81,-(sp)
0x0001c22f <fixsb+367>: calls $0x5,0x19374 <run_program>
0x0001c236 <fixsb+374>: ret
End of assembler dump.

Anyway, it's late again...

> 		David/absolute       -- www.NetBSD.org: No hype required --
-Olaf.
-- 
___ Olaf 'Rhialto' Seibert      -- You author it, and I'll reader it.
\X/ rhialto/at/xs4all.nl        -- Cetero censeo "authored" delendum esse.