Javi Roman wrote:
Date: Wed, 31 Jan 2007 18:23:06 +0800
From: "Yanbo Li" <dreamfly281@xxxxxxxxx>
Subject: Re: How to make a tag in task_struct.
On 1/31/07, Mulyadi Santosa <mulyadi.santosa@xxxxxxxxx> wrote:
> Hi
> > But I can't modify the task_struct , in another word , I can't change
> > the kernel.
> > What I can do is just using a module.
> I am afraid you can't do that via module. In fact you must be careful on
> where to insert that new tag, because some properties in task_struct are
> accessed via offset, so if you change the order, it is likely made
> another codes broken. Conclusion: do it by directly patching the kernel,
> or use another way to tag the task. I think creating a linked list
> containing the PIDs could be a favorable choice.
>
> regards,
>
> Mulyadi
I think it's possible add new struct entries without problems with
offsets if you use this tool:
http://oops.ghostprotocols.net:81/blog/?p=49
http://lwn.net/Articles/206805/
regards,
javi roman
--
Kernelnewbies: Help each other learn about the Linux kernel.
Archive: http://mail.nl.linux.org/kernelnewbies/
FAQ: http://kernelnewbies.org/faq/
Hi all.
Thanks for your pointer, I have implement the function by pahole.
It detect the hole of the struct (see below eg: task_stuct) , we can using
the hole that system ignored. But this is not suitable for portable, so it just
a skill for some special using.
Another trick is it hard to get the address of a bit field, but we
can get it by this:
(assumption we want get the address of bit field swappable)
unsigned int ptr;
ptr = (unsigned int)¤t->cnswap;
ptr += 4;
The attach is a sample to using the hole, help it is useful for
someone. Any suggestion
and criticise is welcome.
BR
LiYanbo
/* <e12> linux-2.4.22/include/asm/processor.h:419 */
struct task_struct {
volatile long int state; /* 0 4 */
long unsigned int flags; /* 4 4 */
int sigpending; /* 8 4 */
mm_segment_t addr_limit; /* 12 4 */
struct exec_domain * exec_domain; /* 16 4 */
volatile long int need_resched; /* 20 4 */
long unsigned int ptrace; /* 24 4 */
int lock_depth; /* 28 4 */
long int counter; /* 32 4 */
long int nice; /* 36 4 */
long unsigned int policy; /* 40 4 */
struct mm_struct * mm; /* 44 4 */
int processor; /* 48 4 */
long unsigned int cpus_runnable; /* 52 4 */
long unsigned int cpus_allowed; /* 56 4 */
struct list_head run_list; /* 60 8 */
/* --- cacheline 1 boundary (64 bytes) was 4 bytes ago --- */
long unsigned int sleep_time; /* 68 4 */
struct task_struct * next_task; /* 72 4 */
struct task_struct * prev_task; /* 76 4 */
struct mm_struct * active_mm; /* 80 4 */
struct list_head local_pages; /* 84 8 */
unsigned int allocation_order; /* 92 4 */
unsigned int nr_local_pages; /* 96 4 */
struct linux_binfmt * binfmt; /* 100 4 */
int exit_code; /* 104 4 */
int exit_signal; /* 108 4 */
int pdeath_signal; /* 112 4 */
long unsigned int personality; /* 116 4 */
int did_exec:1; /* 120 4 */
unsigned int task_dumpable:1; /* 120 4 */
/* XXX 30 bits hole, try to pack */
pid_t pid; /* 124 4 */
/* --- cacheline 2 boundary (128 bytes) --- */
pid_t pgrp; /* 128 4 */
pid_t tty_old_pgrp; /* 132 4 */
pid_t session; /* 136 4 */
pid_t tgid; /* 140 4 */
int leader; /* 144 4 */
struct task_struct * p_opptr; /* 148 4 */
struct task_struct * p_pptr; /* 152 4 */
struct task_struct * p_cptr; /* 156 4 */
struct task_struct * p_ysptr; /* 160 4 */
struct task_struct * p_osptr; /* 164 4 */
struct list_head thread_group; /* 168 8 */
struct task_struct * pidhash_next; /* 176 4 */
struct task_struct * * pidhash_pprev; /* 180 4 */
wait_queue_head_t wait_chldexit; /* 184 16 */
/* --- cacheline 3 boundary (192 bytes) was 8 bytes ago --- */
struct completion * vfork_done; /* 200 4 */
long unsigned int rt_priority; /* 204 4 */
long unsigned int it_real_value; /* 208 4 */
long unsigned int it_prof_value; /* 212 4 */
long unsigned int it_virt_value; /* 216 4 */
long unsigned int it_real_incr; /* 220 4 */
long unsigned int it_prof_incr; /* 224 4 */
long unsigned int it_virt_incr; /* 228 4 */
struct timer_list real_timer; /* 232 20 */
struct tms times; /* 252 16 */
/* --- cacheline 4 boundary (256 bytes) was 12 bytes ago --- */
long unsigned int start_time; /* 268 4 */
long int per_cpu_utime[32]; /* 272 128 */
/* --- cacheline 6 boundary (384 bytes) was 16 bytes ago --- */
long int per_cpu_stime[32]; /* 400 128 */
/* --- cacheline 8 boundary (512 bytes) was 16 bytes ago --- */
long unsigned int min_flt; /* 528 4 */
long unsigned int maj_flt; /* 532 4 */
long unsigned int nswap; /* 536 4 */
long unsigned int cmin_flt; /* 540 4 */
long unsigned int cmaj_flt; /* 544 4 */
long unsigned int cnswap; /* 548 4 */
int swappable:1; /* 552 4 */
/* XXX 31 bits hole, try to pack */
uid_t uid; /* 556 4 */
uid_t euid; /* 560 4 */
uid_t suid; /* 564 4 */
uid_t fsuid; /* 568 4 */
gid_t gid; /* 572 4 */
/* --- cacheline 9 boundary (576 bytes) --- */
gid_t egid; /* 576 4 */
gid_t sgid; /* 580 4 */
gid_t fsgid; /* 584 4 */
int ngroups; /* 588 4 */
gid_t groups[32]; /* 592 128 */
/* --- cacheline 11 boundary (704 bytes) was 16 bytes ago --- */
kernel_cap_t cap_effective; /* 720 4 */
kernel_cap_t cap_inheritable; /* 724 4 */
kernel_cap_t cap_permitted; /* 728 4 */
int keep_capabilities:1; /* 732 4 */
/* XXX 31 bits hole, try to pack */
struct user_struct * user; /* 736 4 */
struct rlimit rlim[11]; /* 740 88 */
/* --- cacheline 12 boundary (768 bytes) was 60 bytes ago --- */
short unsigned int used_math; /* 828 2 */
char comm[16]; /* 830 16 */
/* XXX 2 bytes hole, try to pack */
/* --- cacheline 13 boundary (832 bytes) was 16 bytes ago --- */
int link_count; /* 848 4 */
int total_link_count; /* 852 4 */
struct tty_struct * tty; /* 856 4 */
unsigned int locks; /* 860 4 */
struct sem_undo * semundo; /* 864 4 */
struct sem_queue * semsleeping; /* 868 4 */
/* XXX 8 bytes hole, try to pack */
struct thread_struct thread; /* 880 736 */
/* XXX last struct has 4 bytes of padding */
/* --- cacheline 25 boundary (1600 bytes) was 16 bytes ago --- */
struct fs_struct * fs; /* 1616 4 */
struct files_struct * files; /* 1620 4 */
struct namespace * namespace; /* 1624 4 */
spinlock_t sigmask_lock; /* 1628 8 */
struct signal_struct * sig; /* 1636 4 */
sigset_t blocked; /* 1640 8 */
struct sigpending pending; /* 1648 16 */
/* --- cacheline 26 boundary (1664 bytes) --- */
long unsigned int sas_ss_sp; /* 1664 4 */
size_t sas_ss_size; /* 1668 4 */
int (*notifier)(void *); /* 1672 4 */
void * notifier_data; /* 1676 4 */
sigset_t * notifier_mask; /* 1680 4 */
u32 parent_exec_id; /* 1684 4 */
u32 self_exec_id; /* 1688 4 */
spinlock_t alloc_lock; /* 1692 8 */
void * journal_info; /* 1700 4 */
}; /* size: 1712, cachelines: 27 */
/* sum members: 1694, holes: 2, sum holes: 10 */
/* bit holes: 3, sum bit holes: 92 bits */
/* padding: 8 */
/* paddings: 1, sum paddings: 4 */
/* last cacheline: 48 bytes */
#define NEFC_MAX_BUFF 100
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/proc_fs.h>
#include <linux/sched.h>
#include <asm/uaccess.h>
static int nefc_read_proc(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
unsigned int ptr;
unsigned int tag;
ptr = (unsigned int)¤t->cnswap;
ptr += 4;
printk("Current comm is %s\n", current->comm);
printk("Tag is %X\n", *(unsigned int *)ptr);
tag = *(unsigned int *)ptr;
tag = tag >> 1;
printk("After right rotate tag is %X\n", tag);
sprintf(page, "%u\n", tag);
return sizeof(tag);
}
static int nefc_write_proc(struct file *file, const char *buffer,
unsigned long count, void *data)
{
unsigned int ptr;
unsigned int tag;
char buff[NEFC_MAX_BUFF];
MOD_INC_USE_COUNT;
if (count >= NEFC_MAX_BUFF)
return -EFAULT;
if(copy_from_user(buff, buffer, count)) {
MOD_DEC_USE_COUNT;
return -EFAULT;
}
buff[count] = '\0';
tag = simple_strtol(buff, NULL, 10);
printk("Tag is %X\n", tag);
tag = tag << 1;
printk("After left rotate tag is %X\n", tag);
// ptr = (unsigned int)¤t->parent->cnswap;
ptr = (unsigned int)¤t->cnswap;
ptr += 4;
printk("Before assign swappable is %X\n", *(unsigned int *)ptr);
/* clear the last value first */
*(unsigned int *)ptr &= 0x0001;
*(unsigned int *)ptr |= tag;
// printk("Change father's comm is %s\n", current->parent->comm);
printk("Change's comm is %s\n", current->comm);
printk("After assign swappable is %X\n", *(unsigned int *)ptr);
MOD_DEC_USE_COUNT;
return count;
}
void nefc_create_proc()
{
struct proc_dir_entry *entry;
entry = create_proc_entry("nefc", 0666, &proc_root);
if(entry) {
entry->read_proc = nefc_read_proc;
entry->write_proc = nefc_write_proc;
}
}
void nefc_remove_proc()
{
remove_proc_entry("nefc", NULL);
}