Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.compilers > #987 > unrolled thread
| Started by | "news" <news@fx32.iad.highwinds-media.com> |
|---|---|
| First post | 2013-10-12 00:05 +0000 |
| Last post | 2013-10-13 10:44 +0200 |
| Articles | 7 — 7 participants |
Back to article view | Back to comp.compilers
Executing from dynamically allocated memory "news" <news@fx32.iad.highwinds-media.com> - 2013-10-12 00:05 +0000
Re: Executing from dynamically allocated memory "James Harris" <james.harris.1@gmail.com> - 2013-10-12 10:10 +0100
Re: Executing from dynamically allocated memory Sébastien Fricker <sebastien.fricker@gmail.com> - 2013-10-12 11:52 +0200
Re: Executing from dynamically allocated memory chakaram@auth.gr - 2013-10-12 19:20 +0300
Re: Executing from dynamically allocated memory Alex McDonald <blog@rivadpm.com> - 2013-10-12 11:12 -0700
Re: Executing from dynamically allocated memory sandmann@cs.au.dk (Søren Sandmann) - 2013-10-12 20:58 +0200
Re: Executing from dynamically allocated memory Jens Kallup <jkallup@web.de> - 2013-10-13 10:44 +0200
| From | "news" <news@fx32.iad.highwinds-media.com> |
|---|---|
| Date | 2013-10-12 00:05 +0000 |
| Subject | Executing from dynamically allocated memory |
| Message-ID | <13-10-004@comp.compilers> |
In the past, I've malloc'd memory, written machine instructions into it, and called the function I built there. All this on a 32-bit intel instruction set, on a Debian system. This appears no longer too work. My program gives a segmentation fault. The debugger tells me that the segmentation fault occurs on the first instruction of the called function, a push %ebp residing in malloced memory. Now it was a year or three ago that this worked. Has Linux changed in this respect? Is there something new I have to do to allocate executable writable memory for this purpose? Or might there be something even weirder going on? -- hendrik [ Sounds like the NX bit. See http://en.wikipedia.org/wiki/NX_bit#Linux -John]
[toc] | [next] | [standalone]
| From | "James Harris" <james.harris.1@gmail.com> |
|---|---|
| Date | 2013-10-12 10:10 +0100 |
| Message-ID | <13-10-005@comp.compilers> |
| In reply to | #987 |
"news" <news@fx32.iad.highwinds-media.com> wrote in message > In the past, I've malloc'd memory, written machine instructions into it, > and called the function I built there. > > All this on a 32-bit intel instruction set, on a Debian system. > > This appears no longer too work. My program gives a segmentation fault. > The debugger tells me that the segmentation fault occurs on the first > instruction of the called function, a > push %ebp > residing in malloced memory. > > Now it was a year or three ago that this worked. Has Linux changed in > this respect? Is there something new I have to do to allocate executable > writable memory for this purpose? Possibly. As John says, this could be caused by current Linux setting the NX bit for malloced pages. The dump may/should show if that is the case, if you can decipher the dump. Instead of malloc you may need to use mmap. It allows permissions to be specified. James
[toc] | [prev] | [next] | [standalone]
| From | Sébastien Fricker <sebastien.fricker@gmail.com> |
|---|---|
| Date | 2013-10-12 11:52 +0200 |
| Message-ID | <13-10-006@comp.compilers> |
| In reply to | #987 |
On 12.10.13 02:05, news wrote: > In the past, I've malloc'd memory, written machine instructions into it, > and called the function I built there. ... > Now it was a year or three ago that this worked. Has Linux changed in > this respect? Is there something new I have to do to allocate executable > writable memory for this purpose? > > Or might there be something even weirder going on? > > -- hendrik > > [ Sounds like the NX bit. See http://en.wikipedia.org/wiki/NX_bit#Linux -John] Hendrik, this does not wonder me that it does not work anymore. In 2003, I was working on the ARM-Linux kernel and I could see that more and more the MMU protection bit get used principally to avoid the possibility to misuse buffer-overflow. But did you have a look on mmap()? (man mmap) There is a flag PROT_EXEC. I guess this should permit to create a memory area on which you can execute code. SC)bastien
[toc] | [prev] | [next] | [standalone]
| From | chakaram@auth.gr |
|---|---|
| Date | 2013-10-12 19:20 +0300 |
| Message-ID | <13-10-007@comp.compilers> |
| In reply to | #987 |
As our moderator pointed out, sounds like NX. Use mmap() with PROT_READ|PROT_WRITE|PROT_EXEC or just PROT_WRITE and then mprotect() your region to PROT_READ|PROT_EXEC. If you're on an i386, then it's probably some kernel hardening patch that makes the heap non executable. ./ck -- Chariton Karamitas Electrical and Computer Engineering Department Fuculty of Engineering Aristotle University of Thessaloniki, Greece
[toc] | [prev] | [next] | [standalone]
| From | Alex McDonald <blog@rivadpm.com> |
|---|---|
| Date | 2013-10-12 11:12 -0700 |
| Message-ID | <13-10-008@comp.compilers> |
| In reply to | #987 |
On Saturday, 12 October 2013 01:05:39 UTC+1, news wrote: > In the past, I've malloc'd memory, written machine instructions into it, > and called the function I built there. > All this on a 32-bit intel instruction set, on a Debian system. ... > Now it was a year or three ago that this worked. Has Linux changed in > this respect? Is there something new I have to do to allocate executable > writable memory for this purpose? > > Or might there be something even weirder going on? > [ Sounds like the NX bit. See http://en.wikipedia.org/wiki/NX_bit#Linux -John] mprotect(2) - Linux man page Name mprotect - set protection on a region of memory Synopsis #include <sys/mman.h> int mprotect(void *addr, size_t len, int prot); Description mprotect() changes protection for the calling process's memory page(s) containing any part of the address range in the interval [addr, addr+len-1]. addr must be aligned to a page boundary. If the calling process tries to access memory in a manner that violates the protection, then the kernel generates a SIGSEGV signal for the process. prot is either PROT_NONE or a bitwise-or of the other values in the following list: ... PROT_EXEC The memory can be executed. ...
[toc] | [prev] | [next] | [standalone]
| From | sandmann@cs.au.dk (Søren Sandmann) |
|---|---|
| Date | 2013-10-12 20:58 +0200 |
| Message-ID | <13-10-009@comp.compilers> |
| In reply to | #987 |
"news" <news@fx32.iad.highwinds-media.com> writes:
> In the past, I've malloc'd memory, written machine instructions into it,
> and called the function I built there.
>
> All this on a 32-bit intel instruction set, on a Debian system.
>
> This appears no longer too work. My program gives a segmentation fault.
> The debugger tells me that the segmentation fault occurs on the first
> instruction of the called function, a
> push %ebp
> residing in malloced memory.
>
> Now it was a year or three ago that this worked. Has Linux changed in
> this respect? Is there something new I have to do to allocate executable
> writable memory for this purpose?
>
> Or might there be something even weirder going on?
It's probably just that anonymous memory is not executable by default
anymore. Take a look at this:
http://www.akkadia.org/drepper/selinux-mem.html
in particular the execmem case. There is also example code.
SC8ren
[toc] | [prev] | [next] | [standalone]
| From | Jens Kallup <jkallup@web.de> |
|---|---|
| Date | 2013-10-13 10:44 +0200 |
| Message-ID | <13-10-010@comp.compilers> |
| In reply to | #987 |
Hello,
this should be work:
#include <errno.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
extern int errno;
static volatile sig_atomic_t sflag;
static sigset_t signal_neu, signal_alt, signal_leer;
void sigfunc1(int);
void sigfunc2(int);
void signale_mmap(void)
{
if(signal(SIGSEGV, sigfunc1) == SIG_ERR)
{
fprintf(stderr, "Konnte signalhandler fC<r SIGSEGV nicht
einrichten\n");
exit(0);
}
if(signal(SIGBUS, sigfunc2) == SIG_ERR)
{
fprintf(stderr, "Konnte signalhandler fC<r SIGBUS nicht
einrichten\n");
exit(0);
}
sigemptyset(&signal_leer);
sigemptyset(&signal_neu);
sigaddset(&signal_neu, SIGSEGV);
sigaddset(&signal_neu, SIGBUS);
if(sigprocmask(SIG_BLOCK, &signal_neu, &signal_alt) < 0)
exit(0);
}
void sigfunc1(int sig)
{
printf("SIGSEGV: Versuch auf einen unerlaubten Speicherbereich zu
schreiben\n");
exit(0);
}
void sigfunc2(int sig)
{
printf("SIGBUS: Der Speicherbereich ist nicht mehr gC<ltig\n");
exit(0);
}
void fun1(int v)
{
printf("value --> 0x%x\n",v);
}
int main(int argc, char **argv)
{
int fd,fd1;
void (*callback1)(int);
printf("exit-> 0x%x\n",exit);
printf("puts-> 0x%x\n",puts);
printf("fun1-> 0x%x\n",fun1);
struct stat attr;
signale_mmap();
if((fd1=open(argv[1],O_RDONLY)) < 0)
{
fprintf(stderr,"%s : Konnte %s nicht
C6ffnen\n",strerror(errno),argv[2]);
exit(0);
}
if(fstat(fd1, &attr) == -1)
{
fprintf(stderr,"Fehler bei fstat.......\n");
exit(0);
}
callback1 = mmap(0, attr.st_size, PROT_READ | PROT_EXEC, MAP_SHARED,
fd1, 0);
printf("val: 0x%x\n",callback1);
if((callback1 == ((caddr_t) -1)) )
{
fprintf(stderr, "%s: Fehler bei mmap ...........\n",strerror(errno));
exit(0);
}
close(fd1);
printf("start...\n");
callback1((int)callback1);
printf("ende...\n");
exit(0);
}
// the following code is compiled with nasm 32 bit
bits 32
org 0x0
;-----------------------------------
; Version 1.0
;-----------------------------------
%define FuncPuts 1
%define FuncFun1 2
segment .text
start:
push ebp
mov ebp, esp
mov eax, [ebp + 8]
add eax, LC1
push eax
mov eax, [ebp + 8]
call dword [eax + func_entry + (FuncPuts * 4)]
pop eax
leave
ret
segment .data
LC1: db "Hello You!", 10, 0
func_entry:
dd 31102011 ; version
dd 0x4015d0 ; puts
; cheers and good luck
; Jens
[toc] | [prev] | [standalone]
Back to top | Article view | comp.compilers
csiph-web