On Sun, 2002/07/14 at 23:08:21 -0400, Mike Barcroft wrote:
> Thomas Moestl <[EMAIL PROTECTED]> writes:
> > (Disclaimer: my solution below is untested, so it may all be bogus)
> 
> As request, here are the test results.
> 
> Most rules work, except my final one:
> %%%
> bowie# ipfw add allow all from any to any
> ipfw: getsockopt(IP_FW_ADD): Invalid argument
> %%%

Oh, right, that's related: the kernel checks for a minimum size of the
passed data on two occasions, first in sooptcopyin(), and then again
in check_ipfw_struct().
It the size to be at least sizeof(struct ip_fw), however for
structures containing just one action (like the one for the command
above) this is again too much in the 64-bit case because of the
padding. Can you please try the attached patch (against the CVS
version)?

        - thomas

-- 
Thomas Moestl <[EMAIL PROTECTED]> http://www.tu-bs.de/~y0015675/
              <[EMAIL PROTECTED]> http://people.FreeBSD.org/~tmm/
PGP fingerprint: 1C97 A604 2BD0 E492 51D0  9C0F 1FE6 4F1D 419C 776C

Index: ip_fw.h
===================================================================
RCS file: /home/ncvs/src/sys/netinet/ip_fw.h,v
retrieving revision 1.71
diff -u -r1.71 ip_fw.h
--- ip_fw.h     8 Jul 2002 22:39:19 -0000       1.71
+++ ip_fw.h     15 Jul 2002 10:48:19 -0000
@@ -294,8 +294,9 @@
 #define ACTION_PTR(rule)                               \
        (ipfw_insn *)( (u_int32_t *)((rule)->cmd) + ((rule)->act_ofs) )
 
-#define RULESIZE(rule)  (sizeof(struct ip_fw) + \
-       ((struct ip_fw *)(rule))->cmd_len * 4 - 4)
+#define        RULESIZE_FROMLEN(len)   (offsetof(struct ip_fw, cmd) + (len) * 4)
+#define        RULESIZE(rule)  RULESIZE_FROMLEN(((struct ip_fw *)(rule))->cmd_len)
+#define        RULESIZE_MIN    RULESIZE_FROMLEN(1)
 
 /*
  * This structure is used as a flow mask and a flow id for various
Index: ip_fw2.c
===================================================================
RCS file: /home/ncvs/src/sys/netinet/ip_fw2.c,v
retrieving revision 1.4
diff -u -r1.4 ip_fw2.c
--- ip_fw2.c    8 Jul 2002 22:46:01 -0000       1.4
+++ ip_fw2.c    15 Jul 2002 10:38:09 -0000
@@ -2142,7 +2142,7 @@
        int have_action=0;
        ipfw_insn *cmd;
 
-       if (size < sizeof(*rule)) {
+       if (size < RULESIZE_MIN) {
                printf("ipfw: rule too short\n");
                return (EINVAL);
        }
@@ -2428,7 +2428,7 @@
        case IP_FW_ADD:
                rule = (struct ip_fw *)rule_buf; /* XXX do a malloc */
                error = sooptcopyin(sopt, rule, sizeof(rule_buf),
-                       sizeof(struct ip_fw) );
+                       RULESIZE_MIN);
                size = sopt->sopt_valsize;
                if (error || (error = check_ipfw_struct(rule, size)))
                        break;

To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-current" in the body of the message

Reply via email to