From owner-svn-src-stable@FreeBSD.ORG Thu Jan 30 10:54:12 2014 Return-Path: Delivered-To: svn-src-stable@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id F05C95DF; Thu, 30 Jan 2014 10:54:11 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id D0CE01F22; Thu, 30 Jan 2014 10:54:11 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.7/8.14.7) with ESMTP id s0UAsBCS096103; Thu, 30 Jan 2014 10:54:11 GMT (envelope-from ae@svn.freebsd.org) Received: (from ae@localhost) by svn.freebsd.org (8.14.7/8.14.7/Submit) id s0UAsBtq096102; Thu, 30 Jan 2014 10:54:11 GMT (envelope-from ae@svn.freebsd.org) Message-Id: <201401301054.s0UAsBtq096102@svn.freebsd.org> From: "Andrey V. Elsukov" Date: Thu, 30 Jan 2014 10:54:11 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org Subject: svn commit: r261286 - stable/9/sys/geom X-SVN-Group: stable-9 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.17 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 30 Jan 2014 10:54:12 -0000 Author: ae Date: Thu Jan 30 10:54:11 2014 New Revision: 261286 URL: http://svnweb.freebsd.org/changeset/base/261286 Log: MFC r261084: malloc() with M_WAITOK doesn't return NULL. MFC r261085: Fix typo in r261084. Add to the gctl_error() an ability to specify error description even if numeric error code is already specified. Also by default set error code to EINVAL. PR: 185852 MFC r261086: In gctl_copyin() remove unused error variable. geom_alloc_copyin() can't return ENOMEM, so describe its fail as bad control request. Add check for NULL pointer in gctl_dump(), since it can be NULL when geom_alloc_copyin() failed. MFC r261089: Remove another unneeded NULL check from geom_alloc_copyin(). Do copyout in case of gctl version mismatch and fix sbuf leak in g_ctl_ioctl_ctl(). MFC r261091: Always free sbuf in gctl_free(). Modified: stable/9/sys/geom/geom_ctl.c Directory Properties: stable/9/sys/ (props changed) Modified: stable/9/sys/geom/geom_ctl.c ============================================================================== --- stable/9/sys/geom/geom_ctl.c Thu Jan 30 10:53:29 2014 (r261285) +++ stable/9/sys/geom/geom_ctl.c Thu Jan 30 10:54:11 2014 (r261286) @@ -84,8 +84,8 @@ g_ctl_init(void) } /* - * Report an error back to the user in ascii format. Return whatever copyout - * returned, or EINVAL if it succeeded. + * Report an error back to the user in ascii format. Return nerror + * or EINVAL if nerror isn't specified. */ int gctl_error(struct gctl_req *req, const char *fmt, ...) @@ -99,9 +99,10 @@ gctl_error(struct gctl_req *req, const c if (sbuf_done(req->serror)) { if (!req->nerror) req->nerror = EEXIST; - } - if (req->nerror) return (req->nerror); + } + if (!req->nerror) + req->nerror = EINVAL; va_start(ap, fmt); sbuf_vprintf(req->serror, fmt, ap); @@ -109,7 +110,7 @@ gctl_error(struct gctl_req *req, const c sbuf_finish(req->serror); if (g_debugflags & G_F_CTLDUMP) printf("gctl %p error \"%s\"\n", req, sbuf_data(req->serror)); - return (0); + return (req->nerror); } /* @@ -122,27 +123,23 @@ geom_alloc_copyin(struct gctl_req *req, void *ptr; ptr = g_malloc(len, M_WAITOK); - if (ptr == NULL) - req->nerror = ENOMEM; - else - req->nerror = copyin(uaddr, ptr, len); + req->nerror = copyin(uaddr, ptr, len); if (!req->nerror) return (ptr); - if (ptr != NULL) - g_free(ptr); + g_free(ptr); return (NULL); } static void gctl_copyin(struct gctl_req *req) { - int error, i; struct gctl_req_arg *ap; char *p; + int i; ap = geom_alloc_copyin(req, req->arg, req->narg * sizeof(*ap)); if (ap == NULL) { - req->nerror = ENOMEM; + gctl_error(req, "bad control request"); req->arg = NULL; return; } @@ -154,10 +151,9 @@ gctl_copyin(struct gctl_req *req) ap[i].kvalue = NULL; } - error = 0; for (i = 0; i < req->narg; i++) { if (ap[i].nlen < 1 || ap[i].nlen > SPECNAMELEN) { - error = gctl_error(req, + gctl_error(req, "wrong param name length %d: %d", i, ap[i].nlen); break; } @@ -165,14 +161,14 @@ gctl_copyin(struct gctl_req *req) if (p == NULL) break; if (p[ap[i].nlen - 1] != '\0') { - error = gctl_error(req, "unterminated param name"); + gctl_error(req, "unterminated param name"); g_free(p); break; } ap[i].name = p; ap[i].flag |= GCTL_PARAM_NAMEKERNEL; if (ap[i].len <= 0) { - error = gctl_error(req, "negative param length"); + gctl_error(req, "negative param length"); break; } p = geom_alloc_copyin(req, ap[i].value, ap[i].len); @@ -180,7 +176,7 @@ gctl_copyin(struct gctl_req *req) break; if ((ap[i].flag & GCTL_PARAM_ASCII) && p[ap[i].len - 1] != '\0') { - error = gctl_error(req, "unterminated param value"); + gctl_error(req, "unterminated param value"); g_free(p); break; } @@ -218,6 +214,7 @@ gctl_free(struct gctl_req *req) { int i; + sbuf_delete(req->serror); if (req->arg == NULL) return; for (i = 0; i < req->narg; i++) { @@ -228,15 +225,14 @@ gctl_free(struct gctl_req *req) g_free(req->arg[i].kvalue); } g_free(req->arg); - sbuf_delete(req->serror); } static void gctl_dump(struct gctl_req *req) { + struct gctl_req_arg *ap; u_int i; int j; - struct gctl_req_arg *ap; printf("Dump of gctl request at %p:\n", req); if (req->nerror > 0) { @@ -244,6 +240,8 @@ gctl_dump(struct gctl_req *req) if (sbuf_len(req->serror) > 0) printf(" error:\t\"%s\"\n", sbuf_data(req->serror)); } + if (req->arg == NULL) + return; for (i = 0; i < req->narg; i++) { ap = &req->arg[i]; if (!(ap->flag & GCTL_PARAM_NAMEKERNEL)) @@ -464,30 +462,31 @@ g_ctl_ioctl_ctl(struct cdev *dev, u_long req = (void *)data; req->nerror = 0; - req->serror = sbuf_new_auto(); /* It is an error if we cannot return an error text */ if (req->lerror < 2) return (EINVAL); if (!useracc(req->error, req->lerror, VM_PROT_WRITE)) return (EINVAL); + req->serror = sbuf_new_auto(); /* Check the version */ - if (req->version != GCTL_VERSION) - return (gctl_error(req, - "kernel and libgeom version mismatch.")); - - /* Get things on board */ - gctl_copyin(req); - - if (g_debugflags & G_F_CTLDUMP) - gctl_dump(req); - - if (!req->nerror) { - g_waitfor_event(g_ctl_req, req, M_WAITOK, NULL); - gctl_copyout(req); + if (req->version != GCTL_VERSION) { + gctl_error(req, "kernel and libgeom version mismatch."); + req->arg = NULL; + } else { + /* Get things on board */ + gctl_copyin(req); + + if (g_debugflags & G_F_CTLDUMP) + gctl_dump(req); + + if (!req->nerror) { + g_waitfor_event(g_ctl_req, req, M_WAITOK, NULL); + gctl_copyout(req); + } } if (sbuf_done(req->serror)) { - req->nerror = copyout(sbuf_data(req->serror), req->error, + copyout(sbuf_data(req->serror), req->error, imin(req->lerror, sbuf_len(req->serror) + 1)); }