1 /*- 2 * Copyright (c) 1989, 1992, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * This code is derived from software developed by the Computer Systems 6 * Engineering group at Lawrence Berkeley Laboratory under DARPA contract 7 * BG 91-66 and contributed to Berkeley. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. Neither the name of the University nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * 33 * @(#)kvm.c 8.2 (Berkeley) 2/13/94 34 * $FreeBSD: src/lib/libkvm/kvm.c,v 1.12.2.3 2002/09/13 14:53:43 nectar Exp $ 35 */ 36 37 #include <sys/user.h> /* MUST BE FIRST */ 38 #include <sys/param.h> 39 #include <sys/ioctl.h> 40 #include <sys/stat.h> 41 #include <sys/sysctl.h> 42 #include <sys/linker.h> 43 44 #include <vm/vm.h> 45 #include <vm/vm_param.h> 46 #include <vm/swap_pager.h> 47 48 #include <machine/vmparam.h> 49 50 #include <ctype.h> 51 #include <fcntl.h> 52 #include <limits.h> 53 #include <nlist.h> 54 #include <paths.h> 55 #include <stdio.h> 56 #include <stdlib.h> 57 #include <string.h> 58 #include <stdarg.h> 59 #include <unistd.h> 60 61 #include "kvm.h" 62 #include "kvm_private.h" 63 64 /* from src/lib/libc/gen/nlist.c */ 65 int __fdnlist (int, struct nlist *); 66 67 static int 68 kvm_notrans(kvm_t *kd) 69 { 70 return kvm_ishost(kd) || kvm_isvkernel(kd); 71 } 72 73 char * 74 kvm_geterr(kvm_t *kd) 75 { 76 return (kd->errbuf); 77 } 78 79 /* 80 * Report an error using printf style arguments. "program" is kd->program 81 * on hard errors, and 0 on soft errors, so that under sun error emulation, 82 * only hard errors are printed out (otherwise, programs like gdb will 83 * generate tons of error messages when trying to access bogus pointers). 84 */ 85 void 86 _kvm_err(kvm_t *kd, const char *program, const char *fmt, ...) 87 { 88 va_list ap; 89 90 va_start(ap, fmt); 91 if (program != NULL) { 92 (void)fprintf(stderr, "%s: ", program); 93 (void)vfprintf(stderr, fmt, ap); 94 (void)fputc('\n', stderr); 95 } else 96 (void)vsnprintf(kd->errbuf, 97 sizeof(kd->errbuf), fmt, ap); 98 99 va_end(ap); 100 } 101 102 void 103 _kvm_syserr(kvm_t *kd, const char *program, const char *fmt, ...) 104 { 105 va_list ap; 106 int n; 107 108 va_start(ap, fmt); 109 if (program != NULL) { 110 (void)fprintf(stderr, "%s: ", program); 111 (void)vfprintf(stderr, fmt, ap); 112 (void)fprintf(stderr, ": %s\n", strerror(errno)); 113 } else { 114 char *cp = kd->errbuf; 115 116 (void)vsnprintf(cp, sizeof(kd->errbuf), fmt, ap); 117 n = strlen(cp); 118 (void)snprintf(&cp[n], sizeof(kd->errbuf) - n, ": %s", 119 strerror(errno)); 120 } 121 va_end(ap); 122 } 123 124 void * 125 _kvm_malloc(kvm_t *kd, size_t n) 126 { 127 void *p; 128 129 if ((p = calloc(n, sizeof(char))) == NULL) 130 _kvm_err(kd, kd->program, "can't allocate %zd bytes: %s", 131 n, strerror(errno)); 132 return (p); 133 } 134 135 static int 136 is_proc_mem(const char *p) 137 { 138 static char proc[] = "/proc/"; 139 static char mem[] = "/mem"; 140 if (strncmp(proc, p, sizeof(proc) - 1)) 141 return 0; 142 p += sizeof(proc) - 1; 143 for (; *p != '\0'; ++p) 144 if (!isdigit(*p)) 145 break; 146 if (!isdigit(*(p - 1))) 147 return 0; 148 return !strncmp(p, mem, sizeof(mem) - 1); 149 } 150 151 static kvm_t * 152 _kvm_open(kvm_t *kd, const char *uf, const char *mf, int flag, char *errout) 153 { 154 struct stat st; 155 156 kd->vmfd = -1; 157 kd->pmfd = -1; 158 kd->nlfd = -1; 159 kd->vmst = 0; 160 kd->procbase = NULL; 161 kd->procend = NULL; 162 kd->argspc = 0; 163 kd->argv = 0; 164 kd->flags = 0; 165 166 if (uf == NULL) 167 uf = getbootfile(); 168 else if (strlen(uf) >= MAXPATHLEN) { 169 _kvm_err(kd, kd->program, "exec file name too long"); 170 goto failed; 171 } 172 if (flag & ~O_RDWR) { 173 _kvm_err(kd, kd->program, "bad flags arg"); 174 goto failed; 175 } 176 if (mf == NULL) 177 mf = _PATH_MEM; 178 179 if ((kd->pmfd = open(mf, flag, 0)) < 0) { 180 _kvm_syserr(kd, kd->program, "%s", mf); 181 goto failed; 182 } 183 if (fstat(kd->pmfd, &st) < 0) { 184 _kvm_syserr(kd, kd->program, "%s", mf); 185 goto failed; 186 } 187 if (fcntl(kd->pmfd, F_SETFD, FD_CLOEXEC) < 0) { 188 _kvm_syserr(kd, kd->program, "%s", mf); 189 goto failed; 190 } 191 if (S_ISCHR(st.st_mode)) { 192 /* 193 * If this is a character special device, then check that 194 * it's /dev/mem. If so, open kmem too. (Maybe we should 195 * make it work for either /dev/mem or /dev/kmem -- in either 196 * case you're working with a live kernel.) 197 */ 198 if (strcmp(mf, _PATH_DEVNULL) == 0) { 199 kd->vmfd = open(_PATH_DEVNULL, O_RDONLY); 200 } else { 201 if ((kd->vmfd = open(_PATH_KMEM, flag)) < 0) { 202 _kvm_syserr(kd, kd->program, "%s", _PATH_KMEM); 203 goto failed; 204 } 205 if (fcntl(kd->vmfd, F_SETFD, FD_CLOEXEC) < 0) { 206 _kvm_syserr(kd, kd->program, "%s", _PATH_KMEM); 207 goto failed; 208 } 209 } 210 kd->flags |= KVMF_HOST; 211 } else { 212 /* 213 * Crash dump or vkernel /proc/$pid/mem file: 214 * can't use kldsym, we are going to need ->nlfd 215 */ 216 if ((kd->nlfd = open(uf, O_RDONLY, 0)) < 0) { 217 _kvm_syserr(kd, kd->program, "%s", uf); 218 goto failed; 219 } 220 if (fcntl(kd->nlfd, F_SETFD, FD_CLOEXEC) < 0) { 221 _kvm_syserr(kd, kd->program, "%s", uf); 222 goto failed; 223 } 224 if(is_proc_mem(mf)) { 225 /* 226 * It's /proc/$pid/mem, so we rely on the host 227 * kernel to do address translation for us. 228 */ 229 kd->vmfd = kd->pmfd; 230 kd->pmfd = -1; 231 kd->flags |= KVMF_VKERN; 232 } else { 233 if (st.st_size <= 0) { 234 errno = EINVAL; 235 _kvm_syserr(kd, kd->program, "empty file"); 236 goto failed; 237 } 238 239 /* 240 * This is a crash dump. 241 * Initialize the virtual address translation machinery, 242 * but first setup the namelist fd. 243 */ 244 if (_kvm_initvtop(kd) < 0) 245 goto failed; 246 } 247 } 248 return (kd); 249 failed: 250 /* 251 * Copy out the error if doing sane error semantics. 252 */ 253 if (errout != NULL) 254 strlcpy(errout, kd->errbuf, _POSIX2_LINE_MAX); 255 (void)kvm_close(kd); 256 return (0); 257 } 258 259 kvm_t * 260 kvm_openfiles(const char *uf, const char *mf, const char *sf __unused, int flag, 261 char *errout) 262 { 263 kvm_t *kd; 264 265 if ((kd = malloc(sizeof(*kd))) == NULL) { 266 (void)strlcpy(errout, strerror(errno), _POSIX2_LINE_MAX); 267 return (0); 268 } 269 memset(kd, 0, sizeof(*kd)); 270 kd->program = 0; 271 return (_kvm_open(kd, uf, mf, flag, errout)); 272 } 273 274 kvm_t * 275 kvm_open(const char *uf, const char *mf, const char *sf __unused, int flag, 276 const char *errstr) 277 { 278 kvm_t *kd; 279 280 if ((kd = malloc(sizeof(*kd))) == NULL) { 281 if (errstr != NULL) 282 (void)fprintf(stderr, "%s: %s\n", 283 errstr, strerror(errno)); 284 return (0); 285 } 286 memset(kd, 0, sizeof(*kd)); 287 kd->program = errstr; 288 return (_kvm_open(kd, uf, mf, flag, NULL)); 289 } 290 291 int 292 kvm_close(kvm_t *kd) 293 { 294 int error = 0; 295 296 if (kd->pmfd >= 0) 297 error |= close(kd->pmfd); 298 if (kd->vmfd >= 0) 299 error |= close(kd->vmfd); 300 if (kd->nlfd >= 0) 301 error |= close(kd->nlfd); 302 if (kd->vmst) 303 _kvm_freevtop(kd); 304 if (kd->procbase != NULL) 305 free(kd->procbase); 306 if (kd->argv != 0) 307 free((void *)kd->argv); 308 free((void *)kd); 309 310 return (0); 311 } 312 313 int 314 kvm_nlist(kvm_t *kd, struct nlist *nl) 315 { 316 struct nlist *p; 317 int nvalid; 318 struct kld_sym_lookup lookup; 319 int error; 320 321 /* 322 * If we can't use the kld symbol lookup, revert to the 323 * slow library call. 324 */ 325 if (!kvm_ishost(kd)) 326 return (__fdnlist(kd->nlfd, nl)); 327 328 /* 329 * We can use the kld lookup syscall. Go through each nlist entry 330 * and look it up with a kldsym(2) syscall. 331 */ 332 nvalid = 0; 333 for (p = nl; p->n_name && p->n_name[0]; ++p) { 334 lookup.version = sizeof(lookup); 335 lookup.symname = p->n_name; 336 lookup.symvalue = 0; 337 lookup.symsize = 0; 338 339 if (lookup.symname[0] == '_') 340 lookup.symname++; 341 342 if (kldsym(0, KLDSYM_LOOKUP, &lookup) != -1) { 343 p->n_type = N_TEXT; 344 p->n_other = 0; 345 p->n_desc = 0; 346 p->n_value = lookup.symvalue; 347 ++nvalid; 348 /* lookup.symsize */ 349 } 350 } 351 /* 352 * Return the number of entries that weren't found. If they exist, 353 * also fill internal error buffer. 354 */ 355 error = ((p - nl) - nvalid); 356 if (error) 357 _kvm_syserr(kd, kd->program, "kvm_nlist"); 358 return (error); 359 } 360 361 ssize_t 362 kvm_read(kvm_t *kd, u_long kva, void *buf, size_t len) 363 { 364 int cc; 365 void *cp; 366 367 if (kvm_notrans(kd)) { 368 /* 369 * We're using /dev/kmem. Just read straight from the 370 * device and let the active kernel do the address translation. 371 */ 372 errno = 0; 373 if (lseek(kd->vmfd, (off_t)kva, 0) == -1 && errno != 0) { 374 _kvm_err(kd, 0, "invalid address (%lx)", kva); 375 return (-1); 376 } 377 378 /* 379 * Try to pre-fault the user memory to reduce instances of 380 * races within the kernel. XXX workaround for kernel bug 381 * where kernel does a sanity check, but user faults during 382 * the copy can block and race against another kernel entity 383 * unmapping the memory in question. 384 */ 385 bzero(buf, len); 386 cc = read(kd->vmfd, buf, len); 387 if (cc < 0) { 388 _kvm_syserr(kd, 0, "kvm_read"); 389 return (-1); 390 } else if (cc < (ssize_t)len) 391 _kvm_err(kd, kd->program, "short read"); 392 return (cc); 393 } else { 394 cp = buf; 395 while (len > 0) { 396 off_t pa; 397 398 cc = _kvm_kvatop(kd, kva, &pa); 399 if (cc == 0) 400 return (-1); 401 if (cc > (ssize_t)len) 402 cc = len; 403 errno = 0; 404 if (lseek(kd->pmfd, pa, 0) == -1 && errno != 0) { 405 _kvm_syserr(kd, 0, _PATH_MEM); 406 break; 407 } 408 bzero(cp, cc); 409 cc = read(kd->pmfd, cp, cc); 410 if (cc < 0) { 411 _kvm_syserr(kd, kd->program, "kvm_read"); 412 break; 413 } 414 /* 415 * If kvm_kvatop returns a bogus value or our core 416 * file is truncated, we might wind up seeking beyond 417 * the end of the core file in which case the read will 418 * return 0 (EOF). 419 */ 420 if (cc == 0) 421 break; 422 cp = (char *)cp + cc; 423 kva += cc; 424 len -= cc; 425 } 426 return ((char *)cp - (char *)buf); 427 } 428 /* NOTREACHED */ 429 } 430 431 char * 432 kvm_readstr(kvm_t *kd, u_long kva, char *buf, size_t *lenp) 433 { 434 size_t len, cc, pos; 435 char ch; 436 int asize = -1; 437 438 if (buf == NULL) { 439 asize = len = 16; 440 buf = malloc(len); 441 if (buf == NULL) { 442 _kvm_syserr(kd, kd->program, "kvm_readstr"); 443 return NULL; 444 } 445 } else { 446 len = *lenp; 447 } 448 449 if (kvm_notrans(kd)) { 450 /* 451 * We're using /dev/kmem. Just read straight from the 452 * device and let the active kernel do the address translation. 453 */ 454 errno = 0; 455 if (lseek(kd->vmfd, (off_t)kva, 0) == -1 && errno != 0) { 456 _kvm_err(kd, 0, "invalid address (%lx)", kva); 457 return NULL; 458 } 459 460 for (pos = 0, ch = -1; ch != 0; pos++) { 461 cc = read(kd->vmfd, &ch, 1); 462 if ((ssize_t)cc < 0) { 463 _kvm_syserr(kd, 0, "kvm_readstr"); 464 return NULL; 465 } else if (cc < 1) 466 _kvm_err(kd, kd->program, "short read"); 467 if (asize > 0 && asize == (ssize_t)pos) { 468 buf = realloc(buf, asize *= 2); 469 if (buf == NULL) { 470 _kvm_syserr(kd, kd->program, "kvm_readstr"); 471 return NULL; 472 } 473 len = asize; 474 } 475 if (pos < len) 476 buf[pos] = ch; 477 } 478 479 if (lenp != NULL) 480 *lenp = pos; 481 if (pos > len) 482 return NULL; 483 else 484 return buf; 485 } else { 486 size_t left = 0; 487 for (pos = 0, ch = -1; ch != 0; pos++, left--, kva++) { 488 if (left == 0) { 489 off_t pa; 490 491 left = _kvm_kvatop(kd, kva, &pa); 492 if (left == 0) 493 return NULL; 494 errno = 0; 495 if (lseek(kd->pmfd, (off_t)pa, 0) == -1 && errno != 0) { 496 _kvm_syserr(kd, 0, _PATH_MEM); 497 return NULL; 498 } 499 } 500 cc = read(kd->pmfd, &ch, 1); 501 if ((ssize_t)cc < 0) { 502 _kvm_syserr(kd, 0, "kvm_readstr"); 503 return NULL; 504 } else if (cc < 1) 505 _kvm_err(kd, kd->program, "short read"); 506 if (asize > 0 && asize == (ssize_t)pos) { 507 buf = realloc(buf, asize *= 2); 508 if (buf == NULL) { 509 _kvm_syserr(kd, kd->program, "kvm_readstr"); 510 return NULL; 511 } 512 len = asize; 513 } 514 if (pos < len) 515 buf[pos] = ch; 516 } 517 518 if (lenp != NULL) 519 *lenp = pos; 520 if (pos > len) 521 return NULL; 522 else 523 return buf; 524 } 525 /* NOTREACHED */ 526 } 527 528 ssize_t 529 kvm_write(kvm_t *kd, u_long kva, const void *buf, size_t len) 530 { 531 int cc; 532 533 if (kvm_notrans(kd)) { 534 /* 535 * Just like kvm_read, only we write. 536 */ 537 errno = 0; 538 if (lseek(kd->vmfd, (off_t)kva, 0) == -1 && errno != 0) { 539 _kvm_err(kd, 0, "invalid address (%lx)", kva); 540 return (-1); 541 } 542 cc = write(kd->vmfd, buf, len); 543 if (cc < 0) { 544 _kvm_syserr(kd, 0, "kvm_write"); 545 return (-1); 546 } else if (cc < (ssize_t)len) 547 _kvm_err(kd, kd->program, "short write"); 548 return (cc); 549 } else { 550 _kvm_err(kd, kd->program, 551 "kvm_write not implemented for dead kernels"); 552 return (-1); 553 } 554 /* NOTREACHED */ 555 } 556