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