mirror of
https://github.com/zeek/zeek.git
synced 2025-10-09 18:18:19 +00:00
ScannedFile: Identify already scanned files by device and inode
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. This problem may be hit when `ZEEKPATH` points to separate filesystems and two script files happen have the same `st_ino` value - definitely not very likely, but possibly very confusing when it happens. The following test case creates two zeek scripts on separate filesystems. As the filesystems are freshly created and of the same type, the files will (tested a few times with xfs/ext4) have the same `st_ino` values. #!/bin/bash ZEEKDIR=${ZEEKDIR:-/home/awelzel/projects/zeek} export ZEEKPATH=.:${ZEEKDIR}/build/scripts:${ZEEKDIR}/scripts cat << EOF > hello.zeek event zeek_init() { print("Hello, once or twice?"); } EOF for i in 1 2 ; do dd if=/dev/urandom of=img${i} count=16 bs=1M 2>/dev/null sudo mkfs.xfs -q ./img${i} mkdir -p mount${i} sudo mount ./img${i} ./mount${i} sudo cp hello.zeek ./mount${i}/hello.zeek done ls ./mount*/*zeek stat -c "%n: device=%d inode=%i" ./mount*/hello.zeek ${ZEEKDIR}/build/src/zeek -b ./mount1/hello.zeek ./mount2/hello.zeek # Cleanup for i in 1 2 ; do sudo umount ./mount${i} rm -rfv ./img${i} ./mount${i} rm -rfv hello.zeek done Before this patch, `Hello, once or twice?` is printed only once, afterwards twice: $ sh testcase.sh [sudo] password for awelzel: ./mount1/hello.zeek ./mount2/hello.zeek ./mount1/hello.zeek: device=1794 inode=6915 ./mount2/hello.zeek: device=1795 inode=6915 Hello, once or twice? Hello, once or twice?
This commit is contained in:
parent
48fba11c51
commit
4b4595f5db
2 changed files with 19 additions and 19 deletions
28
src/scan.l
28
src/scan.l
|
@ -91,7 +91,7 @@ static string find_relative_script_file(const string& filename)
|
|||
return find_script_file(filename, bro_path());
|
||||
}
|
||||
|
||||
static ino_t get_inode_num(FILE* f, const string& path)
|
||||
static std::pair<dev_t, ino_t> get_inode(FILE* f, const string& path)
|
||||
{
|
||||
struct stat b;
|
||||
|
||||
|
@ -99,20 +99,20 @@ static ino_t get_inode_num(FILE* f, const string& path)
|
|||
reporter->FatalError("fstat of %s failed: %s\n", path.c_str(),
|
||||
strerror(errno));
|
||||
|
||||
return b.st_ino;
|
||||
return std::pair<dev_t, ino_t>{b.st_dev, b.st_ino};
|
||||
}
|
||||
|
||||
static ino_t get_inode_num(const string& path)
|
||||
static std::pair<dev_t, ino_t> get_inode(const string& path)
|
||||
{
|
||||
FILE* f = open_file(path);
|
||||
|
||||
if ( ! f )
|
||||
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);
|
||||
|
||||
return inum;
|
||||
return inode;
|
||||
}
|
||||
|
||||
class FileInfo {
|
||||
|
@ -420,7 +420,8 @@ when return TOK_WHEN;
|
|||
else
|
||||
{
|
||||
// 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.first, i.second, file_stack.length(), path, true);
|
||||
files_scanned.push_back(sf);
|
||||
}
|
||||
}
|
||||
|
@ -587,13 +588,10 @@ YYLTYPE GetCurrentLocation()
|
|||
return currloc;
|
||||
}
|
||||
|
||||
|
||||
static bool already_scanned(ino_t i)
|
||||
static bool already_scanned(const std::pair<dev_t, ino_t>& i)
|
||||
{
|
||||
list<ScannedFile>::const_iterator it;
|
||||
|
||||
for ( it = files_scanned.begin(); it != files_scanned.end(); ++it )
|
||||
if ( it->inode == i )
|
||||
for ( auto it : files_scanned )
|
||||
if ( it.dev == i.first && it.inode == i.second )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
@ -601,7 +599,7 @@ static bool already_scanned(ino_t i)
|
|||
|
||||
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)
|
||||
|
@ -656,7 +654,7 @@ static int load_files(const char* orig_file)
|
|||
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) )
|
||||
{
|
||||
|
@ -666,7 +664,7 @@ static int load_files(const char* orig_file)
|
|||
return 0;
|
||||
}
|
||||
|
||||
ScannedFile sf(i, file_stack.length(), file_path);
|
||||
ScannedFile sf(i.first, i.second, file_stack.length(), file_path);
|
||||
files_scanned.push_back(sf);
|
||||
|
||||
if ( g_policy_debug && ! file_path.empty() )
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue