All of lore.kernel.org
 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.