* [uml-devel] [PATCH] fix writing into /dev/kmem
@ 2004-02-29 2:36 Jeff Dike
2004-02-29 12:25 ` BlaisorBlade
2004-02-29 16:20 ` BlaisorBlade
0 siblings, 2 replies; 9+ messages in thread
From: Jeff Dike @ 2004-02-29 2:36 UTC (permalink / raw)
To: user-mode-linux-devel
The patch below fixes a bug in the /dev/kmem driver which causes UML to
die if you write to it. Of course, the kernel will die if you write random
crap to kernel memory, but at least it doesn't die in a UML-specific way.
This is a cut'n'paste from an xterm, so apply with patch -l.
Jeff
--- drivers/char/mem.c~ 2004-01-05 11:23:32.000000000 -0500
+++ drivers/char/mem.c 2004-02-27 08:52:14.000000000 -0500
@@ -287,6 +287,7 @@
ssize_t virtr = 0;
char * kbuf; /* k-addr because vwrite() takes vmlist_lock rwlock */
+ p = (unsigned long) __va(p);
if (p < (unsigned long) high_memory) {
wrote = count;
if (count > (unsigned long) high_memory - p)
@@ -321,7 +322,7 @@
free_page((unsigned long)kbuf);
}
- *ppos = p;
+ *ppos = __pa((void *) p);
return virtr + wrote;
}
-------------------------------------------------------
SF.Net is sponsored by: Speed Start Your Linux Apps Now.
Build and deploy apps & Web services for Linux with
a free DVD software kit from IBM. Click Now!
http://ads.osdn.com/?ad_id=1356&alloc_id=3438&op=click
_______________________________________________
User-mode-linux-devel mailing list
User-mode-linux-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [uml-devel] [PATCH] fix writing into /dev/kmem
2004-02-29 2:36 [uml-devel] [PATCH] fix writing into /dev/kmem Jeff Dike
@ 2004-02-29 12:25 ` BlaisorBlade
2004-03-02 1:31 ` Jeff Dike
2004-02-29 16:20 ` BlaisorBlade
1 sibling, 1 reply; 9+ messages in thread
From: BlaisorBlade @ 2004-02-29 12:25 UTC (permalink / raw)
To: user-mode-linux-devel; +Cc: Jeff Dike
Alle 03:36, domenica 29 febbraio 2004, Jeff Dike ha scritto:
> The patch below fixes a bug in the /dev/kmem driver which causes UML to
> die if you write to it. Of course, the kernel will die if you write random
> crap to kernel memory, but at least it doesn't die in a UML-specific way.
> This is a cut'n'paste from an xterm, so apply with patch -l.
This patch is like the one for the read from /dev/kmem (i.e. the one fixing
the panic when one does "cat /dev/kmem": you can reproduce this panic on
Uml2.6): it makes it behave like /dev/mem (man 4 mem is indeed helpful!). So
it is basically not *the right way*.
Also, someone got a panic with the read patch applied while klogd was reading
something. The diagnosys was that the /dev/mem driver checks for overflows,
while this patched /dev/kmem driver does not. To read the physical address
0x1with /dev/kmem, you are supposed to read 0xc0000001; so with that patch
any proper user of /dev/kmem will overflow p.
So, I propose to either return -EFAULT with not accessible addresses (which is
the proper fix), or to (at least and as a workaround) correct the "fops"
fields of /dev/kmem to redirect it on /dev/mem (at least this avoids the
crash better than the current patches).
--
Paolo Giarrusso, aka Blaisorblade
Linux registered user n. 292729
-------------------------------------------------------
SF.Net is sponsored by: Speed Start Your Linux Apps Now.
Build and deploy apps & Web services for Linux with
a free DVD software kit from IBM. Click Now!
http://ads.osdn.com/?ad_id=1356&alloc_id=3438&op=click
_______________________________________________
User-mode-linux-devel mailing list
User-mode-linux-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [uml-devel] [PATCH] fix writing into /dev/kmem
2004-02-29 2:36 [uml-devel] [PATCH] fix writing into /dev/kmem Jeff Dike
2004-02-29 12:25 ` BlaisorBlade
@ 2004-02-29 16:20 ` BlaisorBlade
2004-03-02 1:11 ` Jeff Dike
2004-03-02 1:31 ` Jeff Dike
1 sibling, 2 replies; 9+ messages in thread
From: BlaisorBlade @ 2004-02-29 16:20 UTC (permalink / raw)
To: user-mode-linux-devel; +Cc: Jeff Dike
[-- Attachment #1: Type: text/plain, Size: 1218 bytes --]
Alle 03:36, domenica 29 febbraio 2004, Jeff Dike ha scritto:
> The patch below fixes a bug in the /dev/kmem driver which causes UML to
> die if you write to it.
Also, I forgot one thing, about this Oops:
the i386 Oopses, normally, kill only the thread which triggered the fault -
while instead Uml panics altogether. Cannot this be changed at
arch/um/kernel/trap_kern.c:segv()?
if(!is_user)
- panic("Kernel mode fault at addr 0x%lx, ip 0x%lx",
- address, ip);
+ die("Oops".....) //some printk calls... can be omitted
+ do_exit(SIGKILL);
like arch/i386/mm/fault.c: do_page_fault() ?
With the above change, cat /dev/kmem could only create an Oops on the cat
process (and possibly some deadlock, but better than a straight crash).
By the way: in handle_page_fault(), there is some dead code (attached is the
removal patch).
I also do not understand the loop around handle_mm_fault call, but I could be
wrong: are you sure that after a successful handle_mm_fault (i.e. a major or
minor fault) pte_present(*pte) could be false? If handle_mm_fault is not
successful, we exit the loop anyway.
--
Paolo Giarrusso, aka Blaisorblade
Linux registered user n. 292729
[-- Attachment #2: Dead-trap-code.patch --]
[-- Type: text/x-diff, Size: 444 bytes --]
--- ./arch/um/kernel/trap_kern.c.fix 2004-02-20 18:43:26.000000000 +0100
+++ ./arch/um/kernel/trap_kern.c 2004-02-29 17:12:49.000000000 +0100
@@ -74,13 +74,7 @@
err = -ENOMEM;
goto out_of_memory;
default:
- if (current->pid == 1) {
- up_read(&mm->mmap_sem);
- yield();
- down_read(&mm->mmap_sem);
- goto survive;
- }
- goto out;
+ BUG();
}
pte = pte_offset_kernel(pmd, page);
} while(!pte_present(*pte));
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [uml-devel] [PATCH] fix writing into /dev/kmem
2004-02-29 16:20 ` BlaisorBlade
@ 2004-03-02 1:11 ` Jeff Dike
2004-03-02 1:31 ` Jeff Dike
1 sibling, 0 replies; 9+ messages in thread
From: Jeff Dike @ 2004-03-02 1:11 UTC (permalink / raw)
To: BlaisorBlade; +Cc: user-mode-linux-devel
blaisorblade_spam@yahoo.it said:
> the i386 Oopses, normally, kill only the thread which triggered the
> fault - while instead Uml panics altogether. Cannot this be changed
> at arch/um/kernel/trap_kern.c:segv()?
If there's an unexplained kernel mode access fault, anything could be wrong.
I don't see that it's reasonable to just kill the process when kernel data
could be corrupted as far as we know.
I don't know why x86 thinks it can just kill the process.
> By the way: in handle_page_fault(), there is some dead code (attached
> is the removal patch).
That shouldn't be dead code. I think it should be attached to the VM_FAULT_OOM
case - I copied it from x86, so check there to be sure.
> I also do not understand the loop around handle_mm_fault call, but I
> could be wrong: are you sure that after a successful handle_mm_fault
> (i.e. a major or minor fault) pte_present(*pte) could be false? If
> handle_mm_fault is not successful, we exit the loop anyway.
It's possible that the page could have been swapped out between fixing the
fault and the return from handle_mm_fault. Way back in history, I had a
check for the same fault happening twice in a row, and panicing if it happened.
This was when UML's fault handling still needed debugging. To prevent the
case I just mentioned from triggering that panic, I added the loop to make sure
the page was good before returning to userspace.
Jeff
-------------------------------------------------------
SF.Net is sponsored by: Speed Start Your Linux Apps Now.
Build and deploy apps & Web services for Linux with
a free DVD software kit from IBM. Click Now!
http://ads.osdn.com/?ad_id=1356&alloc_id=3438&op=click
_______________________________________________
User-mode-linux-devel mailing list
User-mode-linux-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [uml-devel] [PATCH] fix writing into /dev/kmem
2004-02-29 12:25 ` BlaisorBlade
@ 2004-03-02 1:31 ` Jeff Dike
2004-03-02 18:41 ` BlaisorBlade
0 siblings, 1 reply; 9+ messages in thread
From: Jeff Dike @ 2004-03-02 1:31 UTC (permalink / raw)
To: BlaisorBlade; +Cc: user-mode-linux-devel
blaisorblade_spam@yahoo.it said:
> This patch is like the one for the read from /dev/kmem (i.e. the one
> fixing the panic when one does "cat /dev/kmem": you can reproduce
> this panic on Uml2.6): it makes it behave like /dev/mem (man 4 mem is
> indeed helpful!). So it is basically not *the right way*.
Well, if you look at read_kmem, the thing that it reads is physical memory
plus kernel virtual memory. I.e. /dev/kmem is /dev/mem + the kernel virtual
memory areas.
Addmittedly, I don't see how x86 gets away with dereferencing address 0, but
I don't see what's wrong with my fixes. The file offsets being passed in
are effectively physical addresses, which need to be converted into virtual
addresses before being dereferenced, with is what __va() does, and __pa()
undoes.
Also, read_mem does the _va() correctly:
if (copy_to_user(buf, __va(p), count))
return -EFAULT;
while read_kmem does not:
if (copy_to_user(buf, (char *)p, read))
return -EFAULT;
The only out that I can see is that readers of kmem are supposed to pass in
kernel virtual addresses, 0xc0000000 and up. But, if so, those guys
fundamentally aren't going to work on UML because those addresses will be
wrong.
It would be nice to see exactly what klogd is doing.
> To read the physical address 0x1with /dev/kmem, you are supposed to
> read 0xc0000001; so with that patch any proper user of /dev/kmem will
> overflow p.
0xa0000001, actually, which is what __va does.
Jeff
-------------------------------------------------------
SF.Net is sponsored by: Speed Start Your Linux Apps Now.
Build and deploy apps & Web services for Linux with
a free DVD software kit from IBM. Click Now!
http://ads.osdn.com/?ad_id=1356&alloc_id=3438&op=click
_______________________________________________
User-mode-linux-devel mailing list
User-mode-linux-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [uml-devel] [PATCH] fix writing into /dev/kmem
2004-02-29 16:20 ` BlaisorBlade
2004-03-02 1:11 ` Jeff Dike
@ 2004-03-02 1:31 ` Jeff Dike
1 sibling, 0 replies; 9+ messages in thread
From: Jeff Dike @ 2004-03-02 1:31 UTC (permalink / raw)
To: BlaisorBlade; +Cc: user-mode-linux-devel
-------------------------------------------------------
SF.Net is sponsored by: Speed Start Your Linux Apps Now.
Build and deploy apps & Web services for Linux with
a free DVD software kit from IBM. Click Now!
http://ads.osdn.com/?ad_id=1356&alloc_id=3438&op=click
_______________________________________________
User-mode-linux-devel mailing list
User-mode-linux-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [uml-devel] [PATCH] fix writing into /dev/kmem
2004-03-02 1:31 ` Jeff Dike
@ 2004-03-02 18:41 ` BlaisorBlade
2004-03-04 2:02 ` Jeff Dike
0 siblings, 1 reply; 9+ messages in thread
From: BlaisorBlade @ 2004-03-02 18:41 UTC (permalink / raw)
To: user-mode-linux-devel; +Cc: Jeff Dike
Alle 02:31, martedì 2 marzo 2004, Jeff Dike ha scritto:
> blaisorblade_spam@yahoo.it said:
> > This patch is like the one for the read from /dev/kmem (i.e. the one
> > fixing the panic when one does "cat /dev/kmem": you can reproduce
> > this panic on Uml2.6): it makes it behave like /dev/mem (man 4 mem is
> > indeed helpful!). So it is basically not *the right way*.
>
> Well, if you look at read_kmem, the thing that it reads is physical memory
> plus kernel virtual memory. I.e. /dev/kmem is /dev/mem + the kernel
> virtual memory areas.
No, I do not agree (and man 4 mem agrees with me; I've quoted it below). As
you later say after reading the code (which contains The Truth), the address
passed to /dev/kmem as already been __va'ed. I.e., if those devices were
array we could say:
/dev/kmem[ __va (address) ] == /dev/mem [ address ];
> Addmittedly, I don't see how x86 gets away with dereferencing address 0
Well, physical address 0 does exist, for /dev/mem; /dev/kmem instead returns
-EFAULT (try cat /dev/kmem), because copy_to_user returns a fault state.
Actually, 0 is derefereced, and the CPU throws an exception; but thanks to the
__extable section and "search_exception_table", that exception is "caught".
Read Documentation/exception.txt. I.e., copy_to_user actually checks both the
"to" and "from" addresses.
Instead, in UML skas mode, possibly because the process VMA's are not mapped
in the kernel thread, the page tables for the user are checked by hand (by
um_virt_to_phys); but the check is done only for the userspace address (i.e.
the "to" address for copy_to_user; everything applies even to copy_from_user,
of course).
In tt mode it uses actually exception, even if they are coded by hand without
using __extable (I see a flag here, probably set while catching SIGSEGV).
So, probably (to check), the kernel panic would happen only in tt mode.
Anyway, here comes that copy_{to,from}_user are buggy. Since fixing those
would have a good performance hit (to test, but that will probably be
sensitive; Documentation/exception.txt says exactly this, because most
programs have no bug so checking the page tables has a big cost) and klogd
would not work anyway, add an XXX comment, add it on your TODO and make
/dev/kmem always return -EFAULT, as a workaround; or make it check the
address with maybe_map (and #ifdef the change; even other archs have
arch-specific code there).
> but I don't see what's wrong with my fixes.
[From below]
> The only out that I can see is that readers of kmem are supposed to pass in
> kernel virtual addresses, 0xc0000000 and up.
Yes, this is the reality.
So, __va(p) will overflow. That has *actually* happened (in fact I studied
what I say in these mails when someone got a fault if he loaded the LVM
modules). In fact, in the read_mem there is a check against the overflow:
if (p >= end_mem)
return 0;
Well, I said you to read mem(4), you didn't, so I quote:
Mem is a character device file that is an image of the main memory of
the computer. It may be used, for example, to examine (and even patch)
the system.
Byte addresses in mem are interpreted as *physical* memory
addresses.
[...]
The file kmem is the same as mem, except that the kernel virtual memory
rather than physical memory is accessed.
In fact, see this:
# cat /dev/kmem
cat: /dev/kmem: Bad address
> > To read the physical address 0x1with /dev/kmem, you are supposed to
> > read 0xc0000001; so with that patch any proper user of /dev/kmem will
> > overflow p.
>
> 0xa0000001, actually, which is what __va does.
Well, on *i386* that is 0xc0000001; since klogd is built with i386 kernel
headers, it will use those.
--
Paolo Giarrusso, aka Blaisorblade
Linux registered user n. 292729
-------------------------------------------------------
SF.Net is sponsored by: Speed Start Your Linux Apps Now.
Build and deploy apps & Web services for Linux with
a free DVD software kit from IBM. Click Now!
http://ads.osdn.com/?ad_id\x1356&alloc_id438&opÌk
_______________________________________________
User-mode-linux-devel mailing list
User-mode-linux-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [uml-devel] [PATCH] fix writing into /dev/kmem
2004-03-02 18:41 ` BlaisorBlade
@ 2004-03-04 2:02 ` Jeff Dike
2004-03-08 11:50 ` BlaisorBlade
0 siblings, 1 reply; 9+ messages in thread
From: Jeff Dike @ 2004-03-04 2:02 UTC (permalink / raw)
To: BlaisorBlade; +Cc: user-mode-linux-devel
blaisorblade_spam@yahoo.it said:
> Well, on *i386* that is 0xc0000001; since klogd is built with i386
> kernel headers, it will use those.
This was the stupidity that I was refusing to believe in. This means that
if you take a normal klogd and move it to a 2G/2G system, where the kernel
starts at 0x80000000, it won't work.
> Anyway, here comes that copy_{to,from}_user are buggy. Since fixing
> those would have a good performance hit (to test, but that will
> probably be sensitive
In skas mode, I wasn't expecting any legitimate unfixable kernel mode access
faults, so I wasn't setting up the fault_catcher. So, what I did was add
a wrapper around the guts of copy_user which does a setjmp, and returns
whether it got longjmp-ed back to.
Reading /dev/kmem now produces -EFAULT. Writing to it still causes a hang
because write_kmem doesn't check the return value of do_write_mem. With that
fixed, everything produces -EFAULT.
The fix will be in the next patch.
Jeff
-------------------------------------------------------
This SF.Net email is sponsored by: IBM Linux Tutorials
Free Linux tutorial presented by Daniel Robbins, President and CEO of
GenToo technologies. Learn everything from fundamentals to system
administration.http://ads.osdn.com/?ad_id=1470&alloc_id=3638&op=click
_______________________________________________
User-mode-linux-devel mailing list
User-mode-linux-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [uml-devel] [PATCH] fix writing into /dev/kmem
2004-03-04 2:02 ` Jeff Dike
@ 2004-03-08 11:50 ` BlaisorBlade
0 siblings, 0 replies; 9+ messages in thread
From: BlaisorBlade @ 2004-03-08 11:50 UTC (permalink / raw)
To: Jeff Dike; +Cc: user-mode-linux-devel
Alle 03:02, giovedì 4 marzo 2004, Jeff Dike ha scritto:
> blaisorblade_spam@yahoo.it said:
> > Well, on *i386* that is 0xc0000001; since klogd is built with i386
> > kernel headers, it will use those.
>
> This was the stupidity that I was refusing to believe in. This means that
> if you take a normal klogd and move it to a 2G/2G system, where the kernel
> starts at 0x80000000, it won't work.
Well, that can be stupid (and is), but needing to recompile iptables when
upgrading kernel from 2.4.21-Mandrake (i.e. 2.4.21-rc#) to 2.4.21 is even
more stupid, right? However that was real.
> > Anyway, here comes that copy_{to,from}_user are buggy. Since fixing
> > those would have a good performance hit (to test, but that will
> > probably be sensitive
>
> In skas mode, I wasn't expecting any legitimate unfixable kernel mode
> access faults, so I wasn't setting up the fault_catcher. So, what I did
> was add a wrapper around the guts of copy_user which does a setjmp, and
> returns whether it got longjmp-ed back to.
Yes, fault_catcher (i.e. memory exceptions) works for kernel addresses at very
little cost. Not for userspace addresses, sadly.
> Reading /dev/kmem now produces -EFAULT.
Well, if you only changed copy_user, there should be some working addresses to
read there, right? Even if klogd would need recompilation to handle it right.
In the case /dev/kmem does not work at all we could live with it, but it is a
bit unclean.
> Writing to it still causes a hang
> because write_kmem doesn't check the return value of do_write_mem. With
> that fixed, everything produces -EFAULT.
I'm sending the return check fix to LKML+ Andrew Morton, together with some
cleanup for the unused params of do_write_mem.
--
Paolo Giarrusso, aka Blaisorblade
Linux registered user n. 292729
-------------------------------------------------------
This SF.Net email is sponsored by: IBM Linux Tutorials
Free Linux tutorial presented by Daniel Robbins, President and CEO of
GenToo technologies. Learn everything from fundamentals to system
administration.http://ads.osdn.com/?ad_id\x1470&alloc_id638&opÌk
_______________________________________________
User-mode-linux-devel mailing list
User-mode-linux-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2004-03-09 19:48 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-02-29 2:36 [uml-devel] [PATCH] fix writing into /dev/kmem Jeff Dike
2004-02-29 12:25 ` BlaisorBlade
2004-03-02 1:31 ` Jeff Dike
2004-03-02 18:41 ` BlaisorBlade
2004-03-04 2:02 ` Jeff Dike
2004-03-08 11:50 ` BlaisorBlade
2004-02-29 16:20 ` BlaisorBlade
2004-03-02 1:11 ` Jeff Dike
2004-03-02 1:31 ` Jeff Dike
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox