mirror of
https://https.git.savannah.gnu.org/git/patch.git
synced 2026-01-27 09:54:55 +00:00
Fix inname test case
* src/safe.h (unsafe): New flag to allow turning off safe file operations. * src/safe.c (safe_xstat, safe_open, safe_rename, safe_mkdir, safe_rmdir, safe_unlink, safe_symlink, safe_chmod, safe_lchown, safe_lutimens, safe_readlink, safe_access): When safe file operations are turned off, skip safe path traversal. Any symlink checks of the last path component are still done though. * src/patch.c (main): When the file to patch is specified on the command line, turn off safe file operations. * tests/inname: Fix typo in test.
This commit is contained in:
parent
70532e21a8
commit
83a3ed012c
@ -176,6 +176,12 @@ main (int argc, char **argv)
|
||||
/* Make sure we clean up in case of disaster. */
|
||||
set_signals (false);
|
||||
|
||||
/* When the file to patch is specified on the command line, allow that file
|
||||
to lie outside the current working tree. Still doesn't allow to follow
|
||||
symlinks. */
|
||||
if (inname)
|
||||
unsafe = true;
|
||||
|
||||
if (inname && outfile)
|
||||
{
|
||||
/* When an input and an output filename is given and the patch is
|
||||
|
||||
40
src/safe.c
40
src/safe.c
@ -48,6 +48,10 @@
|
||||
|
||||
static const unsigned int MAX_PATH_COMPONENTS = 1024;
|
||||
|
||||
/* Flag to turn the safe_* functions into their unsafe variants; files may then
|
||||
lie outside the current working directory. */
|
||||
bool unsafe;
|
||||
|
||||
/* Path lookup results are cached in a hash table + LRU list. When the
|
||||
cache is full, the oldest entries are removed. */
|
||||
|
||||
@ -543,6 +547,9 @@ static int safe_xstat (const char *pathname, struct stat *buf, int flags)
|
||||
{
|
||||
int dirfd;
|
||||
|
||||
if (unsafe)
|
||||
return fstatat (AT_FDCWD, pathname, buf, flags);
|
||||
|
||||
dirfd = traverse_path (&pathname);
|
||||
if (dirfd < 0 && dirfd != AT_FDCWD)
|
||||
return dirfd;
|
||||
@ -566,6 +573,9 @@ int safe_open (const char *pathname, int flags, mode_t mode)
|
||||
{
|
||||
int dirfd;
|
||||
|
||||
if (unsafe)
|
||||
return open (pathname, flags, mode);
|
||||
|
||||
dirfd = traverse_path (&pathname);
|
||||
if (dirfd < 0 && dirfd != AT_FDCWD)
|
||||
return dirfd;
|
||||
@ -578,6 +588,9 @@ int safe_rename (const char *oldpath, const char *newpath)
|
||||
int olddirfd, newdirfd;
|
||||
int ret;
|
||||
|
||||
if (unsafe)
|
||||
return rename (oldpath, newpath);
|
||||
|
||||
olddirfd = traverse_path (&oldpath);
|
||||
if (olddirfd < 0 && olddirfd != AT_FDCWD)
|
||||
return olddirfd;
|
||||
@ -600,6 +613,9 @@ int safe_mkdir (const char *pathname, mode_t mode)
|
||||
{
|
||||
int dirfd;
|
||||
|
||||
if (unsafe)
|
||||
return mkdir (pathname, mode);
|
||||
|
||||
dirfd = traverse_path (&pathname);
|
||||
if (dirfd < 0 && dirfd != AT_FDCWD)
|
||||
return dirfd;
|
||||
@ -612,6 +628,9 @@ int safe_rmdir (const char *pathname)
|
||||
int dirfd;
|
||||
int ret;
|
||||
|
||||
if (unsafe)
|
||||
return rmdir (pathname);
|
||||
|
||||
dirfd = traverse_path (&pathname);
|
||||
if (dirfd < 0 && dirfd != AT_FDCWD)
|
||||
return dirfd;
|
||||
@ -627,6 +646,9 @@ int safe_unlink (const char *pathname)
|
||||
{
|
||||
int dirfd;
|
||||
|
||||
if (unsafe)
|
||||
return unlink (pathname);
|
||||
|
||||
dirfd = traverse_path (&pathname);
|
||||
if (dirfd < 0 && dirfd != AT_FDCWD)
|
||||
return dirfd;
|
||||
@ -638,6 +660,9 @@ int safe_symlink (const char *target, const char *linkpath)
|
||||
{
|
||||
int dirfd;
|
||||
|
||||
if (unsafe)
|
||||
return symlink (target, linkpath);
|
||||
|
||||
dirfd = traverse_path (&linkpath);
|
||||
if (dirfd < 0 && dirfd != AT_FDCWD)
|
||||
return dirfd;
|
||||
@ -649,6 +674,9 @@ int safe_chmod (const char *pathname, mode_t mode)
|
||||
{
|
||||
int dirfd;
|
||||
|
||||
if (unsafe)
|
||||
return chmod (pathname, mode);
|
||||
|
||||
dirfd = traverse_path (&pathname);
|
||||
if (dirfd < 0 && dirfd != AT_FDCWD)
|
||||
return dirfd;
|
||||
@ -660,6 +688,9 @@ int safe_lchown (const char *pathname, uid_t owner, gid_t group)
|
||||
{
|
||||
int dirfd;
|
||||
|
||||
if (unsafe)
|
||||
return lchown (pathname, owner, group);
|
||||
|
||||
dirfd = traverse_path (&pathname);
|
||||
if (dirfd < 0 && dirfd != AT_FDCWD)
|
||||
return dirfd;
|
||||
@ -671,6 +702,9 @@ int safe_lutimens (const char *pathname, struct timespec const times[2])
|
||||
{
|
||||
int dirfd;
|
||||
|
||||
if (unsafe)
|
||||
return utimensat (AT_FDCWD, pathname, times, AT_SYMLINK_NOFOLLOW);
|
||||
|
||||
dirfd = traverse_path (&pathname);
|
||||
if (dirfd < 0 && dirfd != AT_FDCWD)
|
||||
return dirfd;
|
||||
@ -682,6 +716,9 @@ ssize_t safe_readlink (const char *pathname, char *buf, size_t bufsiz)
|
||||
{
|
||||
int dirfd;
|
||||
|
||||
if (unsafe)
|
||||
return readlink (pathname, buf, bufsiz);
|
||||
|
||||
dirfd = traverse_path (&pathname);
|
||||
if (dirfd < 0 && dirfd != AT_FDCWD)
|
||||
return dirfd;
|
||||
@ -693,6 +730,9 @@ int safe_access (const char *pathname, int mode)
|
||||
{
|
||||
int dirfd;
|
||||
|
||||
if (unsafe)
|
||||
return access (pathname, mode);
|
||||
|
||||
dirfd = traverse_path (&pathname);
|
||||
if (dirfd < 0 && dirfd != AT_FDCWD)
|
||||
return dirfd;
|
||||
|
||||
@ -18,6 +18,10 @@
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
extern bool unsafe;
|
||||
|
||||
int safe_stat (const char *pathname, struct stat *buf);
|
||||
int safe_lstat (const char *pathname, struct stat *buf);
|
||||
int safe_open (const char *pathname, int flags, mode_t mode);
|
||||
|
||||
@ -51,5 +51,5 @@ cat > g.diff <<EOF
|
||||
EOF
|
||||
|
||||
check 'patch ../file1 < g.diff' <<EOF
|
||||
patching file ../file
|
||||
patching file ../file1
|
||||
EOF
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user