PR/18663: Jeremy Reed: pax/tar/cpio allows ".." in names.
We now disallow it by default on both archive creation and extraction. Add --insecure option to override.
This commit is contained in:
parent
a2e26d6e11
commit
ca541391bc
@ -1,4 +1,4 @@
|
|||||||
/* $NetBSD: extern.h,v 1.32 2002/10/13 00:34:16 mrg Exp $ */
|
/* $NetBSD: extern.h,v 1.33 2002/10/15 16:16:29 christos Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 1992 Keith Muller.
|
* Copyright (c) 1992 Keith Muller.
|
||||||
@ -56,6 +56,7 @@ extern time_t starttime;
|
|||||||
extern int force_one_volume;
|
extern int force_one_volume;
|
||||||
extern char *chdname;
|
extern char *chdname;
|
||||||
extern int forcelocal;
|
extern int forcelocal;
|
||||||
|
extern int secure;
|
||||||
|
|
||||||
int ar_open(const char *);
|
int ar_open(const char *);
|
||||||
void ar_close(void);
|
void ar_close(void);
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $NetBSD: options.c,v 1.46 2002/10/15 14:58:53 christos Exp $ */
|
/* $NetBSD: options.c,v 1.47 2002/10/15 16:16:29 christos Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 1992 Keith Muller.
|
* Copyright (c) 1992 Keith Muller.
|
||||||
@ -42,7 +42,7 @@
|
|||||||
#if 0
|
#if 0
|
||||||
static char sccsid[] = "@(#)options.c 8.2 (Berkeley) 4/18/94";
|
static char sccsid[] = "@(#)options.c 8.2 (Berkeley) 4/18/94";
|
||||||
#else
|
#else
|
||||||
__RCSID("$NetBSD: options.c,v 1.46 2002/10/15 14:58:53 christos Exp $");
|
__RCSID("$NetBSD: options.c,v 1.47 2002/10/15 16:16:29 christos Exp $");
|
||||||
#endif
|
#endif
|
||||||
#endif /* not lint */
|
#endif /* not lint */
|
||||||
|
|
||||||
@ -98,6 +98,25 @@ static int getline_error;
|
|||||||
#define GZIP_CMD "gzip" /* command to run as gzip */
|
#define GZIP_CMD "gzip" /* command to run as gzip */
|
||||||
#define COMPRESS_CMD "compress" /* command to run as compress */
|
#define COMPRESS_CMD "compress" /* command to run as compress */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Long options.
|
||||||
|
*/
|
||||||
|
#define OPT_USE_COMPRESS_PROGRAM 0
|
||||||
|
#define OPT_CHECKPOINT 1
|
||||||
|
#define OPT_UNLINK 2
|
||||||
|
#define OPT_HELP 3
|
||||||
|
#define OPT_ATIME_PRESERVE 4
|
||||||
|
#define OPT_IGNORE_FAILED_READ 5
|
||||||
|
#define OPT_REMOVE_FILES 6
|
||||||
|
#define OPT_NULL 7
|
||||||
|
#define OPT_TOTALS 8
|
||||||
|
#define OPT_VERSION 9
|
||||||
|
#define OPT_EXCLUDE 10
|
||||||
|
#define OPT_BLOCK_COMPRESS 11
|
||||||
|
#define OPT_NORECURSE 12
|
||||||
|
#define OPT_FORCE_LOCAL 13
|
||||||
|
#define OPT_INSECURE 14
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Format specific routine table - MUST BE IN SORTED ORDER BY NAME
|
* Format specific routine table - MUST BE IN SORTED ORDER BY NAME
|
||||||
* (see pax.h for description of each function)
|
* (see pax.h for description of each function)
|
||||||
@ -181,6 +200,11 @@ options(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct option pax_longopts[] = {
|
||||||
|
{ "insecure", no_argument, 0,
|
||||||
|
OPT_INSECURE },
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* pax_options()
|
* pax_options()
|
||||||
* look at the user specified flags. set globals as required and check if
|
* look at the user specified flags. set globals as required and check if
|
||||||
@ -200,8 +224,9 @@ pax_options(int argc, char **argv)
|
|||||||
/*
|
/*
|
||||||
* process option flags
|
* process option flags
|
||||||
*/
|
*/
|
||||||
while ((c = getopt(argc, argv,
|
while ((c = getopt_long(argc, argv,
|
||||||
"ab:cdf:iklno:p:rs:tuvwx:zAB:DE:G:HLMN:OPT:U:XYZ")) != -1) {
|
"ab:cdf:iklno:p:rs:tuvwx:zAB:DE:G:HLMN:OPT:U:XYZ",
|
||||||
|
pax_longopts, NULL)) != -1) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'a':
|
case 'a':
|
||||||
/*
|
/*
|
||||||
@ -555,6 +580,9 @@ pax_options(int argc, char **argv)
|
|||||||
Zflag = 1;
|
Zflag = 1;
|
||||||
flg |= CZF;
|
flg |= CZF;
|
||||||
break;
|
break;
|
||||||
|
case OPT_INSECURE:
|
||||||
|
secure = 0;
|
||||||
|
break;
|
||||||
case '?':
|
case '?':
|
||||||
default:
|
default:
|
||||||
pax_usage();
|
pax_usage();
|
||||||
@ -638,21 +666,6 @@ pax_options(int argc, char **argv)
|
|||||||
* the user specified a legal set of flags. If not, complain and exit
|
* the user specified a legal set of flags. If not, complain and exit
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define OPT_USE_COMPRESS_PROGRAM 0
|
|
||||||
#define OPT_CHECKPOINT 1
|
|
||||||
#define OPT_UNLINK 2
|
|
||||||
#define OPT_HELP 3
|
|
||||||
#define OPT_ATIME_PRESERVE 4
|
|
||||||
#define OPT_IGNORE_FAILED_READ 5
|
|
||||||
#define OPT_REMOVE_FILES 6
|
|
||||||
#define OPT_NULL 7
|
|
||||||
#define OPT_TOTALS 8
|
|
||||||
#define OPT_VERSION 9
|
|
||||||
#define OPT_EXCLUDE 10
|
|
||||||
#define OPT_BLOCK_COMPRESS 11
|
|
||||||
#define OPT_NORECURSE 12
|
|
||||||
#define OPT_FORCE_LOCAL 13
|
|
||||||
|
|
||||||
struct option tar_longopts[] = {
|
struct option tar_longopts[] = {
|
||||||
{ "block-size", required_argument, 0, 'b' },
|
{ "block-size", required_argument, 0, 'b' },
|
||||||
{ "create", no_argument, 0, 'c' }, /* F */
|
{ "create", no_argument, 0, 'c' }, /* F */
|
||||||
@ -693,6 +706,8 @@ struct option tar_longopts[] = {
|
|||||||
OPT_USE_COMPRESS_PROGRAM },
|
OPT_USE_COMPRESS_PROGRAM },
|
||||||
{ "force-local", no_argument, 0,
|
{ "force-local", no_argument, 0,
|
||||||
OPT_FORCE_LOCAL },
|
OPT_FORCE_LOCAL },
|
||||||
|
{ "insecure", no_argument, 0,
|
||||||
|
OPT_INSECURE },
|
||||||
#if 0 /* Not implemented */
|
#if 0 /* Not implemented */
|
||||||
{ "catenate", no_argument, 0, 'A' }, /* F */
|
{ "catenate", no_argument, 0, 'A' }, /* F */
|
||||||
{ "concatenate", no_argument, 0, 'A' }, /* F */
|
{ "concatenate", no_argument, 0, 'A' }, /* F */
|
||||||
@ -996,6 +1011,9 @@ tar_options(int argc, char **argv)
|
|||||||
case OPT_FORCE_LOCAL:
|
case OPT_FORCE_LOCAL:
|
||||||
forcelocal = 1;
|
forcelocal = 1;
|
||||||
break;
|
break;
|
||||||
|
case OPT_INSECURE:
|
||||||
|
secure = 0;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
tar_usage();
|
tar_usage();
|
||||||
break;
|
break;
|
||||||
@ -1222,10 +1240,12 @@ struct option cpio_longopts[] = {
|
|||||||
{ "pattern-file", required_argument, 0, 'E' },
|
{ "pattern-file", required_argument, 0, 'E' },
|
||||||
{ "file", required_argument, 0, 'F' },
|
{ "file", required_argument, 0, 'F' },
|
||||||
{ "force-local", no_argument, 0,
|
{ "force-local", no_argument, 0,
|
||||||
OPT_FORCE_LOCAL },
|
OPT_FORCE_LOCAL },
|
||||||
{ "format", required_argument, 0, 'H' },
|
{ "format", required_argument, 0, 'H' },
|
||||||
{ "dereference", no_argument, 0, 'L' },
|
{ "dereference", no_argument, 0, 'L' },
|
||||||
{ "swap-halfwords", no_argument, 0, 'S' },
|
{ "swap-halfwords", no_argument, 0, 'S' },
|
||||||
|
{ "insecure", no_argument, 0,
|
||||||
|
OPT_INSECURE },
|
||||||
|
|
||||||
#ifdef notyet
|
#ifdef notyet
|
||||||
/* Not implemented */
|
/* Not implemented */
|
||||||
@ -1237,19 +1257,19 @@ struct option cpio_longopts[] = {
|
|||||||
{ "owner", required_argument, 0 'R' },
|
{ "owner", required_argument, 0 'R' },
|
||||||
{ "dot", no_argument, 0, 'V' },
|
{ "dot", no_argument, 0, 'V' },
|
||||||
{ "block-size", required_argument, 0,
|
{ "block-size", required_argument, 0,
|
||||||
OPT_BLOCK_SIZE },
|
OPT_BLOCK_SIZE },
|
||||||
{ "no-absolute-pathnames", no_argument, 0,
|
{ "no-absolute-pathnames", no_argument, 0,
|
||||||
OPT_NO_ABSOLUTE_PATHNAMES },
|
OPT_NO_ABSOLUTE_PATHNAMES },
|
||||||
{ "no-preserve-owner", no_argument, 0,
|
{ "no-preserve-owner", no_argument, 0,
|
||||||
OPT_NO_PRESERVE_OWNER },
|
OPT_NO_PRESERVE_OWNER },
|
||||||
{ "only-verify-crc", no_argument, 0,
|
{ "only-verify-crc", no_argument, 0,
|
||||||
OPT_ONLY_VERIFY_CRC },
|
OPT_ONLY_VERIFY_CRC },
|
||||||
{ "rsh-command", required_argument, 0,
|
{ "rsh-command", required_argument, 0,
|
||||||
OPT_RSH_COMMAND },
|
OPT_RSH_COMMAND },
|
||||||
{ "sparce", no_argument, 0,
|
{ "sparce", no_argument, 0,
|
||||||
OPT_SPARSE },
|
OPT_SPARSE },
|
||||||
{ "version", no_argument, 0,
|
{ "version", no_argument, 0,
|
||||||
OPT_VERSION },
|
OPT_VERSION },
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1282,7 +1302,7 @@ cpio_options(int argc, char **argv)
|
|||||||
* process option flags
|
* process option flags
|
||||||
*/
|
*/
|
||||||
while ((c = getoldopt(argc, argv,
|
while ((c = getoldopt(argc, argv,
|
||||||
"abcdfiklmoprstuvzABC:E:F:H:I:LM:O:R:SVZ6",
|
"+abcdfiklmoprstuvzABC:E:F:H:I:LM:O:R:SVZ6",
|
||||||
cpio_longopts, NULL)) != -1) {
|
cpio_longopts, NULL)) != -1) {
|
||||||
switch(c) {
|
switch(c) {
|
||||||
case 'a':
|
case 'a':
|
||||||
@ -1513,6 +1533,9 @@ cpio_options(int argc, char **argv)
|
|||||||
case OPT_FORCE_LOCAL:
|
case OPT_FORCE_LOCAL:
|
||||||
forcelocal = 1;
|
forcelocal = 1;
|
||||||
break;
|
break;
|
||||||
|
case OPT_INSECURE:
|
||||||
|
secure = 0;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
cpio_usage();
|
cpio_usage();
|
||||||
break;
|
break;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $NetBSD: pat_rep.c,v 1.14 2002/10/12 15:39:30 christos Exp $ */
|
/* $NetBSD: pat_rep.c,v 1.15 2002/10/15 16:16:30 christos Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 1992 Keith Muller.
|
* Copyright (c) 1992 Keith Muller.
|
||||||
@ -42,7 +42,7 @@
|
|||||||
#if 0
|
#if 0
|
||||||
static char sccsid[] = "@(#)pat_rep.c 8.2 (Berkeley) 4/18/94";
|
static char sccsid[] = "@(#)pat_rep.c 8.2 (Berkeley) 4/18/94";
|
||||||
#else
|
#else
|
||||||
__RCSID("$NetBSD: pat_rep.c,v 1.14 2002/10/12 15:39:30 christos Exp $");
|
__RCSID("$NetBSD: pat_rep.c,v 1.15 2002/10/15 16:16:30 christos Exp $");
|
||||||
#endif
|
#endif
|
||||||
#endif /* not lint */
|
#endif /* not lint */
|
||||||
|
|
||||||
@ -82,6 +82,7 @@ static int tty_rename(ARCHD *);
|
|||||||
static int fix_path(char *, int *, char *, int);
|
static int fix_path(char *, int *, char *, int);
|
||||||
static int fn_match(char *, char *, char **);
|
static int fn_match(char *, char *, char **);
|
||||||
static char * range_match(char *, int);
|
static char * range_match(char *, int);
|
||||||
|
static int checkdotdot(const char *);
|
||||||
#ifdef NET2_REGEX
|
#ifdef NET2_REGEX
|
||||||
static int resub(regexp *, char *, char *, char *);
|
static int resub(regexp *, char *, char *, char *);
|
||||||
#else
|
#else
|
||||||
@ -670,6 +671,19 @@ mod_name(ARCHD *arcn)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (secure) {
|
||||||
|
if (checkdotdot(arcn->name)) {
|
||||||
|
tty_warn(0, "Ignoring file containing `..' (%s)",
|
||||||
|
arcn->name);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (checkdotdot(arcn->ln_name)) {
|
||||||
|
tty_warn(0, "Ignoring link containing `..' (%s)",
|
||||||
|
arcn->ln_name);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* IMPORTANT: We have a problem. what do we do with symlinks?
|
* IMPORTANT: We have a problem. what do we do with symlinks?
|
||||||
* Modifying a hard link name makes sense, as we know the file it
|
* Modifying a hard link name makes sense, as we know the file it
|
||||||
@ -1041,6 +1055,35 @@ rep_name(char *name, size_t namelen, int *nlen, int prnt)
|
|||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* checkdotdot()
|
||||||
|
* Return true if a component of the name contains a reference to ".."
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
checkdotdot(const char *name)
|
||||||
|
{
|
||||||
|
const char *p;
|
||||||
|
/* 1. "..{[/],}" */
|
||||||
|
if (name[0] == '.' && name[1] == '.' &&
|
||||||
|
(name[2] == '/' || name[2] == '\0'))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
/* 2. "*[/]..[/]*" */
|
||||||
|
if (strstr(name, "/../") != NULL)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
/* 3. "*[/].." */
|
||||||
|
for (p = name; *p; p++)
|
||||||
|
continue;
|
||||||
|
if (p - name < 3)
|
||||||
|
return 0;
|
||||||
|
if (p[-1] == '.' && p[-2] == '.' && p[-3] == '/')
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef NET2_REGEX
|
#ifdef NET2_REGEX
|
||||||
/*
|
/*
|
||||||
* resub()
|
* resub()
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $NetBSD: pax.c,v 1.19 2002/10/13 00:31:28 mrg Exp $ */
|
/* $NetBSD: pax.c,v 1.20 2002/10/15 16:16:30 christos Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 1992 Keith Muller.
|
* Copyright (c) 1992 Keith Muller.
|
||||||
@ -47,7 +47,7 @@ __COPYRIGHT("@(#) Copyright (c) 1992, 1993\n\
|
|||||||
#if 0
|
#if 0
|
||||||
static char sccsid[] = "@(#)pax.c 8.2 (Berkeley) 4/18/94";
|
static char sccsid[] = "@(#)pax.c 8.2 (Berkeley) 4/18/94";
|
||||||
#else
|
#else
|
||||||
__RCSID("$NetBSD: pax.c,v 1.19 2002/10/13 00:31:28 mrg Exp $");
|
__RCSID("$NetBSD: pax.c,v 1.20 2002/10/15 16:16:30 christos Exp $");
|
||||||
#endif
|
#endif
|
||||||
#endif /* not lint */
|
#endif /* not lint */
|
||||||
|
|
||||||
@ -116,6 +116,7 @@ char *tempbase; /* basename of tempfile to use for mkstemp(3) */
|
|||||||
int forcelocal; /* force local operation even if the name
|
int forcelocal; /* force local operation even if the name
|
||||||
* contains a :
|
* contains a :
|
||||||
*/
|
*/
|
||||||
|
int secure = 1; /* don't extract names that contain .. */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* PAX - Portable Archive Interchange
|
* PAX - Portable Archive Interchange
|
||||||
|
Loading…
Reference in New Issue
Block a user