Signed-off-by: Aruna Balakrishnaiah <aruna at linux.vnet.ibm.com> --- eppic_scripts/README | 294 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 294 insertions(+) create mode 100644 eppic_scripts/README diff --git a/eppic_scripts/README b/eppic_scripts/README new file mode 100644 index 0000000..040b3ba --- /dev/null +++ b/eppic_scripts/README @@ -0,0 +1,294 @@ +=================================== + Eppic scripts README +================================== + +The eppic scripts are based on the fedora 19 kernel. + +1. Eppic script: proc_names.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.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.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.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.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.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_buf.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.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.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