Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 15 Jul 2002 04:00:08 -0700
From:      Luigi Rizzo <luigi@FreeBSD.org>
To:        Mike Barcroft <mike@FreeBSD.org>, current@FreeBSD.org
Subject:   Re: different packing of structs in kernel vs. userland ?
Message-ID:  <20020715040008.A85276@iguana.icir.org>
In-Reply-To: <20020715105158.GA314@crow.dom2ip.de>; from tmoestl@gmx.net on Mon, Jul 15, 2002 at 12:51:58PM %2B0200
References:  <20020714011810.A72236@iguana.icir.org> <20020714203642.GD314@crow.dom2ip.de> <20020714230821.C64412@espresso.q9media.com> <20020715105158.GA314@crow.dom2ip.de>

next in thread | previous in thread | raw e-mail | index | archive | help
sorry but all this just does not make sense to me.

sizeof(foo) should give the same result irrespective of
where you use it.

Perhaps the best thing would be to put a

	printf("struct ip_fw has size %d\n", sizeof(struct ip_fw));

both in ipfw2.c and somewhere in ip_fw2.c and see if there is
a mismatch between the two numbers.

	cheers
	luigi

On Mon, Jul 15, 2002 at 12:51:58PM +0200, Thomas Moestl wrote:
> 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?20020715040008.A85276>