From patchwork Fri Jan 15 16:51:15 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hannes Frederic Sowa X-Patchwork-Id: 568224 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id A2E8E140C4B for ; Sat, 16 Jan 2016 03:51:28 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=stressinduktion.org header.i=@stressinduktion.org header.b=GKB9ts9X; dkim=pass (1024-bit key; unprotected) header.d=messagingengine.com header.i=@messagingengine.com header.b=GIolvKEL; dkim-atps=neutral Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754730AbcAOQvY (ORCPT ); Fri, 15 Jan 2016 11:51:24 -0500 Received: from out5-smtp.messagingengine.com ([66.111.4.29]:46976 "EHLO out5-smtp.messagingengine.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753421AbcAOQvX (ORCPT ); Fri, 15 Jan 2016 11:51:23 -0500 Received: from compute1.internal (compute1.nyi.internal [10.202.2.41]) by mailout.nyi.internal (Postfix) with ESMTP id D143920426 for ; Fri, 15 Jan 2016 11:51:22 -0500 (EST) Received: from frontend1 ([10.202.2.160]) by compute1.internal (MEProxy); Fri, 15 Jan 2016 11:51:22 -0500 DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d= stressinduktion.org; h=cc:date:from:message-id:subject:to :x-sasl-enc:x-sasl-enc; s=mesmtp; bh=jfxGrBALA5wE3FbfA41gHkwWluQ =; b=GKB9ts9Xrjzz0IT7VEAofFHWPsjAFjOsdP98qBtKPFOvzbaB5AiyUFhRf1B tCac57jb65w/AcEUwEKPmlJ+0xQJ8vJaF90F+eh2HcRa4+I5afHz70b5GQ40UDR8 7f+iGwSbHW+fJKn0J9CvsbG0otT/fWvEV9LUjj41qCSKre2A= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d= messagingengine.com; h=cc:date:from:message-id:subject:to :x-sasl-enc:x-sasl-enc; s=smtpout; bh=jfxGrBALA5wE3FbfA41gHkwWlu Q=; b=GIolvKELdLQk5XdpOYjryL+tIbLbTNoNFkLeIp63G5GUkHcJ8NgHjFESKR 78oTaTbXBiHTGVhMkn3O6uLWJ2FAMr70WFH08z1+vW1u+WGq6EAhHGxKDzARoSGA cC4NkA/edICLokk5ry8AufDpsRBdfDDPgwWzEx1OxDh8A2ecM= X-Sasl-enc: XL6sQ3dDBiwNEuUsBEj7CmsD//i4LaEET4szWqZ5VQJi 1452876682 Received: from z.localhost.localdomain (unknown [213.55.184.142]) by mail.messagingengine.com (Postfix) with ESMTPA id 9E8DDC00017; Fri, 15 Jan 2016 11:51:21 -0500 (EST) From: Hannes Frederic Sowa To: netdev@vger.kernel.org Cc: Pravin Shelar , Simon Horman , Eric Dumazet Subject: [PATCH net v4] ovs: limit ovs recursions in ovs_execute_actions to not corrupt stack Date: Fri, 15 Jan 2016 17:51:15 +0100 Message-Id: <1452876675-19834-1-git-send-email-hannes@stressinduktion.org> X-Mailer: git-send-email 2.5.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org It was seen that defective configurations of openvswitch could overwrite the STACK_END_MAGIC and cause a hard crash of the kernel because of too many recursions within ovs. This problem arises due to the high stack usage of openvswitch. The rest of the kernel is fine with the current limit of 10 (RECURSION_LIMIT). We use the already existing recursion counter in ovs_execute_actions to implement an upper bound of 5 recursions. Cc: Pravin Shelar Cc: Simon Horman Cc: Eric Dumazet Signed-off-by: Hannes Frederic Sowa Reviewed-by: Simon Horman --- v2) added preemption guards v3) Pravin suggested to reuse the ovs_execute_actions counter which this patch does. Also only allow 5 recursions as suggested by Pravin. v4) added unlikely as suggested by Eric Thanks to all reviewers! net/openvswitch/actions.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c index c88d0f2d3e019b..da66f9e1660dbb 100644 --- a/net/openvswitch/actions.c +++ b/net/openvswitch/actions.c @@ -1160,17 +1160,28 @@ int ovs_execute_actions(struct datapath *dp, struct sk_buff *skb, const struct sw_flow_actions *acts, struct sw_flow_key *key) { - int level = this_cpu_read(exec_actions_level); - int err; + static const int ovs_recursion_limit = 5; + int err, level; + + preempt_disable(); + level = __this_cpu_inc_return(exec_actions_level); + if (unlikely(level > ovs_recursion_limit)) { + net_crit_ratelimited("ovs: recursion limit reached on datapath %s, probable configuration error\n", + ovs_dp_name(dp)); + kfree_skb(skb); + err = -ENETDOWN; + goto out; + } - this_cpu_inc(exec_actions_level); err = do_execute_actions(dp, skb, key, acts->actions, acts->actions_len); - if (!level) + if (level == 1) process_deferred_actions(dp); - this_cpu_dec(exec_actions_level); +out: + __this_cpu_dec(exec_actions_level); + preempt_enable(); return err; }