Re: Verify Kernel Pointer

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

 



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/



[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