From nobody Sun May 5 03:51:01 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1554207464708555.7046011829439; Tue, 2 Apr 2019 05:17:44 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 94602307EA9C; Tue, 2 Apr 2019 12:17:43 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 6CA067F2FE; Tue, 2 Apr 2019 12:17:43 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 0748D1803389; Tue, 2 Apr 2019 12:17:43 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id x32CHgph004727 for ; Tue, 2 Apr 2019 08:17:42 -0400 Received: by smtp.corp.redhat.com (Postfix) id 6BEAC17C3E; Tue, 2 Apr 2019 12:17:42 +0000 (UTC) Received: from moe.brq.redhat.com (unknown [10.43.2.30]) by smtp.corp.redhat.com (Postfix) with ESMTP id C136D17C34; Tue, 2 Apr 2019 12:17:39 +0000 (UTC) From: Michal Privoznik To: libvir-list@redhat.com Date: Tue, 2 Apr 2019 14:17:35 +0200 Message-Id: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH] virDirRead: Fix d_type if needed X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.44]); Tue, 02 Apr 2019 12:17:44 +0000 (UTC) Content-Type: text/plain; charset="utf-8" Some of our code iterates over a directory and does some decisions based on entry type (e.g. if it's not a regular file continue with next iteration). This is done by looking at ent->d_type struct member. However, in some cases (e.g. for some filesystems) the d_type can be set to DT_UNKNOWN which effectively defeats the aforementioned checks. For instance, some XFS' (depending on how they were created) might not bother filling the member. Fix this by running stat() and filling in the member ourselves. If needed. Signed-off-by: Michal Privoznik --- With Dan's patch that fixes stat() mocking, I'm passing tests successfully everywhere I tried (32bit fedora and gentoo on RPi, RHEL-7, amd64 gentoo, fedora rawhide on x86_64) src/util/virfile.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/src/util/virfile.c b/src/util/virfile.c index ec8d85929c..7d7c27a7d2 100644 --- a/src/util/virfile.c +++ b/src/util/virfile.c @@ -2893,6 +2893,39 @@ virDirOpenQuiet(DIR **dirp, const char *name) return virDirOpenInternal(dirp, name, false, true); } =20 +static int +virDirReadFixDType(DIR *dirp, struct dirent *ent) +{ + /* DO NOT CLOSE THIS FD */ + const int fd =3D dirfd(dirp); + struct stat sb; + + if (fd < 0) + return -1; + + if (fstatat(fd, ent->d_name, &sb, AT_NO_AUTOMOUNT | AT_SYMLINK_NOFOLLO= W) < 0) + return -1; + + if (S_ISDIR(sb.st_mode)) + ent->d_type =3D DT_DIR; + else if (S_ISCHR(sb.st_mode)) + ent->d_type =3D DT_CHR; + else if (S_ISBLK(sb.st_mode)) + ent->d_type =3D DT_BLK; + else if (S_ISREG(sb.st_mode)) + ent->d_type =3D DT_REG; + else if (S_ISFIFO(sb.st_mode)) + ent->d_type =3D DT_FIFO; + else if (S_ISLNK(sb.st_mode)) + ent->d_type =3D DT_LNK; + else if (S_ISSOCK(sb.st_mode)) + ent->d_type =3D DT_SOCK; + else + return -1; + + return 0; +} + /** * virDirRead: * @dirp: directory to read @@ -2926,6 +2959,17 @@ int virDirRead(DIR *dirp, struct dirent **ent, const= char *name) } } while (*ent && (STREQ((*ent)->d_name, ".") || STREQ((*ent)->d_name, ".."))); + + if (*ent && + (*ent)->d_type =3D=3D DT_UNKNOWN && + virDirReadFixDType(dirp, *ent) < 0) { + if (name) + virReportSystemError(errno, + _("Unable to fix d_type of '%s/%s'"), + name, (*ent)->d_name); + return -1; + } + return !!*ent; } =20 --=20 2.21.0 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list