copy_from_user problem
Maynard Johnson
maynardj at us.ibm.com
Wed Feb 27 01:49:28 EST 2008
Benjamin Herrenschmidt wrote:
> On Mon, 2008-02-25 at 19:47 -0600, Maynard Johnson wrote:
>> Hi,
>> I'm developing a kernel module that needs to parse the in-memory ELF
>> objects for a shared library (libc, to be specific). When running my
>> test on a 32-bit library, it works fine, but for a 64-bit library, the
>> very first copy_from_user() fails:
>> Elf64_Ehdr ehdr;
>> copy_from_user(&ehdr, location_of_lib, sizeof(Elf64_Ehdr);
>>
>> I talked this over a bit with Will Schmidt. He determined that
>> access_ok (being done as a result of copy_from_user) was failing, but we
>> don't know why. I have 32-bit and 64-bit testcases that start up and
>> then pause, waiting for input. We look at the entry for libc in
>> /proc/<pid>/maps, and the permissions are the same for both 32-bit and
>> 64-bit.
>>
>> I've run this test on both a stock SLES 10 SP1 kernel and on 2.6.24.
>> I'm sure this is a user error, but for the life of me, I don't know what
>> I'm doing wrong.
>>
>> Can anyone out there help?
>
> I would have to look at the code.
Ben,
I've pared down the code to a minimal testcase and attached the source
file. Here are the makefile rules to build it:
----------------------------------------------
obj-m := uaccess_test.o
KDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
default:
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
clean:
rm -f *.mod.c *.ko *.o .*.cmd
rm -rf .tmp_versions
----------------------------------------------
Instructions:
1. Write a simple C program that will pause, waiting for input, so that
you can obtain the address of libc to pass into the uaccess_test kernel
module. For example:
#include <stdio.h>
int main(void)
{
printf("Press Enter to continue.\n");
getchar();
return 0;
}
--------------
2. Compile C program as 32-bit; then run it. While the program is
waiting for input, obtain its PID and do 'cat /proc/<pid>/maps' to get
the address of where libc is loaded.
3. From the dir where you build the uaccess_test kernel module:
'insmod ./uaccess_test.ko lib_addr=0x<mem_loc_libc>'
This should succeed. dmesg to verify.
4. Unload the module.
5. Recompile your C program with -m64; start it up and obtain the
address of libc again (now a 64-bit address).
6. Load the uaccess_test kernel module and pass
'lib_addr=0x<mem_loc_libc>'. Note that this time, the load fails.
dmesg to see debug printk's.
Thanks for any light you can shed on this!
-Maynard
>
> Ben.
>
>
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: uaccess_test.c
URL: <http://lists.ozlabs.org/pipermail/linuxppc-dev/attachments/20080226/b7a23acc/attachment.asc>
More information about the Linuxppc-dev
mailing list