Skip to contentSkip to conversation

mm: NULL ptr deref handling mmaping of special mappings

DISCUSSION Sasha Levin 6 participants 28 messages May 14, 2014 – May 19, 2014 Memory management

lore
Share & tools
lore
#0 lore raw

Hi all,

While fuzzing with trinity inside a KVM tools guest running the latest -next kernel I've stumbled on the following spew:

[ 1634.969408] BUG: unable to handle kernel NULL pointer dereference at           (null)
[ 1634.970538] IP: special_mapping_fault (mm/mmap.c:2961)
[ 1634.971420] PGD 3334fc067 PUD 3334cf067 PMD 0
[ 1634.972081] Oops: 0000 [#1] PREEMPT SMP DEBUG_PAGEALLOC
[ 1634.972913] Dumping ftrace buffer:
[ 1634.975493]    (ftrace buffer empty)
[ 1634.977470] Modules linked in:
[ 1634.977513] CPU: 6 PID: 29578 Comm: trinity-c269 Not tainted 3.15.0-rc5-next-20140513-sasha-00020-gebce144-dirty #461
[ 1634.977513] task: ffff880333158000 ti: ffff88033351e000 task.ti: ffff88033351e000
[ 1634.977513] RIP: special_mapping_fault (mm/mmap.c:2961)
[ 1634.977513] RSP: 0018:ffff88033351faf8  EFLAGS: 00010202
[ 1634.977513] RAX: 0000000000000000 RBX: ffff88033351fbb0 RCX: 0000000000000028
[ 1634.977513] RDX: 0000000000000001 RSI: ffff88033351fb38 RDI: ffff88006d28b600
[ 1634.977513] RBP: ffff88033351fb18 R08: ffff88033351fbb0 R09: 0000000000000000
[ 1634.977513] R10: ffff88001bcca690 R11: 0000000000000000 R12: ffff88001bcca690
[ 1634.977513] R13: ffff880000000748 R14: 0000000000000028 R15: ffff88006d28b600
[ 1634.977513] FS:  00007f79da4b8700(0000) GS:ffff8801b4c00000(0000) knlGS:0000000000000000
[ 1634.977513] CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
[ 1634.977513] CR2: 0000000000000000 CR3: 00000003334fb000 CR4: 00000000000006a0
[ 1634.977513] Stack:
[ 1634.977513]  ffff88033351fb08 00000000000005d1 00000000000005d1 ffff88033351fbb0
[ 1634.977513]  ffff88033351fb78 ffffffffac2b83a9 ffff88033351fc28 ffffffffac1cb679
[ 1634.977513]  0000000000000028 00000007f79da4e9 00007f79da4e9000 0000000000000000
[ 1634.977513] Call Trace:
[ 1634.977513] __do_fault (mm/memory.c:2703)
[ 1634.977513] ? __lock_acquire (kernel/locking/lockdep.c:3189)
[ 1634.977513] do_read_fault.isra.40 (mm/memory.c:2883)
[ 1634.977513] ? get_parent_ip (kernel/sched/core.c:2519)
[ 1634.977513] ? get_parent_ip (kernel/sched/core.c:2519)
[ 1634.977513] ? __mem_cgroup_count_vm_event (include/linux/rcupdate.h:391 include/linux/rcupdate.h:893 mm/memcontrol.c:1302)
[ 1634.977513] ? get_parent_ip (kernel/sched/core.c:2519)
[ 1634.977513] __handle_mm_fault (mm/memory.c:3021 mm/memory.c:3182 mm/memory.c:3306)
[ 1634.977513] ? __const_udelay (arch/x86/lib/delay.c:126)
[ 1634.977513] ? __rcu_read_unlock (kernel/rcu/update.c:97)
[ 1634.977513] handle_mm_fault (mm/memory.c:3329)
[ 1634.977513] __do_page_fault (arch/x86/mm/fault.c:1224)
[ 1634.977513] ? kvm_clock_read (arch/x86/include/asm/preempt.h:90 arch/x86/kernel/kvmclock.c:86)
[ 1634.977513] ? sched_clock (arch/x86/include/asm/paravirt.h:192 arch/x86/kernel/tsc.c:305)
[ 1634.977513] ? sched_clock_local (kernel/sched/clock.c:214)
[ 1634.977513] ? get_parent_ip (kernel/sched/core.c:2519)
[ 1634.977513] ? context_tracking_user_exit (kernel/context_tracking.c:182)
[ 1634.977513] ? __this_cpu_preempt_check (lib/smp_processor_id.c:63)
[ 1634.977513] ? trace_hardirqs_off_caller (kernel/locking/lockdep.c:2638 (discriminator 2))
[ 1634.977513] do_page_fault (arch/x86/mm/fault.c:1277 include/linux/jump_label.h:105 include/linux/context_tracking_state.h:27 include/linux/context_tracking.h:45 arch/x86/mm/fault.c:1278)
[ 1634.977513] do_async_page_fault (arch/x86/kernel/kvm.c:264)
[ 1634.977513] async_page_fault (arch/x86/kernel/entry_64.S:1552)
[ 1634.977513] ? copy_user_generic_unrolled (arch/x86/lib/copy_user_64.S:153)
[ 1634.977513] ? SyS_add_key (security/keys/keyctl.c:109 security/keys/keyctl.c:62)
[ 1634.977513] tracesys (arch/x86/kernel/entry_64.S:746)
[ 1634.977513] Code: 1f 40 00 66 66 66 66 90 55 48 89 e5 53 48 83 ec 18 48 8b 56 08 48 8b 87 a8 00 00 00 48 2b 97 98 00 00 00 74 1e 66 0f 1f 44 00 00 <48> 83 38 00 74 62 48 83 c0 08 48 83 ea 01 75 f0 0f 1f 84 00 00
[ 1634.977513] RIP special_mapping_fault (mm/mmap.c:2961)
[ 1634.977513]  RSP <ffff88033351faf8>
[ 1634.977513] CR2: 0000000000000000

Thanks,
Sasha

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

maintainer
#1 lore raw
Quoted 5 lines · On Wed, 14 May 2014 11:55:45 -0400 Sasha Levin <[email protected]> wrote:

Hi all,

While fuzzing with trinity inside a KVM tools guest running the latest -next kernel I've stumbled on the following spew:

Quoted 10 lines
[ 1634.969408] BUG: unable to handle kernel NULL pointer dereference at           (null)
[ 1634.970538] IP: special_mapping_fault (mm/mmap.c:2961)
[ 1634.971420] PGD 3334fc067 PUD 3334cf067 PMD 0
[ 1634.972081] Oops: 0000 [#1] PREEMPT SMP DEBUG_PAGEALLOC
[ 1634.972913] Dumping ftrace buffer:
[ 1634.975493]    (ftrace buffer empty)
[ 1634.977470] Modules linked in:
[ 1634.977513] CPU: 6 PID: 29578 Comm: trinity-c269 Not tainted 3.15.0-rc5-next-20140513-sasha-00020-gebce144-dirty #461
[ 1634.977513] task: ffff880333158000 ti: ffff88033351e000 task.ti: ffff88033351e000
[ 1634.977513] RIP: special_mapping_fault (mm/mmap.c:2961)

Somebody's gone and broken the x86 oops output. It used to say "special_mapping_fault+0x30/0x120" but the offset info has now disappeared. That was useful for guesstimating whereabouts in the function it died.

The line number isn't very useful as it's not possible (or at least, not convenient) for others to reliably reproduce your kernel.

<scrabbles with git for a while>

: static int special_mapping_fault(struct vm_area_struct *vma,
: struct vm_fault *vmf)
: {
: pgoff_t pgoff;
: struct page **pages;
:
: /*
: * special mappings have no vm_file, and in that case, the mm
: * uses vm_pgoff internally. So we have to subtract it from here.
: * We are allowed to do this because we are the mm; do not copy
: * this code into drivers!
: */
: pgoff = vmf->pgoff - vma->vm_pgoff;
:
: for (pages = vma->vm_private_data; pgoff && *pages; ++pages)
: pgoff--;
:
: if (*pages) {
: struct page *page = *pages;
: get_page(page);
: vmf->page = page;
: return 0;
: }
:
: return VM_FAULT_SIGBUS;
: }

OK so it might be the "if (*pages)". So vma->vm_private_data was NULL and pgoff was zero. As usual, I can't imagine what race would cause that :(

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#2 lore raw
Quoted 18 lines · Andrew Morton
Quoted 5 lines · On Wed, 14 May 2014 11:55:45 -0400 Sasha Levin <[email protected]> wrote:

Hi all,

While fuzzing with trinity inside a KVM tools guest running the latest -next kernel I've stumbled on the following spew:

Quoted 10 lines
[ 1634.969408] BUG: unable to handle kernel NULL pointer dereference at           (null)
[ 1634.970538] IP: special_mapping_fault (mm/mmap.c:2961)
[ 1634.971420] PGD 3334fc067 PUD 3334cf067 PMD 0
[ 1634.972081] Oops: 0000 [#1] PREEMPT SMP DEBUG_PAGEALLOC
[ 1634.972913] Dumping ftrace buffer:
[ 1634.975493]    (ftrace buffer empty)
[ 1634.977470] Modules linked in:
[ 1634.977513] CPU: 6 PID: 29578 Comm: trinity-c269 Not tainted 3.15.0-rc5-next-20140513-sasha-00020-gebce144-dirty #461
[ 1634.977513] task: ffff880333158000 ti: ffff88033351e000 task.ti: ffff88033351e000
[ 1634.977513] RIP: special_mapping_fault (mm/mmap.c:2961)
Quoted 4 lines

Somebody's gone and broken the x86 oops output. It used to say "special_mapping_fault+0x30/0x120" but the offset info has now disappeared. That was useful for guesstimating whereabouts in the function it died.

I'm the one who "broke" the oops output, but I thought I'm helping people read that output instead of making it harder...

What happened before is that due to my rather complex .config, the offsets didn't make sense to anyone who didn't build the kernel with my .config, so I had to repeatedly send it out to folks who attempted to get basic things like line numbers.

Quoted 2 lines

The line number isn't very useful as it's not possible (or at least, not convenient) for others to reliably reproduce your kernel.

I don't understand that part. I'm usually stating in the beginning of my mails that I run my testing on the latest -next kernel. And indeed if you look at today's -next, that line number would point to:

        for (pages = vma->vm_private_data; pgoff && *pages; ++pages) <=== HERE
                pgoff--;

So I'm not sure how replacing the offset with line numbers is making things worse? previously offsets were useless for people who tried to debug these spews so that's why I switched it to line numbers in the first place.

Quoted 29 lines

<scrabbles with git for a while>

: static int special_mapping_fault(struct vm_area_struct *vma,
: struct vm_fault *vmf)
: {
: pgoff_t pgoff;
: struct page **pages;
:
: /*
: * special mappings have no vm_file, and in that case, the mm
: * uses vm_pgoff internally. So we have to subtract it from here.
: * We are allowed to do this because we are the mm; do not copy
: * this code into drivers!
: */
: pgoff = vmf->pgoff - vma->vm_pgoff;
:
: for (pages = vma->vm_private_data; pgoff && *pages; ++pages)
: pgoff--;
:
: if (*pages) {
: struct page *page = *pages;
: get_page(page);
: vmf->page = page;
: return 0;
: }
:
: return VM_FAULT_SIGBUS;
: }

Quoted 3 lines

OK so it might be the "if (*pages)". So vma->vm_private_data was NULL and pgoff was zero. As usual, I can't imagine what race would cause that :(

Yup, it's the *pages part in the 'for' loop above that. I did find the following in the vdso code:

        vma = _install_special_mapping(mm,
                                       addr + image->size,
                                       image->sym_end_mapping - image->size,
                                       VM_READ,
                                       NULL);

Which installs a mapping with a NULL ptr for pages (if I understand that correctly), but that code has been there for a while now.

Thanks,
Sasha
been there

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

maintainer
#3 lore raw
Quoted 32 lines · On Wed, 14 May 2014 16:41:45 -0400 Sasha Levin <[email protected]> wrote:
Quoted 18 lines · Andrew Morton
Quoted 5 lines · On Wed, 14 May 2014 11:55:45 -0400 Sasha Levin <[email protected]> wrote:

Hi all,

While fuzzing with trinity inside a KVM tools guest running the latest -next kernel I've stumbled on the following spew:

Quoted 10 lines
[ 1634.969408] BUG: unable to handle kernel NULL pointer dereference at           (null)
[ 1634.970538] IP: special_mapping_fault (mm/mmap.c:2961)
[ 1634.971420] PGD 3334fc067 PUD 3334cf067 PMD 0
[ 1634.972081] Oops: 0000 [#1] PREEMPT SMP DEBUG_PAGEALLOC
[ 1634.972913] Dumping ftrace buffer:
[ 1634.975493]    (ftrace buffer empty)
[ 1634.977470] Modules linked in:
[ 1634.977513] CPU: 6 PID: 29578 Comm: trinity-c269 Not tainted 3.15.0-rc5-next-20140513-sasha-00020-gebce144-dirty #461
[ 1634.977513] task: ffff880333158000 ti: ffff88033351e000 task.ti: ffff88033351e000
[ 1634.977513] RIP: special_mapping_fault (mm/mmap.c:2961)
Quoted 4 lines

Somebody's gone and broken the x86 oops output. It used to say "special_mapping_fault+0x30/0x120" but the offset info has now disappeared. That was useful for guesstimating whereabouts in the function it died.

I'm the one who "broke" the oops output, but I thought I'm helping people read that output instead of making it harder...

What happened before is that due to my rather complex .config, the offsets didn't make sense to anyone who didn't build the kernel with my .config, so I had to repeatedly send it out to folks who attempted to get basic things like line numbers.

Quoted 5 lines
Quoted 2 lines

The line number isn't very useful as it's not possible (or at least, not convenient) for others to reliably reproduce your kernel.

I don't understand that part. I'm usually stating in the beginning of my mails that I run my testing on the latest -next kernel.

Your "latest next kernel" apparently differes from mine ;( It would be useful if you could just quote the +/-5 lines, perhaps?

Quoted 46 lines

And indeed if
you look at today's -next, that line number would point to:

        for (pages = vma->vm_private_data; pgoff && *pages; ++pages) <=== HERE
                pgoff--;

So I'm not sure how replacing the offset with line numbers is making things worse? previously offsets were useless for people who tried to debug these spews so that's why I switched it to line numbers in the first place.

Quoted 29 lines

<scrabbles with git for a while>

: static int special_mapping_fault(struct vm_area_struct *vma,
: struct vm_fault *vmf)
: {
: pgoff_t pgoff;
: struct page **pages;
:
: /*
: * special mappings have no vm_file, and in that case, the mm
: * uses vm_pgoff internally. So we have to subtract it from here.
: * We are allowed to do this because we are the mm; do not copy
: * this code into drivers!
: */
: pgoff = vmf->pgoff - vma->vm_pgoff;
:
: for (pages = vma->vm_private_data; pgoff && *pages; ++pages)
: pgoff--;
:
: if (*pages) {
: struct page *page = *pages;
: get_page(page);
: vmf->page = page;
: return 0;
: }
:
: return VM_FAULT_SIGBUS;
: }

Quoted 3 lines

OK so it might be the "if (*pages)". So vma->vm_private_data was NULL and pgoff was zero. As usual, I can't imagine what race would cause that :(

Yup, it's the *pages part in the 'for' loop above that. I did find the following in the vdso code:

Quoted 8 lines
        vma = _install_special_mapping(mm,
                                       addr + image->size,
                                       image->sym_end_mapping - image->size,
                                       VM_READ,
                                       NULL);

Which installs a mapping with a NULL ptr for pages (if I understand that correctly), but that code has been there for a while now.

Well that's weird. I don't see anything which permits that. Maybe nobody faulted against that address before?

It's unclear what that code's actually doing and nobody bothered commenting it of course. Maybe it's installing a guard page?

In my linux-next all that code got deleted by Andy's "x86, vdso:
Reimplement vdso.so preparation in build-time C" anyway. What kernel were you looking at?

Andy, are you able to shed some light on why arch_setup_additional_pages() is (or was) passing a NULL into _install_special_mapping()?

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#4 lore raw
Quoted 34 lines · Andrew Morton
Quoted 32 lines · On Wed, 14 May 2014 16:41:45 -0400 Sasha Levin <[email protected]> wrote:
Quoted 18 lines · Andrew Morton
Quoted 5 lines · On Wed, 14 May 2014 11:55:45 -0400 Sasha Levin <[email protected]> wrote:

Hi all,

While fuzzing with trinity inside a KVM tools guest running the latest -next kernel I've stumbled on the following spew:

Quoted 10 lines
[ 1634.969408] BUG: unable to handle kernel NULL pointer dereference at           (null)
[ 1634.970538] IP: special_mapping_fault (mm/mmap.c:2961)
[ 1634.971420] PGD 3334fc067 PUD 3334cf067 PMD 0
[ 1634.972081] Oops: 0000 [#1] PREEMPT SMP DEBUG_PAGEALLOC
[ 1634.972913] Dumping ftrace buffer:
[ 1634.975493]    (ftrace buffer empty)
[ 1634.977470] Modules linked in:
[ 1634.977513] CPU: 6 PID: 29578 Comm: trinity-c269 Not tainted 3.15.0-rc5-next-20140513-sasha-00020-gebce144-dirty #461
[ 1634.977513] task: ffff880333158000 ti: ffff88033351e000 task.ti: ffff88033351e000
[ 1634.977513] RIP: special_mapping_fault (mm/mmap.c:2961)
Quoted 4 lines

Somebody's gone and broken the x86 oops output. It used to say "special_mapping_fault+0x30/0x120" but the offset info has now disappeared. That was useful for guesstimating whereabouts in the function it died.

I'm the one who "broke" the oops output, but I thought I'm helping people read that output instead of making it harder...

What happened before is that due to my rather complex .config, the offsets didn't make sense to anyone who didn't build the kernel with my .config, so I had to repeatedly send it out to folks who attempted to get basic things like line numbers.

Quoted 8 lines
Quoted 5 lines
Quoted 2 lines

The line number isn't very useful as it's not possible (or at least, not convenient) for others to reliably reproduce your kernel.

I don't understand that part. I'm usually stating in the beginning of my mails that I run my testing on the latest -next kernel.

Your "latest next kernel" apparently differes from mine ;( It would be useful if you could just quote the +/-5 lines, perhaps?

Oh, I see what happened. I have the remap_file_pages() get_file/fput fix merged in which modified line count.

Yup, I'll start quoting the line themselves as well.

Quoted 58 lines
Quoted 46 lines

And indeed if
you look at today's -next, that line number would point to:

        for (pages = vma->vm_private_data; pgoff && *pages; ++pages) <=== HERE
                pgoff--;

So I'm not sure how replacing the offset with line numbers is making things worse? previously offsets were useless for people who tried to debug these spews so that's why I switched it to line numbers in the first place.

Quoted 29 lines

<scrabbles with git for a while>

: static int special_mapping_fault(struct vm_area_struct *vma,
: struct vm_fault *vmf)
: {
: pgoff_t pgoff;
: struct page **pages;
:
: /*
: * special mappings have no vm_file, and in that case, the mm
: * uses vm_pgoff internally. So we have to subtract it from here.
: * We are allowed to do this because we are the mm; do not copy
: * this code into drivers!
: */
: pgoff = vmf->pgoff - vma->vm_pgoff;
:
: for (pages = vma->vm_private_data; pgoff && *pages; ++pages)
: pgoff--;
:
: if (*pages) {
: struct page *page = *pages;
: get_page(page);
: vmf->page = page;
: return 0;
: }
:
: return VM_FAULT_SIGBUS;
: }

Quoted 3 lines

OK so it might be the "if (*pages)". So vma->vm_private_data was NULL and pgoff was zero. As usual, I can't imagine what race would cause that :(

Yup, it's the *pages part in the 'for' loop above that. I did find the following in the vdso code:

Quoted 8 lines
        vma = _install_special_mapping(mm,
                                       addr + image->size,
                                       image->sym_end_mapping - image->size,
                                       VM_READ,
                                       NULL);

Which installs a mapping with a NULL ptr for pages (if I understand that correctly), but that code has been there for a while now.

Well that's weird. I don't see anything which permits that. Maybe nobody faulted against that address before?

Quoted 6 lines

It's unclear what that code's actually doing and nobody bothered commenting it of course. Maybe it's installing a guard page?

In my linux-next all that code got deleted by Andy's "x86, vdso:
Reimplement vdso.so preparation in build-time C" anyway. What kernel were you looking at?

Deleted? It appears in today's -next. arch/x86/vdso/vma.c:124 .

I don't see Andy's patch removing that code either.

I'm running next-20140514...

Thanks,
Sasha

#27 lore raw
In reply to Andrew Morton
Quoted 105 lines · Andrew Morton
Quoted 32 lines · On Wed, 14 May 2014 16:41:45 -0400 Sasha Levin <[email protected]> wrote:
Quoted 18 lines · Andrew Morton
Quoted 5 lines · On Wed, 14 May 2014 11:55:45 -0400 Sasha Levin <[email protected]> wrote:

Hi all,

While fuzzing with trinity inside a KVM tools guest running the latest -next kernel I've stumbled on the following spew:

Quoted 10 lines
[ 1634.969408] BUG: unable to handle kernel NULL pointer dereference at           (null)
[ 1634.970538] IP: special_mapping_fault (mm/mmap.c:2961)
[ 1634.971420] PGD 3334fc067 PUD 3334cf067 PMD 0
[ 1634.972081] Oops: 0000 [#1] PREEMPT SMP DEBUG_PAGEALLOC
[ 1634.972913] Dumping ftrace buffer:
[ 1634.975493]    (ftrace buffer empty)
[ 1634.977470] Modules linked in:
[ 1634.977513] CPU: 6 PID: 29578 Comm: trinity-c269 Not tainted 3.15.0-rc5-next-20140513-sasha-00020-gebce144-dirty #461
[ 1634.977513] task: ffff880333158000 ti: ffff88033351e000 task.ti: ffff88033351e000
[ 1634.977513] RIP: special_mapping_fault (mm/mmap.c:2961)
Quoted 4 lines

Somebody's gone and broken the x86 oops output. It used to say "special_mapping_fault+0x30/0x120" but the offset info has now disappeared. That was useful for guesstimating whereabouts in the function it died.

I'm the one who "broke" the oops output, but I thought I'm helping people read that output instead of making it harder...

What happened before is that due to my rather complex .config, the offsets didn't make sense to anyone who didn't build the kernel with my .config, so I had to repeatedly send it out to folks who attempted to get basic things like line numbers.

Quoted 5 lines
Quoted 2 lines

The line number isn't very useful as it's not possible (or at least, not convenient) for others to reliably reproduce your kernel.

I don't understand that part. I'm usually stating in the beginning of my mails that I run my testing on the latest -next kernel.

Your "latest next kernel" apparently differes from mine ;( It would be useful if you could just quote the +/-5 lines, perhaps?

Quoted 46 lines

And indeed if
you look at today's -next, that line number would point to:

        for (pages = vma->vm_private_data; pgoff && *pages; ++pages) <=== HERE
                pgoff--;

So I'm not sure how replacing the offset with line numbers is making things worse? previously offsets were useless for people who tried to debug these spews so that's why I switched it to line numbers in the first place.

Quoted 24 lines

<scrabbles with git for a while>

: static int special_mapping_fault(struct vm_area_struct *vma,
: struct vm_fault *vmf)
: {
: pgoff_t pgoff;
: struct page **pages;
:
: /*

:    * special mappings have no vm_file, and in that case, the mm
:    * uses vm_pgoff internally. So we have to subtract it from here.
:    * We are allowed to do this because we are the mm; do not copy
:    * this code into drivers!
:    */

: pgoff = vmf->pgoff - vma->vm_pgoff;
:
: for (pages = vma->vm_private_data; pgoff && *pages; ++pages)
: pgoff--;
:
: if (*pages) {

:           struct page *page = *pages;
:           get_page(page);
:           vmf->page = page;
:           return 0;
Quoted 8 lines

: }
:
: return VM_FAULT_SIGBUS;
: }

OK so it might be the "if (*pages)". So vma->vm_private_data was NULL and pgoff was zero. As usual, I can't imagine what race would cause that :(

Yup, it's the *pages part in the 'for' loop above that. I did find the following in the vdso code:

Quoted 8 lines
        vma = _install_special_mapping(mm,
                                       addr + image->size,
                                       image->sym_end_mapping - image->size,
                                       VM_READ,
                                       NULL);

Which installs a mapping with a NULL ptr for pages (if I understand that correctly), but that code has been there for a while now.

Well that's weird. I don't see anything which permits that. Maybe nobody faulted against that address before?

It's unclear what that code's actually doing and nobody bothered commenting it of course. Maybe it's installing a guard page?

Quoted 8 lines

In my linux-next all that code got deleted by Andy's "x86, vdso:
Reimplement vdso.so preparation in build-time C" anyway. What kernel were you looking at?

Andy, are you able to shed some light on why arch_setup_additional_pages() is (or was) passing a NULL into _install_special_mapping()?

Ugh. I just moved that code; I didn't delete it. In fact, I likely made it worse by causing x86_64 to use it, too.

Oddly, this code worked when I tested it. Do you know what Trinity did to break it? Did the PTEs get nuked due to memory pressure?

The intent is to use remap_pfn_range (a couple of lines below) to map some kernel data into userspace read-only. I think the right fix would be to pass in the pages array directly but to modify _install_special_mapping to clear VM_MAYWRITE. The idea is that ptrace and mprotect should *not* be usable to COW these pages:
userspace will shoot itself in the foot quite thoroughly if the pages get COWed. Additionally, one of those pages actually represents some hardware registers, which almost certainly needs to be mapped UC.

IIRC on x86_32 there are two pages in there. One is regular kernel memory that has a struct page associated with it. The other is the HPET, which is a page of hardware registers that may not have a struct page.

Can anyone who's less clueless than I am about how vmas work help? Does this need to use its own vmops instead of the special mapping stuff?

--Andy

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

maintainer
#5 lore raw
In reply to Sasha Levin
Quoted 7 lines · On Wed, 14 May 2014 17:11:00 -0400 Sasha Levin <[email protected]> wrote:
Quoted 3 lines

In my linux-next all that code got deleted by Andy's "x86, vdso:
Reimplement vdso.so preparation in build-time C" anyway. What kernel were you looking at?

Deleted? It appears in today's -next. arch/x86/vdso/vma.c:124 .

I don't see Andy's patch removing that code either.

ah, OK, it got moved from arch/x86/vdso/vdso32-setup.c into arch/x86/vdso/vma.c.

Maybe you managed to take a fault against the symbol area between the _install_special_mapping() and the remap_pfn_range() call, but mmap_sem should prevent that.

Or the remap_pfn_range() call never happened. Should map_vdso() be running _install_special_mapping() at all if image->sym_vvar_page==NULL?

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#6 lore raw
Quoted 13 lines · Andrew Morton
Quoted 7 lines · On Wed, 14 May 2014 17:11:00 -0400 Sasha Levin <[email protected]> wrote:
Quoted 3 lines

In my linux-next all that code got deleted by Andy's "x86, vdso:
Reimplement vdso.so preparation in build-time C" anyway. What kernel were you looking at?

Deleted? It appears in today's -next. arch/x86/vdso/vma.c:124 .

I don't see Andy's patch removing that code either.

ah, OK, it got moved from arch/x86/vdso/vdso32-setup.c into arch/x86/vdso/vma.c.

Quoted 7 lines

Maybe you managed to take a fault against the symbol area between the _install_special_mapping() and the remap_pfn_range() call, but mmap_sem should prevent that.

Or the remap_pfn_range() call never happened. Should map_vdso() be running _install_special_mapping() at all if image->sym_vvar_page==NULL?

I'm confused: are we talking about 3.15-rcsomething or linux-next? That code changed.

Would this all make more sense if there were just a single vma in here? cc: Pavel and Cyrill, who might have to deal with this stuff in CRIU

--Andy

Signature · 8 lines
Andy Lutomirski
AMA Capital Management, LLC

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected].  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
#7 lore raw
Quoted 23 lines · Andy Lutomirski
Quoted 13 lines · Andrew Morton
Quoted 7 lines · On Wed, 14 May 2014 17:11:00 -0400 Sasha Levin <[email protected]> wrote:
Quoted 3 lines

In my linux-next all that code got deleted by Andy's "x86, vdso:
Reimplement vdso.so preparation in build-time C" anyway. What kernel were you looking at?

Deleted? It appears in today's -next. arch/x86/vdso/vma.c:124 .

I don't see Andy's patch removing that code either.

ah, OK, it got moved from arch/x86/vdso/vdso32-setup.c into arch/x86/vdso/vma.c.

Quoted 7 lines

Maybe you managed to take a fault against the symbol area between the _install_special_mapping() and the remap_pfn_range() call, but mmap_sem should prevent that.

Or the remap_pfn_range() call never happened. Should map_vdso() be running _install_special_mapping() at all if image->sym_vvar_page==NULL?

Quoted 6 lines

I'm confused: are we talking about 3.15-rcsomething or linux-next? That code changed.

Would this all make more sense if there were just a single vma in here? cc: Pavel and Cyrill, who might have to deal with this stuff in CRIU

Well, for criu we've not modified any vdso kernel's code (except setting VM_SOFTDIRTY for this vdso VMA in _install_special_mapping). And never experienced problems Sasha points. Looks like indeed in -next code is pretty different from mainline one. To figure out why I need to fetch -next branch and get some research. I would try to do that tomorrow (still hoping someone more experienced in mm system would beat me on that).

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#8 lore raw
Quoted 31 lines · Cyrill Gorcunov
Quoted 23 lines · Andy Lutomirski
Quoted 13 lines · Andrew Morton
Quoted 7 lines · On Wed, 14 May 2014 17:11:00 -0400 Sasha Levin <[email protected]> wrote:
Quoted 3 lines

In my linux-next all that code got deleted by Andy's "x86, vdso:
Reimplement vdso.so preparation in build-time C" anyway. What kernel were you looking at?

Deleted? It appears in today's -next. arch/x86/vdso/vma.c:124 .

I don't see Andy's patch removing that code either.

ah, OK, it got moved from arch/x86/vdso/vdso32-setup.c into arch/x86/vdso/vma.c.

Quoted 7 lines

Maybe you managed to take a fault against the symbol area between the _install_special_mapping() and the remap_pfn_range() call, but mmap_sem should prevent that.

Or the remap_pfn_range() call never happened. Should map_vdso() be running _install_special_mapping() at all if image->sym_vvar_page==NULL?

Quoted 6 lines

I'm confused: are we talking about 3.15-rcsomething or linux-next? That code changed.

Would this all make more sense if there were just a single vma in here? cc: Pavel and Cyrill, who might have to deal with this stuff in CRIU

Quoted 7 lines

Well, for criu we've not modified any vdso kernel's code (except setting VM_SOFTDIRTY for this vdso VMA in _install_special_mapping). And never experienced problems Sasha points. Looks like indeed in -next code is pretty different from mainline one. To figure out why I need to fetch -next branch and get some research. I would try to do that tomorrow (still hoping someone more experienced in mm system would beat me on that).

I can summarize:

On 3.14 and before, the vdso is just a bunch of ELF headers and executable data. When executed by 64-bit binaries, it reads from the fixmap to do its thing. That is, it reads from kernel addresses that don't have vmas. When executed by 32-bit binaries, it doesn't read anything, since there was no 32-bit timing code.

On 3.15, the x86_64 vdso is unchanged. The 32-bit vdso is preceded by a separate vma containing two pages worth of time-varying read-only data. The vdso reads those pages using PIC references.

On linux-next, all vdsos work the same way. There are two vmas. The first vma is executable text, which can be poked at by ptrace, etc normally. The second vma contains time-varying state, should not allow poking, and is accessed by PIC references.

What does CRIU do to restore the vdso? Will 3.15 and/or linux-next need to make some concession for CRIU?

--Andy

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#26 lore raw
In reply to Andrew Morton
Quoted 13 lines · Andrew Morton
Quoted 7 lines · On Wed, 14 May 2014 17:11:00 -0400 Sasha Levin <[email protected]> wrote:
Quoted 3 lines

In my linux-next all that code got deleted by Andy's "x86, vdso:
Reimplement vdso.so preparation in build-time C" anyway. What kernel were you looking at?

Deleted? It appears in today's -next. arch/x86/vdso/vma.c:124 .

I don't see Andy's patch removing that code either.

ah, OK, it got moved from arch/x86/vdso/vdso32-setup.c into arch/x86/vdso/vma.c.

Quoted 7 lines

Maybe you managed to take a fault against the symbol area between the _install_special_mapping() and the remap_pfn_range() call, but mmap_sem should prevent that.

Or the remap_pfn_range() call never happened. Should map_vdso() be running _install_special_mapping() at all if image->sym_vvar_page==NULL?

You're almost right, but that was enough to point me in the right direction :)

The mapping is still needed, since there are two pages. qemu -no-hpet will trigger this, but the nohpet kernel option will not. The latter is arguably a bug in the nohpet option.

Fix coming.

Signature · 8 lines
Andy Lutomirski
AMA Capital Management, LLC

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected].  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
#9 lore raw
In reply to Andy Lutomirski
Quoted 48 lines · Andy Lutomirski
Quoted 31 lines · Cyrill Gorcunov
Quoted 23 lines · Andy Lutomirski
Quoted 13 lines · Andrew Morton
Quoted 7 lines · On Wed, 14 May 2014 17:11:00 -0400 Sasha Levin <[email protected]> wrote:
Quoted 3 lines

In my linux-next all that code got deleted by Andy's "x86, vdso:
Reimplement vdso.so preparation in build-time C" anyway. What kernel were you looking at?

Deleted? It appears in today's -next. arch/x86/vdso/vma.c:124 .

I don't see Andy's patch removing that code either.

ah, OK, it got moved from arch/x86/vdso/vdso32-setup.c into arch/x86/vdso/vma.c.

Quoted 7 lines

Maybe you managed to take a fault against the symbol area between the _install_special_mapping() and the remap_pfn_range() call, but mmap_sem should prevent that.

Or the remap_pfn_range() call never happened. Should map_vdso() be running _install_special_mapping() at all if image->sym_vvar_page==NULL?

Quoted 6 lines

I'm confused: are we talking about 3.15-rcsomething or linux-next? That code changed.

Would this all make more sense if there were just a single vma in here? cc: Pavel and Cyrill, who might have to deal with this stuff in CRIU

Quoted 7 lines

Well, for criu we've not modified any vdso kernel's code (except setting VM_SOFTDIRTY for this vdso VMA in _install_special_mapping). And never experienced problems Sasha points. Looks like indeed in -next code is pretty different from mainline one. To figure out why I need to fetch -next branch and get some research. I would try to do that tomorrow (still hoping someone more experienced in mm system would beat me on that).

I can summarize:

On 3.14 and before, the vdso is just a bunch of ELF headers and executable data. When executed by 64-bit binaries, it reads from the fixmap to do its thing. That is, it reads from kernel addresses that don't have vmas. When executed by 32-bit binaries, it doesn't read anything, since there was no 32-bit timing code.

Quoted 8 lines

On 3.15, the x86_64 vdso is unchanged. The 32-bit vdso is preceded by a separate vma containing two pages worth of time-varying read-only data. The vdso reads those pages using PIC references.

On linux-next, all vdsos work the same way. There are two vmas. The first vma is executable text, which can be poked at by ptrace, etc normally. The second vma contains time-varying state, should not allow poking, and is accessed by PIC references.

Is this 2nd vma seen in /proc/pid/maps? And if so, is it marked somehow?

Quoted 2 lines

What does CRIU do to restore the vdso? Will 3.15 and/or linux-next need to make some concession for CRIU?

We detect the vdso by "[vdso]" mark in proc at dump time and mark it in the images. At restore time we check that vdso symbols layout hasn't changed and just remap it in proper location.

If this remains the same in -next, then we're fine :)

Thanks,
Pavel

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#13 lore raw
In reply to Andy Lutomirski
Quoted 11 lines · Andy Lutomirski

I can summarize:

On 3.14 and before, the vdso is just a bunch of ELF headers and executable data. When executed by 64-bit binaries, it reads from the fixmap to do its thing. That is, it reads from kernel addresses that don't have vmas. When executed by 32-bit binaries, it doesn't read anything, since there was no 32-bit timing code.

On 3.15, the x86_64 vdso is unchanged. The 32-bit vdso is preceded by a separate vma containing two pages worth of time-varying read-only data. The vdso reads those pages using PIC references.

Andy, could you please point me where is the code which creates a second vma? latest 3.15 master branch

[root@fc ~]# cat /proc/self/maps
...

7fff57b6e000-7fff57b8f000 rw-p 00000000 00:00 0                          [stack]
7fff57bff000-7fff57c00000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]

[root@fc ~]#

Or you mean vsyscall area? If yes, then in criu we don't dump vsyscall zone. On restore we don't touch vsyscall either but for vdso there are two cases

- if there were no kernel change on vdso contents we simply use vdso provided by the kernel at the moment of criu startup

- if vdso has been changed and looks different from one saved in image during checkpoint, we map it from image but then patch (push jmp instruction) so when application calls for some of vdso function it jumps into vdso code saved in image and then jumps into vdso mapped by the kernel (ie kind of proxy calls) This force us to do own Elf parsing inside criu to calculate proper offsets.

We don't support (and have no plans to support) x86-32 kernels but there left a case with compatible mode (32bit app on 64bit kernel) which has not yet been implemented though.

Quoted 7 lines

On linux-next, all vdsos work the same way. There are two vmas. The first vma is executable text, which can be poked at by ptrace, etc normally. The second vma contains time-varying state, should not allow poking, and is accessed by PIC references.

What does CRIU do to restore the vdso? Will 3.15 and/or linux-next need to make some concession for CRIU?

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#10 lore raw
In reply to Pavel Emelyanov
Quoted 54 lines · Pavel Emelyanov
Quoted 52 lines · Andy Lutomirski
Quoted 31 lines · Cyrill Gorcunov
Quoted 23 lines · Andy Lutomirski
Quoted 13 lines · Andrew Morton
Quoted 7 lines · On Wed, 14 May 2014 17:11:00 -0400 Sasha Levin <[email protected]> wrote:
Quoted 3 lines

In my linux-next all that code got deleted by Andy's "x86, vdso:
Reimplement vdso.so preparation in build-time C" anyway. What kernel were you looking at?

Deleted? It appears in today's -next. arch/x86/vdso/vma.c:124 .

I don't see Andy's patch removing that code either.

ah, OK, it got moved from arch/x86/vdso/vdso32-setup.c into arch/x86/vdso/vma.c.

Quoted 7 lines

Maybe you managed to take a fault against the symbol area between the _install_special_mapping() and the remap_pfn_range() call, but mmap_sem should prevent that.

Or the remap_pfn_range() call never happened. Should map_vdso() be running _install_special_mapping() at all if image->sym_vvar_page==NULL?

Quoted 6 lines

I'm confused: are we talking about 3.15-rcsomething or linux-next? That code changed.

Would this all make more sense if there were just a single vma in here? cc: Pavel and Cyrill, who might have to deal with this stuff in CRIU

Quoted 7 lines

Well, for criu we've not modified any vdso kernel's code (except setting VM_SOFTDIRTY for this vdso VMA in _install_special_mapping). And never experienced problems Sasha points. Looks like indeed in -next code is pretty different from mainline one. To figure out why I need to fetch -next branch and get some research. I would try to do that tomorrow (still hoping someone more experienced in mm system would beat me on that).

I can summarize:

On 3.14 and before, the vdso is just a bunch of ELF headers and executable data. When executed by 64-bit binaries, it reads from the fixmap to do its thing. That is, it reads from kernel addresses that don't have vmas. When executed by 32-bit binaries, it doesn't read anything, since there was no 32-bit timing code.

On 3.15, the x86_64 vdso is unchanged. The 32-bit vdso is preceded by a separate vma containing two pages worth of time-varying read-only data. The vdso reads those pages using PIC references.

Quoted 6 lines
Quoted 4 lines

On linux-next, all vdsos work the same way. There are two vmas. The first vma is executable text, which can be poked at by ptrace, etc normally. The second vma contains time-varying state, should not allow poking, and is accessed by PIC references.

Is this 2nd vma seen in /proc/pid/maps? And if so, is it marked somehow?

It is in maps, and it's not marked. I can write a patch to change that. I imagine it shouldn't be called [vdso], though.

Quoted 9 lines
Quoted 3 lines

What does CRIU do to restore the vdso? Will 3.15 and/or linux-next need to make some concession for CRIU?

We detect the vdso by "[vdso]" mark in proc at dump time and mark it in the images. At restore time we check that vdso symbols layout hasn't changed and just remap it in proper location.

If this remains the same in -next, then we're fine :)

If you just remap the vdso, you'll crash.

This is the case in 3.15, too, for 32-bit apps, anyway.

What happens if you try to checkpoint a program that's in the vdso or, worse, in a signal frame with the vdso on the stack?

--Andy

Quoted 3 lines

Thanks,
Pavel

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#14 lore raw
In reply to Cyrill Gorcunov
Quoted 9 lines · Cyrill Gorcunov
Quoted 8 lines · Andy Lutomirski

I can summarize:

On 3.14 and before, the vdso is just a bunch of ELF headers and executable data. When executed by 64-bit binaries, it reads from the fixmap to do its thing. That is, it reads from kernel addresses that don't have vmas. When executed by 32-bit binaries, it doesn't read anything, since there was no 32-bit timing code.

Quoted 6 lines
Quoted 3 lines

On 3.15, the x86_64 vdso is unchanged. The 32-bit vdso is preceded by a separate vma containing two pages worth of time-varying read-only data. The vdso reads those pages using PIC references.

Andy, could you please point me where is the code which creates a second vma? latest 3.15 master branch

Search for _install_special_mapping in arch/x86/vdso. It's in a different place in 3.15-rc and -next.

Quoted 8 lines

[root@fc ~]# cat /proc/self/maps
...

7fff57b6e000-7fff57b8f000 rw-p 00000000 00:00 0                          [stack]
7fff57bff000-7fff57c00000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]

[root@fc ~]#

What version and bitness is this?

Quoted 2 lines

Or you mean vsyscall area? If yes, then in criu we don't dump vsyscall zone. On restore we don't touch vsyscall either but for vdso there are two cases

vsyscalls are almost gone now :)

Quoted 10 lines

- if there were no kernel change on vdso contents we simply use vdso provided by the kernel at the moment of criu startup

- if vdso has been changed and looks different from one saved in image during checkpoint, we map it from image but then patch (push jmp instruction) so when application calls for some of vdso function it jumps into vdso code saved in image and then jumps into vdso mapped by the kernel (ie kind of proxy calls) This force us to do own Elf parsing inside criu to calculate proper offsets.

Yuck :)

--Andy

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#15 lore raw
Quoted 14 lines · Andy Lutomirski
Quoted 13 lines · Cyrill Gorcunov
Quoted 11 lines · Andy Lutomirski

I can summarize:

On 3.14 and before, the vdso is just a bunch of ELF headers and executable data. When executed by 64-bit binaries, it reads from the fixmap to do its thing. That is, it reads from kernel addresses that don't have vmas. When executed by 32-bit binaries, it doesn't read anything, since there was no 32-bit timing code.

On 3.15, the x86_64 vdso is unchanged. The 32-bit vdso is preceded by a separate vma containing two pages worth of time-varying read-only data. The vdso reads those pages using PIC references.

Quoted 5 lines
Quoted 2 lines

Andy, could you please point me where is the code which creates a second vma? latest 3.15 master branch

Search for _install_special_mapping in arch/x86/vdso. It's in a different place in 3.15-rc and -next.

As far as I see _install_special_mapping allocates one vma from cache and

	vma->vm_start = addr;
	vma->vm_end = addr + len;

so where is the second one?

Quoted 11 lines
Quoted 9 lines

[root@fc ~]# cat /proc/self/maps
...

7fff57b6e000-7fff57b8f000 rw-p 00000000 00:00 0                          [stack]
7fff57bff000-7fff57c00000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]

[root@fc ~]#

What version and bitness is this?

x86-64, 3.15-rc5

Quoted 5 lines
Quoted 3 lines

Or you mean vsyscall area? If yes, then in criu we don't dump vsyscall zone. On restore we don't touch vsyscall either but for vdso there are two cases

vsyscalls are almost gone now :)

Good to know ;)

Quoted 5 lines
Quoted 5 lines

- if there were no kernel change on vdso contents we simply use vdso provided by the kernel at the moment of criu startup

Quoted 8 lines
Quoted 6 lines

- if vdso has been changed and looks different from one saved in image during checkpoint, we map it from image but then patch (push jmp instruction) so when application calls for some of vdso function it jumps into vdso code saved in image and then jumps into vdso mapped by the kernel (ie kind of proxy calls) This force us to do own Elf parsing inside criu to calculate proper offsets.

Yuck :)

Yeah, I know, we simply had no choise.

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#16 lore raw
Quoted 21 lines · Cyrill Gorcunov
Quoted 14 lines · Andy Lutomirski
Quoted 13 lines · Cyrill Gorcunov
Quoted 11 lines · Andy Lutomirski

I can summarize:

On 3.14 and before, the vdso is just a bunch of ELF headers and executable data. When executed by 64-bit binaries, it reads from the fixmap to do its thing. That is, it reads from kernel addresses that don't have vmas. When executed by 32-bit binaries, it doesn't read anything, since there was no 32-bit timing code.

On 3.15, the x86_64 vdso is unchanged. The 32-bit vdso is preceded by a separate vma containing two pages worth of time-varying read-only data. The vdso reads those pages using PIC references.

Quoted 5 lines
Quoted 2 lines

Andy, could you please point me where is the code which creates a second vma? latest 3.15 master branch

Search for _install_special_mapping in arch/x86/vdso. It's in a different place in 3.15-rc and -next.

Quoted 6 lines

As far as I see _install_special_mapping allocates one vma from cache and

        vma->vm_start = addr;
        vma->vm_end = addr + len;

so where is the second one?

Look at its callers in vdso32-setup.c and/or vma.c, depending on version.

Quoted 11 lines
Quoted 11 lines
Quoted 10 lines

[root@fc ~]# cat /proc/self/maps
...

7fff57b6e000-7fff57b8f000 rw-p 00000000 00:00 0                          [stack]
7fff57bff000-7fff57c00000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]

[root@fc ~]#

Quoted 3 lines
Quoted 1 line

What version and bitness is this?

x86-64, 3.15-rc5

Aha. Give tip/x86/vdso or -next a try or boot a 32-bit 3.15-rc kernel and you'll see it.

--Andy

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#17 lore raw
Quoted 7 lines · Andy Lutomirski
Quoted 4 lines
Quoted 2 lines

What version and bitness is this?

x86-64, 3.15-rc5

Aha. Give tip/x86/vdso or -next a try or boot a 32-bit 3.15-rc kernel and you'll see it.

I see what you mean. We're rather targeting on bare x86-64 at the moment but compat mode is needed as well (not yet implemented though). I'll take a precise look into this area. Thanks!

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#18 lore raw
Quoted 4 lines · Cyrill Gorcunov

I see what you mean. We're rather targeting on bare x86-64 at the moment but compat mode is needed as well (not yet implemented though). I'll take a precise look into this area. Thanks!

Indeed, because we were not running 32bit tasks vdso32-setup.c::arch_setup_additional_pages has never been called. That's the mode we will have to implement one day.

Looking forward the question appear -- will VDSO_PREV_PAGES and rest of variables be kind of immutable constants? If yes, we could calculate where the additional vma lives without requiring any kind of [vdso] mark in proc/pid/maps output.

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#19 lore raw
Quoted 6 lines · Cyrill Gorcunov
Quoted 4 lines · Cyrill Gorcunov

I see what you mean. We're rather targeting on bare x86-64 at the moment but compat mode is needed as well (not yet implemented though). I'll take a precise look into this area. Thanks!

Quoted 6 lines

Indeed, because we were not running 32bit tasks vdso32-setup.c::arch_setup_additional_pages has never been called. That's the mode we will have to implement one day.

Looking forward the question appear -- will VDSO_PREV_PAGES and rest of variables be kind of immutable constants? If yes, we could calculate where the additional vma lives without requiring any kind of [vdso] mark in proc/pid/maps output.

Please don't!

These might, in principle, even vary between tasks on the same system.
Certainly the relative positions of the vmas will be different
between 3.15 and 3.16, since we need almost my entire cleanup series to reliably put them into their 3.16 location. And I intend to change the number of pages in 3.16 or 3.17.

--Andy

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#20 lore raw
Quoted 5 lines · Andy Lutomirski
Quoted 4 lines

Looking forward the question appear -- will VDSO_PREV_PAGES and rest of variables be kind of immutable constants? If yes, we could calculate where the additional vma lives without requiring any kind of [vdso] mark in proc/pid/maps output.

Quoted 7 lines

Please don't!

These might, in principle, even vary between tasks on the same system.
Certainly the relative positions of the vmas will be different
between 3.15 and 3.16, since we need almost my entire cleanup series to reliably put them into their 3.16 location. And I intend to change the number of pages in 3.16 or 3.17.

There are other ways how to find where additional pages are laying but it would be great if there a straightforward interface for that (ie some mark in /proc/pid/maps output).

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#21 lore raw
Quoted 14 lines · Cyrill Gorcunov
Quoted 5 lines · Andy Lutomirski
Quoted 4 lines

Looking forward the question appear -- will VDSO_PREV_PAGES and rest of variables be kind of immutable constants? If yes, we could calculate where the additional vma lives without requiring any kind of [vdso] mark in proc/pid/maps output.

Quoted 7 lines

Please don't!

These might, in principle, even vary between tasks on the same system.
Certainly the relative positions of the vmas will be different
between 3.15 and 3.16, since we need almost my entire cleanup series to reliably put them into their 3.16 location. And I intend to change the number of pages in 3.16 or 3.17.

Quoted 3 lines

There are other ways how to find where additional pages are laying but it would be great if there a straightforward interface for that (ie some mark in /proc/pid/maps output).

I'll try to write a patch in time for 3.15.

--Andy

#22 lore raw
Quoted 15 lines · Andy Lutomirski
Quoted 14 lines · Cyrill Gorcunov
Quoted 12 lines · Andy Lutomirski
Quoted 4 lines

Looking forward the question appear -- will VDSO_PREV_PAGES and rest of variables be kind of immutable constants? If yes, we could calculate where the additional vma lives without requiring any kind of [vdso] mark in proc/pid/maps output.

Please don't!

These might, in principle, even vary between tasks on the same system.
Certainly the relative positions of the vmas will be different
between 3.15 and 3.16, since we need almost my entire cleanup series to reliably put them into their 3.16 location. And I intend to change the number of pages in 3.16 or 3.17.

Quoted 6 lines
Quoted 3 lines

There are other ways how to find where additional pages are laying but it would be great if there a straightforward interface for that (ie some mark in /proc/pid/maps output).

I'll try to write a patch in time for 3.15.

My current draft is here:

https://git.kernel.org/cgit/linux/kernel/git/luto/linux.git/log/?h=vdso/cleanups

On 64-bit userspace, it results in:

7fffa1dfd000-7fffa1dfe000 r-xp 00000000 00:00 0 [vdso]
7fffa1dfe000-7fffa1e00000 r--p 00000000 00:00 0 [vvar]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0
[vsyscall]

On 32-bit userspace, it results in:

f7748000-f7749000 r-xp 00000000 00:00 0                                  [vdso]
f7749000-f774b000 r--p 00000000 00:00 0                                  [vvar]
ffd94000-ffdb5000 rw-p 00000000 00:00 0                                  [stack]

Is this good for CRIU? Another approach would be to name both of these things "vdso", since they are sort of both the vdso, but that might be a bit confusing -- [vvar] is not static text the way that [vdso] is.

If I backport this for 3.15 (which might be nasty -- I would argue that the code change is actually a cleanup, but it's fairly intrusive), then [vvar] will be *before* [vdso], not after it. I'd be very hesitant to name both of them "[vdso]" in that case, since there is probably code that assumes that the beginning of "[vdso]" is a DSO.

Note that it is *not* safe to blindly read from "[vvar]". On some configurations you *will* get SIGBUS if you try to read from some of the vvar pages. (That's what started this whole thread.) Some pages in "[vvar]" may have strange caching modes, so SIGBUS might not be the only surprising thing about poking at it.

--Andy

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#23 lore raw
Quoted 29 lines · Andy Lutomirski

My current draft is here:

https://git.kernel.org/cgit/linux/kernel/git/luto/linux.git/log/?h=vdso/cleanups

On 64-bit userspace, it results in:

7fffa1dfd000-7fffa1dfe000 r-xp 00000000 00:00 0 [vdso]
7fffa1dfe000-7fffa1e00000 r--p 00000000 00:00 0 [vvar]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0
[vsyscall]

On 32-bit userspace, it results in:

f7748000-f7749000 r-xp 00000000 00:00 0                                  [vdso]
f7749000-f774b000 r--p 00000000 00:00 0                                  [vvar]
ffd94000-ffdb5000 rw-p 00000000 00:00 0                                  [stack]

Is this good for CRIU? Another approach would be to name both of these things "vdso", since they are sort of both the vdso, but that might be a bit confusing -- [vvar] is not static text the way that [vdso] is.

If I backport this for 3.15 (which might be nasty -- I would argue that the code change is actually a cleanup, but it's fairly intrusive), then [vvar] will be *before* [vdso], not after it. I'd be very hesitant to name both of them "[vdso]" in that case, since there is probably code that assumes that the beginning of "[vdso]" is a DSO.

Quoted 6 lines

Note that it is *not* safe to blindly read from "[vvar]". On some configurations you *will* get SIGBUS if you try to read from some of the vvar pages. (That's what started this whole thread.) Some pages in "[vvar]" may have strange caching modes, so SIGBUS might not be the only surprising thing about poking at it.

mremap() should work on these pages, right?

-hpa

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#24 lore raw
Quoted 6 lines · H. Peter Anvin
Quoted 4 lines · Andy Lutomirski

My current draft is here:

https://git.kernel.org/cgit/linux/kernel/git/luto/linux.git/log/?h=vdso/cleanups

Quoted 4 lines
Quoted 4 lines

On 64-bit userspace, it results in:

7fffa1dfd000-7fffa1dfe000 r-xp 00000000 00:00 0

[vdso]

Quoted 1 line
Quoted 1 line

7fffa1dfe000-7fffa1e00000 r--p 00000000 00:00 0

[vvar]

Quoted 6 lines
Quoted 6 lines

ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0
[vsyscall]

On 32-bit userspace, it results in:

f7748000-f7749000 r-xp 00000000 00:00 0

[vdso]

Quoted 1 line
Quoted 1 line

f7749000-f774b000 r--p 00000000 00:00 0

[vvar]

Quoted 1 line
Quoted 1 line

ffd94000-ffdb5000 rw-p 00000000 00:00 0

[stack]

Quoted 12 lines
Quoted 12 lines

Is this good for CRIU? Another approach would be to name both of these things "vdso", since they are sort of both the vdso, but that might be a bit confusing -- [vvar] is not static text the way that [vdso] is.

If I backport this for 3.15 (which might be nasty -- I would argue that the code change is actually a cleanup, but it's fairly intrusive), then [vvar] will be *before* [vdso], not after it. I'd be very hesitant to name both of them "[vdso]" in that case, since there is probably code that assumes that the beginning of "[vdso]" is a DSO.

Quoted 8 lines
Quoted 6 lines

Note that it is *not* safe to blindly read from "[vvar]". On some configurations you *will* get SIGBUS if you try to read from some of the vvar pages. (That's what started this whole thread.) Some pages in "[vvar]" may have strange caching modes, so SIGBUS might not be the only surprising thing about poking at it.

mremap() should work on these pages, right?

(On phone, so this may bounce)

Does mremap work with remap_pfn_range? We can't handle faults on the vvar mapping.

I haven't tested at all, but it looks like arch_vma_name may get rather confused if mremap happens. Also, 32-bit code will crash and burn if the vdso moves -- sysexit and sigreturn will die horrible deaths, I think. None of these issues are new to 3.15.

--Andy

Quoted 4 lines

-hpa

#25 lore raw
In reply to Andy Lutomirski
Quoted 20 lines · Andy Lutomirski
Quoted 7 lines
Quoted 4 lines

There are other ways how to find where additional pages are laying but it would be great if there a straightforward interface for that (ie some mark in /proc/pid/maps output).

I'll try to write a patch in time for 3.15.

My current draft is here:

https://git.kernel.org/cgit/linux/kernel/git/luto/linux.git/log/?h=vdso/cleanups

On 64-bit userspace, it results in:

7fffa1dfd000-7fffa1dfe000 r-xp 00000000 00:00 0                          [vdso]
7fffa1dfe000-7fffa1e00000 r--p 00000000 00:00 0                          [vvar]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]

On 32-bit userspace, it results in:

Quoted 8 lines
f7748000-f7749000 r-xp 00000000 00:00 0                                  [vdso]
f7749000-f774b000 r--p 00000000 00:00 0                                  [vvar]
ffd94000-ffdb5000 rw-p 00000000 00:00 0                                  [stack]

Is this good for CRIU? Another approach would be to name both of these things "vdso", since they are sort of both the vdso, but that might be a bit confusing -- [vvar] is not static text the way that [vdso] is.

Yeah, thanks a lot, Andy, this is more than enough.

Quoted 11 lines

If I backport this for 3.15 (which might be nasty -- I would argue that the code change is actually a cleanup, but it's fairly intrusive), then [vvar] will be *before* [vdso], not after it. I'd be very hesitant to name both of them "[vdso]" in that case, since there is probably code that assumes that the beginning of "[vdso]" is a DSO.

Note that it is *not* safe to blindly read from "[vvar]". On some configurations you *will* get SIGBUS if you try to read from some of the vvar pages. (That's what started this whole thread.) Some pages in "[vvar]" may have strange caching modes, so SIGBUS might not be the only surprising thing about poking at it.

Ouch. Thanks for the note, I'll read new code with more attention and report the effect it did over criu (prob. on next week).

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#11 lore raw
In reply to Andy Lutomirski
Quoted 60 lines · Andy Lutomirski
Quoted 59 lines · Pavel Emelyanov
Quoted 56 lines · Andy Lutomirski
Quoted 31 lines · Cyrill Gorcunov
Quoted 23 lines · Andy Lutomirski
Quoted 13 lines · Andrew Morton
Quoted 7 lines · On Wed, 14 May 2014 17:11:00 -0400 Sasha Levin <[email protected]> wrote:
Quoted 3 lines

In my linux-next all that code got deleted by Andy's "x86, vdso:
Reimplement vdso.so preparation in build-time C" anyway. What kernel were you looking at?

Deleted? It appears in today's -next. arch/x86/vdso/vma.c:124 .

I don't see Andy's patch removing that code either.

ah, OK, it got moved from arch/x86/vdso/vdso32-setup.c into arch/x86/vdso/vma.c.

Quoted 7 lines

Maybe you managed to take a fault against the symbol area between the _install_special_mapping() and the remap_pfn_range() call, but mmap_sem should prevent that.

Or the remap_pfn_range() call never happened. Should map_vdso() be running _install_special_mapping() at all if image->sym_vvar_page==NULL?

Quoted 6 lines

I'm confused: are we talking about 3.15-rcsomething or linux-next? That code changed.

Would this all make more sense if there were just a single vma in here? cc: Pavel and Cyrill, who might have to deal with this stuff in CRIU

Quoted 7 lines

Well, for criu we've not modified any vdso kernel's code (except setting VM_SOFTDIRTY for this vdso VMA in _install_special_mapping). And never experienced problems Sasha points. Looks like indeed in -next code is pretty different from mainline one. To figure out why I need to fetch -next branch and get some research. I would try to do that tomorrow (still hoping someone more experienced in mm system would beat me on that).

I can summarize:

On 3.14 and before, the vdso is just a bunch of ELF headers and executable data. When executed by 64-bit binaries, it reads from the fixmap to do its thing. That is, it reads from kernel addresses that don't have vmas. When executed by 32-bit binaries, it doesn't read anything, since there was no 32-bit timing code.

On 3.15, the x86_64 vdso is unchanged. The 32-bit vdso is preceded by a separate vma containing two pages worth of time-varying read-only data. The vdso reads those pages using PIC references.

On linux-next, all vdsos work the same way. There are two vmas. The first vma is executable text, which can be poked at by ptrace, etc normally. The second vma contains time-varying state, should not allow poking, and is accessed by PIC references.

Quoted 4 lines
Quoted 1 line

Is this 2nd vma seen in /proc/pid/maps? And if so, is it marked somehow?

It is in maps, and it's not marked. I can write a patch to change that. I imagine it shouldn't be called [vdso], though.

That would be great.

Quoted 8 lines
Quoted 8 lines
Quoted 3 lines

What does CRIU do to restore the vdso? Will 3.15 and/or linux-next need to make some concession for CRIU?

We detect the vdso by "[vdso]" mark in proc at dump time and mark it in the images. At restore time we check that vdso symbols layout hasn't changed and just remap it in proper location.

Quoted 8 lines
Quoted 1 line

If this remains the same in -next, then we're fine :)

If you just remap the vdso, you'll crash.

This is the case in 3.15, too, for 32-bit apps, anyway.

What happens if you try to checkpoint a program that's in the vdso or, worse, in a signal frame with the vdso on the stack?

Nothing good, unfortunately :( And this is one of the things we're investigating. Cyrill can shed more light on it, as he's the one in charge.

Quoted 1 line

--Andy

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#12 lore raw
Quoted 6 lines · Pavel Emelyanov
Quoted 3 lines

What happens if you try to checkpoint a program that's in the vdso or, worse, in a signal frame with the vdso on the stack?

Nothing good, unfortunately :( And this is one of the things we're investigating. Cyrill can shed more light on it, as he's the one in charge.

vdso on stack should not be a big deal, because we keep original vdso proxy.

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>