Re: errno in debug vs. release
Re: errno in debug vs. release
- Subject: Re: errno in debug vs. release
- From: Steve Checkoway <email@hidden>
- Date: Tue, 7 Feb 2006 13:21:13 -0800
On Feb 7, 2006, at 12:21 PM, John W Noerenberg II wrote:
I've been looking at problems with integer arithmetic and
discovered a problem between the default Xcode (v2.2.1) release
configuration and the debug configuration.
My test program is designed to illustrate how integer arithmetic
can introduce subtle vulnerabilities into your code. Here's my
little test program:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/errno.h>
int main (int argc, const char * argv[]) {
char *buf = 0x0;
unsigned short len = 0xffff;
char *bigTrouble = "Gotcha!";
len +=1;
free (buf);
printf (" after free, errno = %d\n", errno);
if (errno) perror("Error - free");
buf = malloc (len);
printf ("after malloc, errno = %d\n", errno);
if (errno) {
perror("Error - malloc");
printf ("Saved by the malloc!\n");
} else {
strcpy (buf, bigTrouble);
printf ("Not good. buf= 0x%x and %s\n", buf, buf);
}
return 0;
}
There a few problems with this. First, free() does not set errno and
it handles freeing NULL gracefully for me. Second, checking errno for
the presence of errors is, in general, incorrect. Most of the
standard library functions return -1 or NULL as in indication of
error and set errno. Many do not touch errno if the allocation
succeeds. In your example, len is set to zero. There doesn't seem to
be any problem with allocating zero bytes (although I seem to recall
that other systems have issues with it) on OS X. Since malloc is
returning a value, it allocated memory for you.
#include <stdio.h>
#include <stdlib.h>
#include <malloc/malloc.h>
int main()
{
void *buf = malloc(0);
printf( "%zu\n", malloc_size(buf) );
free( buf );
return 0;
}
When I run that code, it prints 16. (Note that the man page forgets
to mention that malloc_size is in malloc/malloc.h.)
When I build this with the debug configuration, I see the following
in gdb:
Program loaded.
sharedlibrary apply-load-rules all
run
[Switching to process 1491 local thread 0xf03]
RunningÅ
Pending breakpoint 2 - ""main.c:13" resolved
(gdb) continue
after free, errno = 9
Error - free: Bad file descriptor
after malloc, errno = 9
Error - malloc: Bad file descriptor
Saved by the malloc!
Debugger stopped.
Program exited with status value:0.
Looks good.
No, it doesn't. malloc will never set errno to EBADF. That doesn't
make any sense since no file descriptors are involved. If malloc
returns NULL, it will set errno to ENOMEM. Something else is setting
errno for you before you call free and malloc which are both
succeeding (for some definition of succeed in free's case).
But when I switch to the release config, build and run the program:
[host112:~/mallocFail/build/Release] jwn2% ./mallocFail
after free, errno = 0
after malloc, errno = 0
Not good. buf= 0x500160 and Gotcha!
[host112:~/mallocFail/build/Release] jwn2%
So with the release configuration free releases unallocated memory
and malloc clobbers the heap.
This is programmer error. You allocated 0 bytes and then tried to
write over it. Note that it actually allocated 16 bytes for you so
when you copy those 8 bytes in, nothing bad happened.
I haven't looked to see if there is a simple way to edit the build
configs (not being an Xcode wizard). Does anyone know how to fix
this so the release config invoke versions of malloc and free that
do the right thing?
Don't worry, malloc and free will do the right thing for you. In your
code, try explicitly setting errno = 0; before the first call to free.
- Steve
Attachment:
smime.p7s
Description: S/MIME cryptographic signature
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Xcode-users mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden