[Subject Prev][Subject Next][Thread Prev][Thread Next][Subject Index][Thread Index]

Re: [LI] Hiding LKM's -- Beta-test



On Wed, Jan 19, 2000 at 10:50:28AM +0530, Vimal Mathew wrote:
> 
> Isnt the mod->init() call being done in kernel space, and would glibc be
> involved here?
> 

You're right. My assumption was that a user level program would make a
system call - sys_init_module and pass "mod" as the parameter in %ebx.
And I was assuming that init_module was looking for "mod" in %ebx.

I looked at that code a little more carefully. The hack is more non-portable
than I orignially thought. It won't even work with a compiler other than
gcc.

To: linux-india@xxxxxxxxxxxxxxxxxxxxx
Cc: 
Bcc: 
Subject: Re: [LI] Hiding LKM's -- Beta-test
Reply-To: 
In-Reply-To: <20000119105028.A1016@xxxxxxxxxxxxxxxxxxxxx>; from Vimal Mathew on Wed, Jan 19, 2000 at 10:50:28AM +0530

On Wed, Jan 19, 2000 at 10:50:28AM +0530, Vimal Mathew wrote:
> 
> Isnt the mod->init() call being done in kernel space, and would glibc be
> involved here?
> 

You're right. glibc is not involved. My assumption was that a user level
program would make a system call - sys_init_module and pass "mod" as the
parameter in %ebx.  And I was assuming that init_module was looking for
"mod" in %ebx.

I looked at that code a little more carefully. The hack is more non-portable
than I originally thought. It won't even work with a compiler other than
gcc. Here is the code in question:

/* would need to make a clean search of the right register
 * in the function prologue, since gcc may not always put 
 * struct module *mp in %ebx 
 * 
 * Try %ebx, %edi, %ebp, well, every register actually :)
 */
    register struct module *mp asm("%ebx");

To understand why this is happening, look at the following test program
I wrote:

$ cat foo.c

typedef void (*funcp)();

struct s {
	int i;
	funcp func;
};

f()
{
	register long p asm("%ebx");

	printf("ebx: %x\n", p);
}

main()
{
	struct s s1 = { 10, &f };
	
	printf("s1.func: %x\n", s1.func);	
	s1.func();
}

$ cc foo.c -o foo
$ ./foo
s1.func: 80483c8
ebx: 80483c8
$ cc -S foo.c -o foo.s
$ cat foo.s
<snip>
call printf
addl $8,%esp
movl -4(%ebp),%ebx
call *%ebx 

The last instruction is the code for s1.func(). Your code relies on this
particular sequence of instructions generated by gcc for indirect calls.

If due to register pressure in a large routine with a lot of variables,
the compiler chooses a different register to do the indirect call, the
code won't work.

So I take it back. There is no portable way of doing this, unless the Linux
kernel changed the module interface to pass "mod" to init_module. It's
after all a hack and portable hacks are probably too much to ask for :)

	-Arun
--------------------------------------------------------------------
The Linux India Mailing List Archives are now available.  Please search
the archive at http://lists.linux-india.org/ before posting your question
to avoid repetition and save bandwidth.