--- old/usr/src/common/ctf/ctf_create.c	Mon Feb 10 06:38:24 2020
+++ new/usr/src/common/ctf/ctf_create.c	Mon Feb 10 06:38:24 2020
@@ -35,6 +35,14 @@
 #include <sys/debug.h>
 
 /*
+ * SSIZE_MAX is not available in the kernel, so we define it here rather than
+ * accidentally inject into headers where it's not wanted.
+ */
+#ifndef SSIZE_MAX
+#define	SSIZE_MAX (LONG_MAX)
+#endif
+
+/*
  * This static string is used as the template for initially populating a
  * dynamic container's string table.  We always store \0 in the first byte,
  * and we use the generic string "PARENT" to mark this container's parent
@@ -1258,6 +1266,10 @@
 	ctf_dtdef_t *dtd = NULL;
 	ctf_id_t type = CTF_ERR;
 
+	/* Check we could return something valid in ctf_type_size. */
+	if (size > SSIZE_MAX)
+		return (ctf_set_errno(fp, EINVAL));
+
 	if (name != NULL)
 		hep = ctf_hash_lookup(hp, fp, name, strlen(name));
 
@@ -1277,16 +1289,8 @@
 	VERIFY(type != CTF_ERR);
 	dtd->dtd_data.ctt_info = CTF_TYPE_INFO(CTF_K_ENUM, flag, 0);
 
-	if (size == 0) {
-		dtd->dtd_data.ctt_size = fp->ctf_dmodel->ctd_int;
-	} else {
-		if (size > CTF_MAX_SIZE) {
-			dtd->dtd_data.ctt_size = CTF_LSIZE_SENT;
-			dtd->dtd_data.ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI(size);
-			dtd->dtd_data.ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO(size);
-		} else
-			dtd->dtd_data.ctt_size = size;
-	}
+	ctf_set_ctt_size(&dtd->dtd_data, size == 0 ?
+	    fp->ctf_dmodel->ctd_int : size);
 
 	/*
 	 * Always dirty in case we modified a forward.
@@ -1565,12 +1569,7 @@
 		ssize = MAX(ssize, msize);
 	}
 
-	if (ssize > CTF_MAX_SIZE) {
-		dtd->dtd_data.ctt_size = CTF_LSIZE_SENT;
-		dtd->dtd_data.ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI(ssize);
-		dtd->dtd_data.ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO(ssize);
-	} else
-		dtd->dtd_data.ctt_size = (ushort_t)ssize;
+	ctf_set_ctt_size(&dtd->dtd_data, ssize);
 
 	dtd->dtd_data.ctt_info = CTF_TYPE_INFO(kind, root, vlen + 1);
 	ctf_list_append(&dtd->dtd_u.dtu_members, dmd);
@@ -1707,7 +1706,6 @@
 
 	ctf_dtdef_t *dtd;
 	ctf_funcinfo_t ctc;
-	ssize_t size;
 
 	ctf_hash_t *hp;
 	ctf_helem_t *hep;
@@ -1902,12 +1900,8 @@
 		if (ctf_member_iter(src_fp, src_type, membadd, &dst) != 0)
 			errs++; /* increment errs and fail at bottom of case */
 
-		if ((size = ctf_type_size(src_fp, src_type)) > CTF_MAX_SIZE) {
-			dtd->dtd_data.ctt_size = CTF_LSIZE_SENT;
-			dtd->dtd_data.ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI(size);
-			dtd->dtd_data.ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO(size);
-		} else
-			dtd->dtd_data.ctt_size = (ushort_t)size;
+		ctf_set_ctt_size(&dtd->dtd_data,
+		    ctf_type_size(src_fp, src_type));
 
 		dtd->dtd_data.ctt_info = CTF_TYPE_INFO(kind, flag, vlen);
 
@@ -1942,7 +1936,11 @@
 			    ctf_enum_iter(dst_fp, dst_type, enumcmp, &src))
 				return (ctf_set_errno(dst_fp, ECTF_CONFLICT));
 		} else {
-			size_t size = ctf_type_size(src_fp, src_type);
+			ssize_t size = ctf_type_size(src_fp, src_type);
+
+			if (size == CTF_ERR)
+				return (CTF_ERR); /* errno is set for us */
+
 			dst_type = ctf_add_enum(dst_fp, flag, name, size);
 			if ((dst.ctb_type = dst_type) == CTF_ERR ||
 			    ctf_enum_iter(src_fp, src_type, enumadd, &dst))
@@ -2180,13 +2178,7 @@
 	if (newsz < oldsz)
 		return (ctf_set_errno(fp, EINVAL));
 
-	if (newsz > CTF_MAX_SIZE) {
-		dtd->dtd_data.ctt_size = CTF_LSIZE_SENT;
-		dtd->dtd_data.ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI(newsz);
-		dtd->dtd_data.ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO(newsz);
-	} else {
-		dtd->dtd_data.ctt_size = (ushort_t)newsz;
-	}
+	ctf_set_ctt_size(&dtd->dtd_data, newsz);
 
 	fp->ctf_flags |= LCTF_DIRTY;
 	return (0);
--- old/usr/src/common/ctf/ctf_impl.h	Mon Feb 10 06:38:24 2020
+++ new/usr/src/common/ctf/ctf_impl.h	Mon Feb 10 06:38:24 2020
@@ -254,6 +254,8 @@
 extern ssize_t ctf_get_ctt_size(const ctf_file_t *, const ctf_type_t *,
     ssize_t *, ssize_t *);
 
+extern void ctf_set_ctt_size(ctf_type_t *, ssize_t);
+
 extern const ctf_type_t *ctf_lookup_by_id(ctf_file_t **, ctf_id_t);
 
 extern ctf_file_t *ctf_fdcreate_int(int, int *, ctf_sect_t *);
--- old/usr/src/common/ctf/ctf_types.c	Mon Feb 10 06:38:24 2020
+++ new/usr/src/common/ctf/ctf_types.c	Mon Feb 10 06:38:24 2020
@@ -54,6 +54,18 @@
 	return (size);
 }
 
+void
+ctf_set_ctt_size(ctf_type_t *tp, ssize_t size)
+{
+	if (size > CTF_MAX_SIZE) {
+		tp->ctt_size = CTF_LSIZE_SENT;
+		tp->ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI(size);
+		tp->ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO(size);
+	} else {
+		tp->ctt_size = (ushort_t)size;
+	}
+}
+
 /*
  * Iterate over the members of a STRUCT or UNION.  We pass the name, member
  * type, and offset of each member to the specified callback function.
--- old/usr/src/test/util-tests/tests/ctf/check-common.c	Mon Feb 10 06:38:24 2020
+++ new/usr/src/test/util-tests/tests/ctf/check-common.c	Mon Feb 10 06:38:24 2020
@@ -737,6 +737,7 @@
 	free(args);
 	return (ret);
 }
+
 boolean_t
 ctftest_check_size(const char *type, ctf_file_t *fp, size_t size)
 {
