diff mbox series

[v4l-utils,v5,2/6] v4l2-ctl: check that the size read/write fit the buffer size

Message ID 20190306211752.15531-2-dafna3@gmail.com (mailing list archive)
State New, archived
Headers show
Series [v4l-utils,v5,1/6] v4l2-ctl: in streaming_set_m2m, close file pointers upon error | expand

Commit Message

Dafna Hirschfeld March 6, 2019, 9:17 p.m. UTC
'read_write_padded_frame' should check that the
expected size to read/write is not larger than
the size of the buffer.

Signed-off-by: Dafna Hirschfeld <dafna3@gmail.com>
---
 utils/v4l2-ctl/v4l2-ctl-streaming.cpp | 41 ++++++++++++++++-----------
 1 file changed, 24 insertions(+), 17 deletions(-)
diff mbox series

Patch

diff --git a/utils/v4l2-ctl/v4l2-ctl-streaming.cpp b/utils/v4l2-ctl/v4l2-ctl-streaming.cpp
index ee84abbe..465ba50c 100644
--- a/utils/v4l2-ctl/v4l2-ctl-streaming.cpp
+++ b/utils/v4l2-ctl/v4l2-ctl-streaming.cpp
@@ -749,9 +749,10 @@  void streaming_cmd(int ch, char *optarg)
 	}
 }
 
-static void read_write_padded_frame(cv4l_fmt &fmt, unsigned char *buf,
+static bool read_write_padded_frame(cv4l_fmt &fmt, unsigned char *buf,
 				    FILE *fpointer, unsigned &sz,
-				    unsigned &len, bool is_read)
+				    unsigned &expected_len, unsigned buf_len,
+				    bool is_read)
 {
 	const struct v4l2_fwht_pixfmt_info *info =
 			v4l2_fwht_find_pixfmt(fmt.g_pixelformat());
@@ -771,8 +772,9 @@  static void read_write_padded_frame(cv4l_fmt &fmt, unsigned char *buf,
 	}
 
 	sz = 0;
-	len = real_width * real_height * info->sizeimage_mult / info->sizeimage_div;
-
+	expected_len = real_width * real_height * info->sizeimage_mult / info->sizeimage_div;
+	if (expected_len > buf_len)
+		return false;
 	for (unsigned plane_idx = 0; plane_idx < info->planes_num; plane_idx++) {
 		bool is_chroma_plane = plane_idx == 1 || plane_idx == 2;
 		unsigned h_div = is_chroma_plane ? info->height_div : 1;
@@ -800,7 +802,7 @@  static void read_write_padded_frame(cv4l_fmt &fmt, unsigned char *buf,
 				break;
 			if (wsz != consume_sz) {
 				fprintf(stderr, "padding: needed %u bytes, got %u\n", consume_sz, wsz);
-				return;
+				return true;
 			}
 			sz += wsz;
 			row_p += stride;
@@ -809,6 +811,7 @@  static void read_write_padded_frame(cv4l_fmt &fmt, unsigned char *buf,
 		if (sz == 0)
 			break;
 	}
+	return true;
 }
 
 static bool fill_buffer_from_file(cv4l_fd &fd, cv4l_queue &q, cv4l_buffer &b,
@@ -929,26 +932,30 @@  restart:
 
 	for (unsigned j = 0; j < q.g_num_planes(); j++) {
 		void *buf = q.g_dataptr(b.g_index(), j);
-		unsigned len = q.g_length(j);
+		unsigned buf_len = q.g_length(j);
+		unsigned expected_len = q.g_length(j);
 		unsigned sz;
 		cv4l_fmt fmt;
 
 		fd.g_fmt(fmt, q.g_type());
 		if (from_with_hdr) {
-			len = read_u32(fin);
-			if (len > q.g_length(j)) {
+			expected_len = read_u32(fin);
+			if (expected_len > q.g_length(j)) {
 				fprintf(stderr, "plane size is too large (%u > %u)\n",
-					len, q.g_length(j));
+					expected_len, q.g_length(j));
 				return false;
 			}
 		}
 
-		if (support_out_crop && v4l2_fwht_find_pixfmt(fmt.g_pixelformat()))
-			read_write_padded_frame(fmt, (unsigned char *)buf, fin, sz, len, true);
-		else
-			sz = fread(buf, 1, len, fin);
+		if (support_out_crop && v4l2_fwht_find_pixfmt(fmt.g_pixelformat())) {
+			if (!read_write_padded_frame(fmt, (unsigned char *)buf,
+			    fin, sz, expected_len, buf_len, true))
+				return false;
+		} else {
+			sz = fread(buf, 1, expected_len, fin);
+		}
 
-		if (first && sz != len) {
+		if (first && sz != expected_len) {
 			fprintf(stderr, "Insufficient data\n");
 			return false;
 		}
@@ -958,12 +965,12 @@  restart:
 			goto restart;
 		}
 		b.s_bytesused(sz, j);
-		if (sz == len)
+		if (sz == expected_len)
 			continue;
 		if (sz == 0)
 			return false;
 		if (sz)
-			fprintf(stderr, "%u != %u\n", sz, len);
+			fprintf(stderr, "%u != %u\n", sz, expected_len);
 		continue;
 	}
 	first = false;
@@ -1151,7 +1158,7 @@  static void write_buffer_to_file(cv4l_fd &fd, cv4l_queue &q, cv4l_buffer &buf,
 			sz = fwrite(comp_ptr[j] + offset, 1, used, fout);
 		else if (support_cap_compose && v4l2_fwht_find_pixfmt(fmt.g_pixelformat()))
 			read_write_padded_frame(fmt, (u8 *)q.g_dataptr(buf.g_index(), j) + offset,
-						fout, sz, used, false);
+						fout, sz, used, used, false);
 		else
 			sz = fwrite((u8 *)q.g_dataptr(buf.g_index(), j) + offset, 1, used, fout);