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