> 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);

Reply via email to