git: 4bd4e4b45e8b - main - sesutil: don't malloc in a tight loop

From: Alan Somers <asomers_at_FreeBSD.org>
Date: Mon, 13 Feb 2023 16:06:14 UTC
The branch main has been updated by asomers:

URL: https://cgit.FreeBSD.org/src/commit/?id=4bd4e4b45e8bfbe855406098f393bdf4eda7104d

commit 4bd4e4b45e8bfbe855406098f393bdf4eda7104d
Author:     Alan Somers <asomers@FreeBSD.org>
AuthorDate: 2023-02-09 22:23:51 +0000
Commit:     Alan Somers <asomers@FreeBSD.org>
CommitDate: 2023-02-13 16:04:05 +0000

    sesutil: don't malloc in a tight loop
    
    Reported by:    mav
    MFC after:      1 week
    Sponsored by:   Axcient
    Reviwed by:     mav
    Differential Revision: https://reviews.freebsd.org/D38473
---
 usr.sbin/sesutil/sesutil.c | 42 ++++++++++++++++++++----------------------
 1 file changed, 20 insertions(+), 22 deletions(-)

diff --git a/usr.sbin/sesutil/sesutil.c b/usr.sbin/sesutil/sesutil.c
index 989216690edf..22bd0127a484 100644
--- a/usr.sbin/sesutil/sesutil.c
+++ b/usr.sbin/sesutil/sesutil.c
@@ -417,6 +417,17 @@ objmap(int argc, char **argv __unused)
 		usage(stderr, "map");
 	}
 
+	memset(&e_desc, 0, sizeof(e_desc));
+	/* SES4r02 allows element descriptors of up to 65536 characters */
+	e_desc.elm_desc_str = calloc(UINT16_MAX, sizeof(char));
+	if (e_desc.elm_desc_str == NULL)
+		xo_err(EXIT_FAILURE, "calloc()");
+
+	e_devname.elm_devnames = calloc(128, sizeof(char));
+	if (e_devname.elm_devnames == NULL)
+		xo_err(EXIT_FAILURE, "calloc()");
+	e_devname.elm_names_size = 128;
+
 	/* Get the list of ses devices */
 	if (glob(uflag, 0, NULL, &g) == GLOB_NOMATCH) {
 		globfree(&g);
@@ -481,28 +492,16 @@ objmap(int argc, char **argv __unused)
 				xo_err(EXIT_FAILURE, "ENCIOC_GETELMSTAT");
 			}
 			/* Get the description of the element */
-			memset(&e_desc, 0, sizeof(e_desc));
 			e_desc.elm_idx = e_ptr[j].elm_idx;
 			e_desc.elm_desc_len = UINT16_MAX;
-			e_desc.elm_desc_str = calloc(UINT16_MAX, sizeof(char));
-			if (e_desc.elm_desc_str == NULL) {
-				close(fd);
-				xo_err(EXIT_FAILURE, "calloc()");
-			}
 			if (ioctl(fd, ENCIOC_GETELMDESC,
 			    (caddr_t) &e_desc) < 0) {
 				close(fd);
 				xo_err(EXIT_FAILURE, "ENCIOC_GETELMDESC");
 			}
+			e_desc.elm_desc_str[e_desc.elm_desc_len] = '\0';
 			/* Get the device name(s) of the element */
-			memset(&e_devname, 0, sizeof(e_devname));
 			e_devname.elm_idx = e_ptr[j].elm_idx;
-			e_devname.elm_names_size = 128;
-			e_devname.elm_devnames = calloc(128, sizeof(char));
-			if (e_devname.elm_devnames == NULL) {
-				close(fd);
-				xo_err(EXIT_FAILURE, "calloc()");
-			}
 			if (ioctl(fd, ENCIOC_GETELMDEVNAMES,
 			    (caddr_t) &e_devname) <0) {
 				/* Continue even if we can't look up devnames */
@@ -525,14 +524,14 @@ objmap(int argc, char **argv __unused)
 			}
 			print_extra_status(e_ptr[j].elm_type, e_status.cstat, PRINT_STYLE_DASHED);
 			xo_close_instance("elements");
-			free(e_desc.elm_desc_str);
-			free(e_devname.elm_devnames);
 		}
 		xo_close_list("elements");
 		free(e_ptr);
 		close(fd);
 	}
 	globfree(&g);
+	free(e_devname.elm_devnames);
+	free(e_desc.elm_desc_str);
 	xo_close_list("enclosures");
 	xo_close_container("sesutil");
 	xo_finish();
@@ -727,6 +726,10 @@ show(int argc, char **argv __unused)
 
 	first_ses = true;
 
+	e_desc.elm_desc_str = calloc(UINT16_MAX, sizeof(char));
+	if (e_desc.elm_desc_str == NULL)
+		xo_err(EXIT_FAILURE, "calloc()");
+
 	/* Get the list of ses devices */
 	if (glob(uflag, 0, NULL, &g) == GLOB_NOMATCH) {
 		globfree(&g);
@@ -808,19 +811,14 @@ show(int argc, char **argv __unused)
 				continue;
 
 			/* Get the description of the element */
-			memset(&e_desc, 0, sizeof(e_desc));
 			e_desc.elm_idx = e_ptr[j].elm_idx;
 			e_desc.elm_desc_len = UINT16_MAX;
-			e_desc.elm_desc_str = calloc(UINT16_MAX, sizeof(char));
-			if (e_desc.elm_desc_str == NULL) {
-				close(fd);
-				xo_err(EXIT_FAILURE, "calloc()");
-			}
 			if (ioctl(fd, ENCIOC_GETELMDESC,
 			    (caddr_t) &e_desc) < 0) {
 				close(fd);
 				xo_err(EXIT_FAILURE, "ENCIOC_GETELMDESC");
 			}
+			e_desc.elm_desc_str[e_desc.elm_desc_len] = '\0';
 
 			switch (e_ptr[j].elm_type) {
 			case ELMTYP_DEVICE:
@@ -853,7 +851,6 @@ show(int argc, char **argv __unused)
 				 */
 				break;
 			}
-			free(e_desc.elm_desc_str);
 		}
 		if (prev_type != (elm_type_t)-1 &&
 		    prev_type != ELMTYP_DEVICE && prev_type != ELMTYP_ARRAY_DEV)
@@ -863,6 +860,7 @@ show(int argc, char **argv __unused)
 		close(fd);
 	}
 	globfree(&g);
+	free(e_desc.elm_desc_str);
 	xo_close_list("enclosures");
 	xo_close_container("sesutil");
 	xo_finish();