From 6bd0793cec440ba4438b918ab01fddf667ade3f8 Mon Sep 17 00:00:00 2001 From: pfg Date: Thu, 9 Mar 2017 15:21:03 +0000 Subject: [PATCH] localedef(1): Fix for memory leaks reported by coverity. Also some small cleanups to match better current illumos. CID: 1338540, 1338541, 1338557, 1338566 Obtained from: illumos Discussed with: Yuri Pankov (@Nexenta) MFC after: 5 days --- usr.bin/localedef/collate.c | 6 ++++- usr.bin/localedef/ctype.c | 45 ++++++++++++++++++++++------------- usr.bin/localedef/localedef.c | 22 ++++++++++------- usr.bin/localedef/localedef.h | 3 ++- usr.bin/localedef/time.c | 4 ++-- 5 files changed, 51 insertions(+), 29 deletions(-) diff --git a/usr.bin/localedef/collate.c b/usr.bin/localedef/collate.c index 789053819011..8d1c0fb967e1 100644 --- a/usr.bin/localedef/collate.c +++ b/usr.bin/localedef/collate.c @@ -1,5 +1,5 @@ /* - * Copyright 2010 Nexenta Systems, Inc. All rights reserved. + * Copyright 2017 Nexenta Systems, Inc. * Copyright 2015 John Marino * * This source code is derived from the illumos localedef command, and @@ -1291,21 +1291,25 @@ dump_collate(void) if ((wr_category(vers, COLLATE_STR_LEN, f) < 0) || (wr_category(&collinfo, sizeof (collinfo), f) < 0) || (wr_category(&chars, sizeof (chars), f) < 0)) { + delete_category(f); return; } for (i = 0; i < NUM_WT; i++) { sz = sizeof (collate_subst_t) * collinfo.subst_count[i]; if (wr_category(subst[i], sz, f) < 0) { + delete_category(f); return; } } sz = sizeof (collate_chain_t) * collinfo.chain_count; if (wr_category(chain, sz, f) < 0) { + delete_category(f); return; } sz = sizeof (collate_large_t) * collinfo.large_count; if (wr_category(large, sz, f) < 0) { + delete_category(f); return; } diff --git a/usr.bin/localedef/ctype.c b/usr.bin/localedef/ctype.c index 0e238d79080f..20646d5d5708 100644 --- a/usr.bin/localedef/ctype.c +++ b/usr.bin/localedef/ctype.c @@ -1,5 +1,5 @@ /* - * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + * Copyright 2017 Nexenta Systems, Inc. * Copyright 2012 Garrett D'Amore All rights reserved. * Copyright 2015 John Marino * @@ -306,7 +306,7 @@ dump_ctype(void) return; (void) memcpy(rl.magic, _FILE_RUNE_MAGIC_1, 8); - (void) strncpy(rl.encoding, get_wide_encoding(), sizeof (rl.encoding)); + (void) strlcpy(rl.encoding, get_wide_encoding(), sizeof (rl.encoding)); /* * Initialize the identity map. @@ -379,12 +379,12 @@ dump_ctype(void) if ((ctn->ctype & _ISALPHA) && (ctn->ctype & (_ISPUNCT|_ISDIGIT))) conflict++; - if ((ctn->ctype & _ISPUNCT) & + if ((ctn->ctype & _ISPUNCT) && (ctn->ctype & (_ISDIGIT|_ISALPHA|_ISXDIGIT))) conflict++; if ((ctn->ctype & _ISSPACE) && (ctn->ctype & _ISGRAPH)) conflict++; - if ((ctn->ctype & _ISCNTRL) & _ISPRINT) + if ((ctn->ctype & _ISCNTRL) && (ctn->ctype & _ISPRINT)) conflict++; if ((wc == ' ') && (ctn->ctype & (_ISPUNCT|_ISGRAPH))) conflict++; @@ -412,8 +412,10 @@ dump_ctype(void) ct[rl.runetype_ext_nranges-1].max = wc; } else { rl.runetype_ext_nranges++; - ct = realloc(ct, - sizeof (*ct) * rl.runetype_ext_nranges); + ct = realloc(ct, rl.runetype_ext_nranges * + sizeof (*ct)); + if (ct == NULL) + goto fail; ct[rl.runetype_ext_nranges - 1].min = wc; ct[rl.runetype_ext_nranges - 1].max = wc; ct[rl.runetype_ext_nranges - 1].map = ctn->ctype; @@ -427,8 +429,10 @@ dump_ctype(void) last_lo = ctn; } else { rl.maplower_ext_nranges++; - lo = realloc(lo, - sizeof (*lo) * rl.maplower_ext_nranges); + lo = realloc(lo, rl.maplower_ext_nranges * + sizeof (*lo)); + if (lo == NULL) + goto fail; lo[rl.maplower_ext_nranges - 1].min = wc; lo[rl.maplower_ext_nranges - 1].max = wc; lo[rl.maplower_ext_nranges - 1].map = ctn->tolower; @@ -443,8 +447,10 @@ dump_ctype(void) last_up = ctn; } else { rl.mapupper_ext_nranges++; - up = realloc(up, - sizeof (*up) * rl.mapupper_ext_nranges); + up = realloc(up, rl.mapupper_ext_nranges * + sizeof (*up)); + if (up == NULL) + goto fail; up[rl.mapupper_ext_nranges - 1].min = wc; up[rl.mapupper_ext_nranges - 1].max = wc; up[rl.mapupper_ext_nranges - 1].map = ctn->toupper; @@ -452,12 +458,17 @@ dump_ctype(void) } } - if ((wr_category(&rl, sizeof (rl), f) < 0) || - (wr_category(ct, sizeof (*ct) * rl.runetype_ext_nranges, f) < 0) || - (wr_category(lo, sizeof (*lo) * rl.maplower_ext_nranges, f) < 0) || - (wr_category(up, sizeof (*up) * rl.mapupper_ext_nranges, f) < 0)) { - return; + if ((wr_category(&rl, sizeof (rl), f) == 0) && + (wr_category(ct, sizeof (*ct) * rl.runetype_ext_nranges, f) == 0) && + (wr_category(lo, sizeof (*lo) * rl.maplower_ext_nranges, f) == 0) && + (wr_category(up, sizeof (*up) * rl.mapupper_ext_nranges, f) == 0)) { + close_category(f); + goto out; } - close_category(f); -} +fail: + delete_category(f); +out: + free(ct); + free(lo); + free(up);} diff --git a/usr.bin/localedef/localedef.c b/usr.bin/localedef/localedef.c index e4d0dff5c72a..e2457f296e94 100644 --- a/usr.bin/localedef/localedef.c +++ b/usr.bin/localedef/localedef.c @@ -1,5 +1,5 @@ /* - * Copyright 2010 Nexenta Systems, Inc. All rights reserved. + * Copyright 2017 Nexenta Systems, Inc. * Copyright 2015 John Marino * * This source code is derived from the illumos localedef command, and @@ -125,13 +125,22 @@ open_category(void) return (file); } +void +delete_category(FILE *f) +{ + (void) fclose(f); + (void) unlink(category_file()); +} + void close_category(FILE *f) { - if (fchmod(fileno(f), 0644) < 0) { + if (fchmod(fileno(f), 0644) < 0 || + fclose(f) != 0) { (void) fclose(f); (void) unlink(category_file()); errf(strerror(errno)); + delete_category(f); } if (fclose(f) < 0) { (void) unlink(category_file()); @@ -193,15 +202,13 @@ int putl_category(const char *s, FILE *f) { if (s && fputs(s, f) == EOF) { - (void) fclose(f); - (void) unlink(category_file()); errf(strerror(errno)); + delete_category(f); return (EOF); } if (fputc('\n', f) == EOF) { - (void) fclose(f); - (void) unlink(category_file()); errf(strerror(errno)); + delete_category(f); return (EOF); } return (0); @@ -214,9 +221,8 @@ wr_category(void *buf, size_t sz, FILE *f) return (0); } if (fwrite(buf, sz, 1, f) < 1) { - (void) fclose(f); - (void) unlink(category_file()); errf(strerror(errno)); + delete_category(f); return (EOF); } return (0); diff --git a/usr.bin/localedef/localedef.h b/usr.bin/localedef/localedef.h index 8c829399d186..c6ffdb53083b 100644 --- a/usr.bin/localedef/localedef.h +++ b/usr.bin/localedef/localedef.h @@ -1,5 +1,5 @@ /* - * Copyright 2010 Nexenta Systems, Inc. All rights reserved. + * Copyright 2017 Nexenta Systems, Inc. * Copyright 2015 John Marino * * This source code is derived from the illumos localedef command, and @@ -60,6 +60,7 @@ void warn(const char *, ...); int putl_category(const char *, FILE *); int wr_category(void *, size_t, FILE *); FILE *open_category(void); +void delete_category(FILE *); void close_category(FILE *); void copy_category(char *); const char *category_name(void); diff --git a/usr.bin/localedef/time.c b/usr.bin/localedef/time.c index e40001d18e64..80d04df11c8d 100644 --- a/usr.bin/localedef/time.c +++ b/usr.bin/localedef/time.c @@ -1,5 +1,5 @@ /* - * Copyright 2010 Nexenta Systems, Inc. All rights reserved. + * Copyright 2017 Nexenta Systems, Inc. * Copyright 2015 John Marino * * This source code is derived from the illumos localedef command, and @@ -78,7 +78,7 @@ add_time_str(wchar_t *wcs) break; case T_DATE_FMT: /* - * This one is a Solaris extension, Too bad date just + * This one is a Solaris extension. Too bad date just * doesn't use %c, which would be simpler. */ tm.date_fmt = str;