I have a simple C program that is supposed to read a message sent from another program, from an UNIX named pipe and show it to the user.
The way the program does this is the following :
The code is the following :
void* ReceiveFromPipe(char* Pipe, int* StuffSize){
printf("Opening pipe\n");
int FD = open(Pipe,O_RDONLY);
printf("Pipe opened from the write side\n");
read(FD,StuffSize,sizeof(StuffSize));
printf("Incoming message size : %d\n",*StuffSize);
void* StuffPointer = calloc((*StuffSize) + 1,1);//allocate stuffsize bytes
printf("Allocated memory for stuff\n");
read(FD,StuffPointer,*StuffSize);
printf("Read stuff from pipe\n");
close(FD);
printf("Closed pipe\n");
((int*)StuffPointer)[*StuffSize] = 0x00;
return StuffPointer;
}
And the code in the main function is a simple read-free loop, like this :
int main(void){
char* message;
int msgSize = -1;
while(1){
message = (char*)ReceiveFromPipe("./PSender0",&msgSize);
printf("Got :: %s\n",message);
fflush(stdout);
free(message);
}
}
This will work on any kind of message, unless the message has exactly 6 bytes (7 with the appended null terminator). For example, that exact program with an "HelloWorld!" message will output this :
Opening pipe
Pipe opened from the write side
Incoming message size : 11
Allocated memory for stuff
Read stuff from pipe
Closed pipe
Got :: HelloWorld!
Opening pipe
Which is the expected behaviour, however with the message 123456, the output turns to
Opening pipe
Pipe opened from the write side
Incoming message size : 6
Allocated memory for stuff
Read stuff from pipe
Closed pipe
Got :: 123456
*** Error in `./Receiver': free(): invalid next size (fast): 0x0000008869995420 ***
======= Backtrace: =========
/usr/lib/libc.so.6(+0x72bdd)[0x7f12da646bdd]
/usr/lib/libc.so.6(+0x792ec)[0x7f12da64d2ec]
/usr/lib/libc.so.6(+0x7a6d1)[0x7f12da64e6d1]
./Receiver(+0xb13)[0x8867c07b13]
/usr/lib/libc.so.6(__libc_start_main+0xea)[0x7f12da5f44ca]
./Receiver(+0x9ba)[0x8867c079ba]
======= Memory map: ========
8867c07000-8867c09000 r-xp 00000000 08:05 6030989 /home/andre/EI/SO/PipesTest/Receiver
8867e08000-8867e09000 r--p 00001000 08:05 6030989 /home/andre/EI/SO/PipesTest/Receiver
8867e09000-8867e0a000 rw-p 00002000 08:05 6030989 /home/andre/EI/SO/PipesTest/Receiver
8869995000-88699b6000 rw-p 00000000 00:00 0 [heap]
7f12d4000000-7f12d4021000 rw-p 00000000 00:00 0
7f12d4021000-7f12d8000000 ---p 00000000 00:00 0
7f12da3bd000-7f12da3d3000 r-xp 00000000 08:02 545366 /usr/lib/libgcc_s.so.1
7f12da3d3000-7f12da5d2000 ---p 00016000 08:02 545366 /usr/lib/libgcc_s.so.1
7f12da5d2000-7f12da5d3000 r--p 00015000 08:02 545366 /usr/lib/libgcc_s.so.1
7f12da5d3000-7f12da5d4000 rw-p 00016000 08:02 545366 /usr/lib/libgcc_s.so.1
7f12da5d4000-7f12da771000 r-xp 00000000 08:02 526947 /usr/lib/libc-2.25.so
7f12da771000-7f12da970000 ---p 0019d000 08:02 526947 /usr/lib/libc-2.25.so
7f12da970000-7f12da974000 r--p 0019c000 08:02 526947 /usr/lib/libc-2.25.so
7f12da974000-7f12da976000 rw-p 001a0000 08:02 526947 /usr/lib/libc-2.25.so
7f12da976000-7f12da97a000 rw-p 00000000 00:00 0
7f12da97a000-7f12da99d000 r-xp 00000000 08:02 526937 /usr/lib/ld-2.25.so
7f12dab34000-7f12dab36000 rw-p 00000000 00:00 0
7f12dab9c000-7f12dab9d000 rw-p 00000000 00:00 0
7f12dab9d000-7f12dab9e000 r--p 00023000 08:02 526937 /usr/lib/ld-2.25.so
7f12dab9e000-7f12dab9f000 rw-p 00024000 08:02 526937 /usr/lib/ld-2.25.so
7f12dab9f000-7f12daba0000 rw-p 00000000 00:00 0
7ffe4c462000-7ffe4c483000 rw-p 00000000 00:00 0 [stack]
7ffe4c495000-7ffe4c498000 r--p 00000000 00:00 0 [vvar]
7ffe4c498000-7ffe4c49a000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
Aborted (core dumped)
I can't really find the problem in this code, and can't even imagine why it only fails on 6 char messages, and would appreciate any help
This line:
((int*)StuffPointer)[*StuffSize] = 0x00;
You are casting StuffPointer as an integer pointer, so the array access will be using sizeof int
to calculate where to write the 0 integer value.
This will be writing outside the boundaries of your array, which could then cause the problem you are seeing.
Edit: To fix the issue, you could cast to (char *)
, or make StuffPointer
a char *
to begin with.
Also
read(FD,StuffSize,sizeof(StuffSize));
should be
read(FD,StuffSize,sizeof(*StuffSize));
as sizeof(StuffSize)
is the size of the pointer, which may not be the same as the size of an integer.