perf_reader: allow more than one reader to poll
authorDr.Z <korea.drzix@gmail.com>
Wed, 21 Oct 2015 12:52:10 +0000 (21:52 +0900)
committerDr.Z <korea.drzix@gmail.com>
Wed, 21 Oct 2015 13:08:45 +0000 (22:08 +0900)
When more than one events are used with attach_kprobe, the
perf_reader_poll() will segfault by buffer overflow like below.

*** buffer overflow detected ***: python terminated
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x7338f)[0x7fcc971fb38f]
/lib/x86_64-linux-gnu/libc.so.6(__fortify_fail+0x5c)[0x7fcc97292c9c]
/lib/x86_64-linux-gnu/libc.so.6(+0x109b60)[0x7fcc97291b60]
/lib/x86_64-linux-gnu/libc.so.6(+0x10ac04)[0x7fcc97292c04]
/usr/lib/x86_64-linux-gnu/libbcc.so(perf_reader_poll+0x42)[0x7fcc93969cc2]
/usr/lib/x86_64-linux-gnu/libffi.so.6(ffi_call_unix64+0x4c)[0x7fcc95c2badc]
/usr/lib/x86_64-linux-gnu/libffi.so.6(ffi_call+0x1fc)[0x7fcc95c2b40c]
/usr/lib/python2.7/lib-dynload/_ctypes.x86_64-linux-gnu.so(_ctypes_callproc+0x48e)[0x7fcc95e425fe]
/usr/lib/python2.7/lib-dynload/_ctypes.x86_64-linux-gnu.so(+0x15f9e)[0x7fcc95e43f9e]
python(PyEval_EvalFrameEx+0x965)[0x499be5]
python(PyEval_EvalCodeEx+0x2ac)[0x4a090c]
python(PyEval_EvalFrameEx+0x7d2)[0x499a52]
python[0x4a1634]
python(PyRun_FileExFlags+0x92)[0x44e4a5]
python(PyRun_SimpleFileExFlags+0x2ee)[0x44ec9f]
python(Py_Main+0xb5e)[0x44f904]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf5)[0x7fcc971a9ec5]
python[0x578c4e]

src/cc/perf_reader.c

index 9a9e891..467e704 100644 (file)
@@ -206,11 +206,15 @@ static void event_read(struct perf_reader *reader) {
 }
 
 int perf_reader_poll(int num_readers, struct perf_reader **readers, int timeout) {
-  struct pollfd pfds[] = {
-    {readers[0]->fd, POLLIN},
-  };
+  struct pollfd pfds[num_readers];
+  int i;
+
+  for (i = 0; i <num_readers; ++i) {
+    pfds[i].fd = readers[i]->fd;
+    pfds[i].events = POLLIN;
+  }
+
   if (poll(pfds, num_readers, timeout) > 0) {
-    int i;
     for (i = 0; i < num_readers; ++i) {
       if (pfds[i].revents & POLLIN)
         event_read(readers[i]);