]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
gdb, gdbserver: fix read/write_ptid types
authorMarkus Metzger <markus.t.metzger@intel.com>
Wed, 24 Sep 2025 12:08:55 +0000 (12:08 +0000)
committerMarkus Metzger <markus.t.metzger@intel.com>
Mon, 17 Nov 2025 07:12:38 +0000 (07:12 +0000)
In write_ptid(), a ptid's LWP member, which is declared long, is stored in
an int local variable before printing, potentially truncating it.  Fix it.

In read_ptid(), both PID and LWP are read as ULONGEST and then cast to
their respective type without checking for overflows.  Fix it.

In read_ptid(), an empty component is treated as zero.  Diagnose that as
an error, instead.

Approved-By: Tom Tromey <tom@tromey.com>
gdb/remote.c
gdbserver/remote-utils.cc

index 80d47c16551757337b59201b30262bfe64ed3353..da44b22a259bd294ad96f2315e4de22dd10801d0 100644 (file)
@@ -3676,7 +3676,8 @@ static int remote_newthread_step (threadref *ref, void *context);
 char *
 remote_target::write_ptid (char *buf, const char *endbuf, ptid_t ptid)
 {
-  int pid, tid;
+  ptid_t::pid_type pid;
+  ptid_t::lwp_type lwp;
 
   if (m_features.remote_multi_process_p ())
     {
@@ -3686,11 +3687,11 @@ remote_target::write_ptid (char *buf, const char *endbuf, ptid_t ptid)
       else
        buf += xsnprintf (buf, endbuf - buf, "p%x.", pid);
     }
-  tid = ptid.lwp ();
-  if (tid < 0)
-    buf += xsnprintf (buf, endbuf - buf, "-%x", -tid);
+  lwp = ptid.lwp ();
+  if (lwp < 0)
+    buf += xsnprintf (buf, endbuf - buf, "-%lx", -lwp);
   else
-    buf += xsnprintf (buf, endbuf - buf, "%x", tid);
+    buf += xsnprintf (buf, endbuf - buf, "%lx", lwp);
 
   return buf;
 }
@@ -3704,24 +3705,38 @@ read_ptid (const char *buf, const char **obuf)
 {
   const char *p = buf;
   const char *pp;
-  ULONGEST pid = 0, tid = 0;
+  ptid_t::pid_type pid = 0;
+  ptid_t::lwp_type lwp = 0;
+  ULONGEST hex;
 
   if (*p == 'p')
     {
       /* Multi-process ptid.  */
-      pp = unpack_varlen_hex (p + 1, &pid);
-      if (*pp != '.')
-       error (_("invalid remote ptid: %s"), p);
+      pp = unpack_varlen_hex (p + 1, &hex);
+      if ((pp == (p + 1)) || (*pp != '.'))
+       error (_("invalid remote ptid: %s"), buf);
+
+      pid = (ptid_t::pid_type) (LONGEST) hex;
+      if (hex != ((ULONGEST) pid))
+       error (_("invalid remote ptid: %s"), buf);
+
+      p = pp + 1;
+      pp = unpack_varlen_hex (p, &hex);
+      if (pp == p)
+       error (_("invalid remote ptid: %s"), buf);
+
+      lwp = (ptid_t::lwp_type) (LONGEST) hex;
+      if (hex != ((ULONGEST) lwp))
+       error (_("invalid remote ptid: %s"), buf);
 
-      p = pp;
-      pp = unpack_varlen_hex (p + 1, &tid);
       if (obuf)
        *obuf = pp;
-      return ptid_t (pid, tid);
+
+      return ptid_t (pid, lwp);
     }
 
-  /* No multi-process.  Just a tid.  */
-  pp = unpack_varlen_hex (p, &tid);
+  /* No multi-process.  Just a thread id.  */
+  pp = unpack_varlen_hex (p, &hex);
 
   /* Return null_ptid when no thread id is found.  */
   if (p == pp)
@@ -3731,6 +3746,10 @@ read_ptid (const char *buf, const char **obuf)
       return null_ptid;
     }
 
+  lwp = (ptid_t::lwp_type) (LONGEST) hex;
+  if (hex != ((ULONGEST) lwp))
+    error (_("invalid remote ptid: %s"), buf);
+
   /* Since the stub is not sending a process id, default to what's
      current_inferior, unless it doesn't have a PID yet.  If so,
      then since there's no way to know the pid of the reported
@@ -3743,7 +3762,8 @@ read_ptid (const char *buf, const char **obuf)
 
   if (obuf)
     *obuf = pp;
-  return ptid_t (pid, tid);
+
+  return ptid_t (pid, lwp);
 }
 
 static int
index b7eed731749fe94e38f9419daa073bd7bb842ff6..023420b191fcba7519172f0b372e780f542ddf71 100644 (file)
@@ -519,7 +519,8 @@ char *
 write_ptid (char *buf, ptid_t ptid)
 {
   client_state &cs = get_client_state ();
-  int pid, tid;
+  ptid_t::pid_type pid;
+  ptid_t::lwp_type lwp;
 
   if (cs.multi_process)
     {
@@ -529,11 +530,11 @@ write_ptid (char *buf, ptid_t ptid)
       else
        buf += sprintf (buf, "p%x.", pid);
     }
-  tid = ptid.lwp ();
-  if (tid < 0)
-    buf += sprintf (buf, "-%x", -tid);
+  lwp = ptid.lwp ();
+  if (lwp < 0)
+    buf += sprintf (buf, "-%lx", -lwp);
   else
-    buf += sprintf (buf, "%x", tid);
+    buf += sprintf (buf, "%lx", lwp);
 
   return buf;
 }
@@ -564,45 +565,59 @@ read_ptid (const char *buf, const char **obuf)
 {
   const char *p = buf;
   const char *pp;
+  ptid_t::pid_type pid = 0;
+  ptid_t::lwp_type lwp = 0;
+  ULONGEST hex;
 
   if (*p == 'p')
     {
-      ULONGEST pid;
-
       /* Multi-process ptid.  */
-      pp = unpack_varlen_hex (p + 1, &pid);
-      if (*pp != '.')
-       error ("invalid remote ptid: %s\n", p);
+      pp = unpack_varlen_hex (p + 1, &hex);
+      if (pp == (p + 1) || *pp != '.')
+       error ("invalid remote ptid: %s\n", buf);
+
+      pid = (ptid_t::pid_type) (LONGEST) hex;
+      if (hex != ((ULONGEST) pid))
+       error (_("invalid remote ptid: %s"), buf);
 
       p = pp + 1;
+      hex = hex_or_minus_one (p, &pp);
+      if (pp == p)
+       error ("invalid remote ptid: %s\n", buf);
 
-      ULONGEST tid = hex_or_minus_one (p, &pp);
+      lwp = (ptid_t::lwp_type) (LONGEST) hex;
+      if (hex != ((ULONGEST) lwp))
+       error (_("invalid remote ptid: %s"), buf);
 
       if (obuf)
        *obuf = pp;
 
-      return ptid_t (pid, tid);
+      return ptid_t (pid, lwp);
     }
 
-  /* No multi-process.  Just a tid.  */
-  ULONGEST tid = hex_or_minus_one (p, &pp);
+  /* No multi-process.  Just a thread id.  */
+  hex = hex_or_minus_one (p, &pp);
 
   /* Handle special thread ids.  */
-  if (tid == (ULONGEST) -1)
+  if (hex == (ULONGEST) -1)
     return minus_one_ptid;
 
-  if (tid == 0)
+  if (hex == 0)
     return null_ptid;
 
+  lwp = (ptid_t::lwp_type) (LONGEST) hex;
+  if (hex != ((ULONGEST) lwp))
+    error (_("invalid remote ptid: %s"), buf);
+
   /* Since GDB is not sending a process id (multi-process extensions
      are off), then there's only one process.  Default to the first in
      the list.  */
-  int pid = get_first_process ()->pid;
+  pid = get_first_process ()->pid;
 
   if (obuf)
     *obuf = pp;
 
-  return ptid_t (pid, tid);
+  return ptid_t (pid, lwp);
 }
 
 /* Write COUNT bytes in BUF to the client.  Returns true if all bytes