FreeBSD Bugzilla – Attachment 182421 Details for
Bug 219154
[PATCH] buffer overflows in realpath(3)
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
fixes for realpath(3)
realpath-fixes.patch (text/plain), 3.18 KB, created by
Jan Kokemüller
on 2017-05-08 22:22:54 UTC
(
hide
)
Description:
fixes for realpath(3)
Filename:
MIME Type:
Creator:
Jan Kokemüller
Created:
2017-05-08 22:22:54 UTC
Size:
3.18 KB
patch
obsolete
>diff --git lib/libc/stdlib/realpath.c lib/libc/stdlib/realpath.c >index c4bd953..73f1f9b 100644 >--- lib/libc/stdlib/realpath.c >+++ lib/libc/stdlib/realpath.c >@@ -36,6 +36,7 @@ __FBSDID("$FreeBSD$"); > #include <sys/param.h> > #include <sys/stat.h> > >+#include <assert.h> > #include <errno.h> > #include <stdlib.h> > #include <string.h> >@@ -51,10 +52,11 @@ char * > realpath(const char * __restrict path, char * __restrict resolved) > { > struct stat sb; >- char *p, *q, *s; >- size_t left_len, resolved_len; >+ char *p, *q; >+ size_t left_len, resolved_len, next_token_len; > unsigned symlinks; >- int m, slen; >+ int m; >+ ssize_t slen; > char left[PATH_MAX], next_token[PATH_MAX], symlink[PATH_MAX]; > > if (path == NULL) { >@@ -93,7 +95,8 @@ realpath(const char * __restrict path, char * __restrict resolved) > resolved_len = strlen(resolved); > left_len = strlcpy(left, path, sizeof(left)); > } >- if (left_len >= sizeof(left) || resolved_len >= PATH_MAX) { >+ >+ if (left_len >= sizeof(left)) { > if (m) > free(resolved); > errno = ENAMETOOLONG; >@@ -104,23 +107,28 @@ realpath(const char * __restrict path, char * __restrict resolved) > * Iterate over path components in `left'. > */ > while (left_len != 0) { >+ assert(left[left_len] == '\0'); >+ > /* > * Extract the next path component and adjust `left' > * and its length. > */ > p = strchr(left, '/'); >- s = p ? p : left + left_len; >- if (s - left >= sizeof(next_token)) { >- if (m) >- free(resolved); >- errno = ENAMETOOLONG; >- return (NULL); >+ >+ assert(sizeof(next_token) >= sizeof(left)); >+ >+ next_token_len = p ? p - left : left_len; >+ memcpy(next_token, left, next_token_len); >+ next_token[next_token_len] = '\0'; >+ >+ if (p != NULL) { >+ left_len -= next_token_len + 1; >+ memmove(left, p + 1, left_len + 1); >+ } else { >+ left[0] = '\0'; >+ left_len = 0; > } >- memcpy(next_token, left, s - left); >- next_token[s - left] = '\0'; >- left_len -= s - left; >- if (p != NULL) >- memmove(left, s + 1, left_len + 1); >+ > if (resolved[resolved_len - 1] != '/') { > if (resolved_len + 1 >= PATH_MAX) { > if (m) >@@ -173,19 +181,25 @@ realpath(const char * __restrict path, char * __restrict resolved) > errno = ELOOP; > return (NULL); > } >- slen = readlink(resolved, symlink, sizeof(symlink) - 1); >- if (slen < 0) { >+ slen = readlink(resolved, symlink, sizeof(symlink)); >+ if (slen <= 0 || slen >= sizeof(symlink)) { > if (m) > free(resolved); >+ if (slen < 0) { >+ /* keep errno from readlink(2) call */ >+ } else if (slen == 0) { >+ errno = ENOENT; >+ } else { >+ errno = ENAMETOOLONG; >+ } > return (NULL); > } > symlink[slen] = '\0'; > if (symlink[0] == '/') { > resolved[1] = 0; > resolved_len = 1; >- } else if (resolved_len > 1) { >+ } else { > /* Strip the last path component. */ >- resolved[resolved_len - 1] = '\0'; > q = strrchr(resolved, '/') + 1; > *q = '\0'; > resolved_len = q - resolved; >@@ -209,7 +223,7 @@ realpath(const char * __restrict path, char * __restrict resolved) > } > left_len = strlcat(symlink, left, > sizeof(symlink)); >- if (left_len >= sizeof(left)) { >+ if (left_len >= sizeof(symlink)) { > if (m) > free(resolved); > errno = ENAMETOOLONG;
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 219154
: 182421 |
182684