copy_from_user/syscall got me stock

Gregory (lkhacker@thatindex.com)
Tue, 27 Jun 2000 21:31:28 -0400 (EDT)


Hi,

I am at a dead end of trying to figure out why copy_from_user() fails on
me. Any help or pointers will be greatly appreciated!

I made new system call which is simplified copy of sys_socketcall() system
call with basically copy_from_user() in it, but it results in system Ooops
when called from user space using syscall().

When adding a new system call I edited arch/i386/kernel/entry.S and
increasing the number of system calls to 191. I also edited
include/asm/unistd.h. The new system call is being called.

The new system call is as follows:

asmlinkage int sys_qsocketcall(int call, unsigned long *args)
{
unsigned long a[6];
unsigned long a0,a1;
struct request filter_req;
struct request class_req;

printk( "sys_qsocketcall(): inside. \n");

if(call<1||call>SYS_RECVMSG)
return -EINVAL;

/* copy_from_user should be SMP safe. */
if (copy_from_user(a, args, nargs[call])) // nargs[..]=12
return -EFAULT;

printk( "sys_qsocketcall(): copy_from_user() done. [a0=%X, a1=%X]\n",
a[0], a[1] );

printk( "sys_qsocketcall(): returning.\n" );
return -EINVAL;
}

I am calling this from user space as follows:

....
char *lng_args;

lng_args = (char*)malloc( 3*sizeof(struct request) ); // allocates ~8 KB
memset( lng_args, 3, 3*sizeof(struct request) );

printf( "calling syscall()....\n" );
res = syscall( SYS_qsocketcall, 1, lng_args );
printf( "after syscall()....\n" );
....

There is basically no difference that I can see between my code and how
sys_socketcall() system call works. sys_socketcall() doesn't use any
locks before doing copy so I thought I don't have to either. I just
allocate much bigger chunk of memory, but inside of system call I can't
even read first 12 Bytes under light loads (having ~5 clients call new
system call at the same time).
And here is what I see in a log file:

Jun 24 16:56:36 thinker kernel: sys_qsocketcall(): doing first copy_from_user()....
Jun 24 16:56:36 thinker kernel: sys_qsocketcall(): inside. (call=1, args=080499c8)
Jun 24 16:56:36 thinker kernel: sys_qsocketcall(): doing first copy_from_user()....
Jun 24 16:56:37 thinker kernel: sys_qsocketcall(): inside. (call=1, args=080499c8)
Jun 24 16:56:37 thinker kernel: sys_qsocketcall(): doing first copy_from_user()....
Jun 24 16:56:37 thinker kernel: sys_qsocketcall(): inside. (call=1, args=080499c8)
Jun 24 16:56:37 thinker kernel: sys_qsocketcall(): doing first copy_from_user()....
Jun 24 16:56:37 thinker kernel: sys_qsocketcall(): inside. (call=1, args=080499c8)
Jun 24 16:56:37 thinker kernel: sys_qsocketcall(): doing first copy_from_user()....
Jun 24 16:56:38 thinker kernel: sys_qsocketcall(): inside. (call=1, args=080499c8)
Jun 24 16:56:38 thinker kernel: sys_qsocketcall(): doing first copy_from_user()....
Jun 24 16:57:06 thinker kernel: sys_qsocketcall(): inside. (call=1, args=080499c8)
Jun 24 16:57:06 thinker kernel: sys_qsocketcall(): doing first copy_from_user()....
Jun 24 16:57:06 thinker kernel: sys_qsocketcall(): copy_from_user() done. [a0=D0C0B0A, a1=A100F0E]
Jun 24 16:57:06 thinker kernel: sys_qsocketcall(): returning.
Jun 24 16:57:07 thinker kernel: Unable to handle kernel NULL pointer dereference at virtual address 00000276
Jun 24 16:57:07 thinker kernel: current->tss.cr3 = 0304f000, %cr3 = 0304f000
Jun 24 16:57:07 thinker kernel: *pde = 00000000
Jun 24 16:57:07 thinker kernel: Oops: 0000
Jun 24 16:57:07 thinker kernel: CPU: 0

Any suggestions? What am I missing?
Thanks,

Gregory

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/