Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752583AbdG1PMq (ORCPT ); Fri, 28 Jul 2017 11:12:46 -0400 Received: from mail-oi0-f43.google.com ([209.85.218.43]:35850 "EHLO mail-oi0-f43.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752566AbdG1PMp (ORCPT ); Fri, 28 Jul 2017 11:12:45 -0400 MIME-Version: 1.0 In-Reply-To: <1501241408-19129-1-git-send-email-yujuan.qi@mediatek.com> References: <1501241408-19129-1-git-send-email-yujuan.qi@mediatek.com> From: Paul Moore Date: Fri, 28 Jul 2017 11:12:43 -0400 Message-ID: Subject: Re: [PATCH] Cipso: cipso_v4_optptr enter infinite loop To: Yujuan Qi Cc: "David S. Miller" , Casey Schaufler , netdev@vger.kernel.org, linux-mediatek@lists.infradead.org, linux-kernel@vger.kernel.org, Ryder Lee Content-Type: text/plain; charset="UTF-8" Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 1593 Lines: 50 On Fri, Jul 28, 2017 at 7:30 AM, Yujuan Qi wrote: > From: "yujuan.qi" > > in for(),if((optlen > 0) && (optptr[1] == 0)), enter infinite loop. > > Test: receive a packet which the ip length > 20 and the first byte of ip option is 0, produce this issue > > Signed-off-by: yujuan.qi > --- > net/ipv4/cipso_ipv4.c | 2 ++ > 1 file changed, 2 insertions(+) > > diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c > index ae20616..b3d97c7 100644 > --- a/net/ipv4/cipso_ipv4.c > +++ b/net/ipv4/cipso_ipv4.c > @@ -1528,6 +1528,8 @@ unsigned char *cipso_v4_optptr(const struct sk_buff *skb) > taglen = optptr[1]; > optlen -= taglen; > optptr += taglen; > + if (!taglen) > + break; > } > > return NULL; Thanks for catching this and submitting a patch. Unfortunately checking taglen/optptr[1] isn't going to help with the NOP and EOL options as they are single byte options. I think a for-loop like the following, or something similar, is probably the better solution: for (optlen = iph->ihl*4 - sizeof(struct iphdr); optlen > 0; ) { switch (optptr[0]) { case IPOPT_CIPSO: return optptr; case IPOPT_END: return NULL; case IPOPT_NOOP: taglen = 1; break; default: taglen = optptr[1]; } optlen -= taglen; optptr += taglen; } -- paul moore security @ redhat