OSDev.org
https://forum.osdev.org/

[Solved] Finding offset to write to read() buffer
https://forum.osdev.org/viewtopic.php?f=1&t=31407
Page 1 of 1

Author:  codyd51 [ Thu Mar 09, 2017 12:18 am ]
Post subject:  [Solved] Finding offset to write to read() buffer

Hi!

I've ported newlib to my OS, but am having some issues with read() and getchar(). If I call read() with a buffer on the stack, everything works as expected and I can write to the buffer from the kernel without needing to modify the address at all.

However, if I attempt to call getchar() through newlib, then I see a read() syscall being made with something like the following parameters: read(0, 0x10, 1024). So, read is asking to write to a buffer really low in memory. Am I supposed to be doing something to this address before writing to it? Is this address supposed to be an offset into .bss, or some other segment? If it is an offset into a segment, how am I to differentiate between when the kernel is being given a buffer on the stack (which requires no translation) vs. an offset into a segment (which does require translation)?

Just to demonstrate, here's a screenshot of output when using newlib's getchar() in a loaded ELF. You'll also notice some garbage characters being printed, which is strange considering the ELF loader zeroes-out the .bss segment, and sbrk does the same to any memory it gives it. That's another thing I'm still trying to figure out. http://imgur.com/gallery/wmUKS

Any tips or ideas are appreciated, thanks!

Author:  Velko [ Thu Mar 09, 2017 12:51 am ]
Post subject:  Re: Finding offset to write to read() buffer

Quote:
Am I supposed to be doing something to this address before writing to it?

No. You just fill memory at this address, no translation of any kind. You should, however, validate
if it points to sane location (and refuse to proceed in this particular case).

Newlib allocates buffer(s) in heap for stdio routines. Check if your sbrk() and malloc() works as expected.

Author:  codyd51 [ Thu Mar 09, 2017 11:37 am ]
Post subject:  Re: Finding offset to write to read() buffer

Velko wrote:
Quote:
Am I supposed to be doing something to this address before writing to it?

No. You just fill memory at this address, no translation of any kind. You should, however, validate
if it points to sane location (and refuse to proceed in this particular case).

Newlib allocates buffer(s) in heap for stdio routines. Check if your sbrk() and malloc() works as expected.


Gotcha, thanks for clearing that up! I tried a malloc() with newlib, and, as expected, got a very low address in memory (0x10). Trying getchar() again gives read() a buffer around 0x410. What I don't understand is why these addresses are so low, when sbrk() gives addresses above 0x8050000. Also, when I attempt to write to this buffer without translation, I still get garbled memory on the ELF-side.

Author:  codyd51 [ Thu Mar 09, 2017 11:40 am ]
Post subject:  Re: Finding offset to write to read() buffer

Ah, I just logged sbrk on the elf-side and realized that it's not returning the correct values to the program. I think my syscall handler might be trashing eax after running the syscall function. I'll fix my syscalls to make sure they're returning values as expected and try again. Thanks for your help!

Author:  codyd51 [ Thu Mar 09, 2017 1:15 pm ]
Post subject:  Re: Finding offset to write to read() buffer

Okay, syscalls are now returning values properly. If I read() into a buffer myself and print it out, everything works as expected, However, if I attempt to use getchar(), EOF is returned. Why would this be?

Author:  lkurusa [ Thu Mar 09, 2017 3:18 pm ]
Post subject:  Re: Finding offset to write to read() buffer

Hi,

Is your read system call working properly as expected? In newlib, can you trace what your kernel passes? Maybe it gets zero'd somewhere?

Lastly, do you get EOF as well when you are issuing a read system call?

Author:  codyd51 [ Thu Mar 09, 2017 9:15 pm ]
Post subject:  Re: Finding offset to write to read() buffer

lev wrote:
Hi,

Is your read system call working properly as expected? In newlib, can you trace what your kernel passes? Maybe it gets zero'd somewhere?

Lastly, do you get EOF as well when you are issuing a read system call?



As a matter of fact, yes. If I call read() manually from an ELF, everything works fine. It's only when I try to use newlib's getchar. It seems newlib's sprintf is also borked, which may or may not be a related issue.

No. My current read implementation, for testing purposes, never gives EOF.

Author:  Velko [ Fri Mar 10, 2017 12:55 am ]
Post subject:  Re: Finding offset to write to read() buffer

Return value of read() syscall?

Author:  Solar [ Fri Mar 10, 2017 3:49 am ]
Post subject:  Re: Finding offset to write to read() buffer

Do your OS and newlib agree on what stdin is? This looks like newlib taking its buffer address from some uninitialized structure...?!?

(No idea about newlib's internals, I am just guessing here.)

Author:  codyd51 [ Fri Mar 10, 2017 11:04 pm ]
Post subject:  Re: Finding offset to write to read() buffer

Velko wrote:
Return value of read() syscall?


Thank you!! This was the issue. I appreciate you pointing me in the right direction!

The exact problem was this syscall stub in newlib:

Code:
int read(int fd, char* buf, int count) {
    sys_read(fd, buf, count);
    return 0;
}


For some stupid reason I wasn't returning sys_read's return value. So, the buffer was filled correctly, which is why when calling read() myself the buffer was filled as expected, but the caller is told that no characters were read, which is why getchar() returned EOF.

Thanks for the help, everyone!

Page 1 of 1 All times are UTC - 6 hours
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/