From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753824AbdBPAeI (ORCPT ); Wed, 15 Feb 2017 19:34:08 -0500 Received: from shadbolt.e.decadent.org.uk ([88.96.1.126]:52255 "EHLO shadbolt.e.decadent.org.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752324AbdBOWvO (ORCPT ); Wed, 15 Feb 2017 17:51:14 -0500 Content-Type: text/plain; charset="UTF-8" Content-Disposition: inline Content-Transfer-Encoding: 8bit MIME-Version: 1.0 From: Ben Hutchings To: linux-kernel@vger.kernel.org, stable@vger.kernel.org CC: akpm@linux-foundation.org, "Richard Weinberger" Date: Wed, 15 Feb 2017 22:41:34 +0000 Message-ID: X-Mailer: LinuxStableQueue (scripts by bwh) Subject: [PATCH 3.2 047/126] ubifs: Abort readdir upon error In-Reply-To: X-SA-Exim-Connect-IP: 2a02:8011:400e:2:6f00:88c8:c921:d332 X-SA-Exim-Mail-From: ben@decadent.org.uk X-SA-Exim-Scanned: No (on shadbolt.decadent.org.uk); SAEximRunCond expanded to false Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 3.2.85-rc1 review patch. If anyone has any objections, please let me know. ------------------ From: Richard Weinberger commit c83ed4c9dbb358b9e7707486e167e940d48bfeed upstream. If UBIFS is facing an error while walking a directory, it reports this error and ubifs_readdir() returns the error code. But the VFS readdir logic does not make the getdents system call fail in all cases. When the readdir cursor indicates that more entries are present, the system call will just return and the libc wrapper will try again since it also knows that more entries are present. This causes the libc wrapper to busy loop for ever when a directory is corrupted on UBIFS. A common approach do deal with corrupted directory entries is skipping them by setting the cursor to the next entry. On UBIFS this approach is not possible since we cannot compute the next directory entry cursor position without reading the current entry. So all we can do is setting the cursor to the "no more entries" position and make getdents exit. Signed-off-by: Richard Weinberger [bwh: Backported to 3.2: adjust context] Signed-off-by: Ben Hutchings --- --- a/fs/ubifs/dir.c +++ b/fs/ubifs/dir.c @@ -356,7 +356,7 @@ static unsigned int vfs_dent_type(uint8_ */ static int ubifs_readdir(struct file *file, void *dirent, filldir_t filldir) { - int err, over = 0; + int err = 0, over = 0; loff_t pos = file->f_pos; struct qstr nm; union ubifs_key key; @@ -475,16 +475,14 @@ static int ubifs_readdir(struct file *fi } out: - if (err != -ENOENT) { + if (err != -ENOENT) ubifs_err("cannot find next direntry, error %d", err); - return err; - } kfree(file->private_data); file->private_data = NULL; /* 2 is a special value indicating that there are no more direntries */ file->f_pos = 2; - return 0; + return err; } static loff_t ubifs_dir_llseek(struct file *file, loff_t offset, int origin)