Date: Mon, 1 Feb 1999 20:20:13 -0500 (EST) From: Robert Watson <robert@cyrus.watson.org> To: current@FreeBSD.ORG Subject: swap_page_getswapspace failed (don't do stupid things with /dev/mem) Message-ID: <Pine.BSF.3.96.990201201334.10163A-100000@fledge.watson.org>
next in thread | raw e-mail | index | archive | help
So, never do stupid things as root; that's always my moto. Well, so I did something stupid as root, but it wasn't inherrently *that* stupid, at least not stupid enough to require a hard boot :). Below is the source code for the beginnings of an audit daemon--all it does is disable auditing on its own process, then read from /dev/audit. My goal was simply to make sure that data was going back and forth via the device correctly. Except I decided to test that feature that overrides the device filename (normally /dev/audit). Instead, I chose /dev/mem. Don't do that (ouch). The machine began to churn -- ok, so the buffer expands as necessary without limit, which is something that will go away once I actually write the daemon. But it kept churning, and gradually I lost control of things--my keyboard, eventually my mouse, and eventually the system just hung. Retrying it after a hard boot (and let me tell you that the off switch did not work on my IBM 560E notebook for a few tries :), I tried again on the console. The system is reduced to an endlessly printed: swap_pager_getswapspace: failed from the kernel. And needless to say, it loops fairly tightly and we don't get much in the way of key-pressing. Clearly, this is not something you should do with /dev/mem, but how was I to know :). Perhaps someone could determine if there is a race condition/etc that allows this condition to be entered, and instead default to killing the process or something. My kernel code is a few days old on the 4.0-CURRENT branch. Source: auditd.c (just disable auditing stuff to make it compile). Invoke as auditd /dev/mem. /*- * Copyright (c) 1999 Robert Watson * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $Id: $ */ /* * User-land audit daemon * Listens on /dev/audit reading out records, and dropping them into * /var/log/audit. * Disables its own auditing to prevent nasties. */ #include <sys/types.h> #include <sys/audit.h> #include <sys/fcntl.h> #include <sys/uio.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include "auditd.h" void usage(void) { fprintf(stderr, "auditd [-d] [-f auditdevice]\n"); exit(-1); } void main(int argc, char *argv[]) { int i, fd, size, bufsize, not_daemon; char ch, *buf, *devfile=AUDIT_DEVICE; not_daemon = 0; while ((ch = getopt(argc, argv, "df:")) != -1) { switch(ch) { case 'd': not_daemon = 1; break; case 'f': devfile = optarg; break; default: /* warnx("unknown flag -%c ignored", optopt); */ usage(); } } buf = (char *) malloc(AUDIT_DEF_BUF_SIZE * sizeof(char)); if (!buf) { fprintf(stderr, "auditd: unable to malloc buffer\n"); exit(-1); } bufsize = AUDIT_DEF_BUF_SIZE; i = aud_switch(AUD_STATE_OFF); if (i == -1) { perror("auditd: aud_switch"); exit(-1); } fd = open(devfile, O_RDONLY); if (fd == -1) { perror("auditd: open: audit device"); exit(-1); } if (!not_daemon) { i = daemon(1, 1); if (i == -1) { perror("auditd: daemon"); exit(-1); } } while (1) { /* read the size of the next block */ i = read(fd, &size, sizeof(size)); if (i == sizeof(size)) { if (size > bufsize) { free(buf); bufsize = size; buf = NULL; while (buf == NULL) { buf = (char *) malloc(bufsize * sizeof(char)); } i = read(fd, buf, bufsize); fprintf(stderr, "got stuff (%d/%d)\n", i, bufsize); } } } } Robert N Watson robert@fledge.watson.org http://www.watson.org/~robert/ PGP key fingerprint: 03 01 DD 8E 15 67 48 73 25 6D 10 FC EC 68 C1 1C Carnegie Mellon University http://www.cmu.edu/ TIS Labs at Network Associates, Inc. http://www.tis.com/ SafePort Network Services http://www.safeport.com/ To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-current" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.BSF.3.96.990201201334.10163A-100000>