From 0edbda204bc125e6b59753f4f895473f89bf0ba0 Mon Sep 17 00:00:00 2001 From: Ilya Dryomov Date: Tue, 17 Dec 2013 17:42:30 +0200 Subject: [PATCH] rbd: make coverity happy A recent coverity run found two "defects" in rbd.cc: ** CID 1138367: Time of check time of use (TOCTOU) /rbd.cc: 2024 in do_kernel_rm(const char *)() 2019 const char *fname = "/sys/bus/rbd/remove_single_major"; 2020 if (stat(fname, &sbuf)) { 2021 fname = "/sys/bus/rbd/remove"; 2022 } 2023 2024 int fd = open(fname, O_WRONLY); 2025 if (fd < 0) { ** CID 1138368: Time of check time of use (TOCTOU) /rbd.cc: 1735 in do_kernel_add(const char *, const char *, const char *)() same as above, s/remove/add There is nothing racey going on here, and this is not an instance of TOCTOU, but, instead of silencing coverity with annotatations, redo this with two open() calls. Signed-off-by: Ilya Dryomov --- src/rbd.cc | 45 ++++++++++++++++++++++++--------------------- 1 file changed, 24 insertions(+), 21 deletions(-) diff --git a/src/rbd.cc b/src/rbd.cc index f9d3b65dac79..6a8e6029a262 100644 --- a/src/rbd.cc +++ b/src/rbd.cc @@ -1720,27 +1720,29 @@ static int do_kernel_add(const char *poolname, const char *imgname, } } - // 'add' interface is deprecated, see if 'add_single_major' is - // available and use it if it is + // 'add' interface is deprecated, use 'add_single_major' if it's + // available // // ('add' and 'add_single_major' interfaces are identical, except // that if rbd kernel module is new enough and is configured to use // single-major scheme, 'add' is disabled in order to prevent old // userspace from doing weird things at unmap time) - const char *fname = "/sys/bus/rbd/add_single_major"; - if (stat(fname, &sb)) { - fname = "/sys/bus/rbd/add"; - } - - int fd = open(fname, O_WRONLY); + int fd = open("/sys/bus/rbd/add_single_major", O_WRONLY); if (fd < 0) { - r = -errno; - if (r == -ENOENT) { - cerr << "rbd: /sys/bus/rbd/add does not exist!" << std::endl - << "Did you run 'modprobe rbd' or is your rbd module too old?" - << std::endl; + if (errno == ENOENT) { + fd = open("/sys/bus/rbd/add", O_WRONLY); + if (fd < 0) { + r = -errno; + if (r == -ENOENT) { + cerr << "rbd: /sys/bus/rbd/add does not exist!" << std::endl + << "Did you run 'modprobe rbd' or is your rbd module too old?" + << std::endl; + } + return r; + } + } else { + return -errno; } - return r; } string add = oss.str(); @@ -2016,14 +2018,15 @@ static int do_kernel_rm(const char *dev) // see comment in do_kernel_add(), same goes for 'remove' vs // 'remove_single_major' - const char *fname = "/sys/bus/rbd/remove_single_major"; - if (stat(fname, &sbuf)) { - fname = "/sys/bus/rbd/remove"; - } - - int fd = open(fname, O_WRONLY); + int fd = open("/sys/bus/rbd/remove_single_major", O_WRONLY); if (fd < 0) { - return -errno; + if (errno == ENOENT) { + fd = open("/sys/bus/rbd/remove", O_WRONLY); + if (fd < 0) + return -errno; + } else { + return -errno; + } } r = safe_write(fd, seq_num.c_str(), seq_num.size()); -- 2.47.3