Module: Mesa
Branch: main
Commit: 7e9b06f1c6031224935685a841d81aafcf5bedba
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=7e9b06f1c6031224935685a841d81aafcf5bedba

Author: Benjamin Lee <[email protected]>
Date:   Sat Jun  3 15:53:33 2023 -0700

intel: Fix stack overflow in intel_dump_gpu

Previously, the call to ensure_device_info in the intercepted ioctl
would eventually result in another call to ioctl, recursing until stack
overflow:

 - ioctl (intercepted)
 - ensure_device_info
 - intel_get_device_info_from_fd
 - intel_device_info_i915_get_info_from_fd
 - getparam
 - intel_ioctl
 - ioctl (intercepted)

Signed-off-by: Benjamin Lee <[email protected]>
Reviewed-by: Lionel Landwerlin <[email protected]>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/23418>

---

 src/intel/tools/intel_dump_gpu.c | 30 ++++++++++++++++++++++++++++--
 1 file changed, 28 insertions(+), 2 deletions(-)

diff --git a/src/intel/tools/intel_dump_gpu.c b/src/intel/tools/intel_dump_gpu.c
index 71f29ed92fa..2e047cd2797 100644
--- a/src/intel/tools/intel_dump_gpu.c
+++ b/src/intel/tools/intel_dump_gpu.c
@@ -43,6 +43,7 @@
 #include "intel_aub.h"
 #include "aub_write.h"
 
+#include "c11/threads.h"
 #include "dev/intel_debug.h"
 #include "dev/intel_device_info.h"
 #include "common/intel_gem.h"
@@ -488,8 +489,8 @@ maybe_init(int fd)
              output_filename, device, devinfo.ver);
 }
 
-__attribute__ ((visibility ("default"))) int
-ioctl(int fd, unsigned long request, ...)
+static int
+intercept_ioctl(int fd, unsigned long request, ...)
 {
    va_list args;
    void *argp;
@@ -734,6 +735,31 @@ ioctl(int fd, unsigned long request, ...)
    }
 }
 
+__attribute__ ((visibility ("default"))) int
+ioctl(int fd, unsigned long request, ...)
+{
+   static thread_local bool entered = false;
+   va_list args;
+   void *argp;
+   int ret;
+
+   va_start(args, request);
+   argp = va_arg(args, void *);
+   va_end(args);
+
+   /* Some of the functions called by intercept_ioctl call ioctls of their
+    * own. These need to go to the libc ioctl instead of being passed back to
+    * intercept_ioctl to avoid a stack overflow. */
+   if (entered) {
+      return libc_ioctl(fd, request, argp);
+   } else {
+      entered = true;
+      ret = intercept_ioctl(fd, request, argp);
+      entered = false;
+      return ret;
+   }
+}
+
 static void
 init(void)
 {

Reply via email to