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
------- =_aaaaaaaaaa0 Content-Type: text/plain; charset="us-ascii" Content-ID: <8192.854204687.1@nemeton.com.au> 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 ------- =_aaaaaaaaaa0 Content-Type: text/plain; name="findsb.c"; charset="us-ascii" Content-ID: <8192.854204687.2@nemeton.com.au> /* * 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++; } } ------- =_aaaaaaaaaa0 Content-Type: text/plain; name="icat.c"; charset="us-ascii" Content-ID: <8192.854204687.3@nemeton.com.au> /* * 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; } } ------- =_aaaaaaaaaa0 Content-Type: text/plain; name="icat.man"; charset="us-ascii" Content-ID: <8192.854204687.4@nemeton.com.au> 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. ------- =_aaaaaaaaaa0--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199701251505.CAA08199>