On 4/26/06, Hayim Shaul <hayim@xxxxxxxxxxxxxx> wrote: > >> >kfree calls kfree_debugcheck which looks like (I shortened it): > >>> > >>> struct page *page; > >>> > >>> if (!virt_addr_valid(objp)) > >>> BUG(); > >>> page = virt_to_page(objp); > >>> if (!PageSlab(page)) > >>> BUG(); > >>> > >>> It seems to me that these are the functions you look for. > >> thanks, I will check this out. > > > > I wonder, if above mentioned checks are really going to work for him, because > > the requirement is not only to check validity of received kernel pointer but > > also to be exact pointer (what was passed to application, because the pointer > > is pointer to some context). > > The macro virt_addr_valid(kaddr) expands to > > pfn_to_page(((unsigned long)(kaddr)-PAGE_OFFSET) >> PAGE_SHIFT) > > Basically, what Talib needs is a way to check that the pages containing > the address are allocated to some frame. (Cheking for the validity of the > structure pointed is done independantly by checking some signature+pid > that is supposed to be found at that address.) > > I think this is what virt_addr_valid does (and I would appreciate a > correction if I am wrong). > > PAGE_SHIFT is log(page_size) > PAGE_OFFSET is the first address available for the kernel > pfn_to_page is mem_map + (pfn) > > So, '((kaddr)-PAGE_OFFSET) >> PAGE_SHIFT' really aligns the address and > returns the index of page containing it. 0 being the first page available > to the kernel, etc. (implying virt_addr_valid works only for kernel > space pointers btw.) > > I don't know exactly what mem_map is, but it seems it is an array of all > page structures allocated by the kernel, hence virt_addr_valid returns 0 > iff the address points to a non-allocated page. > mem_map is an array of page structure, each element of this array is of "page" structure type. Actually mem_map is used for reverse mappeing of physical memory of system. This array represents the physical memory interms of page sturcture. Lets say for simplicity we have total physical memory of 256K and one one physical page of 4K, then in taht case mem_map will have 256/4 = 64 enteries and max_mapnr will be set to 64. So as per the kernel sources (file: include/asm-i386/page.h) #define pfn_valid(pfn) ((pfn) < max_mapnr) #define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT) virt_addr_valid() macro only tells whether the given virtual address can be mapped to any physical page or not. __pa() macro gives the physical address for a given virtual address just by subracting the PAGE_OFFSET from given virtual address. Now then we right shift that physical address by page size which gives us the page number in which our physical adress falls and then we look if this page number is less than the total number of physical pages in system, if yes then it means we can mapped this virtual address to some physical address else our given virtual address can not be mapped to any physical address in system. Having understood all this, and applying this information to the actual problem of verifying the virtual address, we can use this macro to just make sure that the kernel virtual address passed by user space back to kernel falls in kernel virtual address space but, we can not be sure if the given address is the same as we passed it to user space earlier, for that as mentioned by some one we need to user some ginature in the structure being pointed by this virtual address. Gaurav > > > > For example, the address passed from kernel to application is 0xC1234567 > > (which is pointing to some transaction allocated). Now if user application > > passed back as 0xC1234568, the above macro will fail to detect (Of course > > address is a valid one, but not what expected). For that matter, in my > > opinion, it won't be possible to check anyway against such examples. > > I think your example is wrong. Since both addresses fall in the same page > it doesn't matter. Now that I think of it, it seems that the check > "if (!PageSlab(page))" is redundant. > > You are correct though (and it slipped me) that if the memory allocated > falls on two pages, he should check the validity of both pages. > > > > I really don't think, receiving a pointer from user space is a good idea. I > > suggest to take recourse of table mechanism suggested in earlier emails. > > I agree on this one. You can have a very efficient table mechanism where > each entry costs you 35 bits (or 67 bits on 64-bit), with 1 lookup for > referencing and 3 lookups for allocating a new transaction. I doubt it > would be less efficient than any other solution, but this is really Talib's > decision to make. > > Hayim > > > Regards, > > Mohanlal > > -- > Kernelnewbies: Help each other learn about the Linux kernel. > Archive: http://mail.nl.linux.org/kernelnewbies/ > FAQ: http://kernelnewbies.org/faq/ > > -- -- -Gaurav Email: gauravd.chd@xxxxxxxxx --------------------------------- Read my blog at: http://lkdp.blogspot.com/ --------------------------------- -- Kernelnewbies: Help each other learn about the Linux kernel. Archive: http://mail.nl.linux.org/kernelnewbies/ FAQ: http://kernelnewbies.org/faq/