On Fri, Mar 18, 2011 at 08:58:01AM +0530, M. Mohan Kumar wrote: > +static int get_dirfd(FsContext *fs_ctx, const char *path) > +{ > + int fd; > + char *dpath = qemu_strdup(path); > + char *last_component; > + > + /* path can not contain ".." */ > + last_component = strrchr(path, '/'); > + if (last_component && !strcmp(last_component, "/..")) { > + error_report("9p path request contains \"..\": %s\n", path); > + qemu_free(dpath); > + errno = EFAULT; > + return -1; > + } > + fd = passthrough_request(fs_ctx, NULL, dirname(dpath), 0, NULL, T_OPEN); > + if (fd < 0) { > + qemu_free(dpath); > + errno = -fd; > + fd = -1; > + } > + return fd; > +}
dpath is leaked in the success case. I suggest writing the function like this: static int get_dirfd(FsContext *fs_ctx, const char *path) { int fd; char *dpath; char *last_component; /* path can not contain ".." */ last_component = strrchr(path, '/'); if (last_component && !strcmp(last_component, "/..")) { error_report("9p path request contains \"..\": %s\n", path); errno = EFAULT; return -1; } dpath = qemu_strdup(path); fd = passthrough_request(fs_ctx, NULL, dirname(dpath), 0, NULL, T_OPEN); qemu_free(dpath); if (fd < 0) { errno = -fd; fd = -1; } return fd; } > -static int local_utimensat(FsContext *s, const char *path, > - const struct timespec *buf) > +static int local_utimensat(FsContext *fs_ctx, const char *path, > + const struct timespec *buf) > { > - return qemu_utimensat(AT_FDCWD, rpath(s, path), buf, > AT_SYMLINK_NOFOLLOW); > + if (fs_ctx->fs_sm == SM_PASSTHROUGH) { > + int fd, retval; > + fd = passthrough_request(fs_ctx, NULL, path, > + O_RDONLY | O_NONBLOCK | O_NOFOLLOW, NULL, T_OPEN); > + if (fd < 0) { > + errno = -fd; > + return -1; > + } > + retval = futimens(fd, buf); > + close(fd); > + return retval; errno is clobbered here. Stefan