Date: Tue, 26 Sep 2000 13:59:31 -0700 From: Alfred Perlstein <bright@wintelcom.net> To: "Yonny Cardenas B." <ycardena@yahoo.com> Cc: questions@FreeBSD.ORG Subject: Re: Add a system call Message-ID: <20000926135931.B9141@fw.wintelcom.net> In-Reply-To: <39D10614.9ECD8635@yahoo.com>; from ycardena@yahoo.com on Tue, Sep 26, 2000 at 03:24:52PM -0500 References: <39D10614.9ECD8635@yahoo.com>
index | next in thread | previous in thread | raw e-mail
* Yonny Cardenas B. <ycardena@yahoo.com> [000926 13:22] wrote:
> Hi,
>
> I have been trying to insert a new system call (very simple),
> I have used the steps in the bottom without problems,
> but I don't understand the behavior of the program:
>
> ::::::::::::::
> mysyscall.c
> ::::::::::::::
> int mysyscall( int *n ) {
> printf("In the kernel!\n");
> *n = ( *n + 1000);
> return 0;
> }
>
> ::::::::::::::
> myprog.c
> ::::::::::::::
> int mysyscall (int * );
>
> int main (void){
> int x = 500;
> mysyscall(&x);
> printf("x= %i\n",x);
> }
>
> The kernel syscall apparently run but it doesn't modify the variable.
>
> $cc -o miprog miprog.c
> $ ./miprog
> x= 500
>
> In the kernel! <--- is showed in the console.
>
> If I compile with the function (syscall), it works apparently correctly.
>
> $cc -o miprog miprog.c mysyscall.c
> $ ./miprog
> In the kernel!
> x= 1500
You can't do that, the kernel and userland address spaces are sorta
seperate, you must use copyin/copyout (there's some other stuff like
suword and SCARG).
Here's what mysyscall needs to look like:
int
mysyscall(struct proc *p, struct mysyscall_args *uap)
{
int x;
printf("In the kernel!\n");
/*
* copy the value from userspace, SCARG just pulls the
* field out of the struct pointer (same as uap->x)
*/
error = copyin(SCARG(uap, x), &x, sizeof(x));
/*
* did they give us a messed up pointer that caused us to fail
* the copy? (maybe NULL? or just invalid?)
*/
if (error)
return (error);
printf("Incrementing!\n");
/* ok they didn't increment what we just got */
x++;
printf("Copying back to userland!\n");
/* now try to write it back over the int they gave us */
error = copyout(&x, SCARG(uap, x), sizeof(x));
/* not likely, same thing as copyin, but you never know. */
if (error)
return (error);
printf("We made it!\n");
/* ok, we're good! */
return (0);
}
You need to make sure your entry in syscalls.master looks like this:
172 STD BSD { int mysyscall(int *x); }
Btw, your code allows the user to specify an arbitrary kernel address
that's going to be incremented, if you want to blow the machine up,
have your application pass in a NULL pointer and watch the kernel
panic.. :)
--
-Alfred Perlstein - [bright@wintelcom.net|alfred@freebsd.org]
"I have the heart of a child; I keep it in a jar on my desk."
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-questions" in the body of the message
help
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20000926135931.B9141>
