49 lines
1.0 KiB
C
49 lines
1.0 KiB
C
|
/* vi: set sw=4 ts=4: */
|
||
|
/*
|
||
|
* Licensed under GPLv2 or later, see file LICENSE in this source tree.
|
||
|
*/
|
||
|
#include "libbb.h"
|
||
|
#include "bb_archive.h"
|
||
|
|
||
|
int FAST_FUNC unsafe_symlink_target(const char *target)
|
||
|
{
|
||
|
const char *dot;
|
||
|
|
||
|
if (target[0] == '/') {
|
||
|
const char *var;
|
||
|
unsafe:
|
||
|
var = getenv("EXTRACT_UNSAFE_SYMLINKS");
|
||
|
if (var) {
|
||
|
if (LONE_CHAR(var, '1'))
|
||
|
return 0; /* pretend it's safe */
|
||
|
return 1; /* "UNSAFE!" */
|
||
|
}
|
||
|
bb_error_msg("skipping unsafe symlink to '%s' in archive,"
|
||
|
" set %s=1 to extract",
|
||
|
target,
|
||
|
"EXTRACT_UNSAFE_SYMLINKS"
|
||
|
);
|
||
|
/* Prevent further messages */
|
||
|
setenv("EXTRACT_UNSAFE_SYMLINKS", "0", 0);
|
||
|
return 1; /* "UNSAFE!" */
|
||
|
}
|
||
|
|
||
|
dot = target;
|
||
|
for (;;) {
|
||
|
dot = strchr(dot, '.');
|
||
|
if (!dot)
|
||
|
return 0; /* safe target */
|
||
|
|
||
|
/* Is it a path component starting with ".."? */
|
||
|
if ((dot[1] == '.')
|
||
|
&& (dot == target || dot[-1] == '/')
|
||
|
/* Is it exactly ".."? */
|
||
|
&& (dot[2] == '/' || dot[2] == '\0')
|
||
|
) {
|
||
|
goto unsafe;
|
||
|
}
|
||
|
/* NB: it can even be trailing ".", should only add 1 */
|
||
|
dot += 1;
|
||
|
}
|
||
|
}
|