diff options
author | Dan McDonald <danmcd@joyent.com> | 2021-03-19 11:38:16 -0400 |
---|---|---|
committer | Dan McDonald <danmcd@joyent.com> | 2021-03-19 11:38:16 -0400 |
commit | a1ce764f98e19204e95ee78d66746478d10ea59c (patch) | |
tree | b210134e2dd21bde06dae97ddebffce293b3d39d /usr/src/lib/libc | |
parent | 1d684b54ff06842338ae5e57f8873ec9b9d24df3 (diff) | |
parent | fc1e9305ae86a296023d90240041e860548ba1bd (diff) | |
download | illumos-joyent-a1ce764f98e19204e95ee78d66746478d10ea59c.tar.gz |
[illumos-gate merge]
commit fc1e9305ae86a296023d90240041e860548ba1bd
13627 chown(2) mixes up chown() and fchown()
commit 173f6047c6877d03cbb55428e6ec95f07c9cbb83
13622 Memory leak in coretemp_create_sensor
commit 1b1c4b089b04ffa47f04c2923dc78c7fcafcf964
13575 loader: use display pixel density for font autoselection
commit 5fbc1fe0da7f34cf8155bf7624c94583cc98e47c
13526 cmd/availdevs always rebuilds
commit b2761fb273089c452ca34297d7ab4a1d1c1f1012
13599 ahci(7d) requires alias for HP AHCI SATA controller
commit 6edc7986d8c0034d072afac8b25477b983bf8f55
13586 getcwd() should accept a 0 length argument (fix mandoc)
commit d6f391ef39bc41c64e16ac5d7b10c1c8d5b1761e
4149 ksh head builtin does not like newlines
commit aa15372140b6b509a26742fd85fe78dd77d9a642
13586 getcwd() should accept a 0 length argument
commit f38f28fdbc29b3c5020295a6c6cb1ac52e949978
13574 loader.efi: efifb_gop_get_edid() is broken
commit 8781de92560745751daa24953330574a84de46e6
13632 smntemp doesn't need smntemp alias
commit 7eb8c88abb70697edf48045434d2c18bb82ad2e7
9620 getcwd() syscall has unbounded memory allocation
commit f9bbf53b825c087ef99dd9b3e51570ec68a51463
12558 Builtin command "printf" of ksh93 does not behave as specified
commit 4162633a7c5961f388fdc51bcecb3016104b359f
3782 ksh93's builtin chown fails with numeric ids
Diffstat (limited to 'usr/src/lib/libc')
-rw-r--r-- | usr/src/lib/libc/port/gen/getcwd.c | 50 |
1 files changed, 48 insertions, 2 deletions
diff --git a/usr/src/lib/libc/port/gen/getcwd.c b/usr/src/lib/libc/port/gen/getcwd.c index d832d798d7..62f12e027e 100644 --- a/usr/src/lib/libc/port/gen/getcwd.c +++ b/usr/src/lib/libc/port/gen/getcwd.c @@ -22,10 +22,9 @@ /* * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * Copyright 2021 OmniOS Community Edition (OmniOSce) Association. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * getcwd() returns the pathname of the current working directory. * On error, a NULL pointer is returned and errno is set. @@ -34,16 +33,63 @@ #pragma weak _getcwd = getcwd #include "lint.h" +#include <sys/param.h> #include <sys/syscall.h> #include <sys/types.h> #include <errno.h> +#include <limits.h> #include <stdlib.h> +#include <string.h> +#include <unistd.h> char * getcwd(char *pathname, size_t size) { int alloc = 0; + if (size == 0 && pathname == NULL) { + /* + * If no size was provided, start with a buffer that should + * accommodate any normal path and, if it is not big enough, + * keep doubling it to try and make enough space. + * + * Any non-global zone path is longer when observed from the + * global zone, and some filesystems, including ZFS, support + * paths much longer than MAXPATHLEN/_PC_PATH_MAX. + * + * To protect against unbounded memory usage, cap to 128KiB. + * This is an arbitrary limit which is far bigger than the + * length of any practical path on the system. + */ + if ((size = pathconf(".", _PC_PATH_MAX)) == -1) + size = MAXPATHLEN; + + while (size <= 0x20000) { + if ((pathname = reallocf(pathname, size)) == NULL) { + errno = ENOMEM; + return (NULL); + } + if (syscall(SYS_getcwd, pathname, size) == 0) { + char *ret; + + /* + * Shrink the buffer to the length actually + * required to hold the final path. + */ + ret = realloc(pathname, strlen(pathname) + 1); + if (ret == NULL) + return (pathname); + + return (ret); + } + if (errno != ERANGE) + break; + size <<= 1; + } + free(pathname); + return (NULL); + } + if (size == 0) { errno = EINVAL; return (NULL); |