remove third argument (`int ns') from ffs_sb_swap(), and let ffs_sb_swap()

determine the endianness of the `struct fs *o' superblock from o->fs_magic
and set needswap as necessary, rather than trusting the caller to get
it right.  invariably, almost every caller of ffs_sb_swap() was calling it
with ns set to the wrong value for ns anyway!
ansi KNF ffs_bswap.c declarations whilst here.

this fixes all sorts of problems when trying to use other-endian file systems,
notably the kernel trying to access memory *way* off, possibly corrupting or
panicing, and userland programs SEGVing and/or corrupting things (e.g,
"fsck_ffs -B"  to swap a file system endianness).

whilst the previous rev of ffs_bswap.c (1.10, 2000/12/23) made this problem
worse, i suspect that the problem was always there and previous versions
just happened not to trash things at the wrong time.

FFS_EI should now be a lot more stable.
This commit is contained in:
lukem 2001-08-17 02:18:46 +00:00
parent a6e8f6814c
commit 1b81d6353d
14 changed files with 68 additions and 59 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: badsect.c,v 1.19 2001/02/19 22:56:18 cgd Exp $ */
/* $NetBSD: badsect.c,v 1.20 2001/08/17 02:18:46 lukem Exp $ */
/*
* Copyright (c) 1981, 1983, 1993
@ -43,7 +43,7 @@ __COPYRIGHT("@(#) Copyright (c) 1981, 1983, 1993\n\
#if 0
static char sccsid[] = "@(#)badsect.c 8.2 (Berkeley) 5/4/95";
#else
__RCSID("$NetBSD: badsect.c,v 1.19 2001/02/19 22:56:18 cgd Exp $");
__RCSID("$NetBSD: badsect.c,v 1.20 2001/08/17 02:18:46 lukem Exp $");
#endif
#endif /* not lint */
@ -158,7 +158,7 @@ main(argc, argv)
errx(1, "%s: bad superblock", name);
}
if (needswap)
ffs_sb_swap(fs, fs, 0);
ffs_sb_swap(fs, fs);
dev_bsize = fs->fs_fsize / fsbtodb(fs, 1);
for (argc -= 2, argv += 2; argc > 0; argc--, argv++) {
number = atoi(*argv);

View File

@ -1,4 +1,4 @@
/* $NetBSD: clri.c,v 1.13 1998/08/25 19:18:13 ross Exp $ */
/* $NetBSD: clri.c,v 1.14 2001/08/17 02:18:47 lukem Exp $ */
/*
* Copyright (c) 1990, 1993
@ -46,7 +46,7 @@ __COPYRIGHT("@(#) Copyright (c) 1990, 1993\n\
#if 0
static char sccsid[] = "@(#)clri.c 8.3 (Berkeley) 4/28/95";
#else
__RCSID("$NetBSD: clri.c,v 1.13 1998/08/25 19:18:13 ross Exp $");
__RCSID("$NetBSD: clri.c,v 1.14 2001/08/17 02:18:47 lukem Exp $");
#endif
#endif /* not lint */
@ -128,7 +128,7 @@ main(argc, argv)
(void)fsync(fd);
if (needswap)
ffs_sb_swap(sbp, sbp, 0);
ffs_sb_swap(sbp, sbp);
bsize = sbp->fs_bsize;
/* remaining arguments are inode numbers. */

View File

@ -1,4 +1,4 @@
/* $NetBSD: ffs_inode.c,v 1.6 2001/08/14 05:44:15 lukem Exp $ */
/* $NetBSD: ffs_inode.c,v 1.7 2001/08/17 02:18:47 lukem Exp $ */
/*-
* Copyright (c) 1980, 1991, 1993, 1994
@ -43,7 +43,7 @@ __COPYRIGHT("@(#) Copyright (c) 1980, 1991, 1993, 1994\n\
#if 0
static char sccsid[] = "@(#)main.c 8.6 (Berkeley) 5/1/95";
#else
__RCSID("$NetBSD: ffs_inode.c,v 1.6 2001/08/14 05:44:15 lukem Exp $");
__RCSID("$NetBSD: ffs_inode.c,v 1.7 2001/08/17 02:18:47 lukem Exp $");
#endif
#endif /* not lint */
@ -93,7 +93,7 @@ fs_read_sblock(char *sblock_buf)
rawread(SBOFF, (char *) sblock, SBSIZE);
if (sblock->fs_magic != FS_MAGIC) {
if (sblock->fs_magic == bswap32(FS_MAGIC)) {
ffs_sb_swap(sblock, sblock, 0);
ffs_sb_swap(sblock, sblock);
needswap = 1;
} else
quit("bad sblock magic number\n");

View File

@ -1,4 +1,4 @@
/* $NetBSD: fsck.h,v 1.26 2001/08/15 03:54:53 lukem Exp $ */
/* $NetBSD: fsck.h,v 1.27 2001/08/17 02:18:47 lukem Exp $ */
/*
* Copyright (c) 1980, 1986, 1993
@ -97,7 +97,7 @@ struct cg *cgrp;
do { \
memmove(sblk.b_un.b_fs, sblock, SBSIZE); \
if (needswap) \
ffs_sb_swap(sblock, sblk.b_un.b_fs, 1); \
ffs_sb_swap(sblock, sblk.b_un.b_fs); \
sblk.b_dirty = 1; \
} while (0)
#define cgdirty() do {copyback_cg(&cgblk); cgblk.b_dirty = 1;} while (0)

View File

@ -1,4 +1,4 @@
/* $NetBSD: pass5.c,v 1.26 2001/01/26 17:37:16 thorpej Exp $ */
/* $NetBSD: pass5.c,v 1.27 2001/08/17 02:18:47 lukem Exp $ */
/*
* Copyright (c) 1980, 1986, 1993
@ -38,7 +38,7 @@
#if 0
static char sccsid[] = "@(#)pass5.c 8.9 (Berkeley) 4/28/95";
#else
__RCSID("$NetBSD: pass5.c,v 1.26 2001/01/26 17:37:16 thorpej Exp $");
__RCSID("$NetBSD: pass5.c,v 1.27 2001/08/17 02:18:47 lukem Exp $");
#endif
#endif /* not lint */
@ -216,8 +216,7 @@ pass5()
memmove(altsblock, asblk.b_un.b_fs,
sblock->fs_sbsize);
if (needswap)
ffs_sb_swap(asblk.b_un.b_fs, altsblock,
needswap);
ffs_sb_swap(asblk.b_un.b_fs, altsblock);
}
if ((asblk.b_errs || cmpsblks(sblock, altsblock)) &&
dofix(&idesc[3],

View File

@ -1,4 +1,4 @@
/* $NetBSD: setup.c,v 1.44 2001/08/15 03:54:53 lukem Exp $ */
/* $NetBSD: setup.c,v 1.45 2001/08/17 02:18:47 lukem Exp $ */
/*
* Copyright (c) 1980, 1986, 1993
@ -38,7 +38,7 @@
#if 0
static char sccsid[] = "@(#)setup.c 8.10 (Berkeley) 5/9/95";
#else
__RCSID("$NetBSD: setup.c,v 1.44 2001/08/15 03:54:53 lukem Exp $");
__RCSID("$NetBSD: setup.c,v 1.45 2001/08/17 02:18:47 lukem Exp $");
#endif
#endif /* not lint */
@ -341,7 +341,7 @@ setup(dev)
if (asblk.b_dirty && !bflag) {
memmove((struct fs*)sblk.b_un.b_fs, sblock, SBSIZE);
if (needswap)
ffs_sb_swap(sblock, (struct fs*)sblk.b_un.b_fs, 1);
ffs_sb_swap(sblock, (struct fs*)sblk.b_un.b_fs);
memmove(asblk.b_un.b_fs, sblk.b_un.b_fs, (size_t)sblock->fs_sbsize);
flush(fswritefd, &asblk);
}
@ -510,11 +510,11 @@ readsb(listerr)
printf("** Swapped byte order\n");
/* swap SB byte order if asked */
if (doswap)
ffs_sb_swap(sblk.b_un.b_fs, sblk.b_un.b_fs, needswap);
ffs_sb_swap(sblk.b_un.b_fs, sblk.b_un.b_fs);
memmove(sblock, sblk.b_un.b_fs, SBSIZE);
if (needswap)
ffs_sb_swap(sblk.b_un.b_fs, sblock, 0);
ffs_sb_swap(sblk.b_un.b_fs, sblock);
/*
* run a few consistency checks of the super block
@ -551,11 +551,11 @@ readsb(listerr)
return (0);
/* swap SB byte order if asked */
if (doswap)
ffs_sb_swap(asblk.b_un.b_fs, asblk.b_un.b_fs, needswap);
ffs_sb_swap(asblk.b_un.b_fs, asblk.b_un.b_fs);
memmove(altsblock, asblk.b_un.b_fs, sblock->fs_sbsize);
if (needswap)
ffs_sb_swap(asblk.b_un.b_fs, altsblock, 0);
ffs_sb_swap(asblk.b_un.b_fs, altsblock);
if (cmpsblks(sblock, altsblock)) {
if (debug) {
long *nlp, *olp, *endlp;

View File

@ -1,4 +1,4 @@
/* $NetBSD: fsirand.c,v 1.13 2001/07/29 11:15:29 lukem Exp $ */
/* $NetBSD: fsirand.c,v 1.14 2001/08/17 02:18:48 lukem Exp $ */
/*-
* Copyright (c) 1997 The NetBSD Foundation, Inc.
@ -38,7 +38,7 @@
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: fsirand.c,v 1.13 2001/07/29 11:15:29 lukem Exp $");
__RCSID("$NetBSD: fsirand.c,v 1.14 2001/08/17 02:18:48 lukem Exp $");
#endif /* lint */
#include <stdio.h>
@ -113,7 +113,7 @@ getsblock(int fd, const char *name, struct disklabel *lab, struct fs *fs)
if (fs->fs_magic != FS_MAGIC) {
if(fs->fs_magic == bswap32(FS_MAGIC)) {
needswap = 1;
ffs_sb_swap(fs, fs, 0);
ffs_sb_swap(fs, fs);
} else
errx(1, "Bad superblock magic number");
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: mkfs.c,v 1.50 2001/07/31 01:31:26 lukem Exp $ */
/* $NetBSD: mkfs.c,v 1.51 2001/08/17 02:18:48 lukem Exp $ */
/*
* Copyright (c) 1980, 1989, 1993
@ -38,7 +38,7 @@
#if 0
static char sccsid[] = "@(#)mkfs.c 8.11 (Berkeley) 5/3/95";
#else
__RCSID("$NetBSD: mkfs.c,v 1.50 2001/07/31 01:31:26 lukem Exp $");
__RCSID("$NetBSD: mkfs.c,v 1.51 2001/08/17 02:18:48 lukem Exp $");
#endif
#endif /* not lint */
@ -606,7 +606,7 @@ next:
sblock.fs_time = utime;
memcpy(writebuf, &sblock, sbsize);
if (needswap)
ffs_sb_swap(&sblock, (struct fs*)writebuf, 1);
ffs_sb_swap(&sblock, (struct fs*)writebuf);
wtfs((int)SBOFF / sectorsize, sbsize, writebuf);
/*
* Write out the duplicate super blocks

View File

@ -1,4 +1,4 @@
/* $NetBSD: tunefs.c,v 1.20 2000/06/15 22:37:17 fvdl Exp $ */
/* $NetBSD: tunefs.c,v 1.21 2001/08/17 02:18:48 lukem Exp $ */
/*
* Copyright (c) 1983, 1993
@ -43,7 +43,7 @@ __COPYRIGHT("@(#) Copyright (c) 1983, 1993\n\
#if 0
static char sccsid[] = "@(#)tunefs.c 8.3 (Berkeley) 5/3/95";
#else
__RCSID("$NetBSD: tunefs.c,v 1.20 2000/06/15 22:37:17 fvdl Exp $");
__RCSID("$NetBSD: tunefs.c,v 1.21 2001/08/17 02:18:48 lukem Exp $");
#endif
#endif /* not lint */
@ -296,7 +296,7 @@ again:
err(3, "cannot open %s for writing", special);
memcpy(buf, (char *)&sblock, SBSIZE);
if (needswap)
ffs_sb_swap((struct fs*)buf, (struct fs*)buf, 1);
ffs_sb_swap((struct fs*)buf, (struct fs*)buf);
bwrite((daddr_t)SBOFF / dev_bsize, buf, SBSIZE);
if (Aflag)
for (i = 0; i < sblock.fs_ncg; i++)
@ -338,7 +338,7 @@ getsb(fs, file)
if (fs->fs_magic != FS_MAGIC) {
if (fs->fs_magic == bswap32(FS_MAGIC)) {
needswap = 1;
ffs_sb_swap(fs, fs, 0);
ffs_sb_swap(fs, fs);
} else
err(5, "%s: bad magic number", file);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: ffs_bswap.c,v 1.10 2000/12/23 14:42:06 enami Exp $ */
/* $NetBSD: ffs_bswap.c,v 1.11 2001/08/17 02:18:48 lukem Exp $ */
/*
* Copyright (c) 1998 Manuel Bouyer.
@ -33,7 +33,9 @@
*/
#include <sys/param.h>
#if defined(_KERNEL)
#include <sys/systm.h>
#endif
#include <ufs/ufs/dinode.h>
#include <ufs/ufs/ufs_bswap.h>
@ -41,20 +43,30 @@
#include <ufs/ffs/ffs_extern.h>
#if !defined(_KERNEL)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define panic(x) printf("%s\n", (x)), abort()
#endif
void
ffs_sb_swap(o, n, ns)
struct fs *o, *n;
int ns;
ffs_sb_swap(struct fs *o, struct fs *n)
{
int i;
int i, needswap, len;
u_int32_t *o32, *n32;
u_int16_t *o16, *n16;
u_int32_t postbloff = ufs_rw32(o->fs_postbloff, ns);
u_int32_t postblfmt = ufs_rw32(o->fs_postblformat, ns);
u_int32_t postbloff, postblfmt;
if (o->fs_magic == FS_MAGIC) {
needswap = 0;
} else if (o->fs_magic == bswap32(FS_MAGIC)) {
needswap = 1;
} else {
panic("ffs_sb_swap: can't determine magic");
}
postbloff = ufs_rw32(o->fs_postbloff, needswap);
postblfmt = ufs_rw32(o->fs_postblformat, needswap);
/*
* In order to avoid a lot of lines, as the first 52 fields of
* the superblock are u_int32_t, we loop here to convert it.
@ -83,15 +95,15 @@ ffs_sb_swap(o, n, ns)
(int16_t *)((u_int8_t *)o + postbloff);
n16 = (postblfmt == FS_42POSTBLFMT) ? n->fs_opostbl[0] :
(int16_t *)((u_int8_t *)n + postbloff);
for (i = 0; i < (postblfmt == FS_42POSTBLFMT ?
len = postblfmt == FS_42POSTBLFMT ?
128 /* fs_opostbl[16][8] */ :
ufs_rw32(o->fs_cpc, ns) * ufs_rw32(o->fs_nrpos, ns)); i++)
ufs_rw32(o->fs_cpc, needswap) * ufs_rw32(o->fs_nrpos, needswap);
for (i = 0; i < len; i++)
n16[i] = bswap16(o16[i]);
}
void
ffs_dinode_swap(o, n)
struct dinode *o, *n;
ffs_dinode_swap(struct dinode *o, struct dinode *n)
{
n->di_mode = bswap16(o->di_mode);
@ -114,9 +126,7 @@ ffs_dinode_swap(o, n)
}
void
ffs_csum_swap(o, n, size)
struct csum *o, *n;
int size;
ffs_csum_swap(struct csum *o, struct csum *n, int size)
{
int i;
u_int32_t *oint, *nint;

View File

@ -1,4 +1,4 @@
/* $NetBSD: ffs_extern.h,v 1.18 2001/08/09 08:15:26 lukem Exp $ */
/* $NetBSD: ffs_extern.h,v 1.19 2001/08/17 02:18:48 lukem Exp $ */
/*-
* Copyright (c) 1991, 1993, 1994
@ -92,7 +92,7 @@ int ffs_balloc __P((void *));
int ffs_ballocn __P((void *));
/* ffs_bswap.c */
void ffs_sb_swap __P((struct fs*, struct fs *, int));
void ffs_sb_swap __P((struct fs*, struct fs *));
void ffs_dinode_swap __P((struct dinode *, struct dinode *));
void ffs_csum_swap __P((struct csum *, struct csum *, int));

View File

@ -1,4 +1,4 @@
/* $NetBSD: ffs_vfsops.c,v 1.82 2001/07/26 07:58:55 lukem Exp $ */
/* $NetBSD: ffs_vfsops.c,v 1.83 2001/08/17 02:18:48 lukem Exp $ */
/*
* Copyright (c) 1989, 1991, 1993, 1994
@ -429,7 +429,7 @@ ffs_reload(mountp, cred, p)
memcpy(newfs, bp->b_data, fs->fs_sbsize);
#ifdef FFS_EI
if (VFSTOUFS(mountp)->um_flags & UFS_NEEDSWAP) {
ffs_sb_swap((struct fs*)bp->b_data, newfs, 0);
ffs_sb_swap((struct fs*)bp->b_data, newfs);
fs->fs_flags |= FS_SWAPPED;
}
#endif
@ -621,7 +621,7 @@ ffs_mountfs(devvp, mp, p)
memcpy(fs, bp->b_data, sbsize);
#ifdef FFS_EI
if (needswap) {
ffs_sb_swap((struct fs*)bp->b_data, fs, 0);
ffs_sb_swap((struct fs*)bp->b_data, fs);
fs->fs_flags |= FS_SWAPPED;
}
#endif
@ -1269,7 +1269,7 @@ ffs_sbupdate(mp, waitfor)
memcpy(bp->b_data, fs, fs->fs_sbsize);
#ifdef FFS_EI
if (mp->um_flags & UFS_NEEDSWAP)
ffs_sb_swap(fs, (struct fs*)bp->b_data, 1);
ffs_sb_swap(fs, (struct fs*)bp->b_data);
#endif
fs->fs_flags |= saveflag;

View File

@ -1,4 +1,4 @@
/* $NetBSD: dumpfs.c,v 1.26 2001/08/15 05:52:28 lukem Exp $ */
/* $NetBSD: dumpfs.c,v 1.27 2001/08/17 02:18:49 lukem Exp $ */
/*
* Copyright (c) 1983, 1992, 1993
@ -43,7 +43,7 @@ __COPYRIGHT("@(#) Copyright (c) 1983, 1992, 1993\n\
#if 0
static char sccsid[] = "@(#)dumpfs.c 8.5 (Berkeley) 4/29/95";
#else
__RCSID("$NetBSD: dumpfs.c,v 1.26 2001/08/15 05:52:28 lukem Exp $");
__RCSID("$NetBSD: dumpfs.c,v 1.27 2001/08/17 02:18:49 lukem Exp $");
#endif
#endif /* not lint */
@ -132,7 +132,7 @@ dumpfs(const char *name)
if (afs.fs_magic != FS_MAGIC) {
if (afs.fs_magic == bswap32(FS_MAGIC)) {
ffs_sb_swap(&afs, &afs, 1);
ffs_sb_swap(&afs, &afs);
needswap = 1;
} else {
warnx("%s: superblock has bad magic number, skipped",

View File

@ -1,4 +1,4 @@
/* $NetBSD: quotacheck.c,v 1.21 2001/02/19 23:22:46 cgd Exp $ */
/* $NetBSD: quotacheck.c,v 1.22 2001/08/17 02:18:49 lukem Exp $ */
/*
* Copyright (c) 1980, 1990, 1993
@ -46,7 +46,7 @@ __COPYRIGHT("@(#) Copyright (c) 1980, 1990, 1993\n\
#if 0
static char sccsid[] = "@(#)quotacheck.c 8.6 (Berkeley) 4/28/95";
#else
__RCSID("$NetBSD: quotacheck.c,v 1.21 2001/02/19 23:22:46 cgd Exp $");
__RCSID("$NetBSD: quotacheck.c,v 1.22 2001/08/17 02:18:49 lukem Exp $");
#endif
#endif /* not lint */
@ -311,7 +311,7 @@ chkquota(type, fsname, mntpt, v, pid)
if (sblock.fs_magic != FS_MAGIC) {
if (sblock.fs_magic== bswap32(FS_MAGIC)) {
needswap = 1;
ffs_sb_swap(&sblock, &sblock, 0);
ffs_sb_swap(&sblock, &sblock);
} else
errx(1, "%s: superblock magic number 0x%x, not 0x%x",
fsname, sblock.fs_magic, FS_MAGIC);