Security: don't follow symlinks to forbidden directories
https://bugs.debian.org/780867 This messy approach is to minimise changes during freeze; for 3.7, I plan to make realpath() handle non-existent files as "realpath they would have if created now" and get rid of fgNormalizePath
This commit is contained in:
parent
1199d6d626
commit
823d57bd53
1 changed files with 31 additions and 6 deletions
|
@ -157,7 +157,7 @@ void fgInitAllowedPaths()
|
||||||
!fgValidatePath(globals->get_fg_home() + "no.log",true).empty() ||
|
!fgValidatePath(globals->get_fg_home() + "no.log",true).empty() ||
|
||||||
!fgValidatePath("..\\" + globals->get_fg_home() + "/no.log",false).empty() ||
|
!fgValidatePath("..\\" + globals->get_fg_home() + "/no.log",false).empty() ||
|
||||||
!fgValidatePath(std::string("/tmp/no.xml"),false).empty() ||
|
!fgValidatePath(std::string("/tmp/no.xml"),false).empty() ||
|
||||||
fgValidatePath(globals->get_fg_home() + "/./ff/../Export\\yes..gg",true).empty() ||
|
fgValidatePath(globals->get_fg_home() + "/./TerraSync/../Export\\yes..gg",true).empty() ||
|
||||||
fgValidatePath(globals->get_fg_home() + "/aircraft-data/yes..xml",true).empty() ||
|
fgValidatePath(globals->get_fg_home() + "/aircraft-data/yes..xml",true).empty() ||
|
||||||
fgValidatePath(globals->get_fg_root() + "/./\\yes.bmp",false).empty()) {
|
fgValidatePath(globals->get_fg_root() + "/./\\yes.bmp",false).empty()) {
|
||||||
flightgear::fatalMessageBox("Nasal initialization error",
|
flightgear::fatalMessageBox("Nasal initialization error",
|
||||||
|
@ -167,15 +167,12 @@ void fgInitAllowedPaths()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check whether Nasal is allowed to access a path
|
// Check whether Nasal is allowed to access a path (assumed already normalized)
|
||||||
std::string fgValidatePath (const std::string& path, bool write)
|
static std::string fgValidatePath_internal (const std::string& normed_path, bool write)
|
||||||
{
|
{
|
||||||
const string_list& allowed_paths(write ? write_allowed_paths : read_allowed_paths);
|
const string_list& allowed_paths(write ? write_allowed_paths : read_allowed_paths);
|
||||||
size_t star_pos;
|
size_t star_pos;
|
||||||
|
|
||||||
// Normalize the path (prevents ../../.. trickery)
|
|
||||||
std::string normed_path = fgNormalizePath(path);
|
|
||||||
|
|
||||||
// Check against each allowed pattern
|
// Check against each allowed pattern
|
||||||
for( string_list::const_iterator it = allowed_paths.begin();
|
for( string_list::const_iterator it = allowed_paths.begin();
|
||||||
it != allowed_paths.end();
|
it != allowed_paths.end();
|
||||||
|
@ -200,6 +197,34 @@ std::string fgValidatePath (const std::string& path, bool write)
|
||||||
// no match found
|
// no match found
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
// Check whether Nasal is allowed to access a path
|
||||||
|
// Warning: because this always (not just on Windows) converts \ to /,
|
||||||
|
// if passing a std::string, use the returned path not the original one
|
||||||
|
// (This warning does not apply to the SGPath variant, as these are
|
||||||
|
// so converted on creation.)
|
||||||
|
std::string fgValidatePath (const std::string& path, bool write)
|
||||||
|
{
|
||||||
|
// Normalize the path (prevents ../../.. trickery)
|
||||||
|
// method 1 allows following symlinks to anywhere
|
||||||
|
// (https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=780867);
|
||||||
|
// method 2 doesn't, and is intended to eventually replace it
|
||||||
|
std::string normed_path1 = fgNormalizePath(path);
|
||||||
|
SGPath path2 = SGPath(path);
|
||||||
|
std::string normed_path2;
|
||||||
|
if (path2.exists()) {
|
||||||
|
normed_path2 = path2.realpath();
|
||||||
|
} else { // realpath can't check non-existent files
|
||||||
|
normed_path2 = SGPath(path2.dir()).realpath()
|
||||||
|
+ "/" + path2.file();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check
|
||||||
|
if (fgValidatePath_internal(normed_path1, write).empty() ||
|
||||||
|
fgValidatePath_internal(normed_path2, write).empty()) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return normed_path1;
|
||||||
|
}
|
||||||
std::string fgValidatePath(const SGPath& path, bool write) { return fgValidatePath(path.str(),write); }
|
std::string fgValidatePath(const SGPath& path, bool write) { return fgValidatePath(path.str(),write); }
|
||||||
// end of util.cxx
|
// end of util.cxx
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue