summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorderaadt <>2019-05-29 11:54:49 +0000
committerderaadt <>2019-05-29 11:54:49 +0000
commit6b1ad48294a0af0fd73aeb2cdf19eedfd6013666 (patch)
tree379a082790aab53f8c0fc76885bc28f362b4301d
parent35418daf72459e257c8c1fa30b78d21cb06ddd8e (diff)
downloadopenbsd-6b1ad48294a0af0fd73aeb2cdf19eedfd6013666.tar.gz
openbsd-6b1ad48294a0af0fd73aeb2cdf19eedfd6013666.tar.bz2
openbsd-6b1ad48294a0af0fd73aeb2cdf19eedfd6013666.zip
There are some bugs in __realpath(2) -- it isn't quite ready so disable
calling it until those are fixed.
-rw-r--r--src/lib/libc/stdlib/realpath.c139
1 files changed, 3 insertions, 136 deletions
diff --git a/src/lib/libc/stdlib/realpath.c b/src/lib/libc/stdlib/realpath.c
index 76f88562fb..dc8aa9af20 100644
--- a/src/lib/libc/stdlib/realpath.c
+++ b/src/lib/libc/stdlib/realpath.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: realpath.c,v 1.23 2019/05/28 13:08:56 beck Exp $ */ 1/* $OpenBSD: realpath.c,v 1.24 2019/05/29 11:54:49 deraadt Exp $ */
2/* 2/*
3 * Copyright (c) 2003 Constantin S. Svintsoff <kostik@iclub.nsu.ru> 3 * Copyright (c) 2003 Constantin S. Svintsoff <kostik@iclub.nsu.ru>
4 * 4 *
@@ -32,8 +32,6 @@
32#include <string.h> 32#include <string.h>
33#include <unistd.h> 33#include <unistd.h>
34#include <limits.h> 34#include <limits.h>
35#include <syslog.h>
36#include <stdarg.h>
37 35
38/* A slightly modified copy of this file exists in libexec/ld.so */ 36/* A slightly modified copy of this file exists in libexec/ld.so */
39 37
@@ -44,8 +42,8 @@
44 * components. Returns (resolved) on success, or (NULL) on failure, 42 * components. Returns (resolved) on success, or (NULL) on failure,
45 * in which case the path which caused trouble is left in (resolved). 43 * in which case the path which caused trouble is left in (resolved).
46 */ 44 */
47static char * 45char *
48urealpath(const char *path, char *resolved) 46realpath(const char *path, char *resolved)
49{ 47{
50 const char *p; 48 const char *p;
51 char *q; 49 char *q;
@@ -53,7 +51,6 @@ urealpath(const char *path, char *resolved)
53 unsigned symlinks; 51 unsigned symlinks;
54 int serrno, mem_allocated; 52 int serrno, mem_allocated;
55 ssize_t slen; 53 ssize_t slen;
56 int trailingslash = 0;
57 char left[PATH_MAX], next_token[PATH_MAX], symlink[PATH_MAX]; 54 char left[PATH_MAX], next_token[PATH_MAX], symlink[PATH_MAX];
58 55
59 if (path == NULL) { 56 if (path == NULL) {
@@ -234,133 +231,3 @@ err:
234 free(resolved); 231 free(resolved);
235 return (NULL); 232 return (NULL);
236} 233}
237
238/*
239 * Copyright (c) 2019 Bob Beck <beck@openbsd.org>
240 *
241 * Permission to use, copy, modify, and/or distribute this software for any
242 * purpose with or without fee is hereby granted, provided that the above
243 * copyright notice and this permission notice appear in all copies.
244 *
245 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
246 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
247 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
248 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
249 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
250 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
251 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
252 */
253
254int __realpath(const char *pathname, char *resolved);
255PROTO_NORMAL(__realpath);
256
257/*
258 * wrapper for kernel __realpath
259 */
260
261char *
262realpath(const char *path, char *resolved)
263{
264 char pbuf[PATH_MAX], rbuf[PATH_MAX], expected[PATH_MAX];
265 struct syslog_data sdata = SYSLOG_DATA_INIT;
266 int usererrno = 0, kernelerrno = 0, trailingslash = 0, save_errno;
267 int kernelonly = (getenv("USE_KERNEL_REALPATH") != NULL);
268 ssize_t i;
269
270 rbuf[0] = pbuf[0] = expected[0] = '\0';
271
272 if (!kernelonly) {
273 memset(expected, 0, sizeof(expected));
274 if (urealpath(path, expected) == NULL) {
275 usererrno = errno;
276 expected[0] = '\0';
277 }
278 }
279
280 if (path == NULL) {
281 kernelerrno = EINVAL;
282 goto out;
283 }
284 if (path[0] == '\0') {
285 kernelerrno = ENOENT;
286 goto out;
287 }
288 if (strlcat(pbuf, path, sizeof(pbuf)) >= sizeof(pbuf)) {
289 kernelerrno = ENAMETOOLONG;
290 goto out;
291 }
292
293 if (pbuf[strlen(pbuf) - 1] == '/')
294 trailingslash = 1;
295
296 if (__realpath(pbuf, rbuf) == -1)
297 kernelerrno = errno;
298
299 /*
300 * XXX XXX XXX
301 *
302 * The old userland implementation strips trailing slashes.
303 * According to Dr. POSIX, realpathing "/bsd" should be fine,
304 * realpathing "/bsd/" should return ENOTDIR.
305 *
306 * Similar, but *different* to the above, The old userland
307 * implementation allows for realpathing "/nonexistent" but
308 * not "/nonexistent/", Both those should return ENOENT
309 * according to POSIX.
310 *
311 * This hack should go away once we decide to match POSIX.
312 * which we should as soon as is convenient.
313 */
314 if (kernelerrno == ENOTDIR) {
315 /* Try again without the trailing slash. */
316 kernelerrno = 0;
317 for (i = strlen(pbuf); i > 1 && pbuf[i - 1] == '/'; i--)
318 pbuf[i - 1] = '\0';
319 rbuf[0] = '\0';
320 if (__realpath(pbuf, rbuf) == -1)
321 kernelerrno = errno;
322 }
323
324out:
325 if (!kernelonly) {
326 /* syslog if kernel and userland are different */
327 save_errno = errno;
328 if (strcmp(rbuf, expected) != 0 || (usererrno == 0 &&
329 kernelerrno != 0))
330 syslog_r(LOG_CRIT | LOG_CONS, &sdata,
331 "realpath '%s' -> '%s' errno %d, "
332 "expected '%s' errno %d", path, rbuf,
333 kernelerrno, expected, usererrno);
334 errno = save_errno;
335
336 /* use userland result */
337 if (usererrno) {
338 errno = usererrno;
339 return NULL;
340 }
341 else
342 errno = 0;
343 if (resolved == NULL)
344 resolved = strdup(expected);
345 else if (strlcpy(resolved, expected, PATH_MAX) >= PATH_MAX) {
346 errno = ENAMETOOLONG;
347 return NULL;
348 }
349
350 } else {
351 /* use kernel result */
352 if (kernelerrno) {
353 errno = kernelerrno;
354 return NULL;
355 }
356 else
357 errno = 0;
358 if (resolved == NULL)
359 resolved = strdup(rbuf);
360 else if (strlcpy(resolved, rbuf, PATH_MAX) >= PATH_MAX) {
361 errno = ENAMETOOLONG;
362 return NULL;
363 }
364 }
365 return (resolved);
366}