Return to BSD News archive
Received: by minnie.vk1xwt.ampr.org with NNTP
id AA7615 ; Mon, 25 Jan 93 12:18:51 EST
Newsgroups: comp.unix.bsd
Path: sserve!manuel.anu.edu.au!munnari.oz.au!metro!ipso!runxtsa!bde
From: bde@runx.oz.au (Bruce Evans)
Subject: [386BSD] Bug + fix: getcwd off by one
Message-ID: <1993Jan22.185211.5564@runx.oz.au>
Organization: RUNX Un*x Timeshare. Sydney, Australia.
Date: Fri, 22 Jan 93 18:52:11 GMT
Lines: 87
getcwd() has two off-by-one bugs in 386BSD-0.1:
1. getcwd(buf, size) fails when the size is just large enough.
2. getcwd(buf + 1, 1) incorrectly succeeds when the current directory
is "/". buf[0] and buf[2] are clobbered.
This program demonstrates the bug:
---
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
int main(void)
{
char buf[5];
int errors;
errors = 0;
if (chdir("/tmp") != 0) {
perror("chdir");
abort();
}
if (getcwd(buf, 5) == NULL) {
perror("oops, getcwd failed for buffer size = size required");
++errors;
}
if (chdir("/") != 0) {
perror("chdir");
abort();
}
buf[0] = 0;
buf[2] = 1;
if (getcwd(buf + 1, 1) != NULL) {
fprintf(stderr,
"oops, getcwd succeeded for buffer size = one too small\n");
++errors;
}
if (buf[0] != 0) {
fprintf(stderr,
"oops, getcwd scribbled on memory before start of buffer\n");
++errors;
}
if (buf[2] != 1) {
fprintf(stderr,
"oops, getcwd scribbled on memory after end of buffer\n");
++errors;
}
exit(errors == 0 ? 0 : 1);
}
---
This might be a fix:
---
*** /usr/src/lib/libc/gen/getcwd.c~ Wed May 1 10:35:50 1991
--- /usr/src/lib/libc/gen/getcwd.c Tue Jan 19 22:22:38 1993
***************
*** 74,78 ****
if (pt) {
ptsize = 0;
! if (!size) {
errno = EINVAL;
return((char *)NULL);
--- 74,78 ----
if (pt) {
ptsize = 0;
! if (size < 2) {
errno = EINVAL;
return((char *)NULL);
***************
*** 186,190 ****
* leading slash.
*/
! if (bpt - pt <= dp->d_namlen + (first ? 1 : 2)) {
size_t len, off;
--- 186,190 ----
* leading slash.
*/
! if (bpt - pt < dp->d_namlen + (first ? 1 : 2)) {
size_t len, off;
---
--
Bruce Evans (bde@runx.oz.au)