How to mprotect the data section? - c

I want to mprotect the data section. The following program will not run correctly. I understand the first argument of mprotect() should be aligned. But how to get an aligned memory address for the data section?
#include <string.h>
#include <sys/mman.h>
#include <stdio.h>
char s[] = "Hello World!";
int main() {
if(mprotect(s, strlen(s) + 1, PROT_EXEC) == -1) {
perror("mprotect()");
return 1;
}
}
$ ./mprotect_prog
mprotect(): Invalid argument
EDIT: I use the following code to get the page size.
{
builtin printf %s '#define PAGESIZE '
getconf PAGESIZE
} > pagesize.h
Then the C code is changed to the following.
#include <string.h>
#include <sys/mman.h>
#include <stdio.h>
#include "pagesize.h"
char s[] __attribute__((aligned(PAGESIZE))) = "Hello World!";
int main() {
if(mprotect(s, strlen(s) + 1, PROT_EXEC) == -1) {
perror("mprotect()");
return 1;
}
}
Then, I get a segmentation fault. Can anybody reproduce this error? What is wrong with it?
$ ./mprotect_prog
Segmentation fault
EDIT2: I have to add the following line below the 's' line to make sure s occupies a whole page on its own. Then, the program works.
char r[] __attribute__((aligned(PAGESIZE))) = "Hello World!";

{
builtin printf %s '#define PAGESIZE '
getconf PAGESIZE
} > pagesize.h
#include <string.h>
#include <sys/mman.h>
#include <stdio.h>
#include "pagesize.h"
char s[] __attribute__((aligned(PAGESIZE))) = "Hello World!";
char r[] __attribute__((aligned(PAGESIZE))) = "Hello World!";
int main() {
if(mprotect(s, strlen(s) + 1, PROT_EXEC) == -1) {
perror("mprotect()");
return 1;
}
}

Related

Segmentation Fault naming constant with a function C

So I have a string like "11111 & 11111" and i need to write this char in the middle in (char operation), but i have Segmentation Fault.
main.c
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char getChar(char *a);
int main(){
char *str = NULL;
size_t n = 0;
int a = getline(&str,&n,stdin);
printf("%c",getChar(str));
char operation = getChar(str);
free(str);
return 0;
}
bin.c(compiling with main.c)
#include <stdio.h>
#include <string.h>
char getChar(char *a){
char *p = strtok(a," ");
while (p != NULL){
p = strtok(NULL," ");
break;
}
return p[0];
}
in main.c this one
printf("%c",getChar(str));
is works well
but when i write this one
char operation = getChar(str);
I get Segmentation Fault

Why can't I access my pointer of char through my function?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <regex.h>
#include <unistd.h>
#include <ctype.h>
#include <assert.h>
void *process(char **nbE)
{
char buffer[8] = "test";
*nbE = &buffer[0];
printf("%s\n", *nbE);
}
int main(int argc, char **argv)
{
char *str;
process(&str);
printf("%s\n", str);
}
I'm trying to get the value of *nbE in main() by making it points to the address of first char in my array.
But it returns something not encoded, why?
What would be a way for me to do this way?
Note: I know I can do it simpler, I have a more complex code and this is a mini example
Basically I have something interesting in my array and want to pass it to my main function through a char* variable
char buffer[8] = "test";
creates a string that is local to the function, it is destroyed once you return from that function. Do this
static char buffer[8] = "test";
or
char * buffer = strdup("test");
you have to release the string when you have finsihed with it in the second case

Correctly hashing a string in C

When using the terminal utility "openssl" with the following command:
echo -n "Hello World!" | openssl sha1
This is the output produced:
(stdin)= 2ef7bde608ce5404e97d5f042f95f89f1c232871
I've tried producing the same output with following C code:
#include <stdio.h>
#include <stdlib.h>
#include <openssl/sha.h>
int main(void){
const unsigned char source_string[1024] = "Hello World!";
unsigned char dest_string[1024];
SHA1(source_string, 16, dest_string);
printf("String: %s\nHashed string: %s\n", source_string, dest_string);
return 0;
}
However, it produces this weird non-unicode output:
String: Hello World!
Hashed string: #�V�#��#�����T\�
How can I make it produce the same output as the before shown openssl terminal command?
You should
Pass the correct length of the string (it is 12-byte long) to SHA1.
Print the result in hexadecimal, not as string.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/sha.h>
int main(void){
const unsigned char source_string[1024] = "Hello World!";
unsigned char dest_string[1024];
int i;
SHA1(source_string, strlen((const char*)source_string), dest_string);
printf("String: %s\nHashed string: ", source_string);
for (i = 0; i < 20; i++) printf("%02x", dest_string[i]);
putchar('\n');
return 0;
}
I didn't check by running this, so there may be other errors.

Is #define var bad with strcmp?

Can i compare#definevarible andchar * in strcmp as below.
#include<stdio.h>
#include<string.h>
#define var "hello"
int main()
{
char *p ="hello";
if(strcmp(p,var)==0)
printf("same\n");
else
printf("not same\n");
return 0;
}
Is there any risk comapre #define with char *as above example?
Don't trust us, trust the preprocessor output
File "foo.c"
#include <stdio.h>
#include <string.h>
#define var "hello"
int main(void)
{
char *buf="hello";
if(strcmp(buf,var)==0) // Is this good
printf("same");
return 0;
}
now:
gcc -E foo.c
lots of output because of standard system libraries then...:
# 5 "foo.c"
int main(void)
{
char *buf="hello";
if(strcmp(buf,"hello")==0)
printf("same");
return 0;
}
as you see your define has been safely replaced by the string literal.
When you have a doubt, just apply this method to make sure (more useful when converting to strings or concatenating tokens, there are traps to avoid)
In your case, you could also avoid the macro and use:
static const char *var = "hello";
which guarantees that only 1 occurrence of "hello" is set (saves data memory).
No, there is no risk to comapre #define with char* at all.
#include <stdio.h>
#include <string.h>
#define var "hello"
int main(void)
{
char *buf="hello";
if(strcmp(buf,var)==0) // Is this good
printf("same");
return 0;
}

Segmentation fault in strlen when using FTS fts_open()

I have a bug that I've found boils down to this:
#include <sys/types.h>
#include <sys/stat.h>
#include <fts.h>
#include <stdlib.h>
int main () {
char *LOG_ROOT = "/var/log";
FTS *ftsp;
FTSENT *p, *chp;
int fts_options = FTS_COMFOLLOW | FTS_LOGICAL | FTS_NOCHDIR;
char *paths[] = { LOG_ROOT };
fts_open(paths, fts_options, NULL);
}
Why does this segfault?
The first arg. is expected to be a NULL terminated array of character pointers.
char *paths[] = { LOG_ROOT, NULL};

Resources