return -2;
}
+ /* O_NONBLOCK should only matter during open() for fifos and
+ * sockets, which we already filtered; but using it prevents a
+ * TOCTTOU race. However, later on we will want to read() the
+ * header from this fd, and virFileRead* routines require a
+ * blocking fd, so fix it up after verifying we avoided a
+ * race. */
if ((fd = open(path, O_RDONLY|O_NONBLOCK|O_NOCTTY)) < 0) {
if ((errno == ENOENT || errno == ELOOP) &&
S_ISLNK(sb->st_mode)) {
return -1;
}
- if (S_ISREG(sb->st_mode))
+ if (S_ISREG(sb->st_mode)) {
mode = VIR_STORAGE_VOL_OPEN_REG;
- else if (S_ISCHR(sb->st_mode))
+ } else if (S_ISCHR(sb->st_mode)) {
mode = VIR_STORAGE_VOL_OPEN_CHAR;
- else if (S_ISBLK(sb->st_mode))
+ } else if (S_ISBLK(sb->st_mode)) {
mode = VIR_STORAGE_VOL_OPEN_BLOCK;
- else if (S_ISDIR(sb->st_mode)) {
+ } else if (S_ISDIR(sb->st_mode)) {
mode = VIR_STORAGE_VOL_OPEN_DIR;
if (STREQ(base, ".") ||
VIR_INFO("Skipping special dir '%s'", base);
return -2;
}
+ } else {
+ VIR_WARN("ignoring unexpected type for file '%s'", path);
+ VIR_FORCE_CLOSE(fd);
+ return -2;
+ }
+
+ if (virSetBlocking(fd, true) < 0) {
+ virReportSystemError(errno, _("unable to set blocking mode for '%s'"),
+ path);
+ VIR_FORCE_CLOSE(fd);
+ return -2;
}
if (!(mode & flags)) {