Search code examples
inotifyosquery

Does osquery inotify install watcher on directory or files


I am using osquery to monitor files and folders to get events on any operation on those files. There is a specific syntax for osquery configuration:

  • "/etc/": watches the entire directory at a depth of 1.
  • "/etc/%": watches the entire directory at a depth of 1.
  • "/etc/%%": watches the entire tree recursively with /etc/ as the root.

I am trying to evaluate the memory usage in case of watching a lot of directories. In this process I found the following statistics:

  • "/etc", "/etc/%", "/etc/%.conf": only 1 inotify handle is found registered in the name of osquery.

  • "/etc/%%: a few more than 289 inotify handles found which are registered in the name of osquery, given that there are a total of 285 directories under the tree. When checking the entries in /proc/$PID/fdinfo, all the inodes listed in the file points to just folders.

eg: for "/etc/%.conf"

$ grep -r "^inotify" /proc/$PID/fdinfo/
18:inotify wd:1 ino:120001 sdev:800001 mask:3ce ignored_mask:0 fhandle-bytes:8 fhandle-type:1 f_handle:01001200bc0f1cab

$ printf "%d\n" 0x120001
1179649

$ sudo debugfs -R "ncheck 1179649" /dev/sda1
debugfs 1.43.4 (31-Jan-2017)
Inode   Pathname
1179649 //etc

The inotify watch is established on the whole directory here, but the events are only reported for the matching files /etc/*.conf. Is osquery filtering the events based on the file_paths supplied, which is what I am assuming, but not sure.

Another experiment that I performed to support the above claim was, use the source in the inotify(7) and run a watcher on a particular file. When I check the list of inotify watchers, it just shows :

$ ./a.out /tmp/inotify.cc &

$ cat /proc/$PID/fdinfo/3
...
inotify wd:1 ino:1a1 sdev:800001 mask:38 ignored_mask:0 fhandle-bytes:8 fhandle-type:1 f_handle:a1010000aae325d7

$ sudo debugfs -R "ncheck 417" /dev/sda1
debugfs 1.43.4 (31-Jan-2017)
Inode   Pathname
417 /tmp/inotify.cc

So, according to this experiment, establishing a watcher on a single file is possible (which is clear from the inotify man page). This supports the claim that osquery is doing some sort of filtering based on the file patterns supplied.

Could someone verify the claim or present otherwise?


My osquery config:

{
  "options": {
    "host_identifier": "hostname",
    "schedule_splay_percent": 10
  },
  "schedule": {
    "file_events": {
      "query": "SELECT * FROM file_events;",
      "interval": 5
    }
  },

  "file_paths": {
    "sys": ["/etc/%.conf"]
  }
}

$ osqueryd --version
osqueryd version 3.3.2

$ uname -a
Linux lab 4.9.0-6-amd64 #1 SMP Debian 4.9.88-1+deb9u1 (2018-05-07) x86_64 GNU/Linux


Solution

  • It sounds like some great sleuthing!

    I think the comments in the source code support that. It's worth skimming it. I think the relevant files: