@@ -36,6 +36,8 @@ PANDAENDCOMMENT */
3636// These need to be extern "C" so that the ABI is compatible with
3737// QEMU/PANDA, which is written in C
3838extern " C" {
39+ // For PANDA Logging
40+ #include " panda/plog.h"
3941
4042bool init_plugin (void *);
4143void uninit_plugin (void *);
@@ -82,14 +84,43 @@ bool is_match(const std::string &filename) {
8284 return fnmatch (target_filename.c_str (), filename.c_str (), FNM_NOESCAPE) == 0 ;
8385}
8486
87+ // Helper function to write the match to the PANDA log
88+ void log_file_taint_match (const std::string &filename, uint64_t pid, uint64_t tid, uint64_t file_id) {
89+ if (!pandalog) {
90+ verbose_printf (" file_taint No PANDA log found\n " );
91+ return ;
92+ }
93+ else {
94+ verbose_printf (" file_taint logging match to PANDA log\n " );
95+ }
96+
97+ // 1. Initialize the specific message
98+ Panda__FileTaintMatch * file_match = (Panda__FileTaintMatch *) malloc (sizeof (Panda__FileTaintMatch));
99+ *file_match = PANDA__FILE_TAINT_MATCH__INIT;
100+
101+ // 2. Populate fields (strings must be duplicated as the log-writer frees them)
102+ file_match->filename = strdup (filename.c_str ());
103+ file_match->pid = pid;
104+ file_match->tid = tid;
105+ file_match->file_id = file_id;
106+
107+ // 4. Write and Cleanup
108+ Panda__LogEntry ple = PANDA__LOG_ENTRY__INIT;
109+ ple.file_taint_match = file_match;
110+ pandalog_write_entry (&ple);
111+
112+ // Clean up: Protobuf-C requires manual freeing of nested allocated fields
113+ free (file_match->filename );
114+ free (file_match);
115+ }
116+
85117// A normalized read_enter function. Called by both Linux and Windows
86118// specific calls.
87119void read_enter (const std::string &filename, uint64_t file_id,
88120 uint64_t position) {
89121 // Check if the filename matched, if not we don't have to do anything.
90122 if (!is_match (filename)) {
91- verbose_printf (" file_taint read_enter: filename \" %s\" not matched\n " ,
92- filename.c_str ());
123+ verbose_printf (" file_taint read_enter: filename \" %s\" not matched\n " , filename.c_str ());
93124 return ;
94125 }
95126 else {
@@ -101,8 +132,7 @@ void read_enter(const std::string &filename, uint64_t file_id,
101132 // to taint.
102133 if (!taint2_enabled ()) {
103134 printf (" file_taint read_enter: first time match of filename pattern \" %s\" , "
104- " enabling taint\n " ,
105- target_filename.c_str ());
135+ " enabling taint\n " , target_filename.c_str ());
106136 taint2_enable_taint ();
107137 }
108138
@@ -116,6 +146,8 @@ void read_enter(const std::string &filename, uint64_t file_id,
116146 key.file_id = file_id;
117147 read_positions[key] = position;
118148
149+ log_file_taint_match (filename, key.process_id , key.thread_id , key.file_id );
150+
119151 verbose_printf (" file_taint read_enter matched: filename=\" %s\" pid=%lu "
120152 " tid=%lu fid=%lu\n " ,
121153 filename.c_str (), proc ? proc->pid : 0 , thr->tid , file_id);
@@ -128,8 +160,7 @@ void read_enter(const std::string &filename, uint64_t file_id,
128160// implementations.
129161void read_return (uint64_t file_id, uint64_t bytes_read,
130162 target_ulong buffer_addr) {
131- // Construct our read key (a tuple of PID, TID, and file ID (handle or
132- // descriptor).
163+ // Construct our read key (a tuple of PID, TID, and file ID (handle or descriptor).
133164 ReadKey key;
134165 std::unique_ptr<OsiProc, decltype (free_osiproc)*> proc { get_current_process (first_cpu), free_osiproc };
135166 std::unique_ptr<OsiThread, decltype (free_osithread)*> thr { get_current_thread (first_cpu), free_osithread };
0 commit comments