Re: Problem with LIST_HEAD and list_add (was Page Fault Handler Hijacking and Oops)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



> > The exception handler function hijacked:
> > 
> > 15.  static asmlinkage void mtpmc_handler(struct pt_regs * regs,
> >     long  error_code)
> >

> I am not actually sure this is supposed to work. asmlinkage changes the
> calling convention so I would expect simply calling it to not work. But
> I don't know the calling convention tricks well enough to be sure. Also
> note, that in 2.6.9 it is asmlinkage, but in 2.6.11 it is fastcall.
> 
> Also are you sure %%cr2 does not get destroyed before you call this. It
> shouldn't be, but anyway.

I'm not using 2.6.X but 2.4.29. It's asmlinkage.
For the %%cr2, it seems to go well. Infact, if I comment the if line:

 if (mtpmc_protected_by_us(address) == 1)

all run. The error seems to be in that function.
I'm just modifying my code using the <linux/list.h> macros but I'm having some 
problems also with it. In particular, with the creation of the lists.
I attach the modified lines of code.
The data structures become:

struct mtpmc_wrprotected_pages{ /* CREARE LIST_HEAD */
 struct list_head list;
 unsigned long address;
};

struct mtpmc_vm_wrprotected{ /* CREARE LIST_HEAD */
 struct list_head list;
 unsigned long vm_start;
 unsigned long vm_end;

 struct mtpmc_wrprotected_pages *pages;
};

the function to scans these list is:


int mtpmc_protected_by_us(unsigned long addr)
{
 struct list_head *vm_list, *page_list;
 struct mtpmc_vm_wrprotected *wr_vma;
 struct mtpmc_wrprotected_pages *wr_page, *temp_page;

 list_for_each(vm_list, &vm_write_protected){
  wr_vma = list_entry(vm_list, struct mtpmc_vm_wrprotected, list);
  if (INSIDE(wr_vma->vm_start, wr_vma->vm_end, addr)){
   temp_page = wr_vma->pages;
   list_for_each(page_list, &temp_page->list){
    wr_page = list_entry(page_list, struct mtpmc_wrprotected_pages, list);
    if ((addr >= wr_page->address) && (addr <(wr_page->address + PAGE_SIZE)))
     return 1;
   }
   return 0;      
  } 
 }
 
 return 0;
}


But the real problem is with the creation of one of the lists. The function in 
which I create them is the following:

 0.  static LIST_HEAD(vm_write_protected);

 1.  void mtpmc_set_mm_not_writable(struct mm_struct *mm)
 2.  {
 3.   struct vm_area_struct *vm;
 4.   struct mtpmc_wrprotected_pages *wr_page, *temp_page_wr;
 5.   struct mtpmc_vm_wrprotected *temp_vma_wr;
 6.   struct page *page;
 7.   pte_t *pte;
 8.   unsigned long addr;
 9.  
10.   down_write(&mm->mmap_sem);
11.   for (vm = mm->mmap; vm!=NULL; vm=vm->vm_next)
12.    if(mtpmc_vm_to_save(mm, vm) == 1){
13.     temp_vma_wr = mtpmc_mk_vm_wrprotected(vm);
14.     list_add_tail(&temp_vma_wr->list, &vm_write_protected);
15.     wr_page = temp_vma_wr->pages;
16.     INIT_LIST_HEAD(&wr_page->list);
17.     for(addr=vm->vm_start;addr<vm->vm_end;addr+=PAGE_SIZE){
18.      pte = mtpmc_get_pte_from_address(mm, addr);
19.      if (pte)
20.       if (pte_write(*pte)){
21.        set_pte(pte, pte_wrprotect(*pte));
22.        list_add_tail(&mtpmc_mk_page_wrprotected(addr)->list,   
             &wr_page->list);
23.   }
24.    }

25.   up_write(&mm->mmap_sem);
26.
27. return;
28.  }

the problem is with INIT_LIST_HEAD in line 16. I receive an error "Unable to 
handle NULL pointer ..." but the pointers in this function are never NULL.
For sake of completeness I post also the two function for creation of 
temp_vma_wr (called from line 13 - mtpmc_mk_vm_wrprotected(vm) ) and to 
create a new temp page (called from  line 22 - 
mtpmc_mk_page_wrprotected(addr) ).
Can you help me in organizing my data structures with the use of Linux 
list_head?


> 
> Anyway, I suspect the problem might be the call to the original handler.
> 
> Also make sure you properly lock the list with irqsaving spinlocks (ie.
> spin_lock_irqsave/spin_unlock_irqrestore outside the handler and
> spin_lock/spin_unlock inside.
> 

I don't use spin_lock as I'm created a uniprocessor program.

Thanks.
Vincenzo Mallozzi.

	

	
		
___________________________________ 
Yahoo! Mail: gratis 1GB per i messaggi e allegati da 10MB 
http://mail.yahoo.it


--
Kernelnewbies: Help each other learn about the Linux kernel.
Archive:       http://mail.nl.linux.org/kernelnewbies/
FAQ:           http://kernelnewbies.org/faq/


[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux