[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