Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933207AbbDIIxN (ORCPT ); Thu, 9 Apr 2015 04:53:13 -0400 Received: from mail.kernel.org ([198.145.29.136]:41752 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755110AbbDIIxG (ORCPT ); Thu, 9 Apr 2015 04:53:06 -0400 From: lizf@kernel.org To: stable@vger.kernel.org Cc: linux-kernel@vger.kernel.org, Jan Kara , Zefan Li Subject: [PATCH 3.4 066/176] isofs: Fix infinite looping over CE entries Date: Thu, 9 Apr 2015 16:45:14 +0800 Message-Id: <1428569224-23820-66-git-send-email-lizf@kernel.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1428569028-23762-1-git-send-email-lizf@kernel.org> References: <1428569028-23762-1-git-send-email-lizf@kernel.org> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 1897 Lines: 64 From: Jan Kara 3.4.107-rc1 review patch. If anyone has any objections, please let me know. ------------------ commit f54e18f1b831c92f6512d2eedb224cd63d607d3d upstream. Rock Ridge extensions define so called Continuation Entries (CE) which define where is further space with Rock Ridge data. Corrupted isofs image can contain arbitrarily long chain of these, including a one containing loop and thus causing kernel to end in an infinite loop when traversing these entries. Limit the traversal to 32 entries which should be more than enough space to store all the Rock Ridge data. Reported-by: P J P Signed-off-by: Jan Kara Signed-off-by: Zefan Li --- fs/isofs/rock.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/fs/isofs/rock.c b/fs/isofs/rock.c index ee62cc0..26859de 100644 --- a/fs/isofs/rock.c +++ b/fs/isofs/rock.c @@ -30,6 +30,7 @@ struct rock_state { int cont_size; int cont_extent; int cont_offset; + int cont_loops; struct inode *inode; }; @@ -73,6 +74,9 @@ static void init_rock_state(struct rock_state *rs, struct inode *inode) rs->inode = inode; } +/* Maximum number of Rock Ridge continuation entries */ +#define RR_MAX_CE_ENTRIES 32 + /* * Returns 0 if the caller should continue scanning, 1 if the scan must end * and -ve on error. @@ -105,6 +109,8 @@ static int rock_continue(struct rock_state *rs) goto out; } ret = -EIO; + if (++rs->cont_loops >= RR_MAX_CE_ENTRIES) + goto out; bh = sb_bread(rs->inode->i_sb, rs->cont_extent); if (bh) { memcpy(rs->buffer, bh->b_data + rs->cont_offset, -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/