From patchwork Wed Dec 11 11:22:06 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wang Shilong X-Patchwork-Id: 3325131 Return-Path: X-Original-To: patchwork-linux-btrfs@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 1412A9F1F0 for ; Wed, 11 Dec 2013 11:23:20 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 9424920607 for ; Wed, 11 Dec 2013 11:23:18 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id BA71F205F5 for ; Wed, 11 Dec 2013 11:23:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751510Ab3LKLXN (ORCPT ); Wed, 11 Dec 2013 06:23:13 -0500 Received: from cn.fujitsu.com ([222.73.24.84]:3218 "EHLO song.cn.fujitsu.com" rhost-flags-OK-FAIL-OK-OK) by vger.kernel.org with ESMTP id S1751172Ab3LKLXM (ORCPT ); Wed, 11 Dec 2013 06:23:12 -0500 X-IronPort-AV: E=Sophos;i="4.93,871,1378828800"; d="scan'208";a="9237322" Received: from unknown (HELO tang.cn.fujitsu.com) ([10.167.250.3]) by song.cn.fujitsu.com with ESMTP; 11 Dec 2013 19:19:04 +0800 Received: from fnstmail02.fnst.cn.fujitsu.com (tang.cn.fujitsu.com [127.0.0.1]) by tang.cn.fujitsu.com (8.14.3/8.13.1) with ESMTP id rBBBMYPn008593 for ; Wed, 11 Dec 2013 19:22:34 +0800 Received: from wangs.fnst.cn.fujitsu.com ([10.167.226.104]) by fnstmail02.fnst.cn.fujitsu.com (Lotus Domino Release 8.5.3) with ESMTP id 2013121119221661-351287 ; Wed, 11 Dec 2013 19:22:16 +0800 From: Wang Shilong To: linux-btrfs@vger.kernel.org Subject: [PATCH] Btrfs-progs: make sure we are not opening a block device in open_file_or_dir() Date: Wed, 11 Dec 2013 19:22:06 +0800 Message-Id: <1386760926-4181-1-git-send-email-wangsl.fnst@cn.fujitsu.com> X-Mailer: git-send-email 1.8.3.1 X-MIMETrack: Itemize by SMTP Server on mailserver/fnst(Release 8.5.3|September 15, 2011) at 2013/12/11 19:22:16, Serialize by Router on mailserver/fnst(Release 8.5.3|September 15, 2011) at 2013/12/11 19:22:16, Serialize complete at 2013/12/11 19:22:16 Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org X-Spam-Status: No, score=-7.1 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Now, open_file_or_dir() will return successfully if we pass a block device for it, this is wrong, we should check if it is a block device before trying to open it. Before this patch: # btrfs sub list /dev/sda8 It will output the following message: ERROR: can't perform the search -Inappropriate ioctl for device ERROR: can't get rootid for '/dev/sda8 After applying the patch, it will output: ERROR: can't access '/dev/sda8' Signed-off-by: Wang Shilong --- utils.c | 50 ++++++++++++++++++++++++++++---------------------- 1 file changed, 28 insertions(+), 22 deletions(-) diff --git a/utils.c b/utils.c index f499023..1c168e2 100644 --- a/utils.c +++ b/utils.c @@ -755,6 +755,31 @@ out: return ret; } +static int __open_file_or_dir(const char *fname, DIR **dirstream) +{ + int ret; + struct stat st; + int fd; + + ret = stat(fname, &st); + if (ret < 0) + return -1; + if (S_ISDIR(st.st_mode)) { + *dirstream = opendir(fname); + if (!*dirstream) + return -2; + fd = dirfd(*dirstream); + } else { + fd = open(fname, O_RDWR); + } + if (fd < 0) { + fd = -3; + if (*dirstream) + closedir(*dirstream); + } + return fd; +} + /* * Given a pathname, return a filehandle to: * the original pathname or, @@ -776,7 +801,7 @@ int open_path_or_dev_mnt(const char *path, DIR **dirstream) errno = EINVAL; return -1; } - fdmnt = open_file_or_dir(mp, dirstream); + fdmnt = __open_file_or_dir(mp, dirstream); } else { fdmnt = open_file_or_dir(path, dirstream); } @@ -1557,28 +1582,9 @@ u64 parse_size(char *s) int open_file_or_dir(const char *fname, DIR **dirstream) { - int ret; - struct stat st; - int fd; - - ret = stat(fname, &st); - if (ret < 0) { + if (is_block_device(fname)) return -1; - } - if (S_ISDIR(st.st_mode)) { - *dirstream = opendir(fname); - if (!*dirstream) - return -2; - fd = dirfd(*dirstream); - } else { - fd = open(fname, O_RDWR); - } - if (fd < 0) { - fd = -3; - if (*dirstream) - closedir(*dirstream); - } - return fd; + return __open_file_or_dir(fname, dirstream); } void close_file_or_dir(int fd, DIR *dirstream)