mirror of
https://github.com/torvalds/linux.git
synced 2026-09-22 12:44:03 +02:00
perf trace-event: Fix integer truncation in do_read() and skip()
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: 4a31e56599 ("perf tools: Get rid of read_or_die() in trace-event-read.c")
Signed-off-by: Tanushree Shah <tshah@linux.ibm.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
This commit is contained in:
parent
1121a7af18
commit
c108c1391b
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user