lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20190418160436.689944333@linuxfoundation.org>
Date:   Thu, 18 Apr 2019 19:57:32 +0200
From:   Greg Kroah-Hartman <gregkh@...uxfoundation.org>
To:     linux-kernel@...r.kernel.org
Cc:     Greg Kroah-Hartman <gregkh@...uxfoundation.org>,
        stable@...r.kernel.org, Alexei Starovoitov <ast@...com>,
        "David S. Miller" <davem@...emloft.net>,
        Balbir Singh <sblbir@...n.com>
Subject: [PATCH 4.14 74/92] bpf: fix verifier memory leaks

From: Alexei Starovoitov <ast@...com>

commit 1969db47f8d0e800397abd4ee4e8d27d2b578587 upstream.

fix verifier memory leaks

Fixes: 638f5b90d460 ("bpf: reduce verifier memory consumption")
Signed-off-by: Alexei Starovoitov <ast@...com>
Signed-off-by: David S. Miller <davem@...emloft.net>
Signed-off-by: Balbir Singh <sblbir@...n.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@...uxfoundation.org>
---
 kernel/bpf/verifier.c |   27 ++++++++++++++++++---------
 1 file changed, 18 insertions(+), 9 deletions(-)

--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -491,10 +491,12 @@ static int realloc_verifier_state(struct
 	return 0;
 }
 
-static void free_verifier_state(struct bpf_verifier_state *state)
+static void free_verifier_state(struct bpf_verifier_state *state,
+				bool free_self)
 {
 	kfree(state->stack);
-	kfree(state);
+	if (free_self)
+		kfree(state);
 }
 
 /* copy verifier state from src to dst growing dst stack space
@@ -532,6 +534,7 @@ static int pop_stack(struct bpf_verifier
 	if (prev_insn_idx)
 		*prev_insn_idx = head->prev_insn_idx;
 	elem = head->next;
+	free_verifier_state(&head->st, false);
 	kfree(head);
 	env->head = elem;
 	env->stack_size--;
@@ -549,14 +552,14 @@ static struct bpf_verifier_state *push_s
 	if (!elem)
 		goto err;
 
-	err = copy_verifier_state(&elem->st, cur);
-	if (err)
-		return NULL;
 	elem->insn_idx = insn_idx;
 	elem->prev_insn_idx = prev_insn_idx;
 	elem->next = env->head;
 	env->head = elem;
 	env->stack_size++;
+	err = copy_verifier_state(&elem->st, cur);
+	if (err)
+		goto err;
 	if (env->stack_size > BPF_COMPLEXITY_LIMIT_STACK) {
 		verbose("BPF program is too complex\n");
 		goto err;
@@ -3812,7 +3815,7 @@ static int is_state_visited(struct bpf_v
 	struct bpf_verifier_state_list *new_sl;
 	struct bpf_verifier_state_list *sl;
 	struct bpf_verifier_state *cur = env->cur_state;
-	int i;
+	int i, err;
 
 	sl = env->explored_states[insn_idx];
 	if (!sl)
@@ -3850,7 +3853,12 @@ static int is_state_visited(struct bpf_v
 		return -ENOMEM;
 
 	/* add new state to the head of linked list */
-	copy_verifier_state(&new_sl->state, cur);
+	err = copy_verifier_state(&new_sl->state, cur);
+	if (err) {
+		free_verifier_state(&new_sl->state, false);
+		kfree(new_sl);
+		return err;
+	}
 	new_sl->next = env->explored_states[insn_idx];
 	env->explored_states[insn_idx] = new_sl;
 	/* connect new state to parentage chain */
@@ -4692,6 +4700,7 @@ static void free_states(struct bpf_verif
 		if (sl)
 			while (sl != STATE_LIST_MARK) {
 				sln = sl->next;
+				free_verifier_state(&sl->state, false);
 				kfree(sl);
 				sl = sln;
 			}
@@ -4768,7 +4777,7 @@ int bpf_check(struct bpf_prog **prog, un
 	env->allow_ptr_leaks = capable(CAP_SYS_ADMIN);
 
 	ret = do_check(env);
-	free_verifier_state(env->cur_state);
+	free_verifier_state(env->cur_state, true);
 	env->cur_state = NULL;
 
 skip_full_check:
@@ -4878,7 +4887,7 @@ int bpf_analyzer(struct bpf_prog *prog,
 	env->allow_ptr_leaks = capable(CAP_SYS_ADMIN);
 
 	ret = do_check(env);
-	free_verifier_state(env->cur_state);
+	free_verifier_state(env->cur_state, true);
 	env->cur_state = NULL;
 
 skip_full_check:


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ