Blob Blame History Raw
From 584ca9f67952162dfdd02d984aa12640e45a4235 Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Wed, 6 Sep 2017 11:53:53 +0200
Subject: [PATCH] lib/bpf: Fix bytecode-file parsing

Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1477491
Upstream Status: iproute2.git commit 7c87c7fed18d1

commit 7c87c7fed18d1162e045c8331cb68fa440bc5728
Author: Phil Sutter <phil@nwl.cc>
Date:   Tue Aug 29 17:09:45 2017 +0200

    lib/bpf: Fix bytecode-file parsing

    The signedness of char type is implementation dependent, and there are
    architectures on which it is unsigned by default. In that case, the
    check whether fgetc() returned EOF failed because the return value was
    assigned an (unsigned) char variable prior to comparison with EOF (which
    is defined to -1). Fix this by using int as type for 'c' variable, which
    also matches the declaration of fgetc().

    While being at it, fix the parser logic to correctly handle multiple
    empty lines and consecutive whitespace and tab characters to further
    improve the parser's robustness. Note that this will still detect double
    separator characters, so doesn't soften up the parser too much.

    Fixes: 3da3ebfca85b8 ("bpf: Make bytecode-file reading a little more robust")
    Cc: Daniel Borkmann <daniel@iogearbox.net>
    Signed-off-by: Phil Sutter <phil@nwl.cc>
    Acked-by: Daniel Borkmann <daniel@iogearbox.net>
---
 lib/bpf.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/lib/bpf.c b/lib/bpf.c
index 73dac5c..3aabf44 100644
--- a/lib/bpf.c
+++ b/lib/bpf.c
@@ -160,8 +160,9 @@ static int bpf_parse_string(char *arg, bool from_file, __u16 *bpf_len,
 
 	if (from_file) {
 		size_t tmp_len, op_len = sizeof("65535 255 255 4294967295,");
-		char *tmp_string, *pos, c, c_prev = ' ';
+		char *tmp_string, *pos, c_prev = ' ';
 		FILE *fp;
+		int c;
 
 		tmp_len = sizeof("4096,") + BPF_MAXINSNS * op_len;
 		tmp_string = pos = calloc(1, tmp_len);
@@ -180,18 +181,20 @@ static int bpf_parse_string(char *arg, bool from_file, __u16 *bpf_len,
 			case '\n':
 				if (c_prev != ',')
 					*(pos++) = ',';
+				c_prev = ',';
 				break;
 			case ' ':
 			case '\t':
 				if (c_prev != ' ')
 					*(pos++) = c;
+				c_prev = ' ';
 				break;
 			default:
 				*(pos++) = c;
+				c_prev = c;
 			}
 			if (pos - tmp_string == tmp_len)
 				break;
-			c_prev = c;
 		}
 
 		if (!feof(fp)) {
-- 
1.8.3.1