aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJiri Olsa <jolsa@kernel.org>2014-05-07 12:51:41 -0400
committerJiri Olsa <jolsa@kernel.org>2014-06-12 10:53:21 -0400
commitc3fbd2a606c5f88de0079b027727a1fb0ae27b65 (patch)
treef3704df2485b4250ac7df3027edf7a665ef68cb1
parentc658045197814b7d762662f9aa9f652379121a03 (diff)
perf tools: Add file size check and factor dso__data_read_offset
Adding file size check, because the lseek will succeed for any offset behind file size and thus succeed when it was expected to fail. Factoring the code to check the offset against file size earlier in the flow. Acked-by: Namhyung Kim <namhyung@kernel.org> Cc: Arnaldo Carvalho de Melo <acme@kernel.org> Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com> Cc: David Ahern <dsahern@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Ingo Molnar <mingo@kernel.org> Cc: Jean Pihet <jean.pihet@linaro.org> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Link: http://lkml.kernel.org/r/1401892622-30848-8-git-send-email-jolsa@kernel.org Signed-off-by: Jiri Olsa <jolsa@kernel.org>
-rw-r--r--tools/perf/util/dso.c64
-rw-r--r--tools/perf/util/dso.h1
2 files changed, 50 insertions, 15 deletions
diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c
index fbf6cc98b8a9..db634383156c 100644
--- a/tools/perf/util/dso.c
+++ b/tools/perf/util/dso.c
@@ -205,6 +205,7 @@ static void close_data_fd(struct dso *dso)
205 if (dso->data.fd >= 0) { 205 if (dso->data.fd >= 0) {
206 close(dso->data.fd); 206 close(dso->data.fd);
207 dso->data.fd = -1; 207 dso->data.fd = -1;
208 dso->data.file_size = 0;
208 dso__list_del(dso); 209 dso__list_del(dso);
209 } 210 }
210} 211}
@@ -373,16 +374,10 @@ dso_cache__memcpy(struct dso_cache *cache, u64 offset,
373} 374}
374 375
375static ssize_t 376static ssize_t
376dso_cache__read(struct dso *dso, struct machine *machine, 377dso_cache__read(struct dso *dso, u64 offset, u8 *data, ssize_t size)
377 u64 offset, u8 *data, ssize_t size)
378{ 378{
379 struct dso_cache *cache; 379 struct dso_cache *cache;
380 ssize_t ret; 380 ssize_t ret;
381 int fd;
382
383 fd = dso__data_fd(dso, machine);
384 if (fd < 0)
385 return -1;
386 381
387 do { 382 do {
388 u64 cache_offset; 383 u64 cache_offset;
@@ -396,10 +391,10 @@ dso_cache__read(struct dso *dso, struct machine *machine,
396 cache_offset = offset & DSO__DATA_CACHE_MASK; 391 cache_offset = offset & DSO__DATA_CACHE_MASK;
397 ret = -EINVAL; 392 ret = -EINVAL;
398 393
399 if (-1 == lseek(fd, cache_offset, SEEK_SET)) 394 if (-1 == lseek(dso->data.fd, cache_offset, SEEK_SET))
400 break; 395 break;
401 396
402 ret = read(fd, cache->data, DSO__DATA_CACHE_SIZE); 397 ret = read(dso->data.fd, cache->data, DSO__DATA_CACHE_SIZE);
403 if (ret <= 0) 398 if (ret <= 0)
404 break; 399 break;
405 400
@@ -417,8 +412,8 @@ dso_cache__read(struct dso *dso, struct machine *machine,
417 return ret; 412 return ret;
418} 413}
419 414
420static ssize_t dso_cache_read(struct dso *dso, struct machine *machine, 415static ssize_t dso_cache_read(struct dso *dso, u64 offset,
421 u64 offset, u8 *data, ssize_t size) 416 u8 *data, ssize_t size)
422{ 417{
423 struct dso_cache *cache; 418 struct dso_cache *cache;
424 419
@@ -426,11 +421,10 @@ static ssize_t dso_cache_read(struct dso *dso, struct machine *machine,
426 if (cache) 421 if (cache)
427 return dso_cache__memcpy(cache, offset, data, size); 422 return dso_cache__memcpy(cache, offset, data, size);
428 else 423 else
429 return dso_cache__read(dso, machine, offset, data, size); 424 return dso_cache__read(dso, offset, data, size);
430} 425}
431 426
432ssize_t dso__data_read_offset(struct dso *dso, struct machine *machine, 427static ssize_t cached_read(struct dso *dso, u64 offset, u8 *data, ssize_t size)
433 u64 offset, u8 *data, ssize_t size)
434{ 428{
435 ssize_t r = 0; 429 ssize_t r = 0;
436 u8 *p = data; 430 u8 *p = data;
@@ -438,7 +432,7 @@ ssize_t dso__data_read_offset(struct dso *dso, struct machine *machine,
438 do { 432 do {
439 ssize_t ret; 433 ssize_t ret;
440 434
441 ret = dso_cache_read(dso, machine, offset, p, size); 435 ret = dso_cache_read(dso, offset, p, size);
442 if (ret < 0) 436 if (ret < 0)
443 return ret; 437 return ret;
444 438
@@ -458,6 +452,46 @@ ssize_t dso__data_read_offset(struct dso *dso, struct machine *machine,
458 return r; 452 return r;
459} 453}
460 454
455static int data_file_size(struct dso *dso)
456{
457 struct stat st;
458
459 if (!dso->data.file_size) {
460 if (fstat(dso->data.fd, &st)) {
461 pr_err("dso mmap failed, fstat: %s\n", strerror(errno));
462 return -1;
463 }
464 dso->data.file_size = st.st_size;
465 }
466
467 return 0;
468}
469
470static ssize_t data_read_offset(struct dso *dso, u64 offset,
471 u8 *data, ssize_t size)
472{
473 if (data_file_size(dso))
474 return -1;
475
476 /* Check the offset sanity. */
477 if (offset > dso->data.file_size)
478 return -1;
479
480 if (offset + size < offset)
481 return -1;
482
483 return cached_read(dso, offset, data, size);
484}
485
486ssize_t dso__data_read_offset(struct dso *dso, struct machine *machine,
487 u64 offset, u8 *data, ssize_t size)
488{
489 if (dso__data_fd(dso, machine) < 0)
490 return -1;
491
492 return data_read_offset(dso, offset, data, size);
493}
494
461ssize_t dso__data_read_addr(struct dso *dso, struct map *map, 495ssize_t dso__data_read_addr(struct dso *dso, struct map *map,
462 struct machine *machine, u64 addr, 496 struct machine *machine, u64 addr,
463 u8 *data, ssize_t size) 497 u8 *data, ssize_t size)
diff --git a/tools/perf/util/dso.h b/tools/perf/util/dso.h
index 90988bf06641..da47b13595f3 100644
--- a/tools/perf/util/dso.h
+++ b/tools/perf/util/dso.h
@@ -103,6 +103,7 @@ struct dso {
103 struct { 103 struct {
104 struct rb_root cache; 104 struct rb_root cache;
105 int fd; 105 int fd;
106 size_t file_size;
106 struct list_head open_entry; 107 struct list_head open_entry;
107 } data; 108 } data;
108 109