Subject: Re: lib/12393: segfault in setenv(3)
To: Simon J. Gerraty <sjg@quick.com.au>
From: Chris G. Demetriou <cgd@sibyte.com>
List: netbsd-bugs
Date: 03/12/2001 11:50:30
[ BTW, for some reason i couldn't get your patch to actually apply... ]
"Simon J. Gerraty" <sjg@quick.com.au> writes:
> for (p = environ, cnt = 0; *p; ++p, ++cnt);
> if (alloced) { /* just increase size */
> - environ = realloc(environ,
> - (size_t)(sizeof(char *) * (cnt + 2)));
> - if (!environ) {
> + p = realloc(environ,
> + (size_t)(sizeof(char *) * (cnt + 2)));
> + if (!p) {
I think the "p != NULL" form is better style for this test.
> rwlock_unlock(&__environ_lock);
> return (-1);
> }
> + environ = p;
> }
> else { /* get new space */
> alloced = 1; /* copy old entries into it */
I looked at the 'else' (! alloced) case as well, and i think it has a
bug: if the malloc fails, alloced will be inappropriately set to 1.
Also, really, the two cases can be collapsed since realloc(NULL, ...)
is allowed by c89 (and we're now allowing c89 8-).
What do you think about the diff below (based on yours 8-)? I've not
tried even compiling it... 8-)
chris
===================================================================
Index: setenv.c
===================================================================
RCS file: /cvsroot/basesrc/lib/libc/stdlib/setenv.c,v
retrieving revision 1.19
diff -c -r1.19 setenv.c
*** setenv.c 2000/12/20 18:38:30 1.19
--- setenv.c 2001/03/12 19:48:19
***************
*** 101,124 ****
char **p;
for (p = environ, cnt = 0; *p; ++p, ++cnt);
! if (alloced) { /* just increase size */
! environ = realloc(environ,
! (size_t)(sizeof(char *) * (cnt + 2)));
! if (!environ) {
! rwlock_unlock(&__environ_lock);
! return (-1);
! }
}
! else { /* get new space */
! alloced = 1; /* copy old entries into it */
! p = malloc((size_t)(sizeof(char *) * (cnt + 2)));
! if (!p) {
! rwlock_unlock(&__environ_lock);
! return (-1);
! }
memcpy(p, environ, cnt * sizeof(char *));
! environ = p;
}
environ[cnt + 1] = NULL;
offset = cnt;
}
--- 101,122 ----
char **p;
for (p = environ, cnt = 0; *p; ++p, ++cnt);
!
! /* Allocate the space for the larger list. */
! p = realloc(alloced ? environ : NULL,
! (size_t)(sizeof(char *) * (cnt + 2)));
! if (p == NULL) {
! rwlock_unlock(&__environ_lock);
! return (-1);
}
!
! /* If new allocation, copy entries from environ. */
! if (!alloced) {
memcpy(p, environ, cnt * sizeof(char *));
! alloced = 1;
}
+
+ environ = p;
environ[cnt + 1] = NULL;
offset = cnt;
}