7

According to this thread,memory allocated by malloc at least have PROT_READ | PROT_EXEC,otherwise the contaned function can't be executed .

man malloc doesn't mention anything about protection thus the question.

miken32
  • 42,008
  • 16
  • 111
  • 154
Je Rog
  • 5,675
  • 8
  • 39
  • 47
  • Are you sure that's the right thread? I don't see anything about PROT_READ or PROT_EXEC there. I thought those two were related to mmap. (See http://pubs.opengroup.org/onlinepubs/007908799/xsh/mmap.html) – Mike Sherrill 'Cat Recall' Jun 11 '11 at 11:00
  • @Catcall ,that's why I say `malloc` returned memory implicitly has `PROT_READ` or `PROT_EXEC` on,as it doesn't have to `mprotect(p, 1024, PROT_READ|PROT_EXEC)` while memory returned by `mmap` has to. – Je Rog Jun 11 '11 at 11:05

4 Answers4

6

malloc() will normally return memory with read and write permissions. Some architectures (e.g: older x86) may not allow disabling execute permission in a straightforward way, but that's just a defficiency of the platform.

If you want to execute code from memory you allocated, you'll have to give execute permissions explicitly, and possibly you'll have to remove write permissions, since having both write and execute permissions on the same memory is considered potentially dangerous on some systems (commonly referred as W^X).

There have been several other threads on executing code from memory allocated by the programmer:

Allocate executable ram in c on linux
Is it possible to execute code from the stack in standard C?

Community
  • 1
  • 1
ninjalj
  • 42,493
  • 9
  • 106
  • 148
6

malloc is not the right tool for allocating memory for code. You should use mmap, and depending on the paranoid security policies on your system, you might need to use mprotect too for changing the permissions.

Among the reasons malloc is not the right tool:

  • Permissions are set only with page granularity, but memory obtained by malloc is unlikely to be page-aligned, and thus you'll end up setting permissions on adjacent memory too, possibly breaking things.
  • If you don't restore the old permissions before calling free, you might break malloc's internals.
R.. GitHub STOP HELPING ICE
  • 208,859
  • 35
  • 376
  • 711
  • Regarding *Permissions are set only with page granularity*,do you mean memory returned by `void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset);` is always in unit of page? Doesn't seem to be garunteed by `length` parameter though. – Je Rog Jun 11 '11 at 13:02
  • 1
    @Je Rog: yes, mmap() creates memory mappings, which have page-granularity (except on !MMU systems) – ninjalj Jun 11 '11 at 13:10
  • 1
    And "!mmu" cannot conform to POSIX (which requires memory protection). – R.. GitHub STOP HELPING ICE Jun 11 '11 at 13:16
  • @ninjalj ,the `length` doesn't need to be a multiple of page,how come? Does that mean if we mmap `4000` bytes ,then `96` bytes will be wasted? – Je Rog Jun 11 '11 at 13:52
  • @Je Rog: They'll be mapped, see `/proc//maps` on Linux. – ninjalj Jun 11 '11 at 14:59
  • Length will be rounded up to page size multiple. – R.. GitHub STOP HELPING ICE Jun 11 '11 at 15:05
  • `A file is mapped in multiples of the page size. For a file that is not a multiple of the page size, the remaining memory is zeroed when mapped, and writes to that region are not written out to the file. The effect of changing the size of the underlying file of a mapping on the pages that correspond to added or removed regions of the file is unspecified.` – Je Rog Jun 11 '11 at 15:07
  • @R..,not rounded,I think **wasted** is more accurate since the effect of writing to the extra 96 bytes is unspecified. – Je Rog Jun 11 '11 at 15:09
2

You may need to call mprotect to set the PROT_EXEC flag yourself, after the memory has been allocated.

$ man mprotect

Paul R
  • 208,748
  • 37
  • 389
  • 560
  • seems not,see the linked paragraph,it doesn't involve `mprotect` which indicates memory returned by `malloc` already has `PROT_EXEC` on. – Je Rog Jun 11 '11 at 10:12
  • @Je Rog: OK - I'm surprised that Linux sets `PROT_EXEC` by default for malloc'd memory - it may be that other operating systems take a more defensive approach - if your question is Linux-specific then you should probably tag it `linux`. – Paul R Jun 11 '11 at 10:15
  • Yeah that's the case,I want to know what other flags are set but `man malloc` gives no clue. Also,I don't know whether it's linux specific,so I don't think it proper to add that tag. – Je Rog Jun 11 '11 at 10:17
  • @Je Rog: it's probably best not to make any assumptions, particularly if you care about portability and being future-proof. – Paul R Jun 11 '11 at 10:18
  • 1
    Older x86 CPUs don't have execute permission bits for pages, so usually read permission implied execute permission. Newer CPUs have an NX (non-execute) bit. – ninjalj Jun 11 '11 at 11:02
0

The malloc() library function is specified by the C language standard, so it is the same on all operating systems. The memory protection is a function of the processor and operating system, so it is done differently on Windows, Linux, etc.

The way this works has changed over the years since malloc() was defined. I remember when most processors did not support a separate "executable" permission for memory - if it was readable, it was executable. Many embedded systems don't have any memory protection at all, all memory can be read, written, and executed. The malloc() function works the same way in all these cases.

John Vincent
  • 681
  • 6
  • 4