Commit | Line | Data |
---|---|---|
e09e518e GM |
1 | #include <lttv/option.h> |
2 | #include <lttv/module.h> | |
3 | #include <lttv/hook.h> | |
4 | #include <lttv/attribute.h> | |
5 | #include <lttv/iattribute.h> | |
6 | #include <lttv/stats.h> | |
7 | #include <lttv/filter.h> | |
8 | #include <ltt/ltt.h> | |
9 | #include <ltt/event.h> | |
10 | #include <ltt/trace.h> | |
11 | #include <stdio.h> | |
12 | #include "chroot_jail.h" | |
13 | ||
14 | GArray *_fsm_list; | |
15 | struct timeval *tv1, *tv2; | |
16 | int max_fsms = 0; | |
17 | static gboolean chroot(void *hook_data, void *call_data){ | |
18 | LttvTracefileState *s = (LttvTracefileState *) call_data; | |
19 | LttEvent *e = ltt_tracefile_get_event(s->parent.tf); | |
20 | LttvTraceHook *th = (LttvTraceHook *)hook_data; | |
21 | struct marker_field *f = lttv_trace_get_hook_field(th, 0); | |
22 | ||
23 | char *rootDirectory = ltt_event_get_string(e, f); | |
24 | ||
25 | LttvTracefileState *tfs = (LttvTracefileState *)call_data; | |
26 | LttvTraceState *ts = (LttvTraceState *) tfs->parent.t_context; | |
27 | LttvProcessState *process = ts->running_process[tfs->cpu]; | |
28 | int pid=process->pid; | |
29 | ||
30 | //initialize a new finite state machine | |
31 | struct rootjail *rjstruct = chrootjail_Init(); | |
32 | //add new fsm to list | |
33 | g_array_append_val(_fsm_list, rjstruct); | |
34 | //call corresponding transition | |
35 | rootjailContext_chroot(&(rjstruct->_fsm), pid, rootDirectory); | |
36 | ||
37 | if(max_fsms<_fsm_list->len) | |
38 | max_fsms=_fsm_list->len; | |
39 | return FALSE; | |
40 | } | |
41 | static gboolean chdir(void *hook_data, void *call_data){ | |
42 | LttvTracefileState *s = (LttvTracefileState *) call_data; | |
43 | LttEvent *e = ltt_tracefile_get_event(s->parent.tf); | |
44 | LttvTraceHook *th = (LttvTraceHook *) hook_data; | |
45 | ||
46 | struct marker_field *f = lttv_trace_get_hook_field(th,0); | |
47 | ||
48 | LttvTracefileState *tfs = (LttvTracefileState *)call_data; | |
49 | LttvTraceState *ts = (LttvTraceState *) tfs->parent.t_context; | |
50 | LttvProcessState *process = ts->running_process[tfs->cpu]; | |
51 | int pid=process->pid; | |
52 | ||
53 | char *newDirectory = ltt_event_get_string(e, f); | |
54 | ||
55 | int i; | |
56 | for(i=0; i<_fsm_list->len; i++){ | |
57 | struct rootjail *rjstruct = g_array_index(_fsm_list, struct rootjail *, i); | |
58 | rootjailContext_chdir(&(rjstruct->_fsm), pid, newDirectory); | |
59 | } | |
60 | ||
61 | return FALSE; | |
62 | ||
63 | } | |
64 | static gboolean open(void *hook_data, void *call_data){ | |
65 | LttvTracefileState *s = (LttvTracefileState *) call_data; | |
66 | LttEvent *e = ltt_tracefile_get_event(s->parent.tf); | |
67 | LttvTraceHook *th = (LttvTraceHook *) hook_data; | |
68 | ||
69 | struct marker_field *f = lttv_trace_get_hook_field(th,0); | |
70 | ||
71 | LttvTracefileState *tfs = (LttvTracefileState *)call_data; | |
72 | LttvTraceState *ts = (LttvTraceState *) tfs->parent.t_context; | |
73 | LttvProcessState *process = ts->running_process[tfs->cpu]; | |
74 | int pid=process->pid; | |
75 | ||
76 | int i; | |
77 | for(i=0; i<_fsm_list->len; i++){ | |
78 | struct rootjail *rjstruct = g_array_index(_fsm_list, struct rootjail *, i); | |
79 | rootjailContext_open(&(rjstruct->_fsm), pid); | |
80 | } | |
81 | ||
82 | return FALSE; | |
83 | ||
84 | } | |
85 | int removefsm(struct rootjail *this){ | |
86 | int i; | |
87 | for(i=0; i<_fsm_list->len; i++) | |
88 | { | |
89 | struct rootjail *rj = g_array_index(_fsm_list, struct rootjail *, i); | |
90 | if(rj==this) | |
91 | { | |
92 | g_array_remove_index(_fsm_list, i); | |
93 | break; | |
94 | } | |
95 | } | |
96 | } | |
97 | static int add_events_by_id_hooks(void *hook_data, void *call_data){ | |
98 | LttvTraceContext *tc = (LttvTraceContext *) call_data; | |
99 | LttTrace *t = tc->t; | |
100 | ||
101 | //EVENT CHROOT | |
102 | GQuark LTT_FACILITY_FS = g_quark_from_string("fs"); | |
103 | GQuark LTT_EVENT_CHROOT = g_quark_from_string("chroot"); | |
104 | //EVENT FIELDS | |
105 | GQuark LTT_FIELD_ROOT = g_quark_from_string("RootDirectory"); | |
106 | ||
107 | ||
108 | GQuark LTT_EVENT_CHDIR = g_quark_from_string("chdir"); | |
109 | GQuark LTT_FIELD_DIRECTORY = g_quark_from_string("Directory"); | |
110 | ||
111 | GQuark LTT_EVENT_OPEN = g_quark_from_string("open"); | |
112 | GQuark LTT_FIELD_FD = g_quark_from_string("fd"); | |
113 | GQuark LTT_FIELD_FILENAME = g_quark_from_string("filename"); | |
114 | ||
115 | GArray *hooks = g_array_sized_new(FALSE, FALSE, sizeof(LttvTraceHook), 3); | |
116 | ||
117 | lttv_trace_find_hook(t, LTT_FACILITY_FS, LTT_EVENT_CHROOT, | |
118 | FIELD_ARRAY(LTT_FIELD_ROOT), | |
119 | chroot, | |
120 | NULL, | |
121 | &hooks); | |
122 | ||
123 | lttv_trace_find_hook(t, LTT_FACILITY_FS, LTT_EVENT_CHDIR, | |
124 | FIELD_ARRAY(LTT_FIELD_DIRECTORY), | |
125 | chdir, | |
126 | NULL, | |
127 | &hooks); | |
128 | ||
129 | ||
130 | lttv_trace_find_hook(t, LTT_FACILITY_FS, LTT_EVENT_OPEN, | |
131 | FIELD_ARRAY(LTT_FIELD_FD, LTT_FIELD_FILENAME), | |
132 | open, | |
133 | NULL, | |
134 | &hooks); | |
135 | ||
136 | int nb_tracefiles = tc->tracefiles->len; | |
137 | //someting may be missing here... after recovery file got split into 2 parts. | |
138 | LttvHooks *needed_hooks; | |
139 | LttvTraceHook *th = (LttvTraceHook *)hook_data; | |
140 | int i, j; | |
141 | for(i=0; i<nb_tracefiles; i++){ | |
142 | tfc = &g_array_index(tc->tracefiles, LttvTracefileContext*, i); | |
143 | for(j=0; j<hooks->len; j++){ | |
144 | th=&g_array_index(hooks, LttvTraceHook, j); | |
145 | needed_hooks = lttv_hooks_by_id_find((*tfc)->event_by_id, th->id); | |
146 | lttv_hooks_add(needed_hooks, th->h, th, LTTV_PRIO_DEFAULT); | |
147 | } | |
148 | } | |
149 | } | |
150 | static void init(){ | |
151 | ||
152 | gboolean result; | |
153 | ||
154 | LttvAttributeValue value; | |
155 | ||
156 | LttvIAttribute *attributes = LTTV_IATTRIBUTE(lttv_global_attributes()); | |
157 | ||
158 | static LttvHooks *before_trace; | |
159 | ||
160 | result = lttv_iattribute_find_by_path(attributes, "hooks/trace/before", LTTV_POINTER, &value); | |
161 | g_assert(result); | |
162 | before_trace = *(value.v_pointer); | |
163 | g_assert(before_trace); | |
164 | ||
165 | //Register add_events_by_id_hook to be called before starting to read the trace | |
166 | //This function will be overwritten between checkers | |
167 | lttv_hooks_add(before_trace, add_events_by_id_hooks, NULL, LTTV_PRIO_DEFAULT); | |
168 | ||
169 | //Initialize empty GArray for FSMs | |
170 | _fsm_list = g_array_new(FALSE, FALSE, sizeof(struct rootjail *)); | |
171 | ||
172 | tv1 = (struct timeval *)malloc(sizeof(struct timeval)); | |
173 | gettimeofday(tv1, NULL); | |
174 | ||
175 | } | |
176 | static void destroy(){ | |
177 | tv2 = (struct timeval *)malloc(sizeof(struct timeval)); | |
178 | gettimeofday(tv2, NULL); | |
179 | int seconds = tv2->tv_sec - tv1->tv_sec; | |
180 | printf("analysis took: %d seconds \n", seconds); | |
181 | printf("total number of coexisting fsms is: %d\n",max_fsms); | |
182 | ||
183 | } | |
184 | ||
185 | LTTV_MODULE("chroot_checker", "Detects improper chroot jailing", | |
186 | "Catches attempts to open files after calling chroot without calling chdir", | |
187 | init, destroy, "stats", "batchAnalysis", "option") |