memory corruption in read()

abhicmrit

New Member
Credits
29
Hi,
I am using linux version 4.1.12-112.14.15.el7uek.x86_64

in one of my program where i am reading data into buffer( pnext) however read() returns a valid return value (len =8) but buffer seems to be corrupted (pnext = 0x64726f7773736170 ). is there any chance read() can lead to this corruption? Below is the code snippet:
do you think uninitialized char * pnext; can lead to any kind of corruption


int len = msglen; //we are assign valid length of structure
157 char *pnext;
158
159 do {
160 len = read(fd, pnext, msglen);
161 if (len < 0) {
162 if (errno == EAGAIN ||
163 errno == EWOULDBLOCK ||
164 errno == EINTR) {
165 continue;
166 }
167 else {
168 break;
169 }
170 }
171 if (len > 0) {
172 msglen -= len;
173 pnext += len;
174 }
175 } while (msglen > 0 && len != 0);
 


JasKinasis

Well-Known Member
Credits
4,005
Hi,
I am using linux version 4.1.12-112.14.15.el7uek.x86_64

in one of my program where i am reading data into buffer( pnext) however read() returns a valid return value (len =8) but buffer seems to be corrupted (pnext = 0x64726f7773736170 ). is there any chance read() can lead to this corruption? Below is the code snippet:
do you think uninitialized char * pnext; can lead to any kind of corruption


int len = msglen; //we are assign valid length of structure
157 char *pnext;
158
159 do {
160 len = read(fd, pnext, msglen);
161 if (len < 0) {
162 if (errno == EAGAIN ||
163 errno == EWOULDBLOCK ||
164 errno == EINTR) {
165 continue;
166 }
167 else {
168 break;
169 }
170 }
171 if (len > 0) {
172 msglen -= len;
173 pnext += len;
174 }
175 } while (msglen > 0 && len != 0);
In one word..... yes!
The problem isn’t with read, the problem exists between the chair and the keyboard!! Ha ha!

Because the pointer is uninitialised, it could be pointing to any memory address. But Read will attempt to populate the address pointed to by your uninitialised pointer.

So effectively, what you’re doing is corrupting the data in memory at that address.

If you declare a pointer variable, it should be initialised to null if it is not going to be pointing at anything straight away.
 

bodeplot

New Member
Credits
125
As @JasKinasis implied, you need to use malloc(). I've reworked your code to make it tidier:

/*msglen implied*/
int len;
char *pnext;

pnext = malloc(msglen); /*allocate dynamic memory*/
if (pnext == NULL) {
printf("Could not allocate memory. Ending program.\n");
exit(-1);
}

do {
len = read(fd, pnext, msglen);
if (len == -1) {
if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR) {
continue;
break;
}

msglen -= len;
pnext += len;
} while (msglen > 0);

Its been about 17 years since I mucked around with asynchronous file operations C. But I preferred to use select() and then run the read() as a blocking operation.

Damn: the forum editor removes the intention :(
 

JasKinasis

Well-Known Member
Credits
4,005
@bodeplot - I didn’t have time to write a code example earlier. I was about to give my girlfriend a driving lesson!
Just came back to post one! Saves me the bother, thanks!!

to preserve indentation, post code inside code tags. You can add them manually, or use the editors insert button “...” and select the “</>code” option and then paste your code in there and it will insert your code into your post inside tags.
 
Last edited:

abhicmrit

New Member
Credits
29
In one word..... yes!
The problem isn’t with read, the problem exists between the chair and the keyboard!! Ha ha!

Because the pointer is uninitialised, it could be pointing to any memory address. But Read will attempt to populate the address pointed to by your uninitialised pointer.

So effectively, what you’re doing is corrupting the data in memory at that address.

If you declare a pointer variable, it should be initialised to null if it is not going to be pointing at anything straight away.
Thanks for your comments.
but i have one more doubt that how read() handle unallocated buffer (i.e char *buff=NULL) vs Allocated Buffer (char *buff = malloc(size))
 

abhicmrit

New Member
Credits
29
As @JasKinasis implied, you need to use malloc(). I've reworked your code to make it tidier:

/*msglen implied*/
int len;
char *pnext;

pnext = malloc(msglen); /*allocate dynamic memory*/
if (pnext == NULL) {
printf("Could not allocate memory. Ending program.\n");
exit(-1);
}

do {
len = read(fd, pnext, msglen);
if (len == -1) {
if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR) {
continue;
break;
}

msglen -= len;
pnext += len;
} while (msglen > 0);

Its been about 17 years since I mucked around with asynchronous file operations C. But I preferred to use select() and then run the read() as a blocking operation.

Damn: the forum editor removes the intention :(
Thanks for your comments.
but i have one more doubt that how read() handle unallocated buffer (i.e char *buff=NULL) vs Allocated Buffer (char *buff = malloc(size))
 

bodeplot

New Member
Credits
125
If there is a condition that read() could load data into an unallocated pointer, then test it first.

Code:
if (pnext == NULL) {
    <handle it>
    return;
}

<Buffer reading code>
 

bodeplot

New Member
Credits
125
Depending on the situation, if it's an already used buffer, and you want to use it again:

Code:
if (pnext != NULL) {
    pnext = realloc(pnext, <new size>);
}
Nb/ Your example only applies to operations on a global or local pointers.

If you are performing these operatings on stack stored pointers (ie: the pointer is a parameter to a function), then you have to use a double pointer. If you don't, the pointer information is lost once the stack pointer is unallocated.
 


Members online


Top