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>
next in thread | previous in thread | raw e-mail | index | archive | help
* 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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20000926135931.B9141>