bin/121897: [PATCH] realpath(3) segmentation fault
Eric Schuele
eric.schuele at computer.org
Thu Mar 20 05:10:02 UTC 2008
>Number: 121897
>Category: bin
>Synopsis: [PATCH] realpath(3) segmentation fault
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Thu Mar 20 05:10:01 UTC 2008
>Closed-Date:
>Last-Modified:
>Originator: Eric Schuele
>Release: FreeBSD 7.0-STABLE
>Organization:
>Environment:
FreeBSD fangorn.nxdomain.org 7.0-STABLE FreeBSD 7.0-STABLE #0: Wed Mar 12 12:50:03 CDT 2008 root at fangorn.nxdomain.org:/usr/obj/usr/src/sys/CUSTOM i386
>Description:
The following code seems to behave a little better on linux than FreeBSD 7.0.
#include <stdio.h>
#include <stdlib.h>
main ()
{
char buf[1024];
char *s = realpath(NULL, buf);
}
On FreeBSD I get a segmentation fault, while linux gracefully sets errno and goes on with its life. Do note that changing the above NULL to something a little more sane of course works.
The man page states:
"All but the last component of pathname must exist when realpath() is called."
So, on one hand maybe I was warned. Upon looking at the FreeBSD implementation of realpath(3) its obvious that a null pointer is not acceptable.
Now below is the first few lines of GNU libc's realpath implementation:
if (name == NULL)
{
/* As per Single Unix Specification V2 we must return an error if
either parameter is a null pointer. We extend this to allow
the RESOLVED parameter to be NULL in case the we are expected to allocate the room for the return value. */
__set_errno (EINVAL);
return NULL;
}
if (name[0] == '\0')
{
/* As per Single Unix Specification V2 we must return an error if
the name argument points to an empty string. */
__set_errno (ENOENT);
return NULL;
}
Seems reasonable we should have a similar approach since SUS requests as much. I have attached a patch which fixes the issue.
>How-To-Repeat:
compile and run the following prog:
#include <stdio.h>
#include <stdlib.h>
main ()
{
char buf[1024];
char *s = realpath(NULL, buf);
}
>Fix:
See attached patch.
Patch attached with submission follows:
--- realpath.c.0 2008-03-19 23:50:39.000000000 -0500
+++ realpath.c 2008-03-19 23:50:57.000000000 -0500
@@ -59,6 +59,15 @@
int serrno, slen;
char left[PATH_MAX], next_token[PATH_MAX], symlink[PATH_MAX];
+ if (path == NULL) {
+ errno = EINVAL;
+ return (NULL);
+ }
+ if (path[0] == '\0') {
+ errno = ENOENT;
+ return (NULL);
+ }
+
serrno = errno;
symlinks = 0;
if (path[0] == '/') {
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-bugs
mailing list