Date: Mon, 15 Jul 2002 12:51:58 +0200 From: Thomas Moestl <tmoestl@gmx.net> To: Mike Barcroft <mike@FreeBSD.org> Cc: Luigi Rizzo <luigi@freebsd.org>, current@freebsd.org Subject: Re: different packing of structs in kernel vs. userland ? Message-ID: <20020715105158.GA314@crow.dom2ip.de> In-Reply-To: <20020714230821.C64412@espresso.q9media.com> References: <20020714011810.A72236@iguana.icir.org> <20020714203642.GD314@crow.dom2ip.de> <20020714230821.C64412@espresso.q9media.com>
next in thread | previous in thread | raw e-mail | index | archive | help
On Sun, 2002/07/14 at 23:08:21 -0400, Mike Barcroft wrote: > Thomas Moestl <tmoestl@gmx.net> 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 <tmoestl@gmx.net> http://www.tu-bs.de/~y0015675/ <tmm@FreeBSD.org> 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 majordomo@FreeBSD.org with "unsubscribe freebsd-current" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20020715105158.GA314>