Problem with syscall(2)
Web Server forum
Back To The Forum Home!Search!Private Messaging System

Web Server Talk Web Server Talk > Unix and Linux reviews > Free Unix support > Unix Programming > Problem with syscall(2)




Pages (2): [1] 2 »   Last Thread   Next Thread Next
  Show Printable Version Email this Page Subscribe to this Thread      Post New Thread    Post A Reply      

    Problem with syscall(2)  
Daniel Rudy


View Ip Address Report This Message To A Moderator Edit/Delete Message


 
07-09-07 12:18 PM


Hello Group,

I am attempting to write a KLD that runs under FreeBSD 6.x.  I have the
function, and the code written, but when I call it from the test
program, the passed parameters are getting clobbered with garbage.  I've
been looking at this for a couple of hours now, and I'm not finding the
problem.  Could someone take a look and see what I'm doing wrong?


**** excerpt from header file:

I copied the padding verbatim from /usr/include/sys/sysproto.h.  It
didn't work with or without the padding.  I left out the padding
definitions.

typedef struct mod_syscall_cmd_disp_tag__ mod_syscmdisp_t;
struct mod_syscall_cmd_disp_tag__
{
/* command id from user */
char command_l_[PADL_(int)]; int command; char command_r_[PADR_(int)
];
/* ptr to aux param block in user space */
char pargs_l_[PADL_(void *)]; void *pargs; char pargs_r_[PADR_(void 
*)];
};


/* aux param: get/set parameter */
typedef struct mod_param_tag__ mod_param_t;
struct mod_param_tag__
{
int param;          /* parameter id */
int value;          /* parameter value */
};



**** excerpt from module source file:


/* command function table (read only) */
static const mod_cmdft_t cmd_func_tab[] = {
{MOD_CMD_SETPARAM, sizeof(mod_param_t), &mod_setparam},
{MOD_CMD_GETPARAM, sizeof(mod_param_t), &mod_getparam},
{MOD_CMD_HKGETDIRENT, 0, &mod_hook_getdirent},
{MOD_CMD_RLGETDIRENT, 0, &mod_unhook_getdirent}
};


/* **** SYSCALL FUNCTION HANDLER */

/* implementation of control syscall */
static int mod_syscall(struct thread *td, void *syscall_args)
{
int i;
int sz;
int cidx;
int error;
void *ptr;
mod_syscmdisp_t *uap;


uap = (mod_syscmdisp_t *)syscall_args;
uprintf("pargs %p\n", uap->pargs);

/* locate the command record */
i = 0;
cidx = -1;
sz = sizeof(cmd_func_tab) / sizeof(mod_cmdft_t);
while (i < sz)
{
uprintf("i %d; sz %d; ucmd %d; tcmd %d\n", i, sz, uap->command,
cmd_func_tab[i].command);
if (uap->command == cmd_func_tab[i].command)
{
cidx = i;
break;
}
i++;
}
uprintf("cidx %d\n", cidx);
if (cidx == -1) return(ENOENT);   <--- not found error

<snip>

return(0);
}


**** test program:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <sys/module.h>
#include <errno.h>
#include <unistd.h>


#include "security.h"


void ferr(int ec)
{
printf("error: %s\n", strerror(ec));
exit(1);
}


int main(int argc, char *argv[])
{
int syscall_num;
int result;
struct module_stat stat;
mod_syscmdisp_t cpm;

/* determine module's offset value */
stat.version = sizeof(stat);
modstat(modfind("security"), &stat);
syscall_num = stat.data.intval;
printf("syscall found at %d\n", syscall_num);

cpm.command = MOD_CMD_HKGETDIRENT;   <--- the command parameters
cpm.pargs = NULL;

result = syscall(syscall_num, &cpm);
if (result != 0) ferr(errno);

return(0);
}

MOD_CMD_HKGETDIRENT is defined at 0x80.  Here's what I'm getting for output:

strata:/home/dr2867/c/modules/kernel/security 1056 ### ->kldload
./security.ko
Security module loaded at syscall offset 210.
strata:/home/dr2867/c/modules/kernel/security 1057 ### ->./test
syscall found at 210
pargs 0x2805173b
i 0; sz 4; ucmd -1077941208; tcmd 0
i 1; sz 4; ucmd -1077941208; tcmd 1
i 2; sz 4; ucmd -1077941208; tcmd 128
i 3; sz 4; ucmd -1077941208; tcmd 129
cidx -1
error: No such file or directory
strata:/home/dr2867/c/modules/kernel/security 1058 ### ->kldunload
security.ko
Security module unloaded from syscall offset 210.
strata:/home/dr2867/c/modules/kernel/security 1059 ### ->

The table command entry (tcmd) correctly says 128 (0x80), but the
command parameter from user space (ucmd) has garbage in it.  Even the
pargs pointer is garbage as it should be NULL.



--
Daniel Rudy

Email address has been base64 encoded to reduce spam
Decode email address using b64decode or uudecode -m

Why geeks like computers: look chat date touch grep make unzip
strip view finger mount fsck more fsck yes spray umount sleep





[ Post a follow-up to this message ]



    Re: Problem with syscall(2)  
Scott Lurndal


View Ip Address Report This Message To A Moderator Edit/Delete Message


 
07-09-07 06:26 PM

Daniel Rudy <spamthis@spamthis.net> writes:
>
>Hello Group,
>
>I am attempting to write a KLD that runs under FreeBSD 6.x.  I have the
>function, and the code written, but when I call it from the test
>program, the passed parameters are getting clobbered with garbage.  I've
>been looking at this for a couple of hours now, and I'm not finding the
>problem.  Could someone take a look and see what I'm doing wrong?

I'm not a bsd expert, but don't you have to 'copyin' the argument from
usermode before accessing it in your system call?

scott





[ Post a follow-up to this message ]



    Re: Problem with syscall(2)  
Daniel Rudy


View Ip Address Report This Message To A Moderator Edit/Delete Message


 
07-10-07 12:20 AM

At about the time of 7/9/2007 11:22 AM, Scott Lurndal stated the following:
> Daniel Rudy <spamthis@spamthis.net> writes: 
>
> I'm not a bsd expert, but don't you have to 'copyin' the argument from
> usermode before accessing it in your system call?
>
> scott

That's what I did initially, but the call would abort with EFAULT.  As
it turns out, *syscall_args is already pointing to kernel space, so
using copyin on it doesn't work.

You know....I just thought of something...I have the number of args set
to 3 in the module definition....I'm only sending 2...Let me fix that
and get back to you.


--
Daniel Rudy

Email address has been base64 encoded to reduce spam
Decode email address using b64decode or uudecode -m

Why geeks like computers: look chat date touch grep make unzip
strip view finger mount fsck more fsck yes spray umount sleep





[ Post a follow-up to this message ]



    Re: Problem with syscall(2)  
Daniel Rudy


View Ip Address Report This Message To A Moderator Edit/Delete Message


 
07-10-07 12:20 AM

At about the time of 7/9/2007 1:22 PM, Daniel Rudy stated the following:
> At about the time of 7/9/2007 11:22 AM, Scott Lurndal stated the following
: 
>
> That's what I did initially, but the call would abort with EFAULT.  As
> it turns out, *syscall_args is already pointing to kernel space, so
> using copyin on it doesn't work.
>
> You know....I just thought of something...I have the number of args set
> to 3 in the module definition....I'm only sending 2...Let me fix that
> and get back to you.
>
>

Didn't work.  I'm still getting garbage in the parameters.

--
Daniel Rudy

Email address has been base64 encoded to reduce spam
Decode email address using b64decode or uudecode -m

Why geeks like computers: look chat date touch grep make unzip
strip view finger mount fsck more fsck yes spray umount sleep





[ Post a follow-up to this message ]



    Re: Problem with syscall(2)  
Scott Lurndal


View Ip Address Report This Message To A Moderator Edit/Delete Message


 
07-10-07 12:20 AM

Daniel Rudy <spamthis@spamthis.net> writes:
>At about the time of 7/9/2007 1:22 PM, Daniel Rudy stated the following: 
>
>Didn't work.  I'm still getting garbage in the parameters.
>

It's possible, I suppose, that BSD's syscall dispatcher will do the copyin
for you, but seems unlikely.    How did you determine that *syscall_args
is pointing to kernel space?

scott





[ Post a follow-up to this message ]



    Re: Problem with syscall(2)  
tedu


View Ip Address Report This Message To A Moderator Edit/Delete Message


 
07-10-07 12:20 AM

On Jul 9, 1:33 am, Daniel Rudy <spamt...@spamthis.net> wrote:
> Hello Group,
>
> I am attempting to write a KLD that runs under FreeBSD 6.x.  I have the
> function, and the code written, but when I call it from the test
> program, the passed parameters are getting clobbered with garbage.  I've
> been looking at this for a couple of hours now, and I'm not finding the
> problem.  Could someone take a look and see what I'm doing wrong?
>
>
> /* implementation of control syscall */
> static int mod_syscall(struct thread *td, void *syscall_args)
>   {
>     int i;
>     int sz;
>     int cidx;
>     int error;
>     void *ptr;
>     mod_syscmdisp_t *uap;
>
>     uap = (mod_syscmdisp_t *)syscall_args;

syscall_args is not a pointer to mod_syscmdisp_t.  it's more likely a
pointer to a pointer of one, based on the usage in your example.






[ Post a follow-up to this message ]



    Re: Problem with syscall(2)  
Daniel Rudy


View Ip Address Report This Message To A Moderator Edit/Delete Message


 
07-10-07 12:20 PM

In-Reply-To: <70yki.4602$rL1.339@newssvr19.news.prodigy.net>
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit
Lines: 45
Message-ID: <prHki.1585$m%.361@newssvr17.news.prodigy.net>
NNTP-Posting-Host: 71.146.37.62
X-Complaints-To: abuse@prodigy.net
X-Trace: newssvr17.news.prodigy.net 1184056149 ST000 71.146.37.62 (Tue, 10 J
ul 2007 04:29:09 EDT)
NNTP-Posting-Date: Tue, 10 Jul 2007 04:29:09 EDT
X-UserInfo1: TSU& #91;@SVEVRRYCTLZNCOF_W\@PJ_^PBQLGPQRZ\YI
JYWZUYICD^RAQBKZQTZ
TX\_I[^G_KGFNON[ZOE_AZNVO^\XGGNTCIRPIJH[@RQKBXLRZ@CD^HKANYVW@RLG
EZEJN@\_WZJBNZYYKVIOR]T]MNMG_Z[YVWSCH_Q[GPC_A@CARQVXDSDA^M]@DRVUM@RB
M
Date: Tue, 10 Jul 2007 01:29:14 -0700
Bytes: 3492
Xref: number1.nntp.dca.giganews.com comp.unix.programmer:179240

At about the time of 7/9/2007 2:45 PM, Scott Lurndal stated the following:
> Daniel Rudy <spamthis@spamthis.net> writes: 
>
> It's possible, I suppose, that BSD's syscall dispatcher will do the copyin
> for you, but seems unlikely.    How did you determine that *syscall_args
> is pointing to kernel space?
>
> scott

Because, the addresses involved when I tried to copy the args to a stack
buffer, were very close...the args were also on the stack.

--
Daniel Rudy

Email address has been base64 encoded to reduce spam
Decode email address using b64decode or uudecode -m

Why geeks like computers: look chat date touch grep make unzip
strip view finger mount fsck more fsck yes spray umount sleep





[ Post a follow-up to this message ]



    Re: Problem with syscall(2)  
Daniel Rudy


View Ip Address Report This Message To A Moderator Edit/Delete Message


 
07-10-07 12:20 PM

At about the time of 7/9/2007 3:02 PM, tedu stated the following:
> On Jul 9, 1:33 am, Daniel Rudy <spamt...@spamthis.net> wrote: 
>
> syscall_args is not a pointer to mod_syscmdisp_t.  it's more likely a
> pointer to a pointer of one, based on the usage in your example.
>

I don't agree....here's why:

/usr/src/sys/kern/sys_generic.c:LINE#96-START
/*
* Read system call.
*/
#ifndef _SYS_SYSPROTO_H_
struct read_args {
int     fd;
void    *buf;
size_t  nbyte;
};
#endif
/*
* MPSAFE
*/
int
read(td, uap)
struct thread *td;
struct read_args *uap;
{
struct uio auio;
struct iovec aiov;
int error;

if (uap->nbyte > INT_MAX)
return (EINVAL);
aiov.iov_base = uap->buf;
aiov.iov_len = uap->nbyte;
auio.uio_iov = &aiov;
auio.uio_iovcnt = 1;
auio.uio_resid = uap->nbyte;
auio.uio_segflg = UIO_USERSPACE;
error = kern_readv(td, uap->fd, &auio);
return(error);
}
/usr/src/sys/kern/sys_generic.c:LINE#118-END

This code is the kernel read syscall.  I don't see anything in there
where it's doing a copyin for any of the uap parameters.  It looks
normal to me, and obviously it correct, because if it wasn't the
computer wouldn't work.  This is from FreeBSD 6.2-RELEASE.


--
Daniel Rudy

Email address has been base64 encoded to reduce spam
Decode email address using b64decode or uudecode -m

Why geeks like computers: look chat date touch grep make unzip
strip view finger mount fsck more fsck yes spray umount sleep





[ Post a follow-up to this message ]



    Re: Problem with syscall(2)  
tedu


View Ip Address Report This Message To A Moderator Edit/Delete Message


 
07-10-07 06:23 PM

On Jul 10, 1:41 am, Daniel Rudy <spamt...@spamthis.net> wrote:
> At about the time of 7/9/2007 3:02 PM, tedu stated the following:
>
>
> 
> 
> 
> 
> 
>
> I don't agree....here's why:
>
> /usr/src/sys/kern/sys_generic.c:LINE#96-START
> /*
>  * Read system call.
>  */
> #ifndef _SYS_SYSPROTO_H_
> struct read_args {
>         int     fd;
>         void    *buf;
>         size_t  nbyte;};
>
> #endif
>
> This code is the kernel read syscall.  I don't see anything in there
> where it's doing a copyin for any of the uap parameters.  It looks
> normal to me, and obviously it correct, because if it wasn't the
> computer wouldn't work.  This is from FreeBSD 6.2-RELEASE.

what does syscall args look like for your syscall?






[ Post a follow-up to this message ]



    Re: Problem with syscall(2)  
Daniel Rudy


View Ip Address Report This Message To A Moderator Edit/Delete Message


 
07-11-07 12:21 PM

At about the time of 7/10/2007 10:45 AM, tedu stated the following:
> On Jul 10, 1:41 am, Daniel Rudy <spamt...@spamthis.net> wrote: 
>
> what does syscall args look like for your syscall?
>

This is the test program:

int main(int argc, char *argv[])
{
int syscall_num;
int result;
struct module_stat stat;
mod_syscmdisp_t cpm;

/*
if (argc != 2) usage(argv[0]);
*/

/* determine module's offset value */
stat.version = sizeof(stat);
modstat(modfind("security"), &stat);
syscall_num = stat.data.intval;
printf("syscall found at %d\n", syscall_num);

printf("mod_syscmdisp_t %d\n", sizeof(mod_syscmdisp_t));
cpm.command = MOD_CMD_HKGETDIRENT;
cpm.pargs = NULL;

result = syscall(syscall_num, &cpm);   <----  Call Here
if (result != 0) ferr(errno);

return(0);
}

But, as someone else pointed out, you are correct in your initial
statement.  It does seem it's a pointer to a pointer issue.  The value
in the command variable is actually a pointer to the actual parameters
on the user stack.  Since it's a pointer to a pointer, I think I know
what to do now.  I'm going to make some code changes and try them out.
I'll post the results here.  Should be interesting.

Furthermore, I wish to extend a big thank you to everyone who has
responded so far.  I'm suprized that I have not yet caused a system
panic with my faulty code.  I have a book on the FreeBSD kernel by one
of the original core developers.  It's a great book if you are looking
though the source to see how it works.  But it doesn't teach you the ins
and outs of kernel mode programming, which is what I need.

--
Daniel Rudy

Email address has been base64 encoded to reduce spam
Decode email address using b64decode or uudecode -m

Why geeks like computers: look chat date touch grep make unzip
strip view finger mount fsck more fsck yes spray umount sleep





[ Post a follow-up to this message ]



    Sponsored Links  




 





   All times are GMT. The time now is 09:03 AM.      Post New Thread    Post A Reply      
Pages (2): [1] 2 »   Last Thread   Next Thread Next


Most Popular forums 

Forum Jump:
Rate This Thread:

Forum Rules:
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is OFF
vB code is ON
Smilies are ON
[IMG] code is OFF
 
Medical and Health forum | Computer Games Reviews | Graphics design forum

Back To The Top
Home | Usercp | Faq | Register