Re: VMAs and "offset"s?

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

 



I think I have some more questions:

On Wed, Apr 9, 2008 at 7:51 AM, Peter Teoh <htmldeveloper@xxxxxxxxx> wrote:
> On Wed, Apr 9, 2008 at 1:05 AM, Robert P. J. Day <rpjday@xxxxxxxxxxxxxx> wrote:
>  >
>  >   when i run "pmap" to examine the VMAs corresponding to, say, init,
>  >  how am i supposed to interpret the "Offset" column.  here:
>  >
>  >  # pmap -d 1
>  >  1:   init [5]
>  >  Address   Kbytes Mode  Offset           Device    Mapping
>  >  00110000       4 r-x-- 0000000000110000 000:00000   [ anon ]
>  >  00967000     220 r-x-- 0000000000000000 0fd:00000 libsepol.so.1
>  >  0099e000       4 rwx-- 0000000000036000 0fd:00000 libsepol.so.1
>  >  00a3d000     100 r-x-- 0000000000000000 0fd:00000 libselinux.so.1
>  >  00a56000       8 rwx-- 0000000000018000 0fd:00000 libselinux.so.1
>  >  00ab0000     108 r-x-- 0000000000000000 0fd:00000 ld-2.7.so
>  >  00acb000       4 r-x-- 000000000001a000 0fd:00000 ld-2.7.so
>  >  00acc000       4 rwx-- 000000000001b000 0fd:00000 ld-2.7.so
>  >  ... etc etc ...
>  >
>  >   so there's my listing of VMAs corresponding to the "init" process,
>  >  and i can see the addresses of each VMA, but what is the informational
>  >  value in the Offset field?
>  >
>  >   if you look at the two entries for, say, libsepol.so.1, those have
>  >  distinct addresses, but the first entry has an offset of zero, while
>  >  the second has an offset of 0x36000.  is that offset meant to
>  >  represent the offset with respect to the beginning of a multi-VMA
>  >  file?  or what?  thanks.
>  >
>  >  rday
>  >  --
>
>  First noticed that there is a identical information provided by "pmap
>  -d 1" and "cat /proc/1/maps":
>
>  /root/download/linux-2.6_latest/fs/proc>cat /proc/1/maps
>  003ed000-00408000 r-xp 00000000 08:05 262713     /lib/ld-2.6.so
>  00408000-00409000 r--p 0001a000 08:05 262713     /lib/ld-2.6.so
>  00409000-0040a000 rw-p 0001b000 08:05 262713     /lib/ld-2.6.so
>  0040c000-0055a000 r-xp 00000000 08:05 262714     /lib/libc-2.6.so
>  0055a000-0055c000 r--p 0014e000 08:05 262714     /lib/libc-2.6.so
>  08051000-08072000 rw-p 08051000 00:00 0          [heap]
>  441bd000-441c0000 r-xp 00000000 08:05 260873     /lib/libdl-2.6.so
>  4cfaa000-4cfc0000 r-xp 00000000 08:05 261141     /lib/libselinux.so.1
>  4cfc0000-4cfc2000 rw-p 00015000 08:05 261141     /lib/libselinux.so.1
>  b7f59000-b7f5b000 rw-p b7f59000 00:00 0
>  b7f6e000-b7f6f000 r-xp b7f6e000 00:00 0          [vdso]
>  bfe59000-bfe6e000 rw-p bffeb000 00:00 0          [stack]
>  /root/download/linux-2.6_latest/fs/proc>pmap -d 1
>
> 1:   init [5]
>  Address   Kbytes Mode  Offset           Device    Mapping
>  003ed000     108 r-x-- 0000000000000000 008:00005 ld-2.6.so
>  00408000       4 r---- 000000000001a000 008:00005 ld-2.6.so
>  00409000       4 rw--- 000000000001b000 008:00005 ld-2.6.so
>  0040c000    1336 r-x-- 0000000000000000 008:00005 libc-2.6.so
>  0055a000       8 r---- 000000000014e000 008:00005 libc-2.6.so
>  08051000     132 rw--- 0000000008051000 000:00000   [ anon ]
>  441bd000      12 r-x-- 0000000000000000 008:00005 libdl-2.6.so
>  b7f6e000       4 r-x-- 00000000b7f6e000 000:00000   [ anon ]
>  bfe59000      84 rw--- 00000000bffeb000 000:00000   [ stack ]
>  mapped: 2136K    writeable/private: 304K    shared: 0K
>
>  (some parts truncated above).
>
>  Since the mapping to /proc is possible, we shall use the kernel source code:
>
>  fs/proc/task_mmu.c: show_map():
>
>         seq_printf(m, "%08lx-%08lx %c%c%c%c %08lx %02x:%02x %lu %n",
>                         vma->vm_start,
>                         vma->vm_end,
>                         flags & VM_READ ? 'r' : '-',
>                         flags & VM_WRITE ? 'w' : '-',
>                         flags & VM_EXEC ? 'x' : '-',
>                         flags & VM_MAYSHARE ? 's' : 'p',
>                         vma->vm_pgoff << PAGE_SHIFT,
>                         MAJOR(dev), MINOR(dev), ino, &len);
>
>  So unambiguously, the offset correspond to vma->vm_pgoff <<
>  PAGE_SHIFT, which is I am not really sure of its semantic meaning.
>  But looking at the definition of vma (vm_area_struct in
>  inlcude/linux/mm_types.h):
>
>         /* Information about our backing store: */
>         unsigned long vm_pgoff;         /* Offset (within vm_file) in PAGE_SIZE
>                                            units, *not* PAGE_CACHE_SIZE */
>         struct file * vm_file;          /* File we map to (can be NULL). */
>
>

Notice that the above listing include libc and "stack" and "heap".
For libc, vm_file is the inode ptr to the physical file, so offset is
within the file, but for heap and stack, they are null, so why
show_map() does this:

        struct file *file = vma->vm_file;

        seq_printf(m, "%08lx-%08lx %c%c%c%c %08lx %02x:%02x %lu %n",
                        vma->vm_start,
                        vma->vm_end,
                        flags & VM_READ ? 'r' : '-',
                        flags & VM_WRITE ? 'w' : '-',
                        flags & VM_EXEC ? 'x' : '-',
                        flags & VM_MAYSHARE ? 's' : 'p',
                        vma->vm_pgoff << PAGE_SHIFT,
                        MAJOR(dev), MINOR(dev), ino, &len);

        if (file) {
                pad_len_spaces(m, len);
                seq_path(m, &file->f_path,
"\n");=====================> libc filename.
        } else {
                const char *name = arch_vma_name(vma);
                if (!name) {
                        if (mm) {
                                if (vma->vm_start <= mm->start_brk &&
                                                vma->vm_end >= mm->brk) {
                                        name = "[heap]";
                                } else if (vma->vm_start <= mm->start_stack &&
                                           vma->vm_end >= mm->start_stack) {
                                        name = "[stack]";
                                }
                        } else {
                                name = "[vdso]";
====================> the three diff variation possible - stack, heap
and vdso, only if vm_file is NULL.

So question now is vm_pgoff for heap, stack and vdso correspond to what?

In mm/memory.c, vm_pgoff is used as here:

        pgoff_t pgoff = (((address & PAGE_MASK)
                        - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff;
        unsigned int flags = (write_access ? FAULT_FLAG_WRITE : 0);

or here:

 *
 *      pfn_of_page == vma->vm_pgoff + ((addr - vma->vm_start) >> PAGE_SHIFT)
 *

So it seemed that vm_pgoff are somewhat related to the offset WITHIN
the kernel's linear address space (not physical, neither the process's
virtual address).   Wow...pmap allow u to see the distribution of
stuff in the kernel....as a userspace tool....is that really true?
Is it not a violation of security? Er......I think not...as a non-root
user, I see nothing for maps.

Are my analysis correct?

-- 
Regards,
Peter Teoh

--
To unsubscribe from this list: send an email with
"unsubscribe kernelnewbies" to ecartis@xxxxxxxxxxxx
Please read the FAQ at 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