Subject: Re: NetBSD/systrace error: EINVAL
To: Kristaps Johnson <kristaps@gradient-enterprises.com>
From: Aaron Hughes <hughesac@gmail.com>
List: tech-misc
Date: 07/04/2006 13:55:10
Seth Kurtzberg wrote:
> On Tue, 4 Jul 2006 09:08:11 -0400 (EDT)
> Kristaps Johnson <kristaps@gradient-enterprises.com> wrote:
> 
>> No, it returns with success.  I just re-ran with:
> 
> In your code, it is not checked, so you can't know that it returned with success.  If the code you are actually running is different, please post that code.  Otherwise, you must check the return value of open, you can't just assume it is correct.
> 
>> $ sudo ./a.out 161
>> a.out: read: /dev/systrace: Invalid argument
>>
>> In this case `161' was a shell session (I hit enter in it).
>>
>>
>>> I don't see a check of the return value of the open() call.  Could it be 
>>> -1 (invalid)?
>>>
>>> On Mon, 3 Jul 2006 17:52:08 -0400 (EDT)
>>> Kristaps Johnson <kristaps@gradient-enterprises.com> wrote:
>>>
>>>> Hello all!
>>>>
>>>> I wonder if somebody can help me with a strange error I receive under
>>>> systrace on NetBSD.  I've included a sample programme below with
>>>> error-checking stripped in non-applicable areas.  The "sys/systrace.h"
>>>> header file is current from CVS. Overall system NetBSD 3.0, GENERIC.  I'm
>>>> trying to port sysjail (sysjail.bsd.lv) to NetBSD and this is keeping me
>>>> hard up.  Suggestions?
>>>>
>>>> Note that this works fine with the OpenBSD systrace (3.9), which adds to
>>>> the mystification.
>>>>
>>>> The "strange error" is EINVAL: Invalid argument.
>>>>
>>>> The below is run as "./a.out 5123", where 5123 is a process doing things (I
>>>> have a script looping echo -n '.').
>>>>
>>>>
>>>> #include <sys/ioctl.h>
>>>> #include <sys/param.h>
>>>> #include <sys/types.h>
>>>> #include <sys/wait.h>
>>>> #ifdef __NetBSD__
>>>> # include <sys/systrace.h>
>>>> #elif __OpenBSD__
>>>> # include <dev/systrace.h>
>>>> #endif
>>>>
>>>> #include <err.h>
>>>> #include <errno.h>
>>>> #include <fcntl.h>
>>>> #include <poll.h>
>>>> #include <stdio.h>
>>>> #include <stdlib.h>
>>>> #include <string.h>
>>>> #include <unistd.h>
>>>>
>>>> int
>>>> main(int argc, const char *argv[])
>>>> {
>>>>          struct str_message msg;
>>>>          struct systrace_policy pol;
>>>>          struct pollfd pfd;
>>>>          int fd, ofd;
>>>>          pid_t cpid;
>>>>
>>>>          cpid = atoi(argv[1]);
>>>>
>>>>          ofd = open("/dev/systrace", O_RDWR | O_NONBLOCK, 0);
>>>> #ifdef __OpenBSD__
>>>>          ioctl(ofd, STRIOCCLONE, &fd);
>>>>          close(ofd);
>>>> #elif __NetBSD__
>>>>          fd = ofd;
>>>> #endif
>>>>          fcntl(fd, F_SETFD, FD_CLOEXEC);
>>>>
>>>>          memset(&pol, 0, sizeof(pol));
>>>>          pol.strp_op = SYSTR_POLICY_NEW;
>>>>          pol.strp_num = -1;
>>>>          pol.strp_maxents = 512;
>>>>
>>>>          ioctl(fd, STRIOCPOLICY, &pol);
>>>>          ioctl(fd, STRIOCATTACH, &cpid);
>>>>
>>>>          memset(&pfd, 0, sizeof(pfd));
>>>>          pfd.fd = fd;
>>>>          pfd.events = POLLIN;
>>>>
>>>>          poll(&pfd, 1, -1);
>>>>
Why does this compile, when read is supposed to take a char * as second 
arg and you're passing pointer to str_message struct?

>>>>          /* RETURNS AN ERROR:
>>>>           * read: /dev/systrace: Invalid argument */
>>>>          if (read(fd, &msg, sizeof(struct str_message))
>>>>                          != sizeof(struct str_message)) {
>>>>                  err(1, "read: /dev/systrace");
>>>>          }
>>>>
>>>>          return(0);
>>>> }
>>>>
>>>>
>> /--
>>    Kristaps Johnson, Chief Technology Officer
>>    Gradient Enterprises Inc.
>>
>>
>