1 /* Host file transfer support for gdbserver. 2 Copyright (C) 2007-2020 Free Software Foundation, Inc. 3 4 Contributed by CodeSourcery. 5 6 This file is part of GDB. 7 8 This program is free software; you can redistribute it and/or modify 9 it under the terms of the GNU General Public License as published by 10 the Free Software Foundation; either version 3 of the License, or 11 (at your option) any later version. 12 13 This program is distributed in the hope that it will be useful, 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 GNU General Public License for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 20 21 #include "server.h" 22 #include "gdb/fileio.h" 23 #include "hostio.h" 24 25 #include <fcntl.h> 26 #include <limits.h> 27 #include <unistd.h> 28 #include <sys/types.h> 29 #include <sys/stat.h> 30 #include "gdbsupport/fileio.h" 31 32 struct fd_list 33 { 34 int fd; 35 struct fd_list *next; 36 }; 37 38 static struct fd_list *open_fds; 39 40 static int 41 safe_fromhex (char a, int *nibble) 42 { 43 if (a >= '0' && a <= '9') 44 *nibble = a - '0'; 45 else if (a >= 'a' && a <= 'f') 46 *nibble = a - 'a' + 10; 47 else if (a >= 'A' && a <= 'F') 48 *nibble = a - 'A' + 10; 49 else 50 return -1; 51 52 return 0; 53 } 54 55 /* Filenames are hex encoded, so the maximum we can handle is half the 56 packet buffer size. Cap to PATH_MAX, if it is shorter. */ 57 #if !defined (PATH_MAX) || (PATH_MAX > (PBUFSIZ / 2 + 1)) 58 # define HOSTIO_PATH_MAX (PBUFSIZ / 2 + 1) 59 #else 60 # define HOSTIO_PATH_MAX PATH_MAX 61 #endif 62 63 static int 64 require_filename (char **pp, char *filename) 65 { 66 int count; 67 char *p; 68 69 p = *pp; 70 count = 0; 71 72 while (*p && *p != ',') 73 { 74 int nib1, nib2; 75 76 /* Don't allow overflow. */ 77 if (count >= HOSTIO_PATH_MAX - 1) 78 return -1; 79 80 if (safe_fromhex (p[0], &nib1) 81 || safe_fromhex (p[1], &nib2)) 82 return -1; 83 84 filename[count++] = nib1 * 16 + nib2; 85 p += 2; 86 } 87 88 filename[count] = '\0'; 89 *pp = p; 90 return 0; 91 } 92 93 static int 94 require_int (char **pp, int *value) 95 { 96 char *p; 97 int count, firstdigit; 98 99 p = *pp; 100 *value = 0; 101 count = 0; 102 firstdigit = -1; 103 104 while (*p && *p != ',') 105 { 106 int nib; 107 108 if (safe_fromhex (p[0], &nib)) 109 return -1; 110 111 if (firstdigit == -1) 112 firstdigit = nib; 113 114 /* Don't allow overflow. */ 115 if (count >= 8 || (count == 7 && firstdigit >= 0x8)) 116 return -1; 117 118 *value = *value * 16 + nib; 119 p++; 120 count++; 121 } 122 123 *pp = p; 124 return 0; 125 } 126 127 static int 128 require_data (char *p, int p_len, char **data, int *data_len) 129 { 130 int input_index, output_index, escaped; 131 132 *data = (char *) xmalloc (p_len); 133 134 output_index = 0; 135 escaped = 0; 136 for (input_index = 0; input_index < p_len; input_index++) 137 { 138 char b = p[input_index]; 139 140 if (escaped) 141 { 142 (*data)[output_index++] = b ^ 0x20; 143 escaped = 0; 144 } 145 else if (b == '}') 146 escaped = 1; 147 else 148 (*data)[output_index++] = b; 149 } 150 151 if (escaped) 152 { 153 free (*data); 154 return -1; 155 } 156 157 *data_len = output_index; 158 return 0; 159 } 160 161 static int 162 require_comma (char **pp) 163 { 164 if (**pp == ',') 165 { 166 (*pp)++; 167 return 0; 168 } 169 else 170 return -1; 171 } 172 173 static int 174 require_end (char *p) 175 { 176 if (*p == '\0') 177 return 0; 178 else 179 return -1; 180 } 181 182 static int 183 require_valid_fd (int fd) 184 { 185 struct fd_list *fd_ptr; 186 187 for (fd_ptr = open_fds; fd_ptr != NULL; fd_ptr = fd_ptr->next) 188 if (fd_ptr->fd == fd) 189 return 0; 190 191 return -1; 192 } 193 194 /* Fill in own_buf with the last hostio error packet, however it 195 suitable for the target. */ 196 static void 197 hostio_error (char *own_buf) 198 { 199 the_target->hostio_last_error (own_buf); 200 } 201 202 static void 203 hostio_packet_error (char *own_buf) 204 { 205 sprintf (own_buf, "F-1,%x", FILEIO_EINVAL); 206 } 207 208 static void 209 hostio_reply (char *own_buf, int result) 210 { 211 sprintf (own_buf, "F%x", result); 212 } 213 214 static int 215 hostio_reply_with_data (char *own_buf, char *buffer, int len, 216 int *new_packet_len) 217 { 218 int input_index, output_index, out_maxlen; 219 220 sprintf (own_buf, "F%x;", len); 221 output_index = strlen (own_buf); 222 223 out_maxlen = PBUFSIZ; 224 225 for (input_index = 0; input_index < len; input_index++) 226 { 227 char b = buffer[input_index]; 228 229 if (b == '$' || b == '#' || b == '}' || b == '*') 230 { 231 /* These must be escaped. */ 232 if (output_index + 2 > out_maxlen) 233 break; 234 own_buf[output_index++] = '}'; 235 own_buf[output_index++] = b ^ 0x20; 236 } 237 else 238 { 239 if (output_index + 1 > out_maxlen) 240 break; 241 own_buf[output_index++] = b; 242 } 243 } 244 245 *new_packet_len = output_index; 246 return input_index; 247 } 248 249 /* Process ID of inferior whose filesystem hostio functions 250 that take FILENAME arguments will use. Zero means to use 251 our own filesystem. */ 252 253 static int hostio_fs_pid; 254 255 /* See hostio.h. */ 256 257 void 258 hostio_handle_new_gdb_connection (void) 259 { 260 hostio_fs_pid = 0; 261 } 262 263 /* Handle a "vFile:setfs:" packet. */ 264 265 static void 266 handle_setfs (char *own_buf) 267 { 268 char *p; 269 int pid; 270 271 /* If the target doesn't have any of the in-filesystem-of methods 272 then there's no point in GDB sending "vFile:setfs:" packets. We 273 reply with an empty packet (i.e. we pretend we don't understand 274 "vFile:setfs:") and that should stop GDB sending any more. */ 275 if (!the_target->supports_multifs ()) 276 { 277 own_buf[0] = '\0'; 278 return; 279 } 280 281 p = own_buf + strlen ("vFile:setfs:"); 282 283 if (require_int (&p, &pid) 284 || pid < 0 285 || require_end (p)) 286 { 287 hostio_packet_error (own_buf); 288 return; 289 } 290 291 hostio_fs_pid = pid; 292 293 hostio_reply (own_buf, 0); 294 } 295 296 static void 297 handle_open (char *own_buf) 298 { 299 char filename[HOSTIO_PATH_MAX]; 300 char *p; 301 int fileio_flags, fileio_mode, flags, fd; 302 mode_t mode; 303 struct fd_list *new_fd; 304 305 p = own_buf + strlen ("vFile:open:"); 306 307 if (require_filename (&p, filename) 308 || require_comma (&p) 309 || require_int (&p, &fileio_flags) 310 || require_comma (&p) 311 || require_int (&p, &fileio_mode) 312 || require_end (p) 313 || fileio_to_host_openflags (fileio_flags, &flags) 314 || fileio_to_host_mode (fileio_mode, &mode)) 315 { 316 hostio_packet_error (own_buf); 317 return; 318 } 319 320 /* We do not need to convert MODE, since the fileio protocol 321 uses the standard values. */ 322 if (hostio_fs_pid != 0) 323 fd = the_target->multifs_open (hostio_fs_pid, filename, flags, mode); 324 else 325 fd = open (filename, flags, mode); 326 327 if (fd == -1) 328 { 329 hostio_error (own_buf); 330 return; 331 } 332 333 /* Record the new file descriptor. */ 334 new_fd = XNEW (struct fd_list); 335 new_fd->fd = fd; 336 new_fd->next = open_fds; 337 open_fds = new_fd; 338 339 hostio_reply (own_buf, fd); 340 } 341 342 static void 343 handle_pread (char *own_buf, int *new_packet_len) 344 { 345 int fd, ret, len, offset, bytes_sent; 346 char *p, *data; 347 static int max_reply_size = -1; 348 349 p = own_buf + strlen ("vFile:pread:"); 350 351 if (require_int (&p, &fd) 352 || require_comma (&p) 353 || require_valid_fd (fd) 354 || require_int (&p, &len) 355 || require_comma (&p) 356 || require_int (&p, &offset) 357 || require_end (p)) 358 { 359 hostio_packet_error (own_buf); 360 return; 361 } 362 363 /* Do not attempt to read more than the maximum number of bytes 364 hostio_reply_with_data can fit in a packet. We may still read 365 too much because of escaping, but this is handled below. */ 366 if (max_reply_size == -1) 367 { 368 sprintf (own_buf, "F%x;", PBUFSIZ); 369 max_reply_size = PBUFSIZ - strlen (own_buf); 370 } 371 if (len > max_reply_size) 372 len = max_reply_size; 373 374 data = (char *) xmalloc (len); 375 #ifdef HAVE_PREAD 376 ret = pread (fd, data, len, offset); 377 #else 378 ret = -1; 379 #endif 380 /* If we have no pread or it failed for this file, use lseek/read. */ 381 if (ret == -1) 382 { 383 ret = lseek (fd, offset, SEEK_SET); 384 if (ret != -1) 385 ret = read (fd, data, len); 386 } 387 388 if (ret == -1) 389 { 390 hostio_error (own_buf); 391 free (data); 392 return; 393 } 394 395 bytes_sent = hostio_reply_with_data (own_buf, data, ret, new_packet_len); 396 397 /* If we were using read, and the data did not all fit in the reply, 398 we would have to back up using lseek here. With pread it does 399 not matter. But we still have a problem; the return value in the 400 packet might be wrong, so we must fix it. This time it will 401 definitely fit. */ 402 if (bytes_sent < ret) 403 bytes_sent = hostio_reply_with_data (own_buf, data, bytes_sent, 404 new_packet_len); 405 406 free (data); 407 } 408 409 static void 410 handle_pwrite (char *own_buf, int packet_len) 411 { 412 int fd, ret, len, offset; 413 char *p, *data; 414 415 p = own_buf + strlen ("vFile:pwrite:"); 416 417 if (require_int (&p, &fd) 418 || require_comma (&p) 419 || require_valid_fd (fd) 420 || require_int (&p, &offset) 421 || require_comma (&p) 422 || require_data (p, packet_len - (p - own_buf), &data, &len)) 423 { 424 hostio_packet_error (own_buf); 425 return; 426 } 427 428 #ifdef HAVE_PWRITE 429 ret = pwrite (fd, data, len, offset); 430 #else 431 ret = -1; 432 #endif 433 /* If we have no pwrite or it failed for this file, use lseek/write. */ 434 if (ret == -1) 435 { 436 ret = lseek (fd, offset, SEEK_SET); 437 if (ret != -1) 438 ret = write (fd, data, len); 439 } 440 441 if (ret == -1) 442 { 443 hostio_error (own_buf); 444 free (data); 445 return; 446 } 447 448 hostio_reply (own_buf, ret); 449 free (data); 450 } 451 452 static void 453 handle_fstat (char *own_buf, int *new_packet_len) 454 { 455 int fd, bytes_sent; 456 char *p; 457 struct stat st; 458 struct fio_stat fst; 459 460 p = own_buf + strlen ("vFile:fstat:"); 461 462 if (require_int (&p, &fd) 463 || require_valid_fd (fd) 464 || require_end (p)) 465 { 466 hostio_packet_error (own_buf); 467 return; 468 } 469 470 if (fstat (fd, &st) == -1) 471 { 472 hostio_error (own_buf); 473 return; 474 } 475 476 host_to_fileio_stat (&st, &fst); 477 478 bytes_sent = hostio_reply_with_data (own_buf, 479 (char *) &fst, sizeof (fst), 480 new_packet_len); 481 482 /* If the response does not fit into a single packet, do not attempt 483 to return a partial response, but simply fail. */ 484 if (bytes_sent < sizeof (fst)) 485 write_enn (own_buf); 486 } 487 488 static void 489 handle_close (char *own_buf) 490 { 491 int fd, ret; 492 char *p; 493 struct fd_list **open_fd_p, *old_fd; 494 495 p = own_buf + strlen ("vFile:close:"); 496 497 if (require_int (&p, &fd) 498 || require_valid_fd (fd) 499 || require_end (p)) 500 { 501 hostio_packet_error (own_buf); 502 return; 503 } 504 505 ret = close (fd); 506 507 if (ret == -1) 508 { 509 hostio_error (own_buf); 510 return; 511 } 512 513 open_fd_p = &open_fds; 514 /* We know that fd is in the list, thanks to require_valid_fd. */ 515 while ((*open_fd_p)->fd != fd) 516 open_fd_p = &(*open_fd_p)->next; 517 518 old_fd = *open_fd_p; 519 *open_fd_p = (*open_fd_p)->next; 520 free (old_fd); 521 522 hostio_reply (own_buf, ret); 523 } 524 525 static void 526 handle_unlink (char *own_buf) 527 { 528 char filename[HOSTIO_PATH_MAX]; 529 char *p; 530 int ret; 531 532 p = own_buf + strlen ("vFile:unlink:"); 533 534 if (require_filename (&p, filename) 535 || require_end (p)) 536 { 537 hostio_packet_error (own_buf); 538 return; 539 } 540 541 if (hostio_fs_pid != 0) 542 ret = the_target->multifs_unlink (hostio_fs_pid, filename); 543 else 544 ret = unlink (filename); 545 546 if (ret == -1) 547 { 548 hostio_error (own_buf); 549 return; 550 } 551 552 hostio_reply (own_buf, ret); 553 } 554 555 static void 556 handle_readlink (char *own_buf, int *new_packet_len) 557 { 558 char filename[HOSTIO_PATH_MAX], linkname[HOSTIO_PATH_MAX]; 559 char *p; 560 int ret, bytes_sent; 561 562 p = own_buf + strlen ("vFile:readlink:"); 563 564 if (require_filename (&p, filename) 565 || require_end (p)) 566 { 567 hostio_packet_error (own_buf); 568 return; 569 } 570 571 if (hostio_fs_pid != 0) 572 ret = the_target->multifs_readlink (hostio_fs_pid, filename, 573 linkname, 574 sizeof (linkname) - 1); 575 else 576 ret = readlink (filename, linkname, sizeof (linkname) - 1); 577 578 if (ret == -1) 579 { 580 hostio_error (own_buf); 581 return; 582 } 583 584 bytes_sent = hostio_reply_with_data (own_buf, linkname, ret, new_packet_len); 585 586 /* If the response does not fit into a single packet, do not attempt 587 to return a partial response, but simply fail. */ 588 if (bytes_sent < ret) 589 sprintf (own_buf, "F-1,%x", FILEIO_ENAMETOOLONG); 590 } 591 592 /* Handle all the 'F' file transfer packets. */ 593 594 int 595 handle_vFile (char *own_buf, int packet_len, int *new_packet_len) 596 { 597 if (startswith (own_buf, "vFile:open:")) 598 handle_open (own_buf); 599 else if (startswith (own_buf, "vFile:pread:")) 600 handle_pread (own_buf, new_packet_len); 601 else if (startswith (own_buf, "vFile:pwrite:")) 602 handle_pwrite (own_buf, packet_len); 603 else if (startswith (own_buf, "vFile:fstat:")) 604 handle_fstat (own_buf, new_packet_len); 605 else if (startswith (own_buf, "vFile:close:")) 606 handle_close (own_buf); 607 else if (startswith (own_buf, "vFile:unlink:")) 608 handle_unlink (own_buf); 609 else if (startswith (own_buf, "vFile:readlink:")) 610 handle_readlink (own_buf, new_packet_len); 611 else if (startswith (own_buf, "vFile:setfs:")) 612 handle_setfs (own_buf); 613 else 614 return 0; 615 616 return 1; 617 } 618