Wed Aug 26 23:08:29 2020 UTC ()
Provide a helpful error message if we don't have privs to read kernel
addresses.


(christos)
diff -r1.113 -r1.114 src/usr.bin/fstat/fstat.c

cvs diff -r1.113 -r1.114 src/usr.bin/fstat/fstat.c (expand / switch to unified diff)

--- src/usr.bin/fstat/fstat.c 2019/09/06 17:08:22 1.113
+++ src/usr.bin/fstat/fstat.c 2020/08/26 23:08:29 1.114
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: fstat.c,v 1.113 2019/09/06 17:08:22 christos Exp $ */ 1/* $NetBSD: fstat.c,v 1.114 2020/08/26 23:08:29 christos Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 1988, 1993 4 * Copyright (c) 1988, 1993
5 * The Regents of the University of California. All rights reserved. 5 * The Regents of the University of California. All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -29,27 +29,27 @@ @@ -29,27 +29,27 @@
29 * SUCH DAMAGE. 29 * SUCH DAMAGE.
30 */ 30 */
31 31
32#include <sys/cdefs.h> 32#include <sys/cdefs.h>
33#ifndef lint 33#ifndef lint
34__COPYRIGHT("@(#) Copyright (c) 1988, 1993\ 34__COPYRIGHT("@(#) Copyright (c) 1988, 1993\
35 The Regents of the University of California. All rights reserved."); 35 The Regents of the University of California. All rights reserved.");
36#endif /* not lint */ 36#endif /* not lint */
37 37
38#ifndef lint 38#ifndef lint
39#if 0 39#if 0
40static char sccsid[] = "@(#)fstat.c 8.3 (Berkeley) 5/2/95"; 40static char sccsid[] = "@(#)fstat.c 8.3 (Berkeley) 5/2/95";
41#else 41#else
42__RCSID("$NetBSD: fstat.c,v 1.113 2019/09/06 17:08:22 christos Exp $"); 42__RCSID("$NetBSD: fstat.c,v 1.114 2020/08/26 23:08:29 christos Exp $");
43#endif 43#endif
44#endif /* not lint */ 44#endif /* not lint */
45 45
46#include <sys/types.h> 46#include <sys/types.h>
47#include <sys/param.h> 47#include <sys/param.h>
48#include <sys/time.h> 48#include <sys/time.h>
49#include <sys/proc.h> 49#include <sys/proc.h>
50#include <sys/stat.h> 50#include <sys/stat.h>
51#include <sys/vnode.h> 51#include <sys/vnode.h>
52#include <sys/socket.h> 52#include <sys/socket.h>
53#include <sys/socketvar.h> 53#include <sys/socketvar.h>
54#include <sys/domain.h> 54#include <sys/domain.h>
55#include <sys/protosw.h> 55#include <sys/protosw.h>
@@ -171,26 +171,27 @@ static const char *inet_addrstr(char *,  @@ -171,26 +171,27 @@ static const char *inet_addrstr(char *,
171static const char *inet6_addrstr(char *, size_t, const struct in6_addr *, 171static const char *inet6_addrstr(char *, size_t, const struct in6_addr *,
172 uint16_t, bool); 172 uint16_t, bool);
173#endif 173#endif
174static const char *at_addrstr(char *, size_t, const struct sockaddr_at *); 174static const char *at_addrstr(char *, size_t, const struct sockaddr_at *);
175static void socktrans(struct file *, struct socket *, int); 175static void socktrans(struct file *, struct socket *, int);
176static void misctrans(struct file *, int); 176static void misctrans(struct file *, int);
177static int ufs_filestat(struct vnode *, struct filestat *); 177static int ufs_filestat(struct vnode *, struct filestat *);
178static void usage(void) __dead; 178static void usage(void) __dead;
179static const char *vfilestat(struct vnode *, struct filestat *); 179static const char *vfilestat(struct vnode *, struct filestat *);
180static void vtrans(struct file *, struct vnode *, int, int, long); 180static void vtrans(struct file *, struct vnode *, int, int, long);
181static void ftrans(fdfile_t *, int); 181static void ftrans(fdfile_t *, int);
182static void ptrans(struct file *, struct pipe *, int); 182static void ptrans(struct file *, struct pipe *, int);
183static void kdriver_init(void); 183static void kdriver_init(void);
 184static void check_privs(void);
184 185
185int 186int
186main(int argc, char **argv) 187main(int argc, char **argv)
187{ 188{
188 struct passwd *passwd; 189 struct passwd *passwd;
189 struct kinfo_proc2 *p, *plast; 190 struct kinfo_proc2 *p, *plast;
190 int arg, ch, what; 191 int arg, ch, what;
191 char *memf, *nlistf; 192 char *memf, *nlistf;
192 char buf[_POSIX2_LINE_MAX]; 193 char buf[_POSIX2_LINE_MAX];
193 int cnt; 194 int cnt;
194 gid_t egid = getegid(); 195 gid_t egid = getegid();
195 196
196 (void)setegid(getgid()); 197 (void)setegid(getgid());
@@ -234,26 +235,28 @@ main(int argc, char **argv) @@ -234,26 +235,28 @@ main(int argc, char **argv)
234 errx(1, "%s: unknown uid", optarg); 235 errx(1, "%s: unknown uid", optarg);
235 } 236 }
236 what = KERN_PROC_UID; 237 what = KERN_PROC_UID;
237 arg = passwd->pw_uid; 238 arg = passwd->pw_uid;
238 break; 239 break;
239 case 'v': 240 case 'v':
240 vflg = 1; 241 vflg = 1;
241 break; 242 break;
242 case '?': 243 case '?':
243 default: 244 default:
244 usage(); 245 usage();
245 } 246 }
246 247
 248 check_privs();
 249
247 kdriver_init(); 250 kdriver_init();
248 251
249 if (*(argv += optind)) { 252 if (*(argv += optind)) {
250 for (; *argv; ++argv) { 253 for (; *argv; ++argv) {
251 if (getfname(*argv)) 254 if (getfname(*argv))
252 checkfile = 1; 255 checkfile = 1;
253 } 256 }
254 if (!checkfile) /* file(s) specified, but none accessible */ 257 if (!checkfile) /* file(s) specified, but none accessible */
255 exit(1); 258 exit(1);
256 } 259 }
257 260
258 ALLOC_OFILES(256); /* reserve space for file pointers */ 261 ALLOC_OFILES(256); /* reserve space for file pointers */
259 262
@@ -299,26 +302,43 @@ main(int argc, char **argv) @@ -299,26 +302,43 @@ main(int argc, char **argv)
299 if (checkfile && fsflg == 0) 302 if (checkfile && fsflg == 0)
300 (void)printf(" NAME\n"); 303 (void)printf(" NAME\n");
301 else 304 else
302 (void)putchar('\n'); 305 (void)putchar('\n');
303 306
304 for (plast = &p[cnt]; p < plast; ++p) { 307 for (plast = &p[cnt]; p < plast; ++p) {
305 if (p->p_stat == SZOMB) 308 if (p->p_stat == SZOMB)
306 continue; 309 continue;
307 dofiles(p); 310 dofiles(p);
308 } 311 }
309 return 0; 312 return 0;
310} 313}
311 314
 315static void
 316check_privs(void)
 317{
 318 int expaddr;
 319 size_t expsize = sizeof(expaddr);
 320 const char *expname = "kern.expose_address";
 321
 322 if (geteuid() == 0)
 323 return;
 324
 325 if (sysctlbyname(expname, &expaddr, &expsize, NULL, 0) == -1)
 326 err(EXIT_FAILURE, "Can't get sysctl `%s'", expname);
 327 if (expaddr == 0)
 328 errx(EXIT_FAILURE, "This program does not work without "
 329 "sysctl `%s' being set", expname);
 330}
 331
312static const char *Uname, *Comm; 332static const char *Uname, *Comm;
313pid_t Pid; 333pid_t Pid;
314 334
315#define PREFIX(i) (void)printf("%-8.8s %-10s %5d", Uname, Comm, Pid); \ 335#define PREFIX(i) (void)printf("%-8.8s %-10s %5d", Uname, Comm, Pid); \
316 switch(i) { \ 336 switch(i) { \
317 case TEXT: \ 337 case TEXT: \
318 (void)printf(" text"); \ 338 (void)printf(" text"); \
319 break; \ 339 break; \
320 case CDIR: \ 340 case CDIR: \
321 (void)printf(" wd"); \ 341 (void)printf(" wd"); \
322 break; \ 342 break; \
323 case RDIR: \ 343 case RDIR: \
324 (void)printf(" root"); \ 344 (void)printf(" root"); \