Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 27922b4260f65d317aabda37e42bbbff > files > 2631

kernel-2.6.18-238.el5.src.rpm

From: Jarod Wilson <jarod@redhat.com>
Date: Wed, 1 Dec 2010 16:17:40 -0500
Subject: [net] filter: fix backport error in prior filter fix
Message-id: <20101201161740.GA28647@redhat.com>
Patchwork-id: 29766
O-Subject: Re: [RHEL5.6 patch] BZ651703 CVE-2010-4158 net: filter: make sure
	filters dont read uninitialized memory
Bugzilla: 651703

On Wed, Nov 24, 2010 at 05:24:16PM +0100, Jiri Pirko wrote:
> BZ651703
> https://bugzilla.redhat.com/show_bug.cgi?id=651703
>
> Description:
> There is a possibility malicious users can get limited information about
> uninitialized stack mem array. Even if sk_run_filter() result is bound
> to packet length (0 .. 65535), we could imagine this can be used by
> hostile user.
>
> Initializing mem[] array, like Dan Rosenberg suggested in his patch is
> expensive since most filters dont even use this array.
>
> Its hard to make the filter validation in sk_chk_filter(), because of
> the jumps. This might be done later.
>
> In this patch, I use a bitmap (a single long var) so that only filters
> using mem[] loads/stores pay the price of added security checks.
>
> For other filters, additional cost is a single instruction.
>
> [ Since we access fentry->k a lot now, cache it in a local variable
>   and mark filter entry pointer as const. -DaveM ]
>
> Upstream:
> http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=57fe93b374a6b8711995c2d466c502af9f3a08bb
>
> Brew:
> https://brewweb.devel.redhat.com/taskinfo?taskID=2911659
>
> Tested with bz-referenced reproducer
>
> Jirka
>
> Signed-off-by: Jiri Pirko <jpirko@redhat.com>
>
> diff --git a/net/core/filter.c b/net/core/filter.c
> index 5b4486a..2f11521 100644
> --- a/net/core/filter.c
> +++ b/net/core/filter.c
> @@ -77,39 +77,41 @@ static inline void *load_pointer(struct sk_buff *skb, int k,
>   */
>  unsigned int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int flen)
>  {
> -	struct sock_filter *fentry;	/* We walk down these */
>  	void *ptr;
>  	u32 A = 0;			/* Accumulator */
>  	u32 X = 0;			/* Index Register */
>  	u32 mem[BPF_MEMWORDS];		/* Scratch Memory Store */
> +	unsigned long memvalid = 0;
>  	u32 tmp;
>  	int k;
>  	int pc;
>
> +	BUILD_BUG_ON(BPF_MEMWORDS > BITS_PER_LONG);
>  	/*
>  	 * Process array of filter instructions.
>  	 */
>  	for (pc = 0; pc < flen; pc++) {
> -		fentry = &filter[pc];
> -
> +		const struct sock_filter *fentry = &filter[pc];
> +		u32 f_k = f_k;
> +

There's a bit of a brown paper bag bug that managed to slip past reviewers
(and which I should have picked up on sooner, but I blame missing it on
the holiday and being sick). That should be u32 f_k = fentry->k; there. As
it is now, bridge interfaces are unable to acquire IP addresses, and thus
all kvm testing in rhts is failing. Obvious one-line patch (which matches
upstream) to fix it, which we've verified in rhts:


diff --git a/net/core/filter.c b/net/core/filter.c
index 2f11521..dcdae0c 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -92,7 +92,7 @@ unsigned int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int
 	 */
 	for (pc = 0; pc < flen; pc++) {
 		const struct sock_filter *fentry = &filter[pc];
-		u32 f_k = f_k;
+		u32 f_k = fentry->k;
 
 		switch (fentry->code) {
 		case BPF_ALU|BPF_ADD|BPF_X: