X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=fs%2Fproc%2Fkcore.c;h=0cda265efcc9bf90ada6659bb4a1b845a7358845;hb=refs%2Fheads%2Fvserver;hp=f7c0cda58f82baa5d240d7d5980ac6a7b2236500;hpb=9bf4aaab3e101692164d49b7ca357651eb691cb6;p=linux-2.6.git diff --git a/fs/proc/kcore.c b/fs/proc/kcore.c index f7c0cda58..0cda265ef 100644 --- a/fs/proc/kcore.c +++ b/fs/proc/kcore.c @@ -9,11 +9,11 @@ * Safe accesses to vmalloc/direct-mapped discontiguous areas, Kanoj Sarcar */ -#include #include #include #include #include +#include #include #include #include @@ -22,15 +22,16 @@ #include #include +#define CORE_STR "CORE" static int open_kcore(struct inode * inode, struct file * filp) { - return capable(CAP_SYS_RAWIO) ? 0 : -EPERM; + return -EPERM; } static ssize_t read_kcore(struct file *, char __user *, size_t, loff_t *); -struct file_operations proc_kcore_operations = { +const struct file_operations proc_kcore_operations = { .read = read_kcore, .open = open_kcore, }; @@ -42,8 +43,6 @@ struct file_operations proc_kcore_operations = { #define kc_offset_to_vaddr(o) ((o) + PAGE_OFFSET) #endif -#define roundup(x, y) ((((x)+((y)-1))/(y))*(y)) - /* An ELF note in memory */ struct memelfnote { @@ -54,7 +53,7 @@ struct memelfnote }; static struct kcore_list *kclist; -static rwlock_t kclist_lock = RW_LOCK_UNLOCKED; +static DEFINE_RWLOCK(kclist_lock); void kclist_add(struct kcore_list *new, void *addr, size_t size) @@ -68,23 +67,6 @@ kclist_add(struct kcore_list *new, void *addr, size_t size) write_unlock(&kclist_lock); } -struct kcore_list * -kclist_del(void *addr) -{ - struct kcore_list *m, **p = &kclist; - - write_lock(&kclist_lock); - for (m = *p; m; p = &m->next) { - if (m->addr == (unsigned long)addr) { - *p = m->next; - write_unlock(&kclist_lock); - return m; - } - } - write_unlock(&kclist_lock); - return NULL; -} - static size_t get_kcore_size(int *nphdr, size_t *elf_buflen) { size_t try, size; @@ -101,10 +83,11 @@ static size_t get_kcore_size(int *nphdr, size_t *elf_buflen) } *elf_buflen = sizeof(struct elfhdr) + (*nphdr + 2)*sizeof(struct elf_phdr) + - 3 * sizeof(struct memelfnote) + - sizeof(struct elf_prstatus) + - sizeof(struct elf_prpsinfo) + - sizeof(struct task_struct); + 3 * ((sizeof(struct elf_note)) + + roundup(sizeof(CORE_STR), 4)) + + roundup(sizeof(struct elf_prstatus), 4) + + roundup(sizeof(struct elf_prpsinfo), 4) + + roundup(sizeof(struct task_struct), 4); *elf_buflen = PAGE_ALIGN(*elf_buflen); return size + *elf_buflen; } @@ -119,7 +102,7 @@ static int notesize(struct memelfnote *en) int sz; sz = sizeof(struct elf_note); - sz += roundup(strlen(en->name), 4); + sz += roundup((strlen(en->name) + 1), 4); sz += roundup(en->datasz, 4); return sz; @@ -135,7 +118,7 @@ static char *storenote(struct memelfnote *men, char *bufp) #define DUMP_WRITE(addr,nr) do { memcpy(bufp,addr,nr); bufp += nr; } while(0) - en.n_namesz = strlen(men->name); + en.n_namesz = strlen(men->name) + 1; en.n_descsz = men->datasz; en.n_type = men->type; @@ -229,7 +212,7 @@ static void elf_kcore_store_hdr(char *bufp, int nphdr, int dataoff) nhdr->p_offset = offset; /* set up the process status */ - notes[0].name = "CORE"; + notes[0].name = CORE_STR; notes[0].type = NT_PRSTATUS; notes[0].datasz = sizeof(struct elf_prstatus); notes[0].data = &prstatus; @@ -240,7 +223,7 @@ static void elf_kcore_store_hdr(char *bufp, int nphdr, int dataoff) bufp = storenote(¬es[0], bufp); /* set up the process info */ - notes[1].name = "CORE"; + notes[1].name = CORE_STR; notes[1].type = NT_PRPSINFO; notes[1].datasz = sizeof(struct elf_prpsinfo); notes[1].data = &prpsinfo; @@ -257,7 +240,7 @@ static void elf_kcore_store_hdr(char *bufp, int nphdr, int dataoff) bufp = storenote(¬es[1], bufp); /* set up the task structure */ - notes[2].name = "CORE"; + notes[2].name = CORE_STR; notes[2].type = NT_TASKSTRUCT; notes[2].datasz = sizeof(struct task_struct); notes[2].data = current; @@ -281,8 +264,7 @@ read_kcore(struct file *file, char __user *buffer, size_t buflen, loff_t *fpos) unsigned long start; read_lock(&kclist_lock); - tsz = get_kcore_size(&nphdr, &elf_buflen); - proc_root_kcore->size = size = tsz + elf_buflen; + proc_root_kcore->size = size = get_kcore_size(&nphdr, &elf_buflen); if (buflen == 0 || *fpos >= size) { read_unlock(&kclist_lock); return 0; @@ -299,12 +281,11 @@ read_kcore(struct file *file, char __user *buffer, size_t buflen, loff_t *fpos) tsz = elf_buflen - *fpos; if (buflen < tsz) tsz = buflen; - elf_buf = kmalloc(elf_buflen, GFP_ATOMIC); + elf_buf = kzalloc(elf_buflen, GFP_ATOMIC); if (!elf_buf) { read_unlock(&kclist_lock); return -ENOMEM; } - memset(elf_buf, 0, elf_buflen); elf_kcore_store_hdr(elf_buf, nphdr, elf_buflen); read_unlock(&kclist_lock); if (copy_to_user(buffer, elf_buf + *fpos, tsz)) { @@ -350,10 +331,9 @@ read_kcore(struct file *file, char __user *buffer, size_t buflen, loff_t *fpos) unsigned long curstart = start; unsigned long cursize = tsz; - elf_buf = kmalloc(tsz, GFP_KERNEL); + elf_buf = kzalloc(tsz, GFP_KERNEL); if (!elf_buf) return -ENOMEM; - memset(elf_buf, 0, tsz); read_lock(&vmlist_lock); for (m=vmlist; m && cursize; m=m->next) { @@ -402,7 +382,7 @@ read_kcore(struct file *file, char __user *buffer, size_t buflen, loff_t *fpos) */ if (n) { if (clear_user(buffer + tsz - n, - tsz - n)) + n)) return -EFAULT; } } else {