aboutsummaryrefslogtreecommitdiffstats
path: root/guts/getcwd.c
diff options
context:
space:
mode:
Diffstat (limited to 'guts/getcwd.c')
-rw-r--r--guts/getcwd.c36
1 files changed, 30 insertions, 6 deletions
diff --git a/guts/getcwd.c b/guts/getcwd.c
index d8f4d36..f6a8521 100644
--- a/guts/getcwd.c
+++ b/guts/getcwd.c
@@ -3,7 +3,7 @@
* wrap_getcwd(char *buf, size_t size) {
* char * rc = NULL;
*/
- pseudo_debug(2, "wrap_getcwd: %p, %lu\n",
+ pseudo_debug(3, "wrap_getcwd: %p, %lu\n",
(void *) buf, (unsigned long) size);
if (!pseudo_cwd) {
pseudo_diag("Asked for CWD, but don't have it!\n");
@@ -12,15 +12,26 @@
}
/* emulate Linux semantics in case of non-Linux systems. */
if (!buf) {
- /* if we don't have one, something's very wrong... */
+ /* if we don't have a cwd, something's very wrong... */
if (!size) {
- size = pseudo_cwd_len;
+ size = pseudo_cwd_len + 1;
+ if (pseudo_chroot_len && size >= pseudo_chroot_len &&
+ !memcmp(pseudo_cwd, pseudo_chroot, pseudo_chroot_len)) {
+ size -= pseudo_chroot_len;
+ /* if cwd is precisely the same as chroot, we
+ * actually want a /, not an empty string
+ */
+ if (size < 2)
+ size = 2;
+ }
}
if (size) {
buf = malloc(size);
} else {
- pseudo_diag("can't figure out CWD: length %ld\n",
- (unsigned long) pseudo_cwd_len);
+ pseudo_diag("can't figure out CWD: length %ld + 1 - %ld => %ld\n",
+ (unsigned long) pseudo_cwd_len,
+ (unsigned long) pseudo_chroot_len,
+ (unsigned long) size);
}
if (!buf) {
pseudo_diag("couldn't allocate requested CWD buffer - need %ld byes\n",
@@ -29,8 +40,21 @@
return NULL;
}
}
+ if (pseudo_cwd_len - (pseudo_cwd_rel - pseudo_cwd) >= size) {
+ pseudo_diag("only %ld bytes available, need %ld (%ld + 1 - %ld)\n",
+ (unsigned long) size,
+ (unsigned long) pseudo_cwd_len + 1 - pseudo_chroot_len,
+ (unsigned long) pseudo_cwd_len,
+ (unsigned long) pseudo_chroot_len);
+ errno = ENAMETOOLONG;
+ return NULL;
+ }
rc = buf;
- memcpy(buf, pseudo_cwd, pseudo_cwd_len + 1);
+ pseudo_debug(3, "getcwd: copying %d (%d + 1 - %d) characters from <%s>.\n",
+ (int) ((pseudo_cwd_len + 1) - pseudo_chroot_len),
+ pseudo_cwd_len, pseudo_chroot_len,
+ pseudo_cwd_rel);
+ memcpy(buf, pseudo_cwd_rel, (pseudo_cwd_len + 1) - (pseudo_cwd_rel - pseudo_cwd));
if (!*buf) {
strcpy(buf, "/");
}