def sync_handle_buf(fan_fd, redis_connection): start_time = time.time() buf = os.read(fan_fd, 4096) assert buf while fanotify.EventOk(buf): buf, event = fanotify.EventNext(buf) if event.mask & fanotify.FAN_Q_OVERFLOW: logging.info('queue overflow') continue fdpath = '/proc/self/fd/{:d}'.format(event.fd) target_path = os.readlink(fdpath) pid = event.pid try: fdpath = '/proc/{:d}/exe'.format(event.pid) name = os.readlink(fdpath) except: pid_has_name = redis_connection.hexists('pid_names', pid) pid_has_path = redis_connection.hexists('pid_paths', pid) if pid_has_name: name = redis_connection.hget('pid_names', pid).decode('utf-8') if pid_has_path: first_path = redis_connection.hget('pid_paths', pid).decode('utf-8') name = first_path else: redis_connection.hset('pid_paths', pid, target_path) name = target_path redis_connection.hset('pid_names', pid, name) logging.info('time: {:f} pid: {:d} exe: {:s} opened {:s}, analysis took {:f} now {:f}'.format(start_time, pid, name, target_path, time.time()-start_time, time.time())) os.close(event.fd) assert not buf
def TestReadLoop(self): # Create a buffer with 1024 events in it r = io.BytesIO(TEST_EVENT * 1024) w = io.BytesIO() # Continue reading and handling events until we've seen all 1024 c = 0 while c < 1024: # The real fanotify fd won't return partial events, but StringIO will. To # combat that we only read in multiples of the event structure size. buf = r.read(len(TEST_EVENT) * 16) while fanotify.EventOk(buf): buf, event = fanotify.EventNext(buf) res = fanotify.Response(event.fd, fanotify.FAN_ALLOW) w.write(res) c += 1 self.assertEqual(w.getvalue(), TEST_RESPONSE * 1024)
def _fa_worker(self): while True: buf = os.read(self.fan_fd, 4096) assert buf while fanotify.EventOk(buf): buf, event = fanotify.EventNext(buf) if event.mask & fanotify.FAN_Q_OVERFLOW: print('Queue overflow !') continue fdpath = '/proc/self/fd/{:d}'.format(event.fd) full_path = os.path.abspath(os.readlink(fdpath)) token = self._get_token(full_path) if token in self.watch_dict: # 获取socket数据 socket_data = self._get_socket_data(token, event.pid) if socket_data != None: self.watch_dict[token][socket_data] = True print(socket_data, full_path) # DEBUG os.write(self.fan_fd, fanotify.Response(event.fd, fanotify.FAN_ALLOW)) os.close(event.fd) assert not buf
def main(): if len(sys.argv) != 2: print('Usage: {} <path>'.format(sys.argv[0])) sys.exit(1) fan_fd = fanotify.Init(fanotify.FAN_CLASS_CONTENT, os.O_RDONLY) fanotify.Mark(fan_fd, fanotify.FAN_MARK_ADD | fanotify.FAN_MARK_MOUNT, fanotify.FAN_OPEN | fanotify.FAN_EVENT_ON_CHILD, -1, sys.argv[1]) while True: buf = os.read(fan_fd, 4096) assert buf while fanotify.EventOk(buf): buf, event = fanotify.EventNext(buf) if event.mask & fanotify.FAN_Q_OVERFLOW: print('Queue overflow !') continue fdpath = '/proc/self/fd/{:d}'.format(event.fd) full_path = os.readlink(fdpath) print(full_path) os.close(event.fd) assert not buf
def main(): if len(sys.argv) != 2: print('Usage: {} <path>'.format(sys.argv[0])) sys.exit(1) fan_fd = fanotify.Init(fanotify.FAN_CLASS_CONTENT, os.O_RDONLY) fanotify.Mark(fan_fd, fanotify.FAN_MARK_ADD, fanotify.FAN_OPEN_PERM, -1, sys.argv[1]) # Loop continuously rejecting events that don't match root's uid. while True: buf = os.read(fan_fd, 4096) assert buf while fanotify.EventOk(buf): buf, event = fanotify.EventNext(buf) if IsRootProcess(event.pid): print('Allowing open from root pid {}'.format(event.pid)) response = fanotify.FAN_ALLOW else: print('Denying open from pid {}'.format(event.pid)) response = fanotify.FAN_DENY os.write(fan_fd, fanotify.Response(event.fd, response)) os.close(event.fd) assert not buf
def TestEventNextRaisesError(self): with self.assertRaises(fanotify.FanotifyError): fanotify.EventNext(b'')
def TestEventNext(self): remaining_buf, event = fanotify.EventNext(TEST_EVENT) self.assertEqual(remaining_buf, b'') self.assertEqual(event.fd, 4) self.assertEqual(event.pid, 7345)