summaryrefslogtreecommitdiff
path: root/eppic_scripts/README
blob: 3038d15ae651e91ba4d4ccc60be88d20dbd86a5a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
===================================
 Eppic scripts README
==================================

These eppic scripts are based on the fedora 19 kernel. eppic scripts
naming convention follows the format:
<eppic_script name>-<valid from kernel version>_to_<valid until kernel version>.c

For example consider dir_names_3_10_to_3_13.c. This script would scrub
sensitive information successfully, when run against kernel version >= 3.10
and kernel version <= 3.13.

1. Eppic script: proc_names_3_10_to_4_8.c
   Description: Scrubs executable name of each user process

   Explanation:
       Walks all processes via the tasks lists starting from init_task

       extern struct task_struct init_task;

       struct task_struct {
            ...
            struct list_head tasks;
            ...
            char comm[TASK_COMM_LEN]; /* executable name excluding path */
            ...
       };

      For each user space process clear executable name

       struct task_struct *tsk;
       list_for_each_entry(tsk, &init_task, tasks) {
           if (tsk->mm)
               memset(tsk->comm, 0, TASK_COMM_LEN);
       }


2. Eppic script: dir_names_3_10_to_3_13.c
   Description: Scrubs filenames of cached dentries

   Explanation:
       i) iterate over all mounted filesystems

       struct vfsmount {
            struct list_head mnt_hash;
            ...
            struct dentry *mnt_root;        /* root of the mounted tree */
            ...
       };

       for (u = 0; i < HASH_SIZE; u++) {
           struct vfsmount *mnt;
           list_for_each_entry(mnt, &mount_hashtable[u], mnt_hash) {
              struct dentry *root;
              root = mnt->mnt_root;
              ...
           }
       }

       ii) recursively walk the dentries of each tree starting from root dentry
           and clear d_name and d_iname

       struct dentry {
            ...
            struct qstr d_name;
            ...
            unsigned char d_iname[DNAME_INLINE_LEN];        /* small names */
            ...
            struct list_head d_subdirs;     /* our children */
            ...
       };

       void walk_dentries(struct dentry *dentry)
       {
           struct dentry *child;
           memset(dentry->d_iname, 0, DNAME_INLINE_LEN);
           memset(dentry->d_name.name, 0, dentry->d_name.len);
           list_for_each_entry(child, &dentry->d_subdirs, d_u.d_child)
               walk_dentries(child);
       }

3. Eppic script: keyring_3_10_to_4_3.c
   Description: Scrubs all entries in the keyring

   Explanation:
       Scan the keyring_name_hash hash table

       static struct list_head keyring_name_hash[KEYRING_NAME_HASH_SIZE];

       for (i = 0; i < KEYRING_NAME_HASH_SIZE; i++)
           if (!list_empty(&keyring_name_hash[i])) {
               ...
           }

       For each non-empty list walk all keyring entries

       struct key {
            ...
            struct key_type         *type;          /* type of key */
            ...
            unsigned short          datalen;        /* payload data length */
            ...
            union {
                    struct list_head        link;
                    ...
            } type_data;
            ...
            union {
                    unsigned long           value;
                    void __rcu              *rcudata;
                    void                    *data;
                    struct keyring_list __rcu *subscriptions;
            } payload;
       };

       struct key *key;
       list_for_each_entry(key, &keyring_name_hash[i], type_data.link) {
           ...
       }

       Clear value/rcudata/data dependent on the type of the key.

4. Eppic script: ap_messages_3_10_to_4_8.c
   Description: Clear the message data of all ap_bus requests

   Explanation:
       Walk all devices in the LIST_HEAD(ap_device_list);

       struct ap_device {
            ...
            struct list_head list;          /* private list of all AP devices. */
           ...
            struct list_head pendingq;      /* List of message sent to AP queue. */
            int pendingq_count;             /* # requests on pendingq list. */
            struct list_head requestq;      /* List of message yet to be sent. */
            int requestq_count;             /* # requests on requestq list. */
            ...
       };

       struct ap_device *device;
       list_for_each_entry(device, &ap_device_list, list) {
            ...
       }

       For each ap device walk the pendingq and requestq list

       struct ap_message {
            struct list_head list;          /* Request queueing. */
            ...
            void *message;                  /* Pointer to message buffer. */
            size_t length;                  /* Message length. */
            ...
       };

       struct ap_message *apmsg;
       list_for_each_entry(apmsg, &device->pendingq, list) {
            ...
       }
       list_for_each_entry(apmsg, &device->requestq, list) {
            ...
       }

       For each message in pendingq and requestq clear the message

       memset(apmsg->message, 0, apmsg->length);

5. Eppic script: tcp_sk_buf_3_10_to_4_8.c
   Description: Scrub data in tcp socket buffers

   Explanation:
	 Find tcp domain sockets (struct sock *sk)

         tcp sockets:

           Iterate from 0 to INET_LHTABLE_SIZE and get inet_list_hashbucket from
           tcp_hash_info.listening_hash[<index>]

	    for (i = 0; i < INET_LHTABLE_SIZE; i++) {
                 struct inet_listen_hashbucket *ilb = &tcp_hashinfo.listening_hash[i];
             }
           For each hash bucket iterate over ilb->head null list to get sockets:
             struct sock *sk;
             sk_nulls_for_each(sk, node, &ilb->head) {
                 ...
             }


           For each socket iterate over the socket buffers in
           sk_receive_queue and sk_write_queue:

           struct sock {
                ...
                struct sk_buff_head     sk_receive_queue;
                ...
                struct sk_buff_head     sk_write_queue;
                ...
           };

           struct sk_buff_head {
                struct sk_buff  *next;
                struct sk_buff  *prev;
           };

           For each struct sk_buff in the two lists clear the memory referenced
           by skb->data / skb->data_len:

           struct sk_buff {
                ...
                unsigned int            data_len;
                ...
                unsigned char           *data;
                ...
           };

6. Eppic script: udp_sk_buf_3_10_to_4_8.c
   Description: Scrub data of udp socket buffers

   Explanation:
     Find all udp sockets (struct sock *sk)

     udp sockets:

       Iterate from 0 to udp_table->mask and get udp_hslot from hash table:
         for (i = 0; i < udp->table->mask; i++) {
             struct udp_hslot *hslot = udp_table->hash[i];
             ...
         }

       For each hslot iterate over hslot->head null list to get sockets:
         struct sock *sk;
         sk_nulls_for_each(sk, node, &hslot->head) {
             ...
         }

      For each socket iterate over the socket buffers in
      sk_receive_queue and sk_write_queue.

      For each struct sk_buff in the two lists clear the memory referenced
      by skb->data / skb->data_len.

7. Eppic script: unix_sk_buff_3_10_to_4_8.c
   Description: Scrub data of unix socket buffers

   Explanation:
       Iterate from 0 to UNIX_HASH_SIZE and then walk the hlist in
       for (i = 0; i < UNIX_HASH_SIZE; i++) {
             struct list_head *list = &unix_socket_table[i];
             ...
       }

       Walk each non-empty list in unix_socket_table
         struct sock *sk;
         sk_for_each(sk, node, &unix_socket_table[i])

       For each socket iterate over the socket buffers in
       sk_receive_queue and sk_write_queue.

       For each struct sk_buff in the two lists clear the memory referenced
       by skb->data / skb->data_len.

8. Eppic script: vhost_net_buffers_3_10_to_3_18.c
   Description: Scrub socket buffers of guest network I/O

   Explanation:
	 Scrub socket buffers of guest network I/O

         vhost_net instance will be attached to the file's private data.
         To get to the right file check the fdtable for each task, if the file
         has registered its fops with vhost_net_open, if so we can retreive the
         file's private data.

         if (task->files->fdt->fd[i]->f_op->open == &vhost_net_open)
                struct vhost_net *net = f->private_data;

         struct vhost_net_virtqueue *nvq = &net->vqs[VHOST_NET_VQ_MAX];
         struct vhost_virtqueue *vq = &nvq->vq;
         struct socket *sock = vq->private_data;
         struct sock *sk = sock->sk;

         struct sk_buff *next = sk->sk_receive_queue.next;
         struct sk_buff *prev = sk->sk_receive_queue.prev;

         Scrub next->data till the end of the sk_receive_queue and
         sk_write_queue list


9. Eppic script: vhost_scsi_buffers_3_10_to_4_8.c
   Description: Scrub buffers involved in guest block I/O

   Explanation:
        vhost_scsi instance will be attached to the file's private data.
        to get to the right file check the fdtable for each task, if the
	file has registered its fops with vhost_net_open, if so we can
	retreive the file's private data.

        if (task->files->fdt->fd[i]->f_op->open == &vhost_scsi_open)
            vhost_scsi *vs = task->files->fdt->fd[i]->private_data;

        struct vhost_virtqueue *vq = (struct vhost_virtqueue *)vs->vqs[i].vq;
        scrub vq->iov[j].iov_base