C - MADV_HUGEPAGE Compile Error - c

I was trying to compile some C code, which works fine on Linux with just one command.
./autogen.sh && ./configure && make
I need this to be compiled for windows, so I installed cygwin and all the dependencies that I could think of, and now I'm getting a compile error. (Error at make).
-cpu-miner.o `test -f 'cpu-miner.c' || echo './'`cpu-miner.c
cpu-miner.c: In function ‘miner_thread’:
cpu-miner.c:1056:139: error: ‘MAP_HUGETLB’ undeclared (first use in this function)
persistentctx = (struct cryptonight_ctx *)mmap(0, sizeof(struct cryptonight_ctx), PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB | MAP_POPULATE, 0, 0);
^
cpu-miner.c:1056:139: note: each undeclared identifier is reported only once for each function it appears in
cpu-miner.c:1056:153: error: ‘MAP_POPULATE’ undeclared (first use in this function)
persistentctx = (struct cryptonight_ctx *)mmap(0, sizeof(struct cryptonight_ctx), PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB | MAP_POPULATE, 0, 0);
^
cpu-miner.c:1058:88: error: ‘MADV_HUGEPAGE’ undeclared (first use in this function)
madvise(persistentctx, sizeof(struct cryptonight_ctx), MADV_RANDOM | MADV_WILLNEED | MADV_HUGEPAGE);
^
make[2]: *** [Makefile:563: minerd-cpu-miner.o] Error 1
The full code is over here:
https://github.com/wolf9466/cpuminer-multi
I installed Cygwin with gcc, ming-w64, libcurl, and openssl, as the project dependencies stated, but I'm stumped here.
(I did make changes to the code for optimization, but they're mathematical tweaks and they work fine on Linux, so I don't think that's the problem.)
Edit 1
It compiles now! I removed the hugepages thing and it compiled - but it's a Linux executable that has a .exe file name. It needs the cygwin dlls to run.

The "hugepage" feature is specific to Linux, and isn't available in Cygwin.

Related

Using personality syscall to make the stack executable

I am trying to understand how to make process stack executable with personality syscall, so I wrote this code that creates a new process with and runs a bash on the stack and I get segment fault because I don't have execute permission on the stack. What am I doing wrong?
#include <stdio.h>
#include <sys/personality.h>
int main()
{
setvbuf(stdout, 0, 2, 0);
unsigned char shellcode[] = "\x48\x31\xf6\x56\x48\xbf\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x57\x54\x5f\x6a\x3b\x58\x99\x0f\x05"; // open bash
if(personality(READ_IMPLIES_EXEC | ADDR_NO_RANDOMIZE) == -1) // return 0
{
printf("personality failed");
exit(0);
}
int (*ret)() = (int(*)())shellcode;
if(fork() == 0) // child proces
ret();
return 0;
}
Compiled with gcc file.c -o file.o
$ uname -r
4.4.179-0404179-generic
$ readelf -l
...
GNU_STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RW 0x10
There are two problems:
You cannot change the personality of a process after it's started. Doing personality(READ_IMPLIES_EXEC) is not going to do anything per se, it just sets the current process' personality value (a simple 32bit integer) and that's it. In order for the change to take effect a new program will need to be executed (i.e. through execve). The current process (and its children) will not be affected.
Linux will ignore the READ_IMPLIES_EXEC personality flag if the ELF includes a PT_GNU_STACK program header that specifies that the stack should not be executable, which is usually the default choice by compilers.
By default GCC will create ELFs with a PT_GNU_STACK program header whose flags are set to RW and not RWX. In order to have an executable stack, you will have to pass the -z execstack option to GCC when compiling, which will set PT_GNU_STACK to RWX. You can check this with readelf -l your_elf (note: readelf will show E instead of X for program header flags).
Therefore, in your case, gcc -zexecstack -o file file.c should do what you want, and you don't need to call personality() nor fork() really. Just put your shellcode on the stack and jump into it. In theory you could also locate the program headers in the ELF file and edit the flags for PT_GNU_STACK manually (7 = RWX) e.g. using an hex editor, but that'd be more work than needed.
So, at the end of the day:
I am trying to understand how to make process stack executable with personality syscall
You cannot. Personality only affects new executions, not already existing ones, and on top of that ELF properties such as the PT_GNU_STACK program header supersede personality. You can however re-compile your program as explained above.
NOTE: you can nonetheless use mprotect() to change the permissions of stack memory pages to RWX, given that you can somehow extrapolate the stack base address and size at runtime (e.g. taking the address of a local variable in a function and zeroing out the lowest 12 bits).
This is enough information for older kernels like yours (4.4), but since Linux v5.8 the situation is a bit more nuanced. Assuming you are on x86, you can take a look at this comment in the source code for an explanation:
/*
* An executable for which elf_read_implies_exec() returns TRUE will
* have the READ_IMPLIES_EXEC personality flag set automatically.
*
* The decision process for determining the results are:
*
* CPU: | lacks NX* | has NX, ia32 | has NX, x86_64 |
* ELF: | | | |
* ---------------------|------------|------------------|----------------|
* missing PT_GNU_STACK | exec-all | exec-all | exec-none |
* PT_GNU_STACK == RWX | exec-stack | exec-stack | exec-stack |
* PT_GNU_STACK == RW | exec-none | exec-none | exec-none |
*
* exec-all : all PROT_READ user mappings are executable, except when
* backed by files on a noexec-filesystem.
* exec-none : only PROT_EXEC user mappings are executable.
* exec-stack: only the stack and PROT_EXEC user mappings are executable.
*
* *this column has no architectural effect: NX markings are ignored by
* hardware, but may have behavioral effects when "wants X" collides with
* "cannot be X" constraints in memory permission flags, as in
* https://lkml.kernel.org/r/20190418055759.GA3155#mellanox.com
*
*/
#define elf_read_implies_exec(ex, executable_stack) \
(mmap_is_ia32() && executable_stack == EXSTACK_DEFAULT)

Cannot create anonymous mapping with MAP_32BIT on MacOS

I'm on a 64-bit system, but want to use mmap to allocate pages within the first 2GB of memory. On Linux, I can do this with the MAP_32BIT flag:
#include <sys/mman.h>
#include <stdio.h>
int main() {
void *addr = mmap(
NULL, // address hint
4096, // size
PROT_READ | PROT_WRITE, // permissions
MAP_32BIT | MAP_PRIVATE | MAP_ANONYMOUS, // flags
-1, // file descriptor
0 // offset
);
if (addr == MAP_FAILED)
perror("mmap");
else
printf("%p", addr);
}
Godbolt link demonstrating that this works on Linux. As of version 10.15, MacOS also allegedly supports the MAP_32BIT flag. However, when I compile and run the program on my system (11.3), it fails with ENOMEM. The mapping does work when MAP_32BIT is removed.
I have a few potential explanations for why this doesn't work, but none of them are very compelling:
The permissions are wrong somehow (although removing either PROT_READ or PROT_WRITE didn't solve it).
I need to specify an address hint for this to work, for some reason.
MacOS (or my version of it) simply doesn't support MAP_32BIT for anonymous mappings.
The problem is the "zero page": on some 32-bit Unixes, the lowest page of memory is commonly configured to be inaccessible so that accesses to NULL can be detected and signal an error. On 64-bit systems, MacOS extends this to the entire first 4 GiB of memory by default. mmap therefore refuses to map addresses in this region, since they are already mapped to page zero.
This can be simply changed using a linker option:
$ cc -Wl,-pagezero_size,0x1000 test.c
$ ./a.out
0xb0e5000

SQLite extensions error, c to dll compiling

What is needed:
Compile the json1 extension for SQLite
What I did:
Reaserched the official extension page: https://sqlite.org/loadext.html
Downloaded the SQLite source code: https://www.sqlite.org/cgi/src/doc/trunk/README.md
Found 2 ways to compile a dll:
cl windows command
gcc linux command
For the cl command I installed Visual Studio and launched the vcvars32.bat file for the enviroment launch, then tried this command: cl ext/misc/json1.c sqlite3ext.h /link /dll.
Docs: https://learn.microsoft.com/en-us/cpp/build/reference/compiler-command-line-syntax?view=vs-2019
However it didnt work and I got an error: fatal error C1083: sqlite3ext.h: No such file or directory.
I have the sqlite3ext.h file and tried moving it arround but nothing worked.
Then I moved to the gcc command:
I used the Ubuntu wsl
Upadated Ubuntu
Downloaded the source code (mensioned above)
Installed the SQLite developer package (can't find it)
Used this command: gcc -g -shared sqlite/ext/misc/json1.c -o json1.dll
Found the command on the SQLite extension page mensioned above
It didn't work and I got this long error message:
sqlite/ext/misc/json1.c: In function ‘jsonEachConnect’:
sqlite/ext/misc/json1.c:2099:29: error: ‘SQLITE_VTAB_INNOCUOUS’ undeclared (first use in this function); did you mean ‘SQLITE_STATIC’?
sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS);
^~~~~~~~~~~~~~~~~~~~~
SQLITE_STATIC
sqlite/ext/misc/json1.c:2099:29: note: each undeclared identifier is reported only once for each function it appears in
sqlite/ext/misc/json1.c: At top level:
sqlite/ext/misc/json1.c:2501:3: warning: excess elements in struct initializer
0 /* xShadowName */
^
sqlite/ext/misc/json1.c:2501:3: note: (near initialization for ‘jsonEachModule’)
sqlite/ext/misc/json1.c:2529:3: warning: excess elements in struct initializer
0 /* xShadowName */
^
sqlite/ext/misc/json1.c:2529:3: note: (near initialization for ‘jsonTreeModule’)
sqlite/ext/misc/json1.c: In function ‘sqlite3Json1Init’:
sqlite/ext/misc/json1.c:2594:8: error: ‘SQLITE_INNOCUOUS’ undeclared (first use in this function); did you mean ‘SQLITE_IGNORE’?
SQLITE_INNOCUOUS;
^~~~~~~~~~~~~~~~
SQLITE_IGNORE
sqlite/ext/misc/json1.c:2602:10: warning: implicit declaration of function ‘sqlite3_create_window_function’; did you mean ‘sqlite3_create_function’? [-Wimplicit-function-declaration]
rc = sqlite3_create_window_function(db, aAgg[i].zName, aAgg[i].nArg,
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
sqlite3_create_function
sqlite/ext/misc/json1.c:2603:34: error: ‘SQLITE_SUBTYPE’ undeclared (first use in this function); did you mean ‘SQLITE_CANTOPEN’?
SQLITE_SUBTYPE | enc, 0,
^~~~~~~~~~~~~~
ANY HELP WOULD BE GREATLY APPRECIATED!
Thanks!
I had this problem with the SQLite UUID extension using "better-sqlite", but that's something else. What I did was replace everything that said SQLITE_INNOCUOUS and SQLITE_DETERMINISTIC with SQLITE_IGNORE. And it worked, at least for this extension. Something like the following:
Before:
{
int rc = SQLITE_OK;
SQLITE_EXTENSION_INIT2(pApi);
(void)pzErrMsg; /* Unused parameter */
rc = sqlite3_create_function(db, "uuid", 0, SQLITE_UTF8|SQLITE_INNOCUOUS, 0,
sqlite3UuidFunc, 0, 0);
if( rc==SQLITE_OK ){
rc = sqlite3_create_function(db, "uuid_str", 1,
SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_DETERMINISTIC,
0, sqlite3UuidStrFunc, 0, 0);
}
if( rc==SQLITE_OK ){
rc = sqlite3_create_function(db, "uuid_blob", 1,
SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_DETERMINISTIC,
0, sqlite3UuidBlobFunc, 0, 0);
}
return rc;
}
After:
{
int rc = SQLITE_OK;
SQLITE_EXTENSION_INIT2(pApi);
(void)pzErrMsg; /* Unused parameter */
rc = sqlite3_create_function(db, "uuid", 0, SQLITE_UTF8 | SQLITE_IGNORE, 0,
sqlite3UuidFunc, 0, 0);
if (rc == SQLITE_OK)
{
rc = sqlite3_create_function(db, "uuid_str", 1,
SQLITE_UTF8 | SQLITE_IGNORE | SQLITE_IGNORE,
0, sqlite3UuidStrFunc, 0, 0);
}
if (rc == SQLITE_OK)
{
rc = sqlite3_create_function(db, "uuid_blob", 1,
SQLITE_UTF8 | SQLITE_IGNORE | SQLITE_IGNORE,
0, sqlite3UuidBlobFunc, 0, 0);
}
return rc;
}
Edit
I just had to declare this at the beginning of the code.
#define SQLITE_DETERMINISTIC 0x000000800
#define SQLITE_DIRECTONLY 0x000080000
#define SQLITE_SUBTYPE 0x000100000
#define SQLITE_INNOCUOUS 0x000200000

recoding malloc: code signing blocked mmap()

I am actually recoding malloc, using an avl, and when i test it with a script like:
#!/bin/sh
export DYLD_LIBRARY_PATH=.
export DYLD_INSERT_LIBRARIES="libft_malloc.so"
export DYLD_FORCE_FLAT_NAMESPACE=1`
$#
and then ./script ls or ./script vim, it works well. But when i export manually the variables in my shell, i have this error:
dyld: warning: could not load inserted library 'libft_malloc.so' into
library validated process because no suitable image found. Did find:
libft_malloc.so: code signing blocked mmap() of 'libft_malloc.so'
here is how is use mmap:
pges_ctrl.header_pge = mmap(NULL, getpagesize() * NB_PAGES, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
if (pges_ctrl.header_pge == MAP_FAILED)
return (0);
and
tmp = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
if (tmp == MAP_FAILED)
{
pges_ctrl.errors |= MMAP_BAD_ALLOC;
return NULL;
}
If you have idea about what could be the cause of it, or how i could debug that, that would help a lot !
I am working on Mac OSX Sierra 10.12.6
Compiled with gcc -Wall -Wextra -Werror
Thanks for the help!

C: mmap failed: No such device

I'm trying to create a memory map using the c commands
void* mem_map = mmap(NULL,
sizeof(serverData), //200000
PROT_READ | PROT_WRITE,
MAP_SHARED,
mem_map_fp,
0);
if(mem_map == MAP_FAILED){
bail_out(EXIT_FAILURE, "mmap");
}
The program compiles, but when trying to run the following error is produced:
mmap: No such device
To my understanding there is nothing wrong with the code which makes me suspect that the reason might be a little more complex.
I'm running this linux version:
Linux ubuntu 4.2.0-16-generic #19-Ubuntu SMP Thu Oct 8 15:35:06 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
I suppose you are trying to allocate memory, so you should use the MAP_ANON or MAP_ANONYMOUS flag, along with the standard arguments -1 for the file descriptor and 0 for the offset, like so :
mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);

Resources