Own syscall implementation
Russell King - ARM Linux
linux at arm.linux.org.uk
Mon Oct 11 08:54:38 EDT 2010
On Mon, Oct 11, 2010 at 02:52:04PM +0300, Oleg Kutkov wrote:
> Hello.
>
> My name is Oleg and i'm newbie in a arm-kernel.
> I doing experiments with kernel and trying to add my own syscall.
> What i'm done:
> 1. Added somewhere this code:
>
> asmlinkage long sys_mycall(int call, unsigned long __user *args);
>
> SYSCALL_DEFINE2(mycall, int, call, unsigned long __user *, args)
> {
> unsigned long a[6];
>
> if (err = copy_from_user(a, args, nargs[call])) {
> return -EFAULT;
> }
>
> ///some cool work///
> }
That's fine, except that there's no bounds checking for the value of
'call', which if it were negative or a large positive number would
overflow the nargs array. You're also not propagating the error back.
> 2. Added to calls.S my function (but i'm not really understand what this :( )
>
> .long sys_mycall
You don't say what kernel version.
> 3. And finally define in unistd.h:
>
> #define __NR_mycall (__NR_SYSCALL_BASE+312)
As 312 is already taken (we're now up to 369), and you're using .long, I
can only assume this is quite an old kernel... Modern kernels use CALL()
in calls.S to ensure that the number of syscalls are properly counted.
Note that this is a problem to people adding random new syscalls - they'll
get in the way of future additions to the kernel, and in some cases, glibc
probes for support for syscalls by trying to call them.
So it's really not a good idea to create new syscalls for production code.
It's usually safer to write something like a char device driver and use
the read/write/ioctl methods instead.
> Everything is good, but when some one calls me from userspace - i
> receiving garbage in args and copy_from_user is failed to copy data...
Have you checked the value of 'call' and nargs[call] ? Note that
copy_from_user() takes the number of _bytes_ to copy, not the number
of arguments.
More information about the linux-arm-kernel
mailing list