summaryrefslogtreecommitdiffstats
path: root/lib/libnv
diff options
context:
space:
mode:
authorpjd <pjd@FreeBSD.org>2015-01-30 09:44:29 +0000
committerpjd <pjd@FreeBSD.org>2015-01-30 09:44:29 +0000
commitd08c53259eac79d61d0f15af9d8a2c5e09e4f89d (patch)
tree4499682cef8975f23d00e1fba77542ee63bee8bd /lib/libnv
parent30e216f85893cebc73455d1d87e357e9867988c2 (diff)
downloadFreeBSD-src-d08c53259eac79d61d0f15af9d8a2c5e09e4f89d.zip
FreeBSD-src-d08c53259eac79d61d0f15af9d8a2c5e09e4f89d.tar.gz
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 <oshogbo@FreeBSD.org> While here, protect errno, so it won't be overwritted by close(2) or free(3).
Diffstat (limited to 'lib/libnv')
-rw-r--r--lib/libnv/nvpair.c32
1 files changed, 27 insertions, 5 deletions
diff --git a/lib/libnv/nvpair.c b/lib/libnv/nvpair.c
index 4f0bd72..a2da8cc 100644
--- a/lib/libnv/nvpair.c
+++ b/lib/libnv/nvpair.c
@@ -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 char *namefmt, va_list nameap)
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, const char *namefmt, va_list nameap)
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
OpenPOWER on IntegriCloud