From 86299552a14c09de033065a8a8c04f414ca0e71e Mon Sep 17 00:00:00 2001 From: Alex Jordan Date: Thu, 7 Jul 2016 09:31:08 -0700 Subject: [PATCH 1/8] Absolute filepath resolution for followsymlink --- src/libpsl-native/src/followsymlink.cpp | 129 +++++++++++++++++------- 1 file changed, 91 insertions(+), 38 deletions(-) diff --git a/src/libpsl-native/src/followsymlink.cpp b/src/libpsl-native/src/followsymlink.cpp index 40e12b9b78..eac83f0d47 100644 --- a/src/libpsl-native/src/followsymlink.cpp +++ b/src/libpsl-native/src/followsymlink.cpp @@ -45,46 +45,99 @@ char* FollowSymLink(const char* fileName) return NULL; } - char buffer[PATH_MAX]; - ssize_t sz = readlink(fileName, buffer, PATH_MAX); + char actualpath[PATH_MAX+1]; + char* realPath = realpath(fileName, actualpath); + - if (sz == -1) + /* if realPath does not return a value, continue with previous implementation of symlink*/ + if (realPath == NULL) { - switch(errno) + char buffer[PATH_MAX]; + ssize_t sz = readlink(fileName, buffer, PATH_MAX); + + if (sz == -1) { - case EACCES: - errno = ERROR_ACCESS_DENIED; - break; - case EFAULT: - errno = ERROR_INVALID_ADDRESS; - break; - case EINVAL: - errno = ERROR_INVALID_NAME; - break; - case EIO: - errno = ERROR_GEN_FAILURE; - break; - case ELOOP: - errno = ERROR_STOPPED_ON_SYMLINK; - break; - case ENAMETOOLONG: - errno = ERROR_BAD_PATH_NAME; - break; - case ENOENT: - errno = ERROR_FILE_NOT_FOUND; - break; - case ENOMEM: - errno = ERROR_OUTOFMEMORY; - break; - case ENOTDIR: - errno = ERROR_BAD_PATH_NAME; - break; - default: - errno = ERROR_INVALID_FUNCTION; - } - return NULL; - } - buffer[sz] = '\0'; - return strndup(buffer, sz + 1); + switch(errno) + + { + case EACCES: + errno = ERROR_ACCESS_DENIED; + break; + case EFAULT: + errno = ERROR_INVALID_ADDRESS; + break; + case EINVAL: + errno = ERROR_INVALID_NAME; + break; + case EIO: + errno = ERROR_GEN_FAILURE; + break; + case ELOOP: + errno = ERROR_STOPPED_ON_SYMLINK; + break; + case ENAMETOOLONG: + errno = ERROR_BAD_PATH_NAME; + break; + case ENOENT: + errno = ERROR_FILE_NOT_FOUND; + break; + case ENOMEM: + errno = ERROR_OUTOFMEMORY; + break; + case ENOTDIR: + errno = ERROR_BAD_PATH_NAME; + break; + default: + errno = ERROR_INVALID_FUNCTION; + } + return NULL; + } + + buffer[sz] = '\0'; + return strndup(buffer, sz + 1); + } + +/*else realpath returned a valid resolved path*/ + else + { + if (sizeof(realPath) == -1) + { + switch(errno) + { + case EACCES: + errno = ERROR_ACCESS_DENIED; + break; + case EFAULT: + errno = ERROR_INVALID_ADDRESS; + break; + case EINVAL: + errno = ERROR_INVALID_NAME; + break; + case EIO: + errno = ERROR_GEN_FAILURE; + break; + case ELOOP: + errno = ERROR_STOPPED_ON_SYMLINK; + break; + case ENAMETOOLONG: + errno = ERROR_BAD_PATH_NAME; + break; + case ENOENT: + errno = ERROR_FILE_NOT_FOUND; + break; + case ENOMEM: + errno = ERROR_OUTOFMEMORY; + break; + case ENOTDIR: + errno = ERROR_BAD_PATH_NAME; + break; + default: + errno = ERROR_INVALID_FUNCTION; + } + return NULL; + } + + return strndup(realPath, strlen(realPath) + 1 ); + } } From 64496d7bcc64159a9f001c48f4cff2fa46e8f762 Mon Sep 17 00:00:00 2001 From: Alex Jordan Date: Thu, 7 Jul 2016 12:12:16 -0700 Subject: [PATCH 2/8] adding check for symlink to followsymlink --- src/libpsl-native/src/followsymlink.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/libpsl-native/src/followsymlink.cpp b/src/libpsl-native/src/followsymlink.cpp index eac83f0d47..d4308f2df6 100644 --- a/src/libpsl-native/src/followsymlink.cpp +++ b/src/libpsl-native/src/followsymlink.cpp @@ -7,7 +7,7 @@ #include #include #include "followsymlink.h" - +#include "issymlink.h" //! @brief Followsymlink determines target path of a sym link //! //! Followsymlink @@ -48,16 +48,14 @@ char* FollowSymLink(const char* fileName) char actualpath[PATH_MAX+1]; char* realPath = realpath(fileName, actualpath); - /* if realPath does not return a value, continue with previous implementation of symlink*/ - if (realPath == NULL) + if (IsSymLink(fileName)) { char buffer[PATH_MAX]; - ssize_t sz = readlink(fileName, buffer, PATH_MAX); + ssize_t sz = readlink(fileName, buffer, PATH_MAX); if (sz == -1) { - switch(errno) { From 2a6b32ce5b342becee227b724efd2719ddb58dd1 Mon Sep 17 00:00:00 2001 From: Alex Jordan Date: Thu, 7 Jul 2016 14:54:47 -0700 Subject: [PATCH 3/8] Refactored followsymlink --- src/libpsl-native/src/followsymlink.cpp | 35 +++++++++++++++++-------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/src/libpsl-native/src/followsymlink.cpp b/src/libpsl-native/src/followsymlink.cpp index d4308f2df6..24a5446645 100644 --- a/src/libpsl-native/src/followsymlink.cpp +++ b/src/libpsl-native/src/followsymlink.cpp @@ -8,6 +8,7 @@ #include #include "followsymlink.h" #include "issymlink.h" + //! @brief Followsymlink determines target path of a sym link //! //! Followsymlink @@ -38,26 +39,30 @@ char* FollowSymLink(const char* fileName) { errno = 0; - // Check parameters + // if filename is null, return null value if (!fileName) { errno = ERROR_INVALID_PARAMETER; return NULL; } - char actualpath[PATH_MAX+1]; - char* realPath = realpath(fileName, actualpath); - - /* if realPath does not return a value, continue with previous implementation of symlink*/ - if (IsSymLink(fileName)) + //if lstat in IsSymLink returns -1, path does not exist + if (IsSymLink(fileName) == -1) { + printf("-1 %s", fileName); + return NULL; + } + + /*If the path is a symlink, the function return the absolute filepath if valid. if not valid, return null*/ + if (IsSymLink(fileName) == 1) + { + printf("readlink %s", fileName); char buffer[PATH_MAX]; ssize_t sz = readlink(fileName, buffer, PATH_MAX); if (sz == -1) { switch(errno) - { case EACCES: errno = ERROR_ACCESS_DENIED; @@ -89,16 +94,23 @@ char* FollowSymLink(const char* fileName) default: errno = ERROR_INVALID_FUNCTION; } + return NULL; } buffer[sz] = '\0'; return strndup(buffer, sz + 1); - } - -/*else realpath returned a valid resolved path*/ + + } + + /*else the path is not a symlink - but attempt to resolve*/ else { + printf("realpath %s", fileName); + //Attempt to resolve with the absolute filepath + char actualpath[PATH_MAX+1]; + char* realPath = realpath(fileName, actualpath); + if (sizeof(realPath) == -1) { switch(errno) @@ -133,9 +145,10 @@ char* FollowSymLink(const char* fileName) default: errno = ERROR_INVALID_FUNCTION; } + return NULL; } - return strndup(realPath, strlen(realPath) + 1 ); + return strndup(realPath, strlen(realPath) + 1 ); } } From 0dc248b6f929781deb31e0834c4dd16ac3da1be5 Mon Sep 17 00:00:00 2001 From: Alex Jordan Date: Thu, 7 Jul 2016 15:02:23 -0700 Subject: [PATCH 4/8] changes to logic in followsymlink --- src/libpsl-native/src/followsymlink.cpp | 103 ++++++++++++------------ 1 file changed, 50 insertions(+), 53 deletions(-) diff --git a/src/libpsl-native/src/followsymlink.cpp b/src/libpsl-native/src/followsymlink.cpp index 24a5446645..1540037eb2 100644 --- a/src/libpsl-native/src/followsymlink.cpp +++ b/src/libpsl-native/src/followsymlink.cpp @@ -49,64 +49,13 @@ char* FollowSymLink(const char* fileName) //if lstat in IsSymLink returns -1, path does not exist if (IsSymLink(fileName) == -1) { - printf("-1 %s", fileName); return NULL; } /*If the path is a symlink, the function return the absolute filepath if valid. if not valid, return null*/ - if (IsSymLink(fileName) == 1) + if (IsSymLink(fileName) == 0) { - printf("readlink %s", fileName); - char buffer[PATH_MAX]; - ssize_t sz = readlink(fileName, buffer, PATH_MAX); - if (sz == -1) - { - switch(errno) - { - case EACCES: - errno = ERROR_ACCESS_DENIED; - break; - case EFAULT: - errno = ERROR_INVALID_ADDRESS; - break; - case EINVAL: - errno = ERROR_INVALID_NAME; - break; - case EIO: - errno = ERROR_GEN_FAILURE; - break; - case ELOOP: - errno = ERROR_STOPPED_ON_SYMLINK; - break; - case ENAMETOOLONG: - errno = ERROR_BAD_PATH_NAME; - break; - case ENOENT: - errno = ERROR_FILE_NOT_FOUND; - break; - case ENOMEM: - errno = ERROR_OUTOFMEMORY; - break; - case ENOTDIR: - errno = ERROR_BAD_PATH_NAME; - break; - default: - errno = ERROR_INVALID_FUNCTION; - } - - return NULL; - } - - buffer[sz] = '\0'; - return strndup(buffer, sz + 1); - - } - - /*else the path is not a symlink - but attempt to resolve*/ - else - { - printf("realpath %s", fileName); //Attempt to resolve with the absolute filepath char actualpath[PATH_MAX+1]; char* realPath = realpath(fileName, actualpath); @@ -150,5 +99,53 @@ char* FollowSymLink(const char* fileName) } return strndup(realPath, strlen(realPath) + 1 ); - } + + } + + /*else the path is not a symlink - but attempt to resolve*/ + else + { + char buffer[PATH_MAX]; + ssize_t sz = readlink(fileName, buffer, PATH_MAX); + + if (sz == -1) + { + switch(errno) + { + case EACCES: + errno = ERROR_ACCESS_DENIED; + break; + case EFAULT: + errno = ERROR_INVALID_ADDRESS; + break; + case EINVAL: + errno = ERROR_INVALID_NAME; + case EIO: + errno = ERROR_GEN_FAILURE; + break; + case ELOOP: + errno = ERROR_STOPPED_ON_SYMLINK; + break; + case ENAMETOOLONG: + errno = ERROR_BAD_PATH_NAME; + break; + case ENOENT: + errno = ERROR_FILE_NOT_FOUND; + break; + case ENOMEM: + errno = ERROR_OUTOFMEMORY; + break; + case ENOTDIR: + errno = ERROR_BAD_PATH_NAME; + break; + default: + errno = ERROR_INVALID_FUNCTION; + } + + return NULL; + } + + buffer[sz] = '\0'; + return strndup(buffer, sz + 1); +} } From e8386bd4b9e13c493e76f2493705f9ea0feea881 Mon Sep 17 00:00:00 2001 From: Alex Jordan Date: Thu, 7 Jul 2016 15:46:58 -0700 Subject: [PATCH 5/8] changing logic around realpath in followsymlink --- src/libpsl-native/src/followsymlink.cpp | 165 +++++++++++++----------- 1 file changed, 87 insertions(+), 78 deletions(-) diff --git a/src/libpsl-native/src/followsymlink.cpp b/src/libpsl-native/src/followsymlink.cpp index 1540037eb2..6a77bcc52b 100644 --- a/src/libpsl-native/src/followsymlink.cpp +++ b/src/libpsl-native/src/followsymlink.cpp @@ -53,99 +53,108 @@ char* FollowSymLink(const char* fileName) } /*If the path is a symlink, the function return the absolute filepath if valid. if not valid, return null*/ - if (IsSymLink(fileName) == 0) + if (IsSymLink(fileName)) { - //Attempt to resolve with the absolute filepath char actualpath[PATH_MAX+1]; char* realPath = realpath(fileName, actualpath); - - if (sizeof(realPath) == -1) - { - switch(errno) + + //if realPath is null, go onto the readlink implementation + if (realPath == NULL) + { + char buffer[PATH_MAX]; + ssize_t sz = readlink(fileName, buffer, PATH_MAX); + + if (sz == -1) { - case EACCES: - errno = ERROR_ACCESS_DENIED; - break; - case EFAULT: - errno = ERROR_INVALID_ADDRESS; - break; - case EINVAL: - errno = ERROR_INVALID_NAME; - break; - case EIO: - errno = ERROR_GEN_FAILURE; - break; - case ELOOP: - errno = ERROR_STOPPED_ON_SYMLINK; - break; - case ENAMETOOLONG: - errno = ERROR_BAD_PATH_NAME; - break; - case ENOENT: - errno = ERROR_FILE_NOT_FOUND; - break; - case ENOMEM: - errno = ERROR_OUTOFMEMORY; - break; - case ENOTDIR: - errno = ERROR_BAD_PATH_NAME; - break; - default: - errno = ERROR_INVALID_FUNCTION; + switch(errno) + { + case EACCES: + errno = ERROR_ACCESS_DENIED; + break; + case EFAULT: + errno = ERROR_INVALID_ADDRESS; /*If the path is a symlink, the function return the absolute filepath if valid. if not valid, return null*/ + break; + case EINVAL: + errno = ERROR_INVALID_NAME; + case EIO: + errno = ERROR_GEN_FAILURE; + break; + case ELOOP: + errno = ERROR_STOPPED_ON_SYMLINK; + break; + case ENAMETOOLONG: + errno = ERROR_BAD_PATH_NAME; + break; + case ENOENT: + errno = ERROR_FILE_NOT_FOUND; + break; + case ENOMEM: + errno = ERROR_OUTOFMEMORY; + break; + case ENOTDIR: + errno = ERROR_BAD_PATH_NAME; + break; + default: + errno = ERROR_INVALID_FUNCTION; } return NULL; + } + + buffer[sz] = '\0'; + return strndup(buffer, sz + 1); } - - return strndup(realPath, strlen(realPath) + 1 ); + else + { + return strndup(realPath, strlen(realPath) + 1 ); + } + } - } - - /*else the path is not a symlink - but attempt to resolve*/ - else + else { - char buffer[PATH_MAX]; - ssize_t sz = readlink(fileName, buffer, PATH_MAX); + char buffer[PATH_MAX]; + ssize_t sz = readlink(fileName, buffer, PATH_MAX); - if (sz == -1) - { - switch(errno) + if (sz == -1) { - case EACCES: - errno = ERROR_ACCESS_DENIED; - break; - case EFAULT: - errno = ERROR_INVALID_ADDRESS; - break; - case EINVAL: - errno = ERROR_INVALID_NAME; - case EIO: - errno = ERROR_GEN_FAILURE; - break; - case ELOOP: - errno = ERROR_STOPPED_ON_SYMLINK; - break; - case ENAMETOOLONG: - errno = ERROR_BAD_PATH_NAME; - break; - case ENOENT: - errno = ERROR_FILE_NOT_FOUND; - break; - case ENOMEM: - errno = ERROR_OUTOFMEMORY; - break; - case ENOTDIR: - errno = ERROR_BAD_PATH_NAME; - break; - default: - errno = ERROR_INVALID_FUNCTION; + switch(errno) + { + case EACCES: + errno = ERROR_ACCESS_DENIED; + break; + case EFAULT: + errno = ERROR_INVALID_ADDRESS; /*If the path is a symlink, the function return the absolute filepath if valid. if not valid, return null*/ + break; + case EINVAL: + errno = ERROR_INVALID_NAME; + case EIO: + errno = ERROR_GEN_FAILURE; + break; + case ELOOP: + errno = ERROR_STOPPED_ON_SYMLINK; + break; + case ENAMETOOLONG: + errno = ERROR_BAD_PATH_NAME; + break; + case ENOENT: + errno = ERROR_FILE_NOT_FOUND; + break; + case ENOMEM: + errno = ERROR_OUTOFMEMORY; + break; + case ENOTDIR: + errno = ERROR_BAD_PATH_NAME; + break; + default: + errno = ERROR_INVALID_FUNCTION; } return NULL; - } + } - buffer[sz] = '\0'; - return strndup(buffer, sz + 1); -} + buffer[sz] = '\0'; + return strndup(buffer, sz + 1); + + } } From 4a4df0f0801fea0b0d07e0b2d195096dcf066c0e Mon Sep 17 00:00:00 2001 From: Alex Jordan Date: Mon, 11 Jul 2016 20:56:34 -0700 Subject: [PATCH 6/8] Editing for OSX passing symbolic links --- .../New-Item.Tests.ps1 | 27 +++++++++---------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/test/powershell/Modules/Microsoft.PowerShell.Management/New-Item.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Management/New-Item.Tests.ps1 index 570b42565c..3955e788b0 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Management/New-Item.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Management/New-Item.Tests.ps1 @@ -36,7 +36,7 @@ Describe "New-Item" { It "Should create a file without error" { New-Item -Name $testfile -Path $tmpDirectory -ItemType file - Test-Path $FullyQualifiedFile | Should Be $true + Test-Path $FullyQualifiedFile | Should Be $true $fileInfo = Get-ChildItem $FullyQualifiedFile $fileInfo.Target | Should Be $null @@ -105,14 +105,15 @@ Describe "New-Item" { } It "Should create a symbolic link of a file without error" { - New-Item -Name $testfile -Path $tmpDirectory -ItemType file - Test-Path $FullyQualifiedFile | Should Be $true + New-Item -Name $testfile -Path $tmpDirectory -ItemType file + Test-Path $FullyQualifiedFile | Should Be $true - New-Item -ItemType SymbolicLink -Target $FullyQualifiedFile -Name $testlink -Path $tmpDirectory - Test-Path $FullyQualifiedLink | Should Be $true + New-Item -ItemType SymbolicLink -Target $FullyQualifiedFile -Name $testlink -Path $tmpDirectory + Test-Path $FullyQualifiedLink | Should Be $true + $target = $FullyQualifiedFile $fileInfo = Get-ChildItem $FullyQualifiedLink - $fileInfo.Target | Should Be $FullyQualifiedFile + $fileInfo.Target | Should Be $target $fileInfo.LinkType | Should Be "SymbolicLink" } @@ -128,18 +129,18 @@ Describe "New-Item" { } It "Should create a symbolic link from directory without error" { - New-Item -Name $testFolder -Path $tmpDirectory -ItemType directory - Test-Path $FullyQualifiedFolder | Should Be $true + New-Item -Name $testFolder -Path $tmpDirectory -ItemType directory + Test-Path $FullyQualifiedFolder | Should Be $true - New-Item -ItemType SymbolicLink -Target $FullyQualifiedFolder -Name $testlink -Path $tmpDirectory - Test-Path $FullyQualifiedLink | Should Be $true + New-Item -ItemType SymbolicLink -Target $FullyQualifiedFolder -Name $testlink -Path $tmpDirectory + Test-Path $FullyQualifiedLink | Should Be $true $fileInfo = Get-ChildItem $FullyQualifiedLink $fileInfo.Target | Should Be $FullyQualifiedFolder $fileInfo.LinkType | Should Be "SymbolicLink" - # Remove the link explicitly to avoid broken symlink issue - Remove-Item $FullyQualifiedLink -Force + # Remove the link explicitly to avoid broken symlink issue + Remove-Item $FullyQualifiedLink -Force } It "Should create a hard link of a file without error" { @@ -154,6 +155,4 @@ Describe "New-Item" { $fileInfo.LinkType | Should Be "HardLink" } - - } From 7c6a0ce2f1ce7af6533af058b68ada2c9329d9f9 Mon Sep 17 00:00:00 2001 From: Alex Jordan Date: Mon, 11 Jul 2016 22:22:45 -0700 Subject: [PATCH 7/8] New-Item tests to use Should Match --- .../Microsoft.PowerShell.Management/New-Item.Tests.ps1 | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/test/powershell/Modules/Microsoft.PowerShell.Management/New-Item.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Management/New-Item.Tests.ps1 index 3955e788b0..2b51c50f40 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Management/New-Item.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Management/New-Item.Tests.ps1 @@ -111,9 +111,8 @@ Describe "New-Item" { New-Item -ItemType SymbolicLink -Target $FullyQualifiedFile -Name $testlink -Path $tmpDirectory Test-Path $FullyQualifiedLink | Should Be $true - $target = $FullyQualifiedFile $fileInfo = Get-ChildItem $FullyQualifiedLink - $fileInfo.Target | Should Be $target + $fileInfo.Target | Should Match $FullyQualifiedFile $fileInfo.LinkType | Should Be "SymbolicLink" } @@ -136,7 +135,7 @@ Describe "New-Item" { Test-Path $FullyQualifiedLink | Should Be $true $fileInfo = Get-ChildItem $FullyQualifiedLink - $fileInfo.Target | Should Be $FullyQualifiedFolder + $fileInfo.Target | Should Match $FullyQualifiedFolder $fileInfo.LinkType | Should Be "SymbolicLink" # Remove the link explicitly to avoid broken symlink issue From 90defe681dcfd6fd63b80571a859cc2fa93ed644 Mon Sep 17 00:00:00 2001 From: Alex Jordan Date: Tue, 12 Jul 2016 15:58:21 -0700 Subject: [PATCH 8/8] Changing childitem to cope with regex --- .../Microsoft.PowerShell.Management/New-Item.Tests.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/powershell/Modules/Microsoft.PowerShell.Management/New-Item.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Management/New-Item.Tests.ps1 index 2b51c50f40..593f892ad9 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Management/New-Item.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Management/New-Item.Tests.ps1 @@ -112,7 +112,7 @@ Describe "New-Item" { Test-Path $FullyQualifiedLink | Should Be $true $fileInfo = Get-ChildItem $FullyQualifiedLink - $fileInfo.Target | Should Match $FullyQualifiedFile + $fileInfo.Target | Should Match ([regex]::Escape($FullyQualifiedFile)) $fileInfo.LinkType | Should Be "SymbolicLink" } @@ -135,7 +135,7 @@ Describe "New-Item" { Test-Path $FullyQualifiedLink | Should Be $true $fileInfo = Get-ChildItem $FullyQualifiedLink - $fileInfo.Target | Should Match $FullyQualifiedFolder + $fileInfo.Target | Should Match ([regex]::Escape($FullyQualifiedFolder)) $fileInfo.LinkType | Should Be "SymbolicLink" # Remove the link explicitly to avoid broken symlink issue