1 #include <lttv/option.h>
2 #include <lttv/module.h>
4 #include <lttv/attribute.h>
5 #include <lttv/iattribute.h>
6 #include <lttv/stats.h>
7 #include <lttv/filter.h>
10 #include <ltt/trace.h>
12 #include "chroot_jail.h"
15 struct timeval
*tv1
, *tv2
;
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);
23 char *rootDirectory
= ltt_event_get_string(e
, f
);
25 LttvTracefileState
*tfs
= (LttvTracefileState
*)call_data
;
26 LttvTraceState
*ts
= (LttvTraceState
*) tfs
->parent
.t_context
;
27 LttvProcessState
*process
= ts
->running_process
[tfs
->cpu
];
30 //initialize a new finite state machine
31 struct rootjail
*rjstruct
= chrootjail_Init();
33 g_array_append_val(_fsm_list
, rjstruct
);
34 //call corresponding transition
35 rootjailContext_chroot(&(rjstruct
->_fsm
), pid
, rootDirectory
);
37 if(max_fsms
<_fsm_list
->len
)
38 max_fsms
=_fsm_list
->len
;
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
;
46 struct marker_field
*f
= lttv_trace_get_hook_field(th
,0);
48 LttvTracefileState
*tfs
= (LttvTracefileState
*)call_data
;
49 LttvTraceState
*ts
= (LttvTraceState
*) tfs
->parent
.t_context
;
50 LttvProcessState
*process
= ts
->running_process
[tfs
->cpu
];
53 char *newDirectory
= ltt_event_get_string(e
, f
);
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
);
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
;
69 struct marker_field
*f
= lttv_trace_get_hook_field(th
,0);
71 LttvTracefileState
*tfs
= (LttvTracefileState
*)call_data
;
72 LttvTraceState
*ts
= (LttvTraceState
*) tfs
->parent
.t_context
;
73 LttvProcessState
*process
= ts
->running_process
[tfs
->cpu
];
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
);
85 int removefsm(struct rootjail
*this){
87 for(i
=0; i
<_fsm_list
->len
; i
++)
89 struct rootjail
*rj
= g_array_index(_fsm_list
, struct rootjail
*, i
);
92 g_array_remove_index(_fsm_list
, i
);
97 static int add_events_by_id_hooks(void *hook_data
, void *call_data
){
98 LttvTraceContext
*tc
= (LttvTraceContext
*) call_data
;
102 GQuark LTT_FACILITY_FS
= g_quark_from_string("fs");
103 GQuark LTT_EVENT_CHROOT
= g_quark_from_string("chroot");
105 GQuark LTT_FIELD_ROOT
= g_quark_from_string("RootDirectory");
108 GQuark LTT_EVENT_CHDIR
= g_quark_from_string("chdir");
109 GQuark LTT_FIELD_DIRECTORY
= g_quark_from_string("Directory");
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");
115 GArray
*hooks
= g_array_sized_new(FALSE
, FALSE
, sizeof(LttvTraceHook
), 3);
117 lttv_trace_find_hook(t
, LTT_FACILITY_FS
, LTT_EVENT_CHROOT
,
118 FIELD_ARRAY(LTT_FIELD_ROOT
),
123 lttv_trace_find_hook(t
, LTT_FACILITY_FS
, LTT_EVENT_CHDIR
,
124 FIELD_ARRAY(LTT_FIELD_DIRECTORY
),
130 lttv_trace_find_hook(t
, LTT_FACILITY_FS
, LTT_EVENT_OPEN
,
131 FIELD_ARRAY(LTT_FIELD_FD
, LTT_FIELD_FILENAME
),
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
;
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
);
154 LttvAttributeValue value
;
156 LttvIAttribute
*attributes
= LTTV_IATTRIBUTE(lttv_global_attributes());
158 static LttvHooks
*before_trace
;
160 result
= lttv_iattribute_find_by_path(attributes
, "hooks/trace/before", LTTV_POINTER
, &value
);
162 before_trace
= *(value
.v_pointer
);
163 g_assert(before_trace
);
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
);
169 //Initialize empty GArray for FSMs
170 _fsm_list
= g_array_new(FALSE
, FALSE
, sizeof(struct rootjail
*));
172 tv1
= (struct timeval
*)malloc(sizeof(struct timeval
));
173 gettimeofday(tv1
, NULL
);
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
);
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")