Understanding the behavior of the 32 bit mmap system call

Paul Procacci pprocacci at gmail.com
Tue Jul 20 20:23:26 UTC 2021


On Tue, Jul 20, 2021 at 10:45 AM Rdbo <rdbodev at gmail.com> wrote:

> Hi, I'm a hobbyist developer working on a multiplatform, multiarch memory
> library, and I chose FreeBSD to be one of the supported operating systems.
> I was playing around with the SYS_mmap system call and I noticed that, for
> x86_32, you have to pass a struct containing all the mmap arguments, rather
> than the arguments themselves. The thing is, this structure is not passed
> as a pointer (like on Linux, for example), so I don't see how one would do
> this syscall from a remote process, as each register is responsible for one
> argument of the syscall, and a single register can't store a structure this
> size. I've tried passing the structure as a pointer, passing each mmap
> argument in a separate register (like __NR_mmap2 on Linux), looking for
> alternative mmap system calls that do not require the struct parameter.
> Unfortunately, these attempts have all failed.
> TLDR; how to run a 32 bit SYS_mmap system call from a remote process when a
> single register can't fit the whole structure and the structure is not
> passed as a pointer?
> Regards, rdbo
> _______________________________________________
> freebsd-questions at freebsd.org mailing list
> https://lists.freebsd.org/mailman/listinfo/freebsd-questions
> To unsubscribe, send any mail to "
> freebsd-questions-unsubscribe at freebsd.org"
>

The calling conventions for arguments on 32 bit FreeBSD is to pass those
arguments on the stack.[1]
I've whipped up the following for you.  I couldn't test it because I don't
have a 32 bit environment to
test on, but it should hopefully give you some insight.

bits 32
> default rel
>
> %define SYS_exit 1
> %define SYS_mmap 477
>
> %define PROT_READ  0x01
> %define PROT_WRITE 0x02
>
> %define MAP_FILE    0x0000
> %define MAP_PRIVATE 0x0002
>
> global _start:function
>
> section .text
>
>         _start:
>                 push    ebp
>                 mov     ebp, esp
>
>                 sub     esp, 24
>
> xor edi, edi
>                 mov     dword [ebp - 4], -1                             ;
> fd
>                 mov     dword [ebp - 12], MAP_FILE  | MAP_PRIVATE       ;
> flags
>                 mov     dword [ebp - 16], PROT_READ | PROT_WRITE        ;
> prot
>                 mov     dword [ebp - 20], 55                            ;
> size
>                 mov     dword [ebp - 24], 0                             ;
> addr
>                 push    0
>                 mov     eax, SYS_mmap
>                 int     80h
>                 add     esp, 24
>
>                 xor     edi, edi
>                 mov     eax, SYS_exit
>                 int     80h



I don't know what you mean by remote process.

~Paul Procacci

[1] Passing arguments via registers is for 64-bit only.

-- 
__________________

:(){ :|:& };:


More information about the freebsd-questions mailing list