Date: Sun, 26 Jan 1997 02:04:59 +1100 From: Giles Lean <giles@nemeton.com.au> Cc: Joshua Pincus <pinc_cif@uhura.cc.rochester.edu>, freebsd-scsi@freebsd.org Subject: Re: DISASTER! Message-ID: <199701251505.CAA08199@nemeton.com.au> In-Reply-To: <199701251407.BAA06874@nemeton.com.au>
next in thread | previous in thread | raw e-mail | index | archive | help
[-- Attachment #1 --]
On Sun, 26 Jan 1997 01:07:52 +1100 Giles Lean wrote:
> #text/plain; name=findsb.c src/findsb.c
> #text/plain; name=icat.c src/icat/icat.c
> #text/plain; name=icat.man src/icat/icat.man
Dammit! How embarassing. Here they are.
Giles
[-- Attachment #2 --]
/*
* Find superblocks on a BSD FFS filesystem.
*
* On NetBSD, need only to check for FS_MAGIC. HP-UX has about three
* flavours of FS_MAGIC. You'll need something else for a Veritas
* file system.
*/
#include <sys/param.h>
#include <sys/types.h>
#include <ufs/ffs/fs.h>
#include <fcntl.h>
#include <stdio.h>
/*
* Usually larger on HP-UX -- too small will only result in the odd
* false match.
*/
#define BLOCKSIZE (4 * 1024)
int
main(int argc, char *argv[])
{
char block[BLOCKSIZE];
int fd;
struct fs *filesys;
int n;
int blockno;
blockno = 0;
filesys = (struct fs *) block;
if (argc != 2) {
fprintf(stderr, "usage: findsb raw_device\n");
exit(1);
}
if ((fd = open(argv[1], O_RDONLY)) < 0) {
perror(argv[1]);
exit(1);
}
while ((n = read(fd, block, BLOCKSIZE)) == BLOCKSIZE) {
if (filesys->fs_magic == FS_MAGIC)
printf("%d\n", blockno * (BLOCKSIZE / 512));
blockno++;
}
}
[-- Attachment #3 --]
/*
* icat -- "cat" some inodes on a given device to standard out.
* WARNING: this program is the biggest security hole in the
* world, it allows you to completely bypass the file System.
* Keep this code under your hat.
*/
#include <sys/param.h>
#include <sys/types.h>
#include <sys/file.h>
#include <sys/time.h>
#include <sys/vnode.h>
#include <ufs/ufs/quota.h>
#include <ufs/ufs/inode.h>
#include <ufs/ffs/fs.h>
#include <errno.h>
#include <stdio.h>
/* 4.4BSD changes */
#ifndef itod
#define itod ino_to_fsba
#define itoo ino_to_fsbo
#endif
#define ISIZ (sizeof(struct dinode))
#define MAXINOPB (MAXBSIZE / ISIZ)
#define MAXNINDIR (MAXBSIZE / sizeof(daddr_t))
union {
char dummy[SBSIZE];
struct fs sblk;
} sb_un;
#define sblock sb_un.sblk
struct dinode *iget();
void bread();
void indir();
char *progname;
int status;
long dev_bsize = 1;
struct dinode *ip;
char bbuf[MAXBSIZE];
main(argc, argv)
int argc;
char *argv[];
{
register int i;
int fd;
progname = argv[0];
if (argc < 3) {
fprintf(stderr, "Usage: %s filsys inumber ...\n", progname);
exit(1);
}
fd = open(argv[1], O_RDONLY);
if (fd < 0) {
fprintf(stderr, "%s: cannot open ", progname);
perror(argv[1]);
exit(1);
}
#ifndef tahoe
bread(fd, SBSIZE, (char *)&sblock, SBSIZE);
#else
bread(fd, SBOFF, (char *)&sblock, SBSIZE);
#endif
if (sblock.fs_magic != FS_MAGIC) {
fprintf(stderr, "%s: bad super-block magic number 0x%x\n",
progname, sblock.fs_magic);
exit(1);
}
dev_bsize = sblock.fs_fsize / fsbtodb(&sblock, 1);
for (i = 2; i < argc; i++) {
if (icatit(fd, argv[i]) == 0)
status++;
}
exit(status);
}
icatit(fd, inumber)
int fd;
char *inumber;
{
register int i;
unsigned int n;
int rsize;
long size;
if (!isnumber(inumber)) {
fprintf(stderr, "%s: %s is not a number\n",
progname, inumber);
return (0);
}
n = atoi(inumber);
if (n == 0) {
fprintf(stderr, "%s: 0 is an invalid inode number\n",
progname);
return (0);
}
ip = iget(fd, n);
if (ip == (struct dinode *)0) {
fprintf(stderr, "%s: cannot read inode number %u\n",
progname, n);
return (0);
}
if ((ip->di_mode & IFMT) != IFREG) {
fprintf(stderr,
"%s: inode %u has mode 0%o; not a regular file\n",
progname, n, ip->di_mode);
return (0);
}
/* direct blocks */
for (i = 0, size = ip->di_size; i < NDADDR && size > 0; i++) {
rsize = MIN(size, sblock.fs_bsize);
if (ip->di_db[i]) {
bread(fd, fsbtodb(&sblock, ip->di_db[i]),
bbuf, (int) sblock.fs_bsize);
} else {
bzero((char *) bbuf, rsize);
}
if (write(1, bbuf, rsize) != rsize) {
fprintf(stderr, "%s: failed write to ", progname);
perror("stdout");
return (0);
}
size -= rsize;
}
/* indirect blocks */
for (i = 0; i < NIADDR && size > 0; i++) {
if (ip->di_ib[i])
indir(fd, ip->di_ib[i], i, &size);
}
return (1);
}
isnumber(s)
char *s;
{
register c;
while(c = *s++)
if (c < '0' || c > '9')
return(0);
return(1);
}
struct dinode *
iget(fd, inum)
int fd;
unsigned int inum;
{
struct ino {
char junk[ISIZ];
};
static struct ino buf[MAXINOPB];
struct dinode *ip;
bread(fd, fsbtodb(&sblock, itod(&sblock, inum)),
(char *)buf, (int) sblock.fs_bsize);
ip = (struct dinode *) &buf[itoo(&sblock, inum)];
return (ip);
}
void
bread(fd, bno, buf, cnt)
int fd;
daddr_t bno;
char *buf;
int cnt;
{
off_t lseek();
register int n;
off_t off;
off = bno * dev_bsize;
if (lseek(fd, off, L_SET) != off) {
fprintf(stderr, "%s: cannot read block 0x%x\n", progname, bno);
exit(1);
}
if ((n = read(fd, buf, cnt)) < 0) {
fprintf(stderr, "%s: premature EOF; ", progname);
fprintf(stderr, "bno = %ld expected = %d count = %d\n",
bno, cnt, n);
exit(1);
}
}
void
indir(fd, blk, lvl, size)
int fd;
daddr_t blk;
int lvl;
long *size;
{
int i, rsize;
daddr_t idblk[MAXNINDIR];
if (blk != 0)
bread(fd, fsbtodb(&sblock, blk),
(char *)idblk, (int)sblock.fs_bsize);
else
bzero((char *)idblk, (int)sblock.fs_bsize);
if (lvl <= 0) {
for (i = 0; i < NINDIR(&sblock) && *size > 0; i++) {
rsize = MIN(*size, sblock.fs_bsize);
if (idblk[i]) {
bread(fd, fsbtodb(&sblock, idblk[i]),
bbuf, (int) sblock.fs_bsize);
} else {
bzero((char *) bbuf, rsize);
}
if (write(1, bbuf, rsize) != rsize) {
fprintf(stderr, "%s: failed write to ",
progname);
perror("stdout");
return;
}
*size -= rsize;
}
return;
}
lvl--;
for (i = 0; i < NINDIR(&sblock); i++) {
indir(fd, idblk[i], lvl, size);
if (*size <= 0)
return;
}
}
[-- Attachment #4 --]
ICAT(8) ICAT(8)
NAME
icat - cat contents of inode
SYNOPSIS
icat filesys inumber ...
DESCRIPTION
Icat works like cat except that rather than working with
file names, it works with (device, inumber) pairs. This
is particularly useful in looking at files that have been
unlinked from the file system but are still open.
fstat(8) and lsof(8L) can be used to identify such files.
SEE ALSO
cat(1), fstat(8), lsof(8L)
WARNING
Icat should only be runnable by the superuser. Under no
circumstances should this program be installed SUID root
or SGID the group that owns the raw disks, because if so,
file system security can be easily circumvented.
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199701251505.CAA08199>
