Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/bin/ps - Be really paranoid. Any time we open a file that i...
details: https://anonhg.NetBSD.org/src/rev/822d5668d916
branches: trunk
changeset: 467725:822d5668d916
user: bgrayson <bgrayson%NetBSD.org@localhost>
date: Sun Mar 28 00:46:47 1999 +0000
description:
- Be really paranoid. Any time we open a file that is in /proc, run
fstatfs() on the open file to verify that no intruder has mounted
something on portions of /proc. This will catch, for instance,
"mount_null /tmp /proc/1378". We already do 5 syscalls per
process, so one more won't hurt :) ... and safety is better than
performance when ps is otherwise broken.
- Also added a few close()'s at early returns, to avoid chewing up fd's.
diffstat:
bin/ps/procfs_ops.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 54 insertions(+), 2 deletions(-)
diffs (105 lines):
diff -r aba7de8b8211 -r 822d5668d916 bin/ps/procfs_ops.c
--- a/bin/ps/procfs_ops.c Sun Mar 28 00:28:17 1999 +0000
+++ b/bin/ps/procfs_ops.c Sun Mar 28 00:46:47 1999 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: procfs_ops.c,v 1.3 1999/03/27 21:38:08 bgrayson Exp $ */
+/* $NetBSD: procfs_ops.c,v 1.4 1999/03/28 00:46:47 bgrayson Exp $ */
/*
* Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -66,29 +66,75 @@
} \
}
+static int verify_procfs_fd __P((int, const char *));
static int parsekinfo __P((const char *, struct kinfo_proc *));
struct kinfo_proc * procfs_getprocs __P((int, int, int *));
static int
+verify_procfs_fd (fd, path)
+ int fd;
+ const char *path;
+{
+ struct statfs procfsstat;
+
+ /* If the fstatfs fails, die immediately. Since we
+ * already have the FD open, any error is probably one
+ * that can't be worked around. */
+ if (fstatfs(fd, &procfsstat)) {
+ err(1, "fstatfs on %s", path);
+ }
+ /* Now verify that the open file is truly on a procfs
+ * filesystem. */
+ if (strcmp(procfsstat.f_fstypename, MOUNT_PROCFS)) {
+ warnx("%s is on a '%s' filesystem, not 'procfs'???", path,
+ procfsstat.f_fstypename);
+ return -1;
+ }
+ return 0;
+}
+
+static int
parsekinfo (path, kp)
const char *path;
struct kinfo_proc *kp;
{
char fullpath[MAXPATHLEN];
- int fd, nbytes, devmajor, devminor;
+ int dirfd, fd, nbytes, devmajor, devminor;
struct timeval usertime, systime, starttime;
char buff[STATUS_SIZE];
char flagstr[256];
+ /* Verify that /proc/<pid> is a procfs file (and that no
+ * one has mounted anything on top of it). If we didn't
+ * do this, an intruder could hide processes by simply
+ * mount_null'ing /tmp on top of the /proc/<pid>
+ * directory. (And we can't just print warnings if we fail
+ * to open /proc/<pid>/status, because the process may
+ * have died since our getdents() call.) */
+ snprintf(fullpath, MAXPATHLEN, "/proc/%s", path);
+ dirfd=open(fullpath, O_RDONLY, 0);
+ if (verify_procfs_fd(dirfd, fullpath)) {
+ close(dirfd);
+ return -1;
+ }
/* Open /proc/"path"/status, and parse it into the kinfo_proc. */
snprintf(fullpath, MAXPATHLEN, "/proc/%s/status", path);
fd=open(fullpath, O_RDONLY, 0);
+ close(dirfd);
if (fd == -1) {
/* Don't print warning, as the process may have
* died since our scan of the directory entries. */
/*warn("Open failed for %s", fullpath);*/
+ close(fd);
return -1; /* Process may no longer exist. */
}
+ /* Bail out for this process attempt if it isn't on a
+ * procfs. Some intruder could have mounted something
+ * on top of portions of /proc. */
+ if (verify_procfs_fd(fd, fullpath)) {
+ close(fd);
+ return -1;
+ }
nbytes=read(fd, buff, STATUS_SIZE);
close(fd);
if (nbytes <= 0) {
@@ -155,12 +201,18 @@
procdirfd = open("/proc", O_RDONLY, 0);
if (procdirfd == -1) {
warn("open of /proc directory");
+ close(procdirfd);
+ return 0;
+ }
+ if (verify_procfs_fd(procdirfd, "/proc")) {
+ close(procdirfd);
return 0;
}
direntbuff = malloc(statbuf.st_blksize);
if (direntbuff == NULL) {
warn("malloc() of %d bytes", statbuf.st_blksize);
+ close(procdirfd);
return 0;
}
/* Use sysctl to find out the total number of processes.
Home |
Main Index |
Thread Index |
Old Index