summaryrefslogtreecommitdiff
path: root/usr/src/lib/libc
diff options
context:
space:
mode:
authorDan McDonald <danmcd@joyent.com>2021-03-19 11:38:16 -0400
committerDan McDonald <danmcd@joyent.com>2021-03-19 11:38:16 -0400
commita1ce764f98e19204e95ee78d66746478d10ea59c (patch)
treeb210134e2dd21bde06dae97ddebffce293b3d39d /usr/src/lib/libc
parent1d684b54ff06842338ae5e57f8873ec9b9d24df3 (diff)
parentfc1e9305ae86a296023d90240041e860548ba1bd (diff)
downloadillumos-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.c50
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);