Program crash on memset? - c

I am struggling with memset.
If I write in my array my program crashes. If I comment out the memset i have no problems.
My type struct:
typedef struct
{
char Frage [maxLEN_F_A];
char Antwort[maxLEN_F_A];
} Fragenfeld;
My declaration of the struct:
Fragenfeld QuizFragen[maxFragen];
Fragenfeld *ptrQuizFragen = QuizFragen;
The memset call:
memset(&ptrQuizFragen,0,maxFragen*sizeof(Fragenfeld));
My function, where I edit the value of the adress:
int Fragen_einlesen(Fragenfeld *Quizfragen)
{
....
strncpy(Quizfragen->Frage,sEingabe, maxLEN_F_A);
}

When you write
memset(&ptrQuizFragen,0,maxFragen*sizeof(Fragenfeld));
you're saying "please set a lot of of bytes, starting at the address of the pointer variable ptrQuizFragen, to zero." Notice that this is different than saying "please set a lot of bytes, starting at the beginning of the array pointed at by ptrQuizFragen, to zero." This means the bytes are getting written to the wrong place, which is what's causing your segfault.
Graphically, the setup looks something like this:
ptrQuizFragen
+-----------+
| |
+-----------+
|
v
+-----------+-----------+-----------+ ... +-----------+
| | | | | |
+-----------+-----------+-----------+ ... +-----------+
QuizFragen
The line you've written puts the bytes starting where ptrQuizFragen is located in memory, which does this:
ptrQuizFragen
+-----------+
| 00000000000000000000000000000000000 ... 000000000000 (oops!)
+-----------+
+-----------+-----------+-----------+ ... +-----------+
| | | | | |
+-----------+-----------+-----------+ ... +-----------+
QuizFragen
The line you want is
memset(ptrQuizFragen, 0, maxFragen * sizeof(Fragenfeld));
which says to put the bytes at the memory location pointed at by ptrQuizFragen. That would do this:
ptrQuizFragen
+-----------+
| |
+-----------+
|
v
+-----------+-----------+-----------+ ... +-----------+
| 000000000 | 000000000 | 000000000 | | 000000000 |
+-----------+-----------+-----------+ ... +-----------+
QuizFragen

This ...
memset(&ptrQuizFragen,0,maxFragen*sizeof(Fragenfeld));
... requests that the memory starting at the address of variable ptrQuizFragen be written, but what you want is that memory at the location to which the pointer points is written:
memset(ptrQuizFragen, 0, maxFragen*sizeof(Fragenfeld));
Alternatively, for the same reason that you can initialize ptrQuizFragen as you do, you could also do away with it altogether:
memset(QuizFragen, 0, maxFragen*sizeof(Fragenfeld));
Additionally, it would be clearer to express the wanted size directly in terms of the object being written to:
memset(QuizFragen, 0, sizeof(QuizFragen));
However, if this is for one-time initialization then I would not use memset at all:
Fragenfeld QuizFragen[maxFragen] = {0};
Although that's valid C with well-defined sematics, some compilers may warn. If yours does, and that makes you uncomfortable, then one alternative would be to expand a bit to
Fragenfeld QuizFragen[maxFragen] = { { {0}, {0} } };

Related

Why is the following code susceptible to heap overflow attack

I'm new to cyber security, and I am trying to understand why the following code is susceptible to a heap overflow attack...
struct data {
char name[128];
};
struct fp {
int (*fp)();
};
void printName() {
printf("Printing function...\n");
}
int main(int argc, char **argv) {
struct data *d;
struct fp *f;
d = malloc(sizeof(struct data));
f = malloc(sizeof(struct fp));
f->fp = printName;
read(stdin,d->name,256);
f->fp();
}
Is it because of the read(stdin, d->name, 256) as it is reading more than the allocated buffer size of 128 for char name in struct data?
Any help would be great
A heap overflow attack is similar to a buffer overflow attack, except instead of overwriting values in the stack, the attacker tramples data in the heap.
Notice in your code that there are two dynamically allocated values:
d = malloc(sizeof(struct data));
f = malloc(sizeof(struct fp));
So d now holds the address of a 128-byte chunk of memory in the heap, while f holds the address of an 8-byte (assuming a 64-bit machine) chunk of memory. Theoretically, these two addresses could be nowhere near each other, but since they're both relatively small, it's likely that the OS allocated one larger chunk of contiguous memory and gave you pointers that are next to each other.
So once you run f->fp = printName;, your heap looks something like this:
Note: Each row is 8 bytes wide
| |
+------------------------+
f -> | <Address of printName> |
+------------------------+
| ▲ |
| 11 more rows |
| not shown |
| |
d -> | <Uninitialized data> |
+------------------------+
| |
Your initial assessment of where the vulnerability comes from is correct. d points to 128 bytes of memory, but you let the user write 256 bytes to that area. C has no mechanism for bounds checking, so the compiler is perfectly happy to let you write past the edge of the d memory. If f is right next to d, you'll fall over the edge of d and into f. Now, an attacker has the ability to modify the contents of f just by writing to d.
To exploit this vulnerability, an attacker feeds the address of some code that they've written to d by repeating it for all 256 bytes of input. If the attacker has stored some malicious code at address 0xbadc0de, they feed in 0xbadc0de to stdin 32 times (256 bytes) so that the heap gets overwritten.
| 0xbadc0de |
+-------------+
f -> | 0xbadc0de |
+-------------+
| ... |
| 0xbadc0de |
| 0xbadc0de |
d -> | 0xbadc0de |
+-------------+
| |
Then, your code reaches the line
f->fp();
which is a function call using the address stored in f. The machine goes to memory location f and retrieves the value stored there, which is now the address of the attacker's malicious code. Since we're calling it as a function, the machine now jumps to that address and begins executing the code stored there, and now you've got a lovely arbitrary code execution attack vector on your hands.

In C language is *p=vec[n] the same as p=&vec[n]?

I'm self-studying pointers in C, and my question is: is *p=vec[n] the same as writing p=&vec[n], where n is just an index and p is a pointer?
Here's a rough graphical explanation in addition to other answers.
They are two distinct expressions:
A pointer is a type which holds the address of a piece of memory. So when you write:
p = &vec[n]
The pointer will have the same address as the address of the nth element of vec
When you write
*p = vec[n]
You actually state that the memory which is located at the address of p should have the same content as the nthe element of vec.
The following might make it clear:
| original | p = &vec[n] | *p = vec[n]
------+-----------------+-----------------+----------------
data | Address Content | Address Content | Address Content
------+-----------------+-----------------+----------------
p | 0x12345 0000000 | 0xabcde 0000005 | 0x12345 0000005
vec[n]| 0xabcde 0000005 | 0xabcde 0000005 | 0xabcde 0000005
No it's not.
When you do *p = ... you assign a value to where p is currently pointing.
With p = ... you make p point somewhere else.

How can I free a struct pointer that i need

I am trying to avoid memory leaks in my code. I need to de-allocate pElement, line and pSecond, without losing the values inside pImage. Because I need to print those values inside my print function.
My add function contains struct GraphicElement *pElements;, struct GraphicElement *pSecond;, struct Point point;.
I allocate memory using malloc for each struct and then add the values and then I pass the final values into pImage. All my other functions work perfectly besides the fact that I always end up with 3 memory leaks. Because I didnt not free(pSecond);....free(pElement)...free(line);
If I try to free them before my function exits and after passing the values into pImage. My values all get erased.
How can I free those values inside my add function locally?
struct Point
{
int x, y;
};
struct Line
{
Point start;
Point end;
};
struct GraphicElement
{
enum{ SIZE = 256 };
unsigned int numLines; //number of lines
Line* pLines; //plines points to start and end
char name[SIZE];
};
typedef struct
{
unsigned int numGraphicElements;
GraphicElement* pElements; //the head points to pLines
} VectorGraphic;
void InitVectorGraphic(VectorGraphic*); //initializes pImage->pElement
void AddGraphicElement(VectorGraphic*); //Used to add
void ReportVectorGraphic(VectorGraphic*); // prints pImage contents
void CleanUpVectorGraphic(VectorGraphic*); //deallocates memory
How can I free those values inside my add function locally?
It is not possible to explicitly free a memory allocated locally. Nor to locally free some memory. Once freed, a memory slot cannot be accessed and the data stored inside are lost.
In C, you have two option to allocate some memory: you can allocate it on the heap or on the stack. The memory slots reserved on the heap can be accessed globally and will remain until they are explicitly freed. The one reserved on the stack are only valid while you stay within the context they were created.
Let's say you execute the following code :
void func()
{
int x = 3; // [2]
int * p = & x; // [3]
}
int main()
{
func(); // [1]
// [4]
return 0;
}
The instruction [2] will allocate some memory on the stack. The second one ([3]) will do the same and will store the address of the of the first variable in the new memory slot. After the function returns ([4]), this memory is freed. Graphically, here is what happens :
Context STACK Address
+---------+
| | 0xa1
main | | 0xa0
+---------+
[1] +---------+
=====> | |
func | | 0xa2
+---------+
| | 0xa1
main | | 0xa0
+---------+
[2] +---------+
=====> | |
func | 3 | 0xa2 <-- x
+---------+
| | 0xa1
main | | 0xa0
+---------+
[3] +---------+
=====> | 0xa2 | 0xa3 <-- p
func | 3 | 0xa2 <-- x
+---------+
| | 0xa1
main | | 0xa0
+---------+
[4] +---------+
=====> | | 0xa1
main | | 0xa0
+---------+
So if i use malloc inside a function. Once I exist the function the allocated memory on the heap is freed automatically?
It's the opposite. If you use, a function like malloc, the memory slot will be allocated on the heap. So if we change the line [3] above to something like
int * p = malloc(sizeof(int)); // [3]
The memory allocated on the stack will be freed as you'll leave the function, but the memory allocated on the heap will remain allocated and will still be accessible, until you free it. Graphically :
HEAP Address Free (y/n)
+---------+
| | 0xb4 - Yes
| | 0xb3 - Yes
+---------+
Context STACK Address
[3] +---------+ +---------+
=====> | 0xb4 | 0xa3 <-- p | | 0xb4 - No
func | 3 | 0xa2 <-- x | | 0xb3 - Yes
+---------+ +---------+
| | 0xa1
main | | 0xa0
+---------+
[4] +---------+ +---------+
=====> | | 0xa1 | | 0xb4 - No !!! Leak !!!
main | | 0xa0 | | 0xb3 - Yes
+---------+ +---------+
As you can see, after you leave the function, you have a memory leak as you don't have any pointer to the dynamically allocated memory. One way to avoid this is to return the pointer (so to pass the address of the new memory slot to the calling function) or to store it somewhere to free it later. It's also possible to allocate the memory before calling the function and to pass it to the function as a parameter. It really depends on your application.

Assigning same values to 2 pointers, not equalising their references (pointers in C)

printf("%p\n\n", element); //0x1000020c0
table->head->element = element;
printf("%p\n\n", table->head->element); //0x1000020c0
I have a pointer to a struct which points to another struct where is char* variable is stored. The problem is a pointer(char * element) which is sent to this method is modified somewhere else, and I don't want those modifications to be affected in table->head->element. Simply said I want to make their values equal, not the reference.
I knew that we can assign same values to 2 pointers like this: *p1=*p2. However, I am not sure how to do that with structs, I tried:
*(table->head->element) = *element;
But it did not work.
I hope I could clarify my question.
If you want the pointed-to string by a copy, not simply a reference, you'll need to strcpy() it into some new memory. e.g.
int len = strlen(element);
table->head->element = malloc(len+1); // +1 for string-terminating null
strcpy(table->head->element, element);
(or use strdup() for a one-line solution, as pointed out in R Sahu's reply).
Responding to OP's comments in the answer by #GrahamPerks.
That will work, but I don't want using additional coping, because we can do it with pointer
Let's say the memory used by element looks like below:
element +---------+ +---+---+---+---+---+---+---+---+------+
| ptr1 | -> | a | | s | t | r | i | n | g | '\0' |
+---------+ +---+---+---+---+---+---+---+---+------+
If you use:
table->head->element = element;
the value of table->head->element is ptr1.
If some time later, you went ahead and changed the contents of ptr1 through element, such as by using:
fscanf(file, "%s", element);
You could end up with:
element +---------+ +---+---+---+---+---+---+---+---+---+---+------+
| ptr1 | -> | n | e | w | | s | t | r | i | n | g | '\0' |
+---------+ +---+---+---+---+---+---+---+---+---+---+------+
At that point, the string that you see from table->head->element is "new string", not "a string".
This is what happens when you don't copy the contents of element but just copy the pointer value of element.
If you want the value of table->head->element to remain "a string" while the value of element changes, you have to copy the contents of element using
int len = strlen(element);
table->head->element = malloc(len+1);
strcpy(table->head->element, element);
or, if your complier supports strdup, by using
table->head->element = strdup(element);

Multiple const in one variable declaration

A colleague of mine is going a bit nuts with const in ANSI C and I wanted to know what you guys thought about it. He writes stuff like this for example:
const uint8* const pt_data
I understand where he's going with this but for me it makes the reading and maintainability harder with all these const everywhere.
It's a const pointer pointing to const data.
The first const prevents *pt_data = 10;
The second const prevents pt_data = stuff;
It looks like it can be pretty legitimate.
const always refers to the word on its right, except if it is at the end of the line, where it refers to the item itself (in higher level languages)
const char* str; //This is a pointer to read-only char data
//Read as to (const char)* str;
//Thus :
// *str = 'a';
//Is forbidden
char* const str; //This is a read-only pointer to a char data
//Read as char* (const str);
//Thus :
// str = &a;
//Is forbidden
const char* const str; //This is a read-only pointer to read-only char data
//Read as (const char)* (const str);
//Thus :
// str = &a
// and
// *str = 'a';
//Is forbidden
You should always initialize those pointers when declaring them (Except if they're a parameter)
const keyword is great at ensuring something will not be modified, and also tells the developper it should not. For example int strlen(const char* str) tells you the char data in your string will not be modified whatsoever.
It is a constant pointer to an constant data.
it means you cannot change the data(whose address pt_data stores) and also cannot change the pointer(pt_data) to point to something else(some other address).
He probably needs it that way.
If you start at the variable name, and going counter-clockwise, pt_data is a const pointer to uint8 which is const.
See the following crude ASCII image:
,--------------------------------.
| |
| ,------------------------. |
| | | |
| | ,------------------. | |
| | | | | |
| | | ,-----------. | | |
| | | | | | | |
const uint8 * const pt_data; | | | |
| | | | | | | |
| | | `-----' | | |
| | | | | |
| | `-------------' | |
| | | |
| `--------------------' |
| |
`--------------------------'
Ever since I saw this scheme in an old C book many years ago, it has helped me understand complex declarations.

Resources