Author: pjd
Date: Fri Jan 30 09:44:29 2015
New Revision: 277920
URL: https://svnweb.freebsd.org/changeset/base/277920

Log:
  If moving descriptor or binary data to an nvlist fails, we need to close the
  descriptor or free the memory before returning.
  
  Submitted by: Mariusz Zaborski <osho...@freebsd.org>
  
  While here, protect errno, so it won't be overwritted by close(2) or free(3).

Modified:
  head/lib/libnv/nvpair.c

Modified: head/lib/libnv/nvpair.c
==============================================================================
--- head/lib/libnv/nvpair.c     Fri Jan 30 09:05:43 2015        (r277919)
+++ head/lib/libnv/nvpair.c     Fri Jan 30 09:44:29 2015        (r277920)
@@ -1100,6 +1100,7 @@ nvpair_t *
 nvpair_movev_string(char *value, const char *namefmt, va_list nameap)
 {
        nvpair_t *nvp;
+       int serrno;
 
        if (value == NULL) {
                errno = EINVAL;
@@ -1108,8 +1109,11 @@ nvpair_movev_string(char *value, const c
 
        nvp = nvpair_allocv(NV_TYPE_STRING, (uint64_t)(uintptr_t)value,
            strlen(value) + 1, namefmt, nameap);
-       if (nvp == NULL)
+       if (nvp == NULL) {
+               serrno = errno;
                free(value);
+               errno = serrno;
+       }
 
        return (nvp);
 }
@@ -1137,28 +1141,46 @@ nvpair_movev_nvlist(nvlist_t *value, con
 nvpair_t *
 nvpair_movev_descriptor(int value, const char *namefmt, va_list nameap)
 {
+       nvpair_t *nvp;
+       int serrno;
 
        if (value < 0 || !fd_is_valid(value)) {
                errno = EBADF;
                return (NULL);
        }
 
-       return (nvpair_allocv(NV_TYPE_DESCRIPTOR, (uint64_t)value,
-           sizeof(int64_t), namefmt, nameap));
+       nvp = nvpair_allocv(NV_TYPE_DESCRIPTOR, (uint64_t)value,
+           sizeof(int64_t), namefmt, nameap);
+       if (nvp == NULL) {
+               serrno = errno;
+               close(value);
+               errno = serrno;
+       }
+
+       return (nvp);
 }
 
 nvpair_t *
 nvpair_movev_binary(void *value, size_t size, const char *namefmt,
     va_list nameap)
 {
+       nvpair_t *nvp;
+       int serrno;
 
        if (value == NULL || size == 0) {
                errno = EINVAL;
                return (NULL);
        }
 
-       return (nvpair_allocv(NV_TYPE_BINARY, (uint64_t)(uintptr_t)value, size,
-           namefmt, nameap));
+       nvp = nvpair_allocv(NV_TYPE_BINARY, (uint64_t)(uintptr_t)value, size,
+           namefmt, nameap);
+       if (nvp == NULL) {
+               serrno = errno;
+               free(value);
+               errno = serrno;
+       }
+
+       return (nvp);
 }
 
 bool
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to