linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
From: Maynard Johnson <maynardj@us.ibm.com>
To: benh@kernel.crashing.org
Cc: linuxppc-dev@ozlabs.org
Subject: Re: copy_from_user problem
Date: Tue, 26 Feb 2008 08:49:28 -0600	[thread overview]
Message-ID: <47C426F8.7070203@us.ibm.com> (raw)
In-Reply-To: <1203994599.15052.84.camel@pasglop>

[-- Attachment #1: Type: text/plain, Size: 2513 bytes --]

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.
> 
> 


[-- Attachment #2: uaccess_test.c --]
[-- Type: text/plain, Size: 1857 bytes --]

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <asm/uaccess.h>

static long lib_addr;
module_param(lib_addr, long, 0);
MODULE_PARM_DESC(lib_addr, "lib_addr");



static unsigned long parse_elf64(unsigned long start_loc)
{
	Elf64_Ehdr * ehdr;
	int ret = 0;

	ehdr = kmalloc(sizeof(Elf64_Ehdr), GFP_KERNEL);
	if (copy_from_user((void *)ehdr, (void *) start_loc, sizeof(Elf64_Ehdr))) {
		printk("cannot get Elf64_Ehdr from "
		       "start_loc %lx\n", start_loc);
			goto out;
	}
	if (ehdr->e_ident[EI_CLASS] != ELFCLASS64) {
		printk("EI_CLASS of Elf64_Hdr is incorrect! %d\n",
		       ehdr->e_ident[EI_CLASS]);
		goto out;
	}
	if (ehdr->e_type != ET_DYN) {
		printk(KERN_INFO "LPA: "
		       "%s, line %d: Unexpected e_type %u parsing ELF\n",
		       __FUNCTION__, __LINE__, ehdr->e_type);
		goto out;
	}
	ret = ehdr->e_ident[EI_CLASS];
	printk(KERN_INFO "Elf class from Ehdr is %d\n", ret);
 out:
	return ret;
}

static unsigned long parse_elf32(unsigned long start_loc)
{
	Elf32_Ehdr ehdr;
	int ret = 0;

	if (copy_from_user(&ehdr, (void *) start_loc, sizeof (ehdr)))
		goto out;
	if (ehdr.e_ident[EI_CLASS] != ELFCLASS32)
		goto out;
	if (ehdr.e_type != ET_DYN) {
		printk(KERN_INFO
		       "%s, line %d: Unexpected e_type %u parsing ELF\n",
		       __FUNCTION__, __LINE__, ehdr.e_type);
		goto out;
	}
	ret = ehdr.e_ident[EI_CLASS];
	printk(KERN_INFO "Elf class from Ehdr is %d\n", ret);
 out:
	return ret;

}

int find_ehdr(unsigned long start_loc)
{
	int ret = 0;
	if (!(ret = parse_elf32(start_loc)))
		ret = parse_elf64(start_loc);
	return ret;
}



int __init init_module(void)
{
	if (!(find_ehdr(lib_addr))) {
		printk(KERN_INFO "uaccess test failed\n");
		return -1;
	}
	    printk(KERN_INFO "uaccess test succeeded\n");
        return 0;
}

void __exit cleanup_module(void)
{
}
MODULE_LICENSE("GPL");


  reply	other threads:[~2008-02-26 14:49 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-02-26  1:47 copy_from_user problem Maynard Johnson
2008-02-26  2:56 ` Benjamin Herrenschmidt
2008-02-26 14:49   ` Maynard Johnson [this message]
2008-02-26 15:01     ` Nathan Lynch
2008-02-26 15:30       ` Nathan Lynch
2008-02-26 15:36       ` Maynard Johnson
2008-02-26 23:22     ` Benjamin Herrenschmidt
2008-02-27 12:27       ` Maynard Johnson
2008-02-27 12:40         ` Arnd Bergmann
2008-02-27 20:24         ` Benjamin Herrenschmidt
2008-02-26  5:29 ` Paul Mackerras
  -- strict thread matches above, loose matches on Subject: below --
2005-08-11  2:52 V MURAHARI
2005-08-11 11:02 ` Clemens Koller
2005-08-11 14:29 ` T Michael Turney

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=47C426F8.7070203@us.ibm.com \
    --to=maynardj@us.ibm.com \
    --cc=benh@kernel.crashing.org \
    --cc=linuxppc-dev@ozlabs.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).