Merge branch 'scanned-file-device-and-inode' of https://github.com/awelzel/zeek

- Minor whitespace adjustments
- Converted std::pair usage to anonymous struct to improve readability

* 'scanned-file-device-and-inode' of https://github.com/awelzel/zeek:
  scan.l: Actually add <utility> include, too.
  ScannedFile: Identify already scanned files by device and inode
This commit is contained in:
Jon Siwek 2020-02-24 17:05:51 -08:00
commit e0da9fbe82
4 changed files with 48 additions and 23 deletions

18
CHANGES
View file

@ -1,4 +1,22 @@
3.2.0-dev.106 | 2020-02-24 17:07:10 -0800
* ScannedFile: Identify already scanned files by device and inode (Arne Welzel)
Zeek scripts located on separate filesystems, but sharing the same inode
number leads to scripts not being loaded. The reason is that a `ScannedFile`
is only identified by `st_ino` which is not enough to uniquely identify a
file in a system.
* GH-808: Add ZEEK_VERSION_NUMBER definition to zeek-config.h (Jon Siwek, Corelight)
This is the result of (major * 10000 + minor * 100 + patch), for example
3.1.2 becomes 30102. This definition may be helpful for external code
that requires conditional compilation to support multiple Zeek
versions with differing APIs.
* Fix CI to checkout right commit of zeek-testing-private (Jon Siwek, Corelight)
3.2.0-dev.99 | 2020-02-21 21:23:52 -0800 3.2.0-dev.99 | 2020-02-21 21:23:52 -0800
* Update a URL in CI README (Jon Siwek, Corelight) * Update a URL in CI README (Jon Siwek, Corelight)

View file

@ -1 +1 @@
3.2.0-dev.99 3.2.0-dev.106

View file

@ -88,20 +88,22 @@ extern iosource::IOSource* current_iosrc;
extern iosource::PktDumper* pkt_dumper; // where to save packets extern iosource::PktDumper* pkt_dumper; // where to save packets
// Script file we have already scanned (or are in the process of scanning). // Script file we have already scanned (or are in the process of scanning).
// They are identified by inode number. // They are identified by device and inode number.
struct ScannedFile { struct ScannedFile {
dev_t dev;
ino_t inode; ino_t inode;
int include_level; int include_level;
string name; string name;
bool skipped; // This ScannedFile was @unload'd. bool skipped; // This ScannedFile was @unload'd.
bool prefixes_checked; // If loading prefixes for this file has been tried. bool prefixes_checked; // If loading prefixes for this file has been tried.
ScannedFile(ino_t arg_inode, int arg_include_level, const string& arg_name, ScannedFile(dev_t arg_dev, ino_t arg_inode, int arg_include_level,
bool arg_skipped = false, const string& arg_name, bool arg_skipped = false,
bool arg_prefixes_checked = false) bool arg_prefixes_checked = false)
: inode(arg_inode), include_level(arg_include_level), : dev(arg_dev), inode(arg_inode),
name(arg_name), skipped(arg_skipped), include_level(arg_include_level),
prefixes_checked(arg_prefixes_checked) name(arg_name), skipped(arg_skipped),
prefixes_checked(arg_prefixes_checked)
{ } { }
}; };

View file

@ -36,6 +36,13 @@
#include "plugin/Manager.h" #include "plugin/Manager.h"
namespace {
struct ZeekINode {
dev_t dev;
ino_t ino;
};
}
extern YYLTYPE yylloc; // holds start line and column of token extern YYLTYPE yylloc; // holds start line and column of token
extern EnumType* cur_enum_type; extern EnumType* cur_enum_type;
@ -91,7 +98,7 @@ static string find_relative_script_file(const string& filename)
return find_script_file(filename, bro_path()); return find_script_file(filename, bro_path());
} }
static ino_t get_inode_num(FILE* f, const string& path) static ZeekINode get_inode(FILE* f, const string& path)
{ {
struct stat b; struct stat b;
@ -99,20 +106,20 @@ static ino_t get_inode_num(FILE* f, const string& path)
reporter->FatalError("fstat of %s failed: %s\n", path.c_str(), reporter->FatalError("fstat of %s failed: %s\n", path.c_str(),
strerror(errno)); strerror(errno));
return b.st_ino; return {b.st_dev, b.st_ino};
} }
static ino_t get_inode_num(const string& path) static ZeekINode get_inode(const string& path)
{ {
FILE* f = open_file(path); FILE* f = open_file(path);
if ( ! f ) if ( ! f )
reporter->FatalError("failed to open %s\n", path.c_str()); reporter->FatalError("failed to open %s\n", path.c_str());
ino_t inum = get_inode_num(f, path); auto inode = get_inode(f, path);
fclose(f); fclose(f);
return inum; return inode;
} }
class FileInfo { class FileInfo {
@ -420,7 +427,8 @@ when return TOK_WHEN;
else else
{ {
// All we have to do is pretend we've already scanned it. // All we have to do is pretend we've already scanned it.
ScannedFile sf(get_inode_num(path), file_stack.length(), path, true); auto i = get_inode(path);
ScannedFile sf(i.dev, i.ino, file_stack.length(), path, true);
files_scanned.push_back(sf); files_scanned.push_back(sf);
} }
} }
@ -587,13 +595,10 @@ YYLTYPE GetCurrentLocation()
return currloc; return currloc;
} }
static bool already_scanned(ZeekINode in)
static bool already_scanned(ino_t i)
{ {
list<ScannedFile>::const_iterator it; for ( const auto& it : files_scanned )
if ( it.dev == in.dev && it.inode == in.ino )
for ( it = files_scanned.begin(); it != files_scanned.end(); ++it )
if ( it->inode == i )
return true; return true;
return false; return false;
@ -601,7 +606,7 @@ static bool already_scanned(ino_t i)
static bool already_scanned(const string& path) static bool already_scanned(const string& path)
{ {
return already_scanned(get_inode_num(path)); return already_scanned(get_inode(path));
} }
static int load_files(const char* orig_file) static int load_files(const char* orig_file)
@ -656,7 +661,7 @@ static int load_files(const char* orig_file)
reporter->FatalError("can't open %s", file_path.c_str()); reporter->FatalError("can't open %s", file_path.c_str());
} }
ino_t i = get_inode_num(f, file_path); auto i = get_inode(f, file_path);
if ( already_scanned(i) ) if ( already_scanned(i) )
{ {
@ -666,7 +671,7 @@ static int load_files(const char* orig_file)
return 0; return 0;
} }
ScannedFile sf(i, file_stack.length(), file_path); ScannedFile sf(i.dev, i.ino, file_stack.length(), file_path);
files_scanned.push_back(sf); files_scanned.push_back(sf);
if ( g_policy_debug && ! file_path.empty() ) if ( g_policy_debug && ! file_path.empty() )