NetBSD Problem Report #16518

Received: (qmail 28842 invoked from network); 27 Apr 2002 11:56:58 -0000
Message-Id: <20020427115657.702EB11754@yamt.dyndns.org>
Date: Sat, 27 Apr 2002 20:56:57 +0900 (JST)
From: yamt@mwd.biglobe.ne.jp
Reply-To: yamt@mwd.biglobe.ne.jp
To: gnats-bugs@gnats.netbsd.org
Subject: some fixes to libpcap
X-Send-Pr-Version: 3.95

>Number:         16518
>Category:       lib
>Synopsis:       some fixes to libpcap
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    lib-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sat Apr 27 11:58:00 +0000 2002
>Closed-Date:    
>Last-Modified:  Tue Feb 20 05:23:33 +0000 2007
>Originator:     YAMAMOTO Takashi
>Release:        NetBSD 1.5ZC
>Organization:
>Environment:


System: NetBSD bear.yamanet 1.5ZC NetBSD 1.5ZC (build) #13: Wed Apr 3 03:54:19 JST 2002 takashi@bear.yamanet:/usr/home/takashi/work/kernel/build i386
Architecture: i386
Machine: i386
>Description:
	- make tcpdump "1>1" works correctly.
	- make things unsigned as in-kernel filter does.
	- fix a bug that prevents optimization. (and might cause bad codes)
	  eg. "1 & len == 1"
	- fix wrong optimizations.
	  eg. "0 >> len == 1", "0 - len == 1"
>How-To-Repeat:
	try above examples.
>Fix:
	apply following patches.
	I sent them to patches@tcpdump.org, too.

Index: gencode.c
===================================================================
RCS file: /cvs/NetBSD/basesrc/lib/libpcap/gencode.c,v
retrieving revision 1.29
diff -u -r1.29 gencode.c
--- gencode.c	2001/06/01 15:49:53	1.29
+++ gencode.c	2002/04/24 18:01:24
@@ -2635,16 +2635,17 @@

 	s0 = xfer_to_x(a1);
 	s1 = xfer_to_a(a0);
-	s2 = new_stmt(BPF_ALU|BPF_SUB|BPF_X);
-	b = new_block(JMP(code));
-	if (code == BPF_JGT || code == BPF_JGE) {
-		reversed = !reversed;
-		b->s.k = 0x80000000;
+	if (code == BPF_JEQ) {
+		s2 = new_stmt(BPF_ALU|BPF_SUB|BPF_X);
+		b = new_block(JMP(code));
+		sappend(s1, s2);
 	}
+	else {
+		b = new_block(BPF_JMP|code|BPF_X);
+	}
 	if (reversed)
 		gen_not(b);

-	sappend(s1, s2);
 	sappend(s0, s1);
 	sappend(a1->s, s0);
 	sappend(a0->s, a1->s);
Index: optimize.c
===================================================================
RCS file: /cvs/NetBSD/basesrc/lib/libpcap/optimize.c,v
retrieving revision 1.13
diff -u -r1.13 optimize.c
--- optimize.c	2001/01/06 02:11:18	1.13
+++ optimize.c	2002/04/24 21:55:22
@@ -585,7 +585,7 @@
 	struct stmt *s;
 	int v0, v1;
 {
-	bpf_int32 a, b;
+	bpf_u_int32 a, b;

 	a = vmap[v0].const_val;
 	b = vmap[v1].const_val;
@@ -669,7 +669,7 @@
 		return;

 	last = s;
-	while (1) {
+	for (;; s = next) {
 		s = this_op(s);
 		if (s == 0)
 			break;
@@ -712,23 +712,23 @@
 			 * any local dependencies.
 			 */
 			if (ATOMELEM(b->out_use, X_ATOM))
-				break;
+				continue;

 			if (next->s.code != (BPF_LDX|BPF_MSH|BPF_B))
 				add = next;
 			else
 				add = this_op(next->next);
 			if (add == 0 || add->s.code != (BPF_ALU|BPF_ADD|BPF_X))
-				break;
+				continue;

 			tax = this_op(add->next);
 			if (tax == 0 || tax->s.code != (BPF_MISC|BPF_TAX))
-				break;
+				continue;

 			ild = this_op(tax->next);
 			if (ild == 0 || BPF_CLASS(ild->s.code) != BPF_LD ||
 			    BPF_MODE(ild->s.code) != BPF_IND)
-				break;
+				continue;
 			/*
 			 * XXX We need to check that X is not
 			 * subsequently used.  We know we can eliminate the
@@ -758,27 +758,21 @@
 			tax->s.code = NOP;
 			done = 0;
 		}
-		s = next;
 	}
 	/*
 	 * If we have a subtract to do a comparison, and the X register
 	 * is a known constant, we can merge this value into the
 	 * comparison.
 	 */
+	if (BPF_OP(b->s.code) == BPF_JEQ) {
+		/* XXX should indent correctly.
+		 * just to make diff small :)
+		 */
 	if (last->s.code == (BPF_ALU|BPF_SUB|BPF_X) &&
 	    !ATOMELEM(b->out_use, A_ATOM)) {
 		val = b->val[X_ATOM];
 		if (vmap[val].is_const) {
-			int op;
-
 			b->s.k += vmap[val].const_val;
-			op = BPF_OP(b->s.code);
-			if (op == BPF_JGT || op == BPF_JGE) {
-				struct block *t = JT(b);
-				JT(b) = JF(b);
-				JF(b) = t;
-				b->s.k += 0x80000000;
-			}
 			last->s.code = NOP;
 			done = 0;
 		} else if (b->s.k == 0) {
@@ -797,19 +791,13 @@
 	 */
 	else if (last->s.code == (BPF_ALU|BPF_SUB|BPF_K) &&
 		 !ATOMELEM(b->out_use, A_ATOM)) {
-		int op;

-		b->s.k += last->s.k;
 		last->s.code = NOP;
-		op = BPF_OP(b->s.code);
-		if (op == BPF_JGT || op == BPF_JGE) {
-			struct block *t = JT(b);
-			JT(b) = JF(b);
-			JF(b) = t;
-			b->s.k += 0x80000000;
-		}
+		b->s.k += last->s.k;
+
 		done = 0;
 	}
+	}
 	/*
 	 * and #k	nop
 	 * jeq #0  ->	jset #k
@@ -988,18 +976,17 @@
 		 * that is 0, and simplify.  This may not seem like
 		 * much of a simplification but it could open up further
 		 * optimizations.
-		 * XXX We could also check for mul by 1, and -1, etc.
+		 * XXX We could also check for mul by 1, etc.
 		 */
 		if (alter && vmap[val[A_ATOM]].is_const
 		    && vmap[val[A_ATOM]].const_val == 0) {
-			if (op == BPF_ADD || op == BPF_OR ||
-			    op == BPF_LSH || op == BPF_RSH || op == BPF_SUB) {
+			if (op == BPF_ADD || op == BPF_OR) {
 				s->code = BPF_MISC|BPF_TXA;
 				vstore(s, &val[A_ATOM], val[X_ATOM], alter);
 				break;
 			}
 			else if (op == BPF_MUL || op == BPF_DIV ||
-				 op == BPF_AND) {
+				 op == BPF_AND || op == BPF_RSH || op == BPF_LSH) {
 				s->code = BPF_LD|BPF_IMM;
 				s->k = 0;
 				vstore(s, &val[A_ATOM], K(s->k), alter);
>Release-Note:
>Audit-Trail:
From: Matthias Drochner <drochner@netbsd.org>
To: gnats-bugs@netbsd.org
Cc: 
Subject: PR/16518 CVS commit: pkgsrc/net/libpcap
Date: Fri, 24 Feb 2006 23:39:44 +0000 (UTC)

 Module Name:	pkgsrc
 Committed By:	drochner
 Date:		Fri Feb 24 23:39:44 UTC 2006

 Modified Files:
 	pkgsrc/net/libpcap: distinfo
 Added Files:
 	pkgsrc/net/libpcap/patches: patch-ae

 Log Message:
 use unsigned ints in filter, to avoid possible portability problems
 with bit shifts,
 this is part of PR lib/16518 by yamt
 (which is filed against base NetBSD sources, but anyway)


 To generate a diff of this commit:
 cvs rdiff -r1.14 -r1.15 pkgsrc/net/libpcap/distinfo
 cvs rdiff -r0 -r1.1 pkgsrc/net/libpcap/patches/patch-ae

 Please note that diffs are not public domain; they are subject to the
 copyright notices on the relevant files.

State-Changed-From-To: open->feedback
State-Changed-By: drochner@netbsd.org
State-Changed-When: Fri, 24 Feb 2006 23:46:38 +0000
State-Changed-Why:
it seems that all your fixes except the unsigned arithmetice have
been applied
I'll request a pullup to stable branches and close the PR if you're
happy with this.


From: Matthias Drochner <drochner@netbsd.org>
To: gnats-bugs@netbsd.org
Cc: 
Subject: PR/16518 CVS commit: src/lib/libpcap
Date: Fri, 24 Feb 2006 23:41:50 +0000 (UTC)

 Module Name:	src
 Committed By:	drochner
 Date:		Fri Feb 24 23:41:50 UTC 2006

 Modified Files:
 	src/lib/libpcap: optimize.c

 Log Message:
 use unsigned ints in filter, to avoid possible portability problems
 with bit shifts,
 this is part of PR lib/16518 by yamt
 (the other concerns in that PR should be solved)


 To generate a diff of this commit:
 cvs rdiff -r1.16 -r1.17 src/lib/libpcap/optimize.c

 Please note that diffs are not public domain; they are subject to the
 copyright notices on the relevant files.

From: YAMAMOTO Takashi <yamt@mwd.biglobe.ne.jp>
To: gnats-bugs@netbsd.org
Cc: lib-bug-people@netbsd.org, netbsd-bugs@netbsd.org,
	gnats-admin@netbsd.org, drochner@netbsd.org
Subject: Re: lib/16518 (some fixes to libpcap)
Date: Sat, 25 Feb 2006 18:39:57 +0900

 > Synopsis: some fixes to libpcap
 > 
 > State-Changed-From-To: open->feedback
 > State-Changed-By: drochner@netbsd.org
 > State-Changed-When: Fri, 24 Feb 2006 23:46:38 +0000
 > State-Changed-Why:
 > it seems that all your fixes except the unsigned arithmetice have
 > been applied
 > I'll request a pullup to stable branches and close the PR if you're
 > happy with this.

 thanks for looking.  but i'm not sure if being different from
 the tcpdump.org version is a good idea.  (it's the reason why the patches
 have not been committed until now.)

 YAMAMOTO Takashi

From: Matthias Drochner <M.Drochner@fz-juelich.de>
To: YAMAMOTO Takashi <yamt@mwd.biglobe.ne.jp>
Cc: gnats-bugs@NetBSD.org, lib-bug-people@NetBSD.org,
	netbsd-bugs@NetBSD.org, gnats-admin@NetBSD.org
Subject: Re: lib/16518 (some fixes to libpcap) 
Date: Sat, 25 Feb 2006 14:28:18 +0100

 yamt@mwd.biglobe.ne.jp said:
 > i'm not sure if being different from the tcpdump.org version is a good
 > idea

 All of your patches went into the tcpdump.org sources and are
 present in 0.9.4. Except that little signed integer bitshift
 portability thing.
 The patches are also present in the NetBSD tree (which is
 at 0.8.3). Partly they were already in the original
 distribution, the rest has been applied later.
 (Except the bitshift thing again.)
 So we are not much different from tcpdump.org in this respect.
 (There are lots of other differences - cleanup, const,
 format strings etc.)

 > it's the reason why the patches have not been committed until now

 Afaict they were committed. (Except the bitshift.)

 best regards
 Matthias


From: YAMAMOTO Takashi <yamt@mwd.biglobe.ne.jp>
To: M.Drochner@fz-juelich.de
Cc: gnats-bugs@NetBSD.org, lib-bug-people@NetBSD.org,
	netbsd-bugs@NetBSD.org, gnats-admin@NetBSD.org
Subject: Re: lib/16518 (some fixes to libpcap) 
Date: Sat, 25 Feb 2006 23:19:50 +0900

 > yamt@mwd.biglobe.ne.jp said:
 > > i'm not sure if being different from the tcpdump.org version is a good
 > > idea
 > 
 > All of your patches went into the tcpdump.org sources and are
 > present in 0.9.4. Except that little signed integer bitshift
 > portability thing.

 portability thing?
 iirc, it was for correct operations, not for portability.

 > The patches are also present in the NetBSD tree (which is
 > at 0.8.3). Partly they were already in the original
 > distribution, the rest has been applied later.
 > (Except the bitshift thing again.)
 > So we are not much different from tcpdump.org in this respect.
 > (There are lots of other differences - cleanup, const,
 > format strings etc.)
 > 
 > > it's the reason why the patches have not been committed until now
 > 
 > Afaict they were committed. (Except the bitshift.)

 i'm talking about the part which hasn't been committed.

 YAMAMOTO Takashi

From: Matthias Drochner <M.Drochner@fz-juelich.de>
To: YAMAMOTO Takashi <yamt@mwd.biglobe.ne.jp>
Cc: gnats-bugs@NetBSD.org, lib-bug-people@NetBSD.org,
	netbsd-bugs@NetBSD.org, gnats-admin@NetBSD.org
Subject: Re: lib/16518 (some fixes to libpcap) 
Date: Sat, 25 Feb 2006 16:16:27 +0100

 yamt@mwd.biglobe.ne.jp said:
 > portability thing? iirc, it was for correct operations, not for
 > portability. 

 OK, I see that there is another case where the signed/unsigned
 makes a difference: division.
 So you are right, it is not just about the ">>" portability.

 Well, the documentation isn't clear in this respect:
 At one point it says:
   P[i:n] gives the data at byte offset
   ``i'' in the packet, interpreted as a word (n=4), unsigned halfword (n=2),
   or unsigned byte (n=1).
 The halfword and byte are explicitely unsigned, the "word" not.
 This might however not refer to arithmetics but just to the fact
 that no sign extension happens when a shorter value is loaded
 into the accumulator.
 There is also the BPF_NEG which wouldn't make much sense in a
 strictly unsigned world.
 Otoh, since the kernel does unsigned arithmetics and has always
 done, I'd definitely expect that the userland filter behaves
 identically.
 I somehow believe that almost noone does arithmetics on values
 which use up the 32 bits, let alone division. That's why
 noone really cares...

 best regards
 Matthias


From: YAMAMOTO Takashi <yamt@mwd.biglobe.ne.jp>
To: M.Drochner@fz-juelich.de
Cc: gnats-bugs@NetBSD.org, lib-bug-people@NetBSD.org,
	netbsd-bugs@NetBSD.org, gnats-admin@NetBSD.org
Subject: Re: lib/16518 (some fixes to libpcap) 
Date: Sun, 26 Feb 2006 00:47:39 +0900

 > yamt@mwd.biglobe.ne.jp said:
 > > portability thing? iirc, it was for correct operations, not for
 > > portability. 
 > 
 > OK, I see that there is another case where the signed/unsigned
 > makes a difference: division.
 > So you are right, it is not just about the ">>" portability.
 > 
 > Well, the documentation isn't clear in this respect:
 > At one point it says:
 >   P[i:n] gives the data at byte offset
 >   ``i'' in the packet, interpreted as a word (n=4), unsigned halfword (n=2),
 >   or unsigned byte (n=1).
 > The halfword and byte are explicitely unsigned, the "word" not.
 > This might however not refer to arithmetics but just to the fact
 > that no sign extension happens when a shorter value is loaded
 > into the accumulator.
 > There is also the BPF_NEG which wouldn't make much sense in a
 > strictly unsigned world.
 > Otoh, since the kernel does unsigned arithmetics and has always
 > done, I'd definitely expect that the userland filter behaves
 > identically.
 > I somehow believe that almost noone does arithmetics on values
 > which use up the 32 bits, let alone division. That's why
 > noone really cares...

 yea, the fundamental problem is that the definition of filter program
 language is somewhat vague about signedness.  the part of patch was
 dropped because the tcpdump.org guy who handled the patch (itojun)
 was not sure which of signed or unsigned should be used.
 (see "Re: some fixes for complier and optimizer in libpcap" mails
 on tcpdump-workers around June 2002)

 i guess it's better to bring a discussion on tcpdump-workers again
 and try to fix the problem in their repository first, rather than just
 being different from their version.

 YAMAMOTO Takashi

From: Matthias Drochner <M.Drochner@fz-juelich.de>
To: YAMAMOTO Takashi <yamt@mwd.biglobe.ne.jp>
Cc: gnats-bugs@NetBSD.org, lib-bug-people@NetBSD.org,
	netbsd-bugs@NetBSD.org, gnats-admin@NetBSD.org
Subject: Re: lib/16518 (some fixes to libpcap) 
Date: Mon, 27 Feb 2006 14:34:10 +0100

 yamt@mwd.biglobe.ne.jp said:
 > was not sure which of signed or unsigned should be used.

 For me it is pretty obvious that unsigned should be used,
 to be consistent with kernel behaviour. While the manpage
 doesn't tell, the kernel implementations are there and
 cannot be changed anymore, just documented.

 > see "Re: some fixes for complier and optimizer in libpcap" mails
 > on tcpdump-workers around June 2002

 The issues broght up there are unrelated afaict: Your patch
 is just about the operators in arithmetics. It doesn't
 affect comparisions. (The wrong optimisation of "1>1" was
 fixed by another patch which went into mainstream sources.
 And why ">"/"<" are not optimized rather than correctly optimized
 now is also another issue. "=" is optimized appearently, see below.)
 And assignments from singed to unsigned int32 values don't
 change anything -- that's more a "lint" issue.

 Just to illustrate things a bit:
 The filter expression "(0x80000000 / 2) > 0x40000000", if not
 optimized, leads to code which rejects everything, because the
 kernel evaluates this to "0x40000000 > 0x40000000".
 With (unpatched) optimization, the resulting program is:
 (000) ld       #0xc0000000
 (001) ldx      #0x40000000
 (002) jgt      x                jt 3    jf 4
 (003) ret      #96
 (004) ret      #0
 which accepts everything.
 Optimization of "=" gets a bit further -- a call of
 tcpdump "(0x80000000 / 2) = 0x40000000"
 does yield
 tcpdump: expression rejects all packets
 while
 tcpdump -O "(0x80000000 / 2) = 0x40000000"
 happily receives packets.

 Your patch fixes exactly these inconsistencies.
 Just to be sure, I'm talking about
 @@ -624,7 +624,7 @@ fold_op(s, v0, v1)
         struct stmt *s;
         int v0, v1;
  {
 -       bpf_int32 a, b;
 +       bpf_u_int32 a, b;

         a = vmap[v0].const_val;
         b = vmap[v1].const_val;

 > i guess it's better to bring a discussion on tcpdump-workers again

 This might be a good idea. Do you want to defent your patch once more?
 I'm just working on an update of NetBSD's libpcap to 0.9.4, and I plan
 to post the more essential changes to tcpdump-workers too.
 (Which is merely some "const" consistency for now, and support for
 the cloning /dev/bpf.)

 > try to fix the problem in their repository first

 We have local changes anyway, so I wouldn't wait if it is fixing
 a bug. And an optimizer changing the effect of code is a bug.
 (Even if only practically useless code is affected...)

 best regards
 Matthias


From: YAMAMOTO Takashi <yamt@mwd.biglobe.ne.jp>
To: M.Drochner@fz-juelich.de
Cc: gnats-bugs@NetBSD.org, lib-bug-people@NetBSD.org,
	netbsd-bugs@NetBSD.org, gnats-admin@NetBSD.org
Subject: Re: lib/16518 (some fixes to libpcap) 
Date: Tue, 28 Feb 2006 08:18:45 +0900

 > yamt@mwd.biglobe.ne.jp said:
 > > was not sure which of signed or unsigned should be used.
 > 
 > For me it is pretty obvious that unsigned should be used,
 > to be consistent with kernel behaviour. While the manpage
 > doesn't tell, the kernel implementations are there and
 > cannot be changed anymore, just documented.

 to be consistent with kernel, yes.  i thought so and made the patch.
 i still support the "fix libpcap optimizer to match to kernel" way.

 but if it's considered a kernel bug, we can fix kernel implementations, IMO.
 see below.

 > Optimization of "=" gets a bit further -- a call of
 > tcpdump "(0x80000000 / 2) = 0x40000000"
 > does yield
 > tcpdump: expression rejects all packets
 > while
 > tcpdump -O "(0x80000000 / 2) = 0x40000000"
 > happily receives packets.
 > 
 > Your patch fixes exactly these inconsistencies.

 sure.

 but, if it was "(-10)/2 == -5", one might think it's natural to
 optimize it to TRUE, and consider it as a kernel bug.
 given the lack of strict specification of the language, i couldn't say
 which was correct.

 > > i guess it's better to bring a discussion on tcpdump-workers again
 > 
 > This might be a good idea. Do you want to defent your patch once more?

 honestly speaking, i don't, as my memory about libpcap and
 the patch is somewhat stale...  i'm happy if you just beat me. :-)

 > I'm just working on an update of NetBSD's libpcap to 0.9.4, and I plan
 > to post the more essential changes to tcpdump-workers too.
 > (Which is merely some "const" consistency for now, and support for
 > the cloning /dev/bpf.)

 great.

 YAMAMOTO Takashi

From: Matthias Drochner <M.Drochner@fz-juelich.de>
To: YAMAMOTO Takashi <yamt@mwd.biglobe.ne.jp>
Cc: gnats-bugs@NetBSD.org, lib-bug-people@NetBSD.org,
	netbsd-bugs@NetBSD.org, gnats-admin@NetBSD.org
Subject: Re: lib/16518 (some fixes to libpcap) 
Date: Tue, 28 Feb 2006 14:17:39 +0100

 yamt@mwd.biglobe.ne.jp said:
 > if it's considered a kernel bug, we can fix kernel implementations

 I don't think this is realistic. The kernel code used unsigned
 all the time, and it was imported into x operating systems.
 (I'd say signed would feel a bit more "natural", but then
 we would need at least need "signed loads" of bytes/shorts,
 or perhaps explicite "sign extend" operations to make it useful.)

 > if it was "(-10)/2 == -5", one might think it's natural to
 > optimize it to TRUE

 Hmm, this would open the way to much more confusion:
 "(-10)/2 > -6" would have to be FALSE because comparisions
 are explicitely unsigned and documented to be so at all places.
 (Well, 2 places I know of: the pcap manpage and the section
 about expressions in tcpdump's.)
 Imho the only way to be consistent is to state that all
 operations are unsigned and that "-X" is just a shortcut
 for "~X + 1".

 > > bring a discussion on tcpdump-workers
 > i'm happy if you just beat me

 I might do so... I'm currently planning for next week and
 it might well happen that I'm AFK all the time.
 It might take some time.

 best regards
 Matthias


From: Matthias Drochner <M.Drochner@fz-juelich.de>
To: YAMAMOTO Takashi <yamt@mwd.biglobe.ne.jp>
Cc: gnats-bugs@NetBSD.org, lib-bug-people@NetBSD.org,
	netbsd-bugs@NetBSD.org, gnats-admin@NetBSD.org
Subject: Re: lib/16518 (some fixes to libpcap) 
Date: Tue, 28 Feb 2006 14:50:38 +0100

 M.Drochner@fz-juelich.de said:
 > "(-10)/2 > -6" would have to be FALSE

 Sorry, wrong example, a good one is eg.:
  "(-10)/2 > 0" would have to be TRUE

 best regards
 Matthias


State-Changed-From-To: feedback->open
State-Changed-By: yamt@netbsd.org
State-Changed-When: Tue, 20 Feb 2007 05:23:33 +0000
State-Changed-Why:
feedback provided.


>Unformatted:

NetBSD Home
NetBSD PR Database Search

(Contact us) $NetBSD: query-full-pr,v 1.39 2013/11/01 18:47:49 spz Exp $
$NetBSD: gnats_config.sh,v 1.8 2006/05/07 09:23:38 tsutsui Exp $
Copyright © 1994-2007 The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.