Date: Thu, 20 Mar 2008 05:09:57 GMT From: Eric Schuele <eric.schuele@computer.org> To: freebsd-gnats-submit@FreeBSD.org Subject: bin/121897: [PATCH] realpath(3) segmentation fault Message-ID: <200803200509.m2K59vIm036244@www.freebsd.org> Resent-Message-ID: <200803200510.m2K5A1O7094121@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>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@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:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200803200509.m2K59vIm036244>