> Another thought --- is it necessary to call realpath at all? > > -- > James
This patch seems to fix the problem --- just don't call realpath. Maybe I'm missing something? I briefly tested vmd as well (just quickly booted up an instance that uses a qcow2 disk image with a local path to a base image). - James diff --git a/usr.sbin/vmd/vioqcow2.c b/usr.sbin/vmd/vioqcow2.c index 34d0f116cc4..792a53ac932 100644 --- a/usr.sbin/vmd/vioqcow2.c +++ b/usr.sbin/vmd/vioqcow2.c @@ -145,8 +145,8 @@ virtio_qcow2_init(struct virtio_backing *file, off_t *szp, int *fd, size_t nfd) ssize_t virtio_qcow2_get_base(int fd, char *path, size_t npath, const char *dpath) { + char pathbuf[PATH_MAX]; char dpathbuf[PATH_MAX]; - char expanded[PATH_MAX]; struct qcheader header; uint64_t backingoff; uint32_t backingsz; @@ -180,29 +180,22 @@ virtio_qcow2_get_base(int fd, char *path, size_t npath, const char *dpath) * rather than relative to the directory vmd happens to be running in, * since this is the only userful interpretation. */ - if (path[0] == '/') { - if (realpath(path, expanded) == NULL || - strlcpy(path, expanded, npath) >= npath) { - log_warnx("unable to resolve %s", path); + if (path[0] != '/') { + if (strlcpy(pathbuf, path, sizeof(pathbuf)) >= + sizeof(pathbuf)) { + log_warnx("path too long: %s", path); return -1; } - } else { if (strlcpy(dpathbuf, dpath, sizeof(dpathbuf)) >= sizeof(dpathbuf)) { log_warnx("path too long: %s", dpath); return -1; } s = dirname(dpathbuf); - if (snprintf(expanded, sizeof(expanded), - "%s/%s", s, path) >= (int)sizeof(expanded)) { + if (snprintf(path, npath, "%s/%s", s, pathbuf) >= (int)npath) { log_warnx("path too long: %s/%s", s, path); return -1; } - if (npath < PATH_MAX || - realpath(expanded, path) == NULL) { - log_warnx("unable to resolve %s", path); - return -1; - } } return strlen(path);