[Forensics-changes] [SCM] UNNAMED PROJECT branch, upstream, updated. upstream/1.18
Daniel Baumann
daniel at debian.org
Sat Feb 9 18:03:45 UTC 2008
The following commit has been merged in the upstream branch:
commit f8b2c7a8e44a90d0c405d8da52c905bec287ccf6
Author: Daniel Baumann <daniel at debian.org>
Date: Sat Feb 9 19:00:20 2008 +0100
Adding upstream version 1.18.
diff --git a/CHANGES b/CHANGES
index c272bca..86881e0 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,54 @@
+Mon Apr 9 09:36:31 EDT 2007
+
+o Bit-rot: the 64-bit workaround for LINUX lseek() is no
+ longer needed, and it didn't compile on some systems.
+
+Thu Jan 11 16:10:29 EST 2007
+
+o Bugfix: the timeout command always reported zero exit status
+ after voluntary child process exit.
+
+Mon Jun 26 18:44:17 EDT 2006
+
+o Bit-rot: update #include statements because code either
+ no longer compiled or compiled with warnings.
+
+Fri Mar 17 09:25:57 EST 2006
+
+o Bit-rot: update #include statements because code either
+ no longer compiled or compiled with warnings.
+
+Tue Jan 6 12:25:32 EST 2004
+
+o Workaround: mactime treated "," as a special character in
+ file names, now it's 0xff.
+
+o Support for ext[23]fs inode file sizes > 32bits.
+
+o Bugfix: ils file sizes larger than unsigned long.
+
+Tue Oct 14 18:23:49 EDT 2003
+
+o pcat now fully supports FreeBSD systems that do not have
+ /proc mounted (it's no longer mounted by default with
+ FreeBSD 5). pcat tries to use /proc if it can, and uses
+ ptrace() and gropes kernel memory if it has to. Operation
+ without /proc requires super-user privileges.
+
+Thu Oct 2 09:14:00 EDT 2003
+
+o Completed support for UFS1 and UFS2 in FreeBSD 5.x. However,
+ the pcat command still requires that the /proc file system
+ is mounted. This will be fixed later.
+
+Sat Aug 30 19:21:29 EDT 2003
+
+o Preliminary FreeBSD 5.0 port. UFS2 support is still to be done.
+
+Fri Aug 1 10:07:39 EDT 2003
+
+o RedHat 9.0 fix by Florin Andrei for the file command.
+
Sat Oct 5 13:47:29 EDT 2002
o Restored tctutils compatibility, which broke with 20020916.
diff --git a/bin/mactime b/bin/mactime
index 5f7855d..a50e2c3 100644
--- a/bin/mactime
+++ b/bin/mactime
@@ -454,10 +454,10 @@ for $n (0..$#{$table{'data'}}) {
#
# If the date on the file is too old, don't put it in the array
#
- $all_files_used{"$st_mtime,$file"} .= "m" if $st_mtime > $in_seconds;
- $all_files_used{"$st_atime,$file"} .= "a" if $st_atime > $in_seconds;
- $all_files_used{"$st_ctime,$file"} .= "c" if $st_ctime > $in_seconds;
- $all_files_used{"$st_dtime,$file"} .= "d" if $st_dtime > $in_seconds;
+ $all_files_used{"$st_mtime\377$file"} .= "m" if $st_mtime > $in_seconds;
+ $all_files_used{"$st_atime\377$file"} .= "a" if $st_atime > $in_seconds;
+ $all_files_used{"$st_ctime\377$file"} .= "c" if $st_ctime > $in_seconds;
+ $all_files_used{"$st_dtime\377$file"} .= "d" if $st_dtime > $in_seconds;
$all_filenames{$file} = $file;
@@ -515,7 +515,7 @@ for $key (sort {$a <=> $b} keys %all_files_used) {
next if $marker;
- ($time, $file) = split(/,/,$key);
+ ($time, $file) = split(/\377/,$key);
print "T-in minus Currfile time = ", $in_seconds - $time, "\n" if $debug;
next if ($in_seconds > $time);
diff --git a/extras/entropy/makedefs b/extras/entropy/makedefs
index 640a959..3c5140c 100644
--- a/extras/entropy/makedefs
+++ b/extras/entropy/makedefs
@@ -8,6 +8,8 @@ case "$SYSTEM.$RELEASE" in
;;
FreeBSD.4*) DEFS="-DFREEBSD4"
;;
+ FreeBSD.5*) DEFS="-DFREEBSD5"
+ ;;
OpenBSD.2*) DEFS="-DOPENBSD2"
;;
OpenBSD.3*) DEFS="-DOPENBSD3"
diff --git a/extras/findkey/makedefs b/extras/findkey/makedefs
index 640a959..3c5140c 100644
--- a/extras/findkey/makedefs
+++ b/extras/findkey/makedefs
@@ -8,6 +8,8 @@ case "$SYSTEM.$RELEASE" in
;;
FreeBSD.4*) DEFS="-DFREEBSD4"
;;
+ FreeBSD.5*) DEFS="-DFREEBSD5"
+ ;;
OpenBSD.2*) DEFS="-DOPENBSD2"
;;
OpenBSD.3*) DEFS="-DOPENBSD3"
diff --git a/lib/ostype.pl b/lib/ostype.pl
index 862dd6d..9efa78e 100644
--- a/lib/ostype.pl
+++ b/lib/ostype.pl
@@ -12,6 +12,7 @@ print "Determining OS (in determine_os())\n" if $verbose;
"FREEBSD2", "FreeBSD.2",
"FREEBSD3", "FreeBSD.3",
"FREEBSD4", "FreeBSD.4",
+ "FREEBSD5", "FreeBSD.5",
"OPENBSD2", "OpenBSD.2",
"OPENBSD3", "OpenBSD.3",
"BSDI2", "BSD\/OS.2",
diff --git a/man/man1/pcat.1 b/man/man1/pcat.1
index dd386a4..cbe4cce 100644
--- a/man/man1/pcat.1
+++ b/man/man1/pcat.1
@@ -28,6 +28,7 @@ the output file, and requires that stdout is redirected to file.
This option does not work on some Solaris versions.
.IP "\fB-m\fR \fImapfile\fR"
Print the process memory map to \fImapfile\fR, one entry per line.
+Specify \fB-m-\fR to write to the standard error stream.
Each map entry consists of a region start address and the first
address beyond that region. Addresses are separated by space,
and are printed as hexadecimal numbers (0xhhhh).
diff --git a/man/man1/timeout.1 b/man/man1/timeout.1
index 5f48a1e..d2f07f9 100644
--- a/man/man1/timeout.1
+++ b/man/man1/timeout.1
@@ -30,8 +30,16 @@ The command to be executed.
.fi
The command exit status is the exit status of the command
(status 1 in case of a usage error).
+.SH LICENSE
+.na
+.nf
+The IBM PUBLIC LICENSE must be distributed with this
+software.
+.SH HISTORY
+.na
+.nf
+This program was first released as part of SATAN.
.SH AUTHOR(S)
.na
.nf
Wietse Venema
-This program is part of SATAN.
diff --git a/patchlevel b/patchlevel
index 0960158..63738cc 100644
--- a/patchlevel
+++ b/patchlevel
@@ -1 +1 @@
-1.11
+1.14
diff --git a/src/aux/error.h b/src/aux/error.h
index cfc8548..c1582cd 100644
--- a/src/aux/error.h
+++ b/src/aux/error.h
@@ -11,9 +11,16 @@
/*
* External interface.
*/
-extern void remark(char *,...);
-extern void error(char *,...);
-extern void panic(char *,...);
+#ifndef PRINTFLIKE
+#if __GNUC__ == 2 && __GNUC_MINOR__ >= 7
+#define PRINTFLIKE(x,y) __attribute__ ((format (printf, (x), (y))))
+#else
+#define PRINTFLIKE(x,y)
+#endif
+#endif
+extern void PRINTFLIKE(1, 2) remark(char *,...);
+extern void PRINTFLIKE(1, 2) error(char *,...);
+extern void PRINTFLIKE(1, 2) panic(char *,...);
extern char *progname;
extern int verbose;
diff --git a/src/aux/makedefs b/src/aux/makedefs
index 384599e..1e34c54 100644
--- a/src/aux/makedefs
+++ b/src/aux/makedefs
@@ -8,6 +8,8 @@ case "$SYSTEM.$RELEASE" in
;;
FreeBSD.4*) DEFS="-DFREEBSD4"
;;
+ FreeBSD.5*) DEFS="-DFREEBSD5"
+ ;;
OpenBSD.2*) DEFS="-DOPENBSD2"
;;
OpenBSD.3*) DEFS="-DOPENBSD3"
diff --git a/src/file/file.h b/src/file/file.h
index ad3e8e0..02d8412 100644
--- a/src/file/file.h
+++ b/src/file/file.h
@@ -102,7 +102,11 @@ extern unsigned long signextend __P((struct magic *, unsigned long));
+#ifdef NEED_ERRNO_H
+#include <errno.h>
+#else
extern int errno; /* Some unixes don't define this.. */
+#endif
extern char *progname; /* the program name */
extern char *magicfile; /* name of the magic file */
diff --git a/src/file/makedefs b/src/file/makedefs
index 576733e..b2f3517 100644
--- a/src/file/makedefs
+++ b/src/file/makedefs
@@ -8,6 +8,8 @@ case "$SYSTEM.$RELEASE" in
;;
FreeBSD.4*) DEFS="-DFREEBSD4"
;;
+ FreeBSD.5*) DEFS="-DFREEBSD5"
+ ;;
OpenBSD.2*) DEFS="-DOPENBSD2"
;;
OpenBSD.3*) DEFS="-DOPENBSD3"
@@ -26,9 +28,9 @@ SunOS.5.[0-5]*) DEFS="-DSUNOS5_0_5"
SunOS.5*) DEFS="-DSUNOS5"
RANLIB=":"
;;
- Linux.2.4*) DEFS="-DLINUX2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64"
+Linux.2.[0-3].*) DEFS="-DLINUX2"
;;
- Linux.2*) DEFS="-DLINUX2"
+ Linux.2.*) DEFS="-DLINUX2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -DNEED_ERRNO_H"
;;
*) echo unsupported system: $SYSTEM.$RELEASE 1>&2; exit 1
;;
diff --git a/src/fstools/Makefile b/src/fstools/Makefile
index fb83ff2..e4ca8f4 100644
--- a/src/fstools/Makefile
+++ b/src/fstools/Makefile
@@ -5,7 +5,7 @@ DEBUG = -g
INCL = -I../aux
CFLAGS = $(DEFS) $(INCL) $(OPT) $(DEBUG)
LIBOBJ = fs_buf.o fs_inode.o fs_io.o fs_copy_file.o fs_open.o ffs.o \
- ext2fs.o mylseek.o
+ ffs2.o ext2fs.o mylseek.o
LIBS = ../aux/aux_lib.a
LIB = fs_lib.a
BIN_DIR = ../../bin
@@ -57,6 +57,8 @@ ext2fs.o: ext2fs.c
ext2fs.o: fs_tools.h
ffs.o: ffs.c
ffs.o: fs_tools.h
+ffs2.o: ffs2.c
+ffs2.o: fs_tools.h
fs_buf.o: fs_buf.c
fs_buf.o: fs_tools.h
fs_buf.o: ../aux/mymalloc.h
diff --git a/src/fstools/ext2fs.c b/src/fstools/ext2fs.c
index 5ab9984..5cb6f5c 100644
--- a/src/fstools/ext2fs.c
+++ b/src/fstools/ext2fs.c
@@ -194,6 +194,10 @@ static void ext2fs_copy_inode(struct ext2_inode * dino, FS_INODE *fs_inode)
fs_inode->mode = dino->i_mode;
fs_inode->nlink = dino->i_links_count;
fs_inode->size = dino->i_size;
+#ifdef i_size_high
+ if (dino->i_size_high)
+ fs_inode->size |= (((OFF_T) dino->i_size_high) << 32);
+#endif
fs_inode->uid = dino->i_uid;
fs_inode->gid = dino->i_gid;
fs_inode->mtime = dino->i_mtime;
@@ -467,8 +471,8 @@ FS_INFO *ext2fs_open(const char *name)
/*
* Other initialization: caches, callbacks.
*/
- ext2fs->inode_map = mymalloc(ext2fs->fs_info.block_size);
- ext2fs->block_map = mymalloc(ext2fs->fs_info.block_size);
+ ext2fs->inode_map = (UCHAR *) mymalloc(ext2fs->fs_info.block_size);
+ ext2fs->block_map = (UCHAR *) mymalloc(ext2fs->fs_info.block_size);
ext2fs->fs_info.seek_pos = -1;
ext2fs->grpnum = -1;
ext2fs->bmap_num = -1;
diff --git a/src/fstools/ffs.c b/src/fstools/ffs.c
index b78371a..63f5cb9 100644
--- a/src/fstools/ffs.c
+++ b/src/fstools/ffs.c
@@ -395,7 +395,8 @@ FS_INFO *ffs_open(const char *name)
if (read(ffs->fs_info.fd, (char *) ffs->fs, len) != len)
error("%s: read superblock: %m", name);
if (ffs->fs->fs_magic != FS_MAGIC)
- error("%s: bad magic number in superblock", name);
+ error("%s: bad magic number 0x%x in superblock",
+ name, ffs->fs->fs_magic);
/*
* Translate some filesystem-specific information to generic form.
diff --git a/src/fstools/fs_tools.h b/src/fstools/fs_tools.h
index 79dc754..5644d1e 100644
--- a/src/fstools/fs_tools.h
+++ b/src/fstools/fs_tools.h
@@ -115,6 +115,24 @@ extern int optind;
#define INO_TO_CG ino_to_cg
#endif
+#if defined(FREEBSD5)
+#define SUPPORTED
+#include <sys/vnode.h>
+#include <ufs/ufs/quota.h>
+#include <ufs/ufs/inode.h>
+#include <ufs/ffs/fs.h>
+#define LSEEK lseek
+#define OFF_T off_t
+#define STRTOUL strtoul
+#define itod(fs,i) ino_to_fsba(fs,i)
+#define itoo(fs,i) ino_to_fsbo(fs,i)
+#define INOTIME(t) (t)
+#define DADDR_T int64_t
+#define UFS_TYPE "ufs"
+#define DEF_FSTYPE UFS_TYPE
+#define INO_TO_CG ino_to_cg
+#endif
+
/*
* BSD/OS can handle filesystems > 2GB.
*/
@@ -185,11 +203,16 @@ extern int optind;
#define SUPPORTED
#include <linux/ext2_fs.h>
#define HAVE_EXT2FS
+#define HAVE_DTIME
+#if (_FILE_OFFSET_BITS == 64)
+#define LSEEK lseek
+#define OFF_T off_t
+#else
#define USE_MYLSEEK
#define HAVE_LLSEEK
-#define HAVE_DTIME
#define LSEEK mylseek
#define OFF_T long long
+#endif
#define STRTOUL strtoul
#define DADDR_T __u32
#define EXT2FS_TYPE "ext2fs"
diff --git a/src/fstools/ils.c b/src/fstools/ils.c
index 6ff6506..56d9882 100644
--- a/src/fstools/ils.c
+++ b/src/fstools/ils.c
@@ -182,10 +182,16 @@ static void print_inode(INUM_T inum, FS_INODE *fs_inode, int flags,
#ifdef HAVE_DTIME
printf("|%lu", (ULONG) fs_inode->dtime);
#endif
- printf("|%lo|%d|%lu|%lu|%lu\n",
- (ULONG) fs_inode->mode, (int) fs_inode->nlink,
- (ULONG) fs_inode->size, (ULONG) fs_inode->direct_addr[0],
- (ULONG) fs_inode->direct_addr[1]);
+ if (sizeof(fs_inode->size) <= sizeof(unsigned long))
+ printf("|%lo|%d|%lu|%lu|%lu\n",
+ (ULONG) fs_inode->mode, (int) fs_inode->nlink,
+ (ULONG) fs_inode->size, (ULONG) fs_inode->direct_addr[0],
+ (ULONG) fs_inode->direct_addr[1]);
+ else
+ printf("|%lo|%d|%llu|%lu|%lu\n",
+ (ULONG) fs_inode->mode, (int) fs_inode->nlink,
+ (unsigned long long) fs_inode->size, (ULONG) fs_inode->direct_addr[0],
+ (ULONG) fs_inode->direct_addr[1]);
}
/* main - open file system, list inode info */
diff --git a/src/fstools/makedefs b/src/fstools/makedefs
index 384599e..0f208bb 100644
--- a/src/fstools/makedefs
+++ b/src/fstools/makedefs
@@ -8,6 +8,8 @@ case "$SYSTEM.$RELEASE" in
;;
FreeBSD.4*) DEFS="-DFREEBSD4"
;;
+ FreeBSD.5*) DEFS="-DFREEBSD5"
+ ;;
OpenBSD.2*) DEFS="-DOPENBSD2"
;;
OpenBSD.3*) DEFS="-DOPENBSD3"
@@ -27,9 +29,9 @@ SunOS.5.[0-5]*) DEFS="-DSUNOS5 -DUSE_PREAD"
SunOS.5*) DEFS="-DSUNOS5 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64"
RANLIB=":"
;;
- Linux.2.4*) DEFS="-DLINUX2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64"
+Linux.2.[0-3].*)DEFS="-DLINUX2"
;;
- Linux.2*) DEFS="-DLINUX2"
+ Linux.2.*) DEFS="-DLINUX2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64"
;;
*) echo unsupported system: $SYSTEM.$RELEASE 1>&2; exit 1
;;
@@ -37,5 +39,5 @@ esac
unset MAKELEVEL # shut up chatty GNU make
-make DEFS="$DEFS" CC="${CC-gcc -Wunused}" RANLIB="${RANLIB-ranlib}" \
+make DEFS="$DEFS" CC="${CC-gcc -Wunused -Wformat}" RANLIB="${RANLIB-ranlib}" \
AR="${AR-ar rv}" SYSLIBS="$SYSLIBS" all
diff --git a/src/fstools/mylseek.c b/src/fstools/mylseek.c
index df4d65d..c5c19e4 100644
--- a/src/fstools/mylseek.c
+++ b/src/fstools/mylseek.c
@@ -23,7 +23,8 @@
#ifdef USE_MYLSEEK
#ifdef HAVE_LLSEEK
#include <errno.h>
-#include <syscall.h>
+#include <unistd.h>
+#include <linux/unistd.h>
/*
* This is LINUX, live on the bleeding edge and watch your software break
diff --git a/src/lastcomm/Makefile b/src/lastcomm/Makefile
index d94fc44..4531e43 100644
--- a/src/lastcomm/Makefile
+++ b/src/lastcomm/Makefile
@@ -2,7 +2,7 @@ SHELL = /bin/sh
CC = gcc
OPT = -O
DEBUG = -g
-INCL =
+INCL = -I.
CFLAGS = $(DEFS) $(INCL) $(OPT) $(DEBUG)
OBJS = lastcomm.o $(MISSING_OBJS)
BIN_DIR = ../../bin
diff --git a/src/lastcomm/makedefs b/src/lastcomm/makedefs
index df2ea63..e16459b 100644
--- a/src/lastcomm/makedefs
+++ b/src/lastcomm/makedefs
@@ -4,10 +4,12 @@ RELEASE=`(uname -r) 2>/dev/null`
case "$SYSTEM.$RELEASE" in
FreeBSD.2*) DEFS="-DFREEBSD2"
;;
- FreeBSD.4*) DEFS="-DFREEBSD3"
- ;;
FreeBSD.3*) DEFS="-DFREEBSD3"
;;
+ FreeBSD.4*) DEFS="-DFREEBSD4"
+ ;;
+ FreeBSD.5*) DEFS="-DFREEBSD5"
+ ;;
OpenBSD.3*) DEFS="-DOPENBSD3"
;;
OpenBSD.2*) DEFS="-DOPENBSD2"
diff --git a/src/lastcomm/sys_defs.h b/src/lastcomm/sys_defs.h
index a2e32b7..e0fd50b 100644
--- a/src/lastcomm/sys_defs.h
+++ b/src/lastcomm/sys_defs.h
@@ -6,6 +6,7 @@
* This software is distributed under the IBM Public License.
*/
#if defined(FREEBSD2) || defined(FREEBSD3) || defined(FREEBSD4) \
+ || defined(FREEBSD5) \
|| defined(BSDI2) || defined(BSDI3) || defined(BSDI4) \
|| defined(OPENBSD2) || defined(OPENBSD3)
#define SUPPORTED
diff --git a/src/major_minor/makedefs b/src/major_minor/makedefs
index 11c2997..0f3c6e6 100644
--- a/src/major_minor/makedefs
+++ b/src/major_minor/makedefs
@@ -6,7 +6,9 @@ case "$SYSTEM.$RELEASE" in
;;
FreeBSD.3*) DEFS="-DFREEBSD3"
;;
- FreeBSD.4*) DEFS="-DFREEBSD3"
+ FreeBSD.4*) DEFS="-DFREEBSD4"
+ ;;
+ FreeBSD.5*) DEFS="-DFREEBSD5"
;;
OpenBSD.2*) DEFS="-DOPENBSD2"
;;
diff --git a/src/misc/makedefs b/src/misc/makedefs
index 640a959..3c5140c 100644
--- a/src/misc/makedefs
+++ b/src/misc/makedefs
@@ -8,6 +8,8 @@ case "$SYSTEM.$RELEASE" in
;;
FreeBSD.4*) DEFS="-DFREEBSD4"
;;
+ FreeBSD.5*) DEFS="-DFREEBSD5"
+ ;;
OpenBSD.2*) DEFS="-DOPENBSD2"
;;
OpenBSD.3*) DEFS="-DOPENBSD3"
diff --git a/src/misc/timeout.c b/src/misc/timeout.c
index 8cda986..e05e007 100644
--- a/src/misc/timeout.c
+++ b/src/misc/timeout.c
@@ -22,14 +22,19 @@
/* DIAGNOSTICS
/* The command exit status is the exit status of the command
/* (status 1 in case of a usage error).
+/* LICENSE
+/* The IBM PUBLIC LICENSE must be distributed with this
+/* software.
+/* HISTORY
+/* This program was first released as part of SATAN.
/* AUTHOR(S)
/* Wietse Venema
-/* This program is part of SATAN.
/*--*/
/* System libraries. */
#include <sys/types.h>
+#include <sys/wait.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
@@ -103,6 +108,6 @@ char **argv;
alarm(time_to_run);
while ((pid = wait(&status)) != -1 && pid != child_pid)
/* void */ ;
- return (pid == child_pid ? status : -1);
+ return (pid == child_pid ? WEXITSTATUS(status) | WTERMSIG(status) : -1);
}
}
diff --git a/src/pcat/makedefs b/src/pcat/makedefs
index 996b57e..c4f9d4b 100644
--- a/src/pcat/makedefs
+++ b/src/pcat/makedefs
@@ -3,10 +3,16 @@ RELEASE=`(uname -r) 2>/dev/null`
case "$SYSTEM.$RELEASE" in
FreeBSD.2*) DEFS="-DFREEBSD2"
+ SYSLIBS="-lkvm"
;;
FreeBSD.3*) DEFS="-DFREEBSD3"
+ SYSLIBS="-lkvm"
;;
FreeBSD.4*) DEFS="-DFREEBSD4"
+ SYSLIBS="-lkvm"
+ ;;
+ FreeBSD.5*) DEFS="-DFREEBSD5"
+ SYSLIBS="-lkvm"
;;
OpenBSD.2*) DEFS="-DOPENBSD2"
SYSLIBS="-lkvm"
diff --git a/src/pcat/pcat.c b/src/pcat/pcat.c
index a7b7463..4ee2f50 100644
--- a/src/pcat/pcat.c
+++ b/src/pcat/pcat.c
@@ -22,6 +22,7 @@
/* This option does not work on some Solaris versions.
/* .IP "\fB-m\fR \fImapfile\fR"
/* Print the process memory map to \fImapfile\fR, one entry per line.
+/* Specify \fB-m-\fR to write to the standard error stream.
/* Each map entry consists of a region start address and the first
/* address beyond that region. Addresses are separated by space,
/* and are printed as hexadecimal numbers (0xhhhh).
@@ -78,6 +79,7 @@
#include <unistd.h>
#include <fcntl.h>
#include <signal.h>
+#include <string.h>
/*
* Solaris 2.x has /proc, which immensely simplifies our task. However, the
@@ -103,10 +105,40 @@
/*
* FreeBSD 2.x and later have /proc, which immensely simplifies our task.
+ * Unfortunately, FreeBSD 5.x no longer mounts /proc by default. We try to
+ * use /proc first and use ptrace() only if we have to.
+ *
+ * FreeBSD PTRACE_DETACH does not resume the target process so we must send
+ * SIGCONT, but only if the process was stopped by us.
+ *
+ * FreeBSD 5 no longer supports ptrace() access to the u area, so we have to
+ * grope kernel memory instead.
*/
-#if defined(FREEBSD2) || defined(FREEBSD3) || defined(FREEBSD4)
+#if defined(FREEBSD2) || defined(FREEBSD3) || defined(FREEBSD4) \
+ || defined(FREEBSD5)
#define SUPPORTED
+#include <sys/param.h>
+#include <sys/user.h>
+#include <sys/proc.h>
+#include <sys/sysctl.h>
+#include <kvm.h>
+#include <stddef.h>
#define HAVE_PROC_MEM
+#define HAVE_PTRACE_MEM
+#define PTRACE_ATTACH PT_ATTACH
+#define PTRACE_DETACH PT_DETACH
+#define PTRACE_PEEKDATA PT_READ_D
+#define PTRACE_ARG3_T caddr_t
+#endif
+
+#if defined(FREEBSD2) || defined(FREEBSD3) || defined(FREEBSD4)
+#define PROCP_STATUS(p) ((p)->kp_proc.p_stat)
+#define PROCP_VMSPACE(p) ((p)->kp_proc.p_vmspace)
+#endif
+
+#if defined(FREEBSD5)
+#define PROCP_STATUS(p) ((p)->ki_stat)
+#define PROCP_VMSPACE(p) ((p)->ki_vmspace)
#endif
/*
@@ -223,12 +255,13 @@ typedef struct {
/*
* Structure to carry around process-related info.
*/
-typedef struct {
+typedef struct PROC_INFO {
#ifdef HAVE_PROC_MEM
int mem_fd; /* process memory */
#endif
pid_t pid; /* a process id */
int map_count; /* nr of map entries */
+ void (*read_proc) (struct PROC_INFO *, char *, int, off_t);
MAP_INFO map_info[1]; /* actually a bunch. */
} PROC_INFO;
@@ -430,11 +463,12 @@ static int call_ptrace(int request, pid_t pid, int addr, int data)
#endif
-/* read_proc - read block of memory at specified position */
+#ifdef HAVE_PROC_MEM
-static void read_proc(PROC_INFO *proc, char *data, int len, off_t offset)
+/* read_proc_mem - read block of memory at specified position */
+
+static void read_proc_mem(PROC_INFO *proc, char *data, int len, off_t offset)
{
-#ifdef HAVE_PROC_MEM
if (verbose)
fprintf(stderr, "read seek to 0x%lx\n", (long) offset);
#ifdef USE_PREAD
@@ -446,11 +480,19 @@ static void read_proc(PROC_INFO *proc, char *data, int len, off_t offset)
if (read(proc->mem_fd, data, len) != len)
error("read: %m");
#endif
+}
#endif
#ifdef HAVE_PTRACE_MEM
+
+/* read_ptrace_mem - read block of memory at specified position */
+
+static void read_ptrace_mem(PROC_INFO *proc, char *data, int len, off_t offset)
+{
#ifdef USE_PTRACE_READDATA
+ if (verbose)
+ fprintf(stderr, "read seek to 0x%lx\n", (long) offset);
if (ptrace(PTRACE_READDATA, proc->pid, (int) offset, len, data) < 0)
error("PTRACE_READDATA: %m%s", errno == EIO ?
"; did you use GCC with another machine's header files?" : "");
@@ -463,6 +505,8 @@ static void read_proc(PROC_INFO *proc, char *data, int len, off_t offset)
* XXX This breaks when memory segments aren't word-aligned or when
* memory segments sizes aren't a multiple of the word size. Tough.
*/
+ if (verbose)
+ fprintf(stderr, "read seek to 0x%lx\n", (long) offset);
if (offset % sizeof(int))
panic("read_proc: offset 0x%lx is not word-aligned", (long) offset);
if (len % sizeof(int))
@@ -473,9 +517,9 @@ static void read_proc(PROC_INFO *proc, char *data, int len, off_t offset)
words[n] = call_ptrace(PTRACE_PEEKDATA, proc->pid, addr, 0);
memcpy(data, (char *) words, len);
#endif
+}
#endif
-}
/* write_here - write a block at specified position */
@@ -509,7 +553,7 @@ static void copy_process(PROC_INFO *proc, int out_fd)
where = proc->map_info[n].start;
while (size > 0) {
len = (size > sizeof(buf) ? sizeof(buf) : size);
- read_proc(proc, buf, len, where);
+ proc->read_proc(proc, buf, len, where);
if (keep_holes) {
write_here(out_fd, buf, len, where);
} else {
@@ -526,44 +570,121 @@ static void copy_process(PROC_INFO *proc, int out_fd)
static PROC_INFO *open_process(pid_t pid)
{
-#if defined(FREEBSD2) || defined(FREEBSD3) || defined(FREEBSD4)
+#if defined(FREEBSD2) || defined(FREEBSD3) || defined(FREEBSD4) \
+ || defined(FREEBSD5)
PROC_INFO *proc = (PROC_INFO *) mymalloc(sizeof(*proc));
- char buf[READ_BUFSIZ_CHARS];
MAP_INFO *mp;
+ struct kinfo_proc *procp;
+ kvm_t *kd;
+ struct vmspace vmspace;
+ struct vm_map_entry entry;
+ u_long addr;
+ int cnt;
+ char buf[READ_BUFSIZ_CHARS];
FILE *map_fp;
/*
- * Attach to process memory. XXX Suspend/resume the process if it isn't
- * stopped.
+ * Attach to process memory. Try to use /proc first. XXX Suspend/resume
+ * the process if it isn't stopped.
*/
- sprintf(buf, "/proc/%ld/mem", (long) pid);
- if ((proc->mem_fd = open(buf, O_RDONLY)) < 0)
- error("open %s: %m", buf);
init_cleanup(pid);
+ sprintf(buf, "/proc/%ld/mem", (long) pid);
+ if ((proc->mem_fd = open(buf, O_RDONLY)) >= 0) {
+ proc->read_proc = read_proc_mem;
+
+ /*
+ * Look up the process memory map.
+ *
+ * XXX The map must fit inside one read operation. If the read fails
+ * with EFBIG then we should increase the read buffer size and retry.
+ */
+ sprintf(buf, "/proc/%ld/map", (long) pid);
+ if ((map_fp = fopen(buf, "r")) == 0)
+ error("open %s: %m", buf);
+
+ for (proc->map_count = 0; fgets(buf, sizeof(buf), map_fp) != 0; proc->map_count++) {
+ if (proc->map_count > 0)
+ proc = (PROC_INFO *) myrealloc((char *) proc,
+ sizeof(*proc) + proc->map_count * sizeof(proc->map_info[0]));
+ mp = proc->map_info + proc->map_count;
+ if (sscanf(buf, "%lx %lx", &mp->start, &mp->end) != 2)
+ error("unexpected map format: %s", buf);
+ if (verbose)
+ fprintf(stderr, "map entry: 0x%lx 0x%lx\n", mp->start, mp->end);
+ if (map_out)
+ fprintf(map_out, "0x%lx 0x%lx\n", mp->start, mp->end);
+ }
+ if (ferror(map_fp))
+ error("map read: %m");
+ (void) fclose(map_fp);
+ }
/*
- * Look up the process memory map.
+ * We can't use /proc so we fall back to ptrace() and to peeking at
+ * kernel memory. Look up the process status before attaching to it: 1)
+ * the ptrace() detach operation will resume a stopped process, so we
+ * must re-suspend it; 2) the ptrace() detach operation will not resume a
+ * process that wasn't stopped, so we must resume it.
*/
- sprintf(buf, "/proc/%ld/map", (long) pid);
- if ((map_fp = fopen(buf, "r")) == 0)
- error("open %s: %m", buf);
+ else {
+ proc->read_proc = read_ptrace_mem;
+
+ /*
+ * Look up the process status before attaching to it: PTRACE_DETACH
+ * will resume a stopped process, so we must re-suspend it.
+ */
+ if ((kd = kvm_open((char *) 0, (char *) 0, (char *) 0, O_RDONLY, "pcat")) == 0)
+ error("kvm_open: %m");
+ if ((procp = kvm_getprocs(kd, KERN_PROC_PID, pid, &cnt)) == 0 || cnt != 1)
+ error("kvm_getprocs: %m");
+ if (PROCP_STATUS(procp) & SSTOP)
+ pre_detach_signal = post_detach_signal = SIGSTOP;
+ else
+ pre_detach_signal = SIGCONT;
+
+ /*
+ * Attach to process memory and stop the process.
+ */
+ init_cleanup(pid);
+ if (ptrace(PTRACE_ATTACH, pid, 0, 0) < 0)
+ error("ptrace PTRACE_ATTACH: %m");
+ ptrace_attach_wait(pid);
+
+ /*
+ * Look up the process memory map. With FreeBSD 5 the u area is no
+ * longer accessible via ptrace() so we must grope kernel memory.
+ * This requires root privileges.
+ */
+ if (kvm_read(kd, (u_long) PROCP_VMSPACE(procp),
+ (void *) &vmspace, sizeof(vmspace)) != sizeof(vmspace))
+ error("struct vmspace kvm_read: %m");
+
+ /*
+ * Copied from the code that implements /proc/pid/map.
+ */
+ for (proc->map_count = 0, addr = (u_long) vmspace.vm_map.header.next;
+ addr != (u_long) PROCP_VMSPACE(procp)
+ + offsetof(struct vmspace, vm_map)
+ + offsetof(struct vm_map, header);
+ proc->map_count++, addr = (u_long) entry.next) {
+
+ if (kvm_read(kd, addr, (void *) &entry,
+ sizeof(entry)) != sizeof(entry))
+ error("struct vm_map_entry kvm_read: %m");
+ if (proc->map_count > 0)
+ proc = (PROC_INFO *) myrealloc((char *) proc,
+ sizeof(*proc) + proc->map_count * sizeof(proc->map_info[0]));
+ mp = proc->map_info + proc->map_count;
+ mp->start = entry.start;
+ mp->end = entry.end;
+ if (verbose)
+ fprintf(stderr, "map entry: 0x%lx 0x%lx\n", mp->start, mp->end);
+ if (map_out)
+ fprintf(map_out, "0x%lx 0x%lx\n", mp->start, mp->end);
+ }
- for (proc->map_count = 0; fgets(buf, sizeof(buf), map_fp) != 0; proc->map_count++) {
- if (proc->map_count > 0)
- proc = (PROC_INFO *) myrealloc((char *) proc,
- sizeof(*proc) + proc->map_count * sizeof(proc->map_info[0]));
- mp = proc->map_info + proc->map_count;
- if (sscanf(buf, "%lx %lx", &mp->start, &mp->end) != 2)
- error("unexpected map format: %s", buf);
- if (verbose)
- fprintf(stderr, "map entry: 0x%lx 0x%lx\n", mp->start, mp->end);
- if (map_out)
- fprintf(map_out, "0x%lx 0x%lx\n", mp->start, mp->end);
+ kvm_close(kd);
}
- if (ferror(map_fp))
- error("map read: %m");
- (void) fclose(map_fp);
-
proc->pid = pid;
return (proc);
@@ -576,6 +697,8 @@ static PROC_INFO *open_process(pid_t pid)
struct prmap *pr;
MAP_INFO *mp;
+ proc->read_proc = read_proc_mem;
+
/*
* Attach to process memory. XXX Suspend/resume the process if it isn't
* stopped.
@@ -590,6 +713,8 @@ static PROC_INFO *open_process(pid_t pid)
*/
if (ioctl(proc->mem_fd, PIOCNMAP, (char *) &proc->map_count) < 0)
error("ioctl PIOCNMAP: %m");
+ proc = (PROC_INFO *) myrealloc((char *) proc,
+ sizeof(*proc) + proc->map_count * sizeof(proc->map_info[0]));
prmap = (struct prmap *) mymalloc((proc->map_count + 1) * sizeof(*prmap));
if (ioctl(proc->mem_fd, PIOCMAP, (char *) prmap) < 0)
error("ioctl PIOCMAP: %m");
@@ -615,6 +740,8 @@ static PROC_INFO *open_process(pid_t pid)
MAP_INFO *mp;
FILE *map_fp;
+ proc->read_proc = read_proc_mem;
+
/*
* Attach to process memory. XXX Suspend/resume the process if it isn't
* stopped.
@@ -663,11 +790,13 @@ static PROC_INFO *open_process(pid_t pid)
*/
init_cleanup(pid);
#ifdef HAVE_PROC_MEM
+ proc->read_proc = read_proc_mem;
sprintf(buf, "/proc/%ld/mem", (long) pid);
if ((proc->mem_fd = open(buf, O_RDONLY)) < 0)
error("open %s: %m", buf);
#endif
#ifdef HAVE_PTRACE_MEM
+ proc->read_proc = read_ptrace_mem;
if (ptrace(PTRACE_ATTACH, pid, 0, 0) < 0)
error("ptrace PTRACE_ATTACH: %m");
ptrace_attach_wait(pid);
@@ -731,6 +860,7 @@ static PROC_INFO *open_process(pid_t pid)
*/
proc = (PROC_INFO *) mymalloc(sizeof(*proc) + 2 * sizeof(MAP_INFO));
proc->map_count = 3;
+ proc->read_proc = read_ptrace_mem;
/*
* Attach to process memory and stop the process.
@@ -818,6 +948,7 @@ static PROC_INFO *open_process(pid_t pid)
*/
proc = (PROC_INFO *) mymalloc(sizeof(*proc) + 2 * sizeof(MAP_INFO));
proc->map_count = 3;
+ proc->read_proc = read_ptrace_mem;
/*
* Attach to process memory and stop the process.
@@ -896,6 +1027,7 @@ static PROC_INFO *open_process(pid_t pid)
*/
proc = (PROC_INFO *) mymalloc(sizeof(*proc) + 2 * sizeof(MAP_INFO));
proc->map_count = 3;
+ proc->read_proc = read_ptrace_mem;
/*
* Attach to process memory and stop the process.
@@ -957,7 +1089,7 @@ static PROC_INFO *open_process(pid_t pid)
static void close_process(PROC_INFO *proc)
{
#ifdef HAVE_PROC_MEM
- if (close(proc->mem_fd) < 0)
+ if (proc->mem_fd >= 0 && close(proc->mem_fd) < 0)
error("close memory: %m");
#endif
free((char *) proc);
@@ -992,8 +1124,12 @@ int main(int argc, char **argv)
keep_holes = 1;
break;
case 'm':
- if ((map_out = fopen(optarg, "w")) == 0)
- error("create map file %s: %m", optarg);
+ if (strcmp(optarg, "-") == 0) {
+ map_out = stderr;
+ } else {
+ if ((map_out = fopen(optarg, "w")) == 0)
+ error("create map file %s: %m", optarg);
+ }
break;
case 'v':
verbose++;
--
UNNAMED PROJECT
More information about the forensics-changes
mailing list