Question about local variables and paging...

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
ajforgue
Posts: 3
Joined: Wed Jan 10, 2007 5:03 pm

Question about local variables and paging...

Post by ajforgue »

I didn't think this would be an issue, but I have a local variable in some function called buffer:

Code: Select all

char buffer[8] = {0xd,0xe,0xa,0xd,0xb,0xe,0xe,0xf};
The deadbeef is there for a memory dump.

This buffer variable is in a static member function in a class (C++ Kernel). Usually this function works fine. But after I enable my own paging that maps only what I need (the kernel intially starts with 4MB identity mapped) like video memory, kernel pages, and the free page stack, calling this function page faults. If I remove that local variable, it's fine. When I check the bochs log, I get this:

Code: Select all

00016288115-@c0100b47-[CPU  ]: page fault for address 00000014 @ c0100b47
00016288115-@c0100b47-[CPU  ]: exception(0x0E)
00016288115-@c0100b41-[CPU  ]: interrupt(): vector = 14, INT = 0, EXT = 1
00016288115-@c0100b41-[CPU  ]: page fault for address 00000070 @ c0100b41
00016288115-@c0100b41-[CPU  ]: exception(0x0E)
00016288115-@c0100b41-[CPU  ]: interrupt(): vector = 8, INT = 0, EXT = 1
00016288115-@c0100b41-[CPU  ]: page fault for address 00000040 @ c0100b41
00016288115-@c0100b41-[CPU  ]: exception(0x0E)
00016288115-@c0100b41-[CPU  ]: protected mode
00016288115-@c0100b41-[CPU  ]: CS.d_b = 32 bit
00016288115-@c0100b41-[CPU  ]: SS.d_b = 32 bit
00016288115-@c0100b41-[CPU  ]: | EAX=00000030  EBX=00002000  ECX=00109000  EDX=00000001
00016288115-@c0100b41-[CPU  ]: | ESP=c0107f98  EBP=00067ee4  ESI=000544c1  EDI=000544c2
00016288115-@c0100b41-[CPU  ]: | IOPL=0 id vip vif ac vm RF nt of df if tf SF zf AF pf cf
00016288115-@c0100b41-[CPU  ]: | SEG selector     base    limit G D
00016288115-@c0100b41-[CPU  ]: | SEG sltr(index|ti|rpl)     base    limit G D
00016288115-@c0100b41-[CPU  ]: |  CS:0008( 0001| 0|  0) 00000000 000fffff 1 1
00016288115-@c0100b41-[CPU  ]: |  DS:0010( 0002| 0|  0) 00000000 000fffff 1 1
00016288115-@c0100b41-[CPU  ]: |  SS:0010( 0002| 0|  0) 00000000 000fffff 1 1
00016288115-@c0100b41-[CPU  ]: |  ES:0010( 0002| 0|  0) 00000000 000fffff 1 1
00016288115-@c0100b41-[CPU  ]: |  FS:0010( 0002| 0|  0) 00000000 000fffff 1 1
00016288115-@c0100b41-[CPU  ]: |  GS:0010( 0002| 0|  0) 00000000 000fffff 1 1
00016288115-@c0100b41-[CPU  ]: | EIP=c0100b41 (c0100b41)
00016288115-@c0100b41-[CPU  ]: | CR0=0x80000011 CR1=0 CR2=0x00000040
00016288115-@c0100b41-[CPU  ]: | CR3=0x00109000 CR4=0x00000010
00016288115-@c0100b41-[CPU  ]: >> mov eax, dword ptr gs:0x14 : 65A114000000
The code disassembly is here (mixed with source):

Code: Select all

   char Convert::Blah(char x, char y)
c0100b2e:   83 ec 1c                sub    esp,0x1c
c0100b31:   8b 44 24 20             mov    eax,DWORD PTR [esp+32]
c0100b35:   8b 54 24 24             mov    edx,DWORD PTR [esp+36]
c0100b39:   88 44 24 08             mov    BYTE PTR [esp+8],al
c0100b3d:   88 54 24 04             mov    BYTE PTR [esp+4],dl
c0100b41:   65 a1 14 00 00 00       mov    eax,gs:0x14
c0100b47:   89 44 24 18             mov    DWORD PTR [esp+24],eax
c0100b4b:   31 c0                   xor    eax,eax
   {
      char buffer[8] = {0xd,0xe,0xa,0xd,0xb,0xe,0xe,0xf};
c0100b4d:   c6 44 24 10 0d          mov    BYTE PTR [esp+16],0xd
c0100b52:   c6 44 24 11 0e          mov    BYTE PTR [esp+17],0xe
c0100b57:   c6 44 24 12 0a          mov    BYTE PTR [esp+18],0xa
c0100b5c:   c6 44 24 13 0d          mov    BYTE PTR [esp+19],0xd
c0100b61:   c6 44 24 14 0b          mov    BYTE PTR [esp+20],0xb
c0100b66:   c6 44 24 15 0e          mov    BYTE PTR [esp+21],0xe
c0100b6b:   c6 44 24 16 0e          mov    BYTE PTR [esp+22],0xe
c0100b70:   c6 44 24 17 0f          mov    BYTE PTR [esp+23],0xf
      return (x+y) & 0x7F;
c0100b75:   0f b6 54 24 08          movzx  edx,BYTE PTR [esp+8]
c0100b7a:   0f b6 44 24 04          movzx  eax,BYTE PTR [esp+4]
c0100b7f:   8d 04 02                lea    eax,[edx+eax]
c0100b82:   0f be c0                movsx  eax,al
c0100b85:   83 e0 7f                and    eax,0x7f
   }
c0100b88:   8b 54 24 18             mov    edx,DWORD PTR [esp+24]
c0100b8c:   65 33 15 14 00 00 00    xor    edx,DWORD PTR gs:0x14
c0100b93:   74 05                   je     c0100b9a <ForgueOS::Convert::Blah(char, char)+0x6c>
c0100b95:   e8 dc f5 ff ff          call   c0100176 <__stack_chk_fail>
c0100b9a:   83 c4 1c                add    esp,0x1c
c0100b9d:   c3                      ret
I have no idea why it'd try to load eax with gs:0x14.

Perhaps something with my linker script?...

I really have no idea what could be causing this or what. I've been hacking on this for a few days now and it's driving me insane, any help is appreciated.
smbogan
Member
Member
Posts: 29
Joined: Tue Nov 21, 2006 3:17 pm

Post by smbogan »

I'm just curious but why are your segment limits only 0xfffff? instead of 0xffffffff? Your point was to have your kernel access all memory right? And is your DX correct at the start of memory + 1?
Jules
Member
Member
Posts: 30
Joined: Mon Jan 08, 2007 3:19 am
Location: UK

Post by Jules »

How are you compiling? If memory serves, gcc uses the GS register to point to a thread-local information block for getting access to thread local variables (among other things). From my reading of the spec, I think %gs:14 would point to a thread-local variable of some kind.

I think the key to understanding this behaviour is in tracking what it does with the value:


mov eax,gs:0x14
mov DWORD PTR [esp+24],eax
[...]
mov edx,DWORD PTR [esp+24]
xor edx,DWORD PTR gs:0x14
[... do something else if the result is zero, i.e. the value is unchanged]
call c0100176 <__stack_chk_fail>

Are you compiling with some kind of stack canary system?
ajforgue
Posts: 3
Joined: Wed Jan 10, 2007 5:03 pm

Post by ajforgue »

Thanks guys, both of your comments needed fixing. The canary system was the cause, and compiling with -fno-stack-protector in GCC fixed the problem. Is that just band-aiding the problem or is it a side effect from enabling paging that breaks the canary system?
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Post by Candy »

ajforgue wrote:Thanks guys, both of your comments needed fixing. The canary system was the cause, and compiling with -fno-stack-protector in GCC fixed the problem. Is that just band-aiding the problem or is it a side effect from enabling paging that breaks the canary system?
Since when does GCC include a canary by default?
ajforgue
Posts: 3
Joined: Wed Jan 10, 2007 5:03 pm

Post by ajforgue »

Ubuntu does by default
Implementation: Implemented
Release goal: Accepted for edgy
User avatar
Brynet-Inc
Member
Member
Posts: 2426
Joined: Tue Oct 17, 2006 9:29 pm
Libera.chat IRC: brynet
Location: Canada
Contact:

Post by Brynet-Inc »

OpenBSD Also includes ProPolice default..

http://en.wikipedia.org/wiki/Stack-smas ... oPolice.29
Image
Twitter: @canadianbryan. Award by smcerm, I stole it. Original was larger.
Post Reply