diff --git a/realpath.c b/realpath.c index 1e0474605..cc96d7a3a 100644 --- a/realpath.c +++ b/realpath.c @@ -104,7 +104,8 @@ char * realpath(old, new) * Resolve the last component of the path if it is a link * until it is a non-link. */ - while ((statbuf.st_mode & _S_IFMT) == _S_IFLNK) { + errno = 0; + while (!lstat(new, &statbuf) && (statbuf.st_mode & _S_IFMT) == _S_IFLNK) { /* it's a link */ if ((len = readlink(new, buf, sizeof(buf))) <= 0) @@ -130,6 +131,10 @@ char * realpath(old, new) } } + /* did an lstat() fail? */ + if (errno) + return(realpath_ret(NULL, cwd)); + /* * separate the last component from the rest of the path * so we can do a getcwd() safely. @@ -155,7 +160,7 @@ char * realpath(old, new) /* append "/" and buf to new but watch for double '/' */ len = strlen(new); if (len) { - temp = new + len; + temp = new + len - 1; if (*temp != '/') { *(++temp) = '/'; *(++temp) = '\0'; diff --git a/sudo_realpath.c b/sudo_realpath.c index 1e0474605..cc96d7a3a 100644 --- a/sudo_realpath.c +++ b/sudo_realpath.c @@ -104,7 +104,8 @@ char * realpath(old, new) * Resolve the last component of the path if it is a link * until it is a non-link. */ - while ((statbuf.st_mode & _S_IFMT) == _S_IFLNK) { + errno = 0; + while (!lstat(new, &statbuf) && (statbuf.st_mode & _S_IFMT) == _S_IFLNK) { /* it's a link */ if ((len = readlink(new, buf, sizeof(buf))) <= 0) @@ -130,6 +131,10 @@ char * realpath(old, new) } } + /* did an lstat() fail? */ + if (errno) + return(realpath_ret(NULL, cwd)); + /* * separate the last component from the rest of the path * so we can do a getcwd() safely. @@ -155,7 +160,7 @@ char * realpath(old, new) /* append "/" and buf to new but watch for double '/' */ len = strlen(new); if (len) { - temp = new + len; + temp = new + len - 1; if (*temp != '/') { *(++temp) = '/'; *(++temp) = '\0';