The do_read() and skip() functions use 'int' for size parameters,
truncating 64-bit sizes from callers. This causes two issues:

1. Uninitialized memory dump: do_read() reads fewer bytes than
   allocated, leaving uninitialized heap memory that gets written
   to output files.

2. Out-of-bounds read: Parsing functions process the full 64-bit
   size while only partial data was read into the buffer.

Change do_read(), __do_read(), and skip() to use size_t for size
parameters and ssize_t for return values (where applicable), matching
read()/write() system calls.
Update callers to use ssize_t for storing return values.

Fixes: 454c407ec17a ("perf tools: Get rid of read_or_die() in 
trace-event-read.c")
Signed-off-by: Tanushree Shah <[email protected]>
---
 tools/perf/util/trace-event-read.c | 28 ++++++++++++++--------------
 1 file changed, 14 insertions(+), 14 deletions(-)

diff --git a/tools/perf/util/trace-event-read.c 
b/tools/perf/util/trace-event-read.c
index afd458cf1387..52ed496d92c3 100644
--- a/tools/perf/util/trace-event-read.c
+++ b/tools/perf/util/trace-event-read.c
@@ -25,18 +25,18 @@ static int input_fd;
 static ssize_t trace_data_size;
 static bool repipe;
 
-static int __do_read(int fd, void *buf, int size)
+static ssize_t __do_read(int fd, void *buf, size_t size)
 {
-       int rsize = size;
+       size_t rsize = size;
 
        while (size) {
-               int ret = read(fd, buf, size);
+               ssize_t ret = read(fd, buf, size);
 
                if (ret <= 0)
                        return -1;
 
                if (repipe) {
-                       int retw = write(STDOUT_FILENO, buf, ret);
+                       ssize_t retw = write(STDOUT_FILENO, buf, ret);
 
                        if (retw <= 0 || retw != ret) {
                                pr_debug("repiping input file");
@@ -51,13 +51,13 @@ static int __do_read(int fd, void *buf, int size)
        return rsize;
 }
 
-static int do_read(void *data, int size)
+static ssize_t do_read(void *data, size_t size)
 {
-       int r;
+       ssize_t r;
 
        r = __do_read(input_fd, data, size);
        if (r <= 0) {
-               pr_debug("reading input file (size expected=%d received=%d)",
+               pr_debug("reading input file (size expected=%zu received=%zd)",
                         size, r);
                return -1;
        }
@@ -68,10 +68,10 @@ static int do_read(void *data, int size)
 }
 
 /* If it fails, the next read will report it */
-static void skip(int size)
+static void skip(size_t size)
 {
        char buf[BUFSIZ];
-       int r;
+       size_t r;
 
        while (size) {
                r = size > BUFSIZ ? BUFSIZ : size;
@@ -202,7 +202,7 @@ static int read_header_files(struct tep_handle *pevent)
        unsigned long long size;
        char *header_page;
        char buf[BUFSIZ];
-       int ret = 0;
+       ssize_t ret = 0;
 
        if (do_read(buf, 12) < 0)
                return -1;
@@ -250,7 +250,7 @@ static int read_header_files(struct tep_handle *pevent)
 
 static int read_ftrace_file(struct tep_handle *pevent, unsigned long long size)
 {
-       int ret;
+       ssize_t ret;
        char *buf;
 
        buf = malloc(size);
@@ -276,7 +276,7 @@ static int read_ftrace_file(struct tep_handle *pevent, 
unsigned long long size)
 static int read_event_file(struct tep_handle *pevent, char *sys,
                           unsigned long long size)
 {
-       int ret;
+       ssize_t ret;
        char *buf;
 
        buf = malloc(size);
@@ -322,7 +322,7 @@ static int read_event_files(struct tep_handle *pevent)
        int systems;
        int count;
        int i,x;
-       int ret;
+       ssize_t ret;
 
        systems = read4(pevent);
 
@@ -350,7 +350,7 @@ static int read_saved_cmdline(struct tep_handle *pevent)
 {
        unsigned long long size;
        char *buf;
-       int ret;
+       ssize_t ret;
 
        /* it can have 0 size */
        size = read8(pevent);
-- 
2.47.3


Reply via email to