From: Markus Metzger Date: Wed, 24 Sep 2025 12:08:55 +0000 (+0000) Subject: gdb, gdbserver: fix read/write_ptid types X-Git-Tag: binutils-2_46~912 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7db0fccae52949d98eba248ba7ecd9318edfe20a;p=thirdparty%2Fbinutils-gdb.git gdb, gdbserver: fix read/write_ptid types 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 --- diff --git a/gdb/remote.c b/gdb/remote.c index 80d47c16551..da44b22a259 100644 --- a/gdb/remote.c +++ b/gdb/remote.c @@ -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 diff --git a/gdbserver/remote-utils.cc b/gdbserver/remote-utils.cc index b7eed731749..023420b191f 100644 --- a/gdbserver/remote-utils.cc +++ b/gdbserver/remote-utils.cc @@ -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