Commit Graph

349 Commits

Author SHA1 Message Date
Kirk McKusick
85ee267a3e Update the libufs cgget() and cgput() interfaces to have a similar
API to the sbget() and sbput() interfaces. Specifically they take
a file descriptor pointer rather than the struct uufsd *disk pointer
used by the libufs cgread() and cgwrite() interfaces. Update fsck_ffs
to use these revised interfaces.

No functional changes intended.

Sponsored by: Netflix
2020-09-19 22:48:30 +00:00
Chuck Silvers
e83370448f Move all of the error prints in readsb() from stderr to stdout.
The only output from fsck that should go to stderr is the usage message.
if setup() fails then exit with EEXIT rather than 0.

Reviewed by:	mckusick
Sponsored by:	Netflix
2020-09-01 18:50:26 +00:00
Kirk McKusick
f644caad88 Use the sbput() function to write alternate superblocks so that
they get a checkhash.

PR:           246983
Sponsored by: Netflix
2020-08-15 21:40:36 +00:00
Kirk McKusick
92c839a156 The libufs library needs to track and free the new fs_si structure
in addition to the fs_csp structure that it references.

PR:           247425
Sponsored by: Netflix
2020-06-23 21:28:26 +00:00
Kirk McKusick
0c08ecdff3 Inode check-hash errors were being reported after system crashes.
Trace the cause down to journalled soft updates recovery code in
fsck failing to recompute the check-hash after updating an inode.

As inode check-hash was first introduced to UFS in FreeBSD 13,
there is no need to MFC this commit.

Reported by:  Chuck Silvers
Sponsored by: Netflix
2020-04-10 23:58:07 +00:00
Kirk McKusick
2a18059670 Add an inode check-hash verification when running the journalled
soft update recovery code with the debugging (-d) option.

As inode check-hash was first introduced to UFS in FreeBSD 13,
there is no need to MFC this commit.

Reported by:  Chuck Silvers
Sponsored by: Netflix
2020-04-10 23:49:34 +00:00
Kyle Evans
c3e9752ea1 fsck_ffs/fsdb: fix -fno-common build
This one is also a small list:

- 3x duplicate definition (ufs2_zino, returntosingle, nflag)
- 5x 'needs extern', 3/5 of which are referenced in fsdb

-fno-common will become the default in GCC10/LLVM11.

MFC after:	1 week
2020-03-29 20:03:46 +00:00
Kirk McKusick
c094263a24 When running fsck_ffs manually, do not ask:
USE JOURNAL? [yn]

when the journal timestamp does not match the filesystem mount time
as we are just going to print an error and fall through to a full fsck.
Instead, just run a full fsck.

Requested by: Bjoern A. Zeeb (bz)
MFC after:    7 days
2019-12-24 23:03:12 +00:00
Xin LI
e87e283ce3 Remove unused includes.
MFC after:	2 weeks
2019-12-22 05:44:29 +00:00
Eric van Gyzen
15da40b0af fsck_ffs: fix some memory leaks found by Coverity.
Reported by:	Coverity
CID:		1380549 1380550 1380551
MFC after:	1 week
Sponsored by:	Dell EMC Isilon
2019-12-10 20:04:08 +00:00
Kirk McKusick
e39c92986d Replace an uninitialized variable with the correct element from the
superblock when doing recovery with journalled soft updates.

Reported by:  Chuck Silvers
MFC after:    3 days
Sponsored by: Netflix
2019-10-22 22:23:59 +00:00
Kirk McKusick
47d3e2f83b Correct the location of the first backup superblock in fsck_ffs.8.
Make a note in the newfs.8 manual page to update the first backup
superblock location when changing the default fragment size for
the filesystem.

Reported by:  O. Hartmann
2019-08-07 16:56:00 +00:00
Kirk McKusick
967d9fa3bb Treat any inode with bad content as unknown (i.e., ask if it should
be cleared).

Sponsored by: Netflix
2019-07-20 21:39:32 +00:00
Kirk McKusick
3bd88193c6 When running with journaled soft updates, some updated inodes were not
having their check hashes recomputed which resulted in spurious inode
check-hash errors when the system came back up after a crash.

Reported by:  Alan Somers
Sponsored by: Netflix
2019-07-20 21:20:40 +00:00
Kirk McKusick
bfc5d3f9c2 This revision began as a simple change to eliminate an uninitialized warning
found by Coverity. However, upon closer inspection the implementation of
fsck_ffs's fsck_readdir() and dircheck() functions is both nearly impossible
to follow and fails to check / fix directories in several cases. So, this
revision is an entire rewrite of these two functions to clarify what they
are doing and also to get something that works properly.

Referred by:  cem
Reviewed by:  kib, David G Lawrence
MFC after:    3 days
CID 1401317:  namlen may be used uninitialized
2019-05-21 22:24:38 +00:00
Kirk McKusick
0061238fb0 This update eliminates a kernel stack disclosure bug in UFS/FFS
directory entries that is caused by uninitialized directory entry
padding written to the disk. It can be viewed by any user with read
access to that directory. Up to 3 bytes of kernel stack are disclosed
per file entry, depending on the the amount of padding the kernel
needs to pad out the entry to a 32 bit boundry. The offset in the
kernel stack that is disclosed is a function of the filename size.
Furthermore, if the user can create files in a directory, this 3
byte window can be expanded 3 bytes at a time to a 254 byte window
with 75% of the data in that window exposed. The additional exposure
is done by removing the entry, creating a new entry with a 4-byte
longer name, extracting 3 more bytes by reading the directory, and
repeating until a 252 byte name is created.

This exploit works in part because the area of the kernel stack
that is being disclosed is in an area that typically doesn't change
that often (perhaps a few times a second on a lightly loaded system),
and these file creates and unlinks themselves don't overwrite the
area of kernel stack being disclosed.

It appears that this bug originated with the creation of the Fast
File System in 4.1b-BSD (Circa 1982, more than 36 years ago!), and
is likely present in every Unix or Unix-like system that uses
UFS/FFS. Amazingly, nobody noticed until now.

This update also adds the -z flag to fsck_ffs to have it scrub
the leaked information in the name padding of existing directories.
It only needs to be run once on each UFS/FFS filesystem after a
patched kernel is installed and running.

Submitted by: David G. Lawrence <dg@dglawrence.com>
Reviewed by:  kib
MFC after:    1 week
2019-05-03 21:54:14 +00:00
Kirk McKusick
d483391306 Followup to -r344552 in which fsck_ffs checks for a size past the
last allocated block of the file and if that is found, shortens the
file to reference the last allocated block thus avoiding having it
reference a hole at its end.

This update corrects an error where fsck_ffs miscalculated the last
logical block of the file when the file contained a large hole.

Reported by:  Jamie Landeg-Jones
Tested by:    Peter Holm
MFC after:    2 weeks
Sponsored by: Netflix
2019-04-13 13:31:06 +00:00
Kirk McKusick
72ef1cb896 Properly calculate the last used logical block of a file when checking
inodes that reference directories. While here tighten the check for
comparing the last logical block with the end of the file.

Reported by:  Peter Holm
Tested by:    Peter Holm
Sponsored by: Netflix
2019-03-02 21:30:01 +00:00
Kirk McKusick
ac4b20a0a7 After a crash, a file that extends into indirect blocks may end up
shorter than its size resulting in a hole as its final block (which
is a violation of the invarients of the UFS filesystem).

Soft updates will always ensure that the file size is correct when
writing inodes to disk for files that contain only direct block
pointers. However soft updates does not roll back sizes for files
with indirect blocks that it has set to unallocated because their
contents have not yet been written to disk. Hence, the file can
appear to have a hole at its end because the block pointer has been
rolled back to zero when its inode was written to disk. Thus,
fsck_ffs calculates the last allocated block in the file. For files
that extend into indirect blocks, fsck_ffs checks for a size past
the last allocated block of the file and if that is found, shortens
the file to reference the last allocated block thus avoiding having
it reference a hole at its end.

Submitted by: Chuck Silvers <chs@netflix.com>
Tested by:    Chuck Silvers <chs@netflix.com>
MFC after:    1 week
Sponsored by: Netflix
2019-02-25 21:58:19 +00:00
Kirk McKusick
7bcd1fab5a Ensure that inode updates are properly flushed out during the first
pass of fsck_ffs. Some changes, such as check-hash corrections were
being lost.

Reported by: Michael Tuexen (tuexen@)
Tested by:   Michael Tuexen (tuexen@)
MFC after:   3 days
2019-02-19 20:12:12 +00:00
Kirk McKusick
e155208020 Fsck would find, report, and offer to fix inode check-hash failures.
If requested to fix the inode check-hash it would confirm having done
it, but then fail to make the fix. The same code is used in fsdb which,
unlike fsck, would actually fix the inode check-hash.

The discrepancy occurred because fsck has two ways to fetch inodes.
The inode by number function ginode() and the streaming inode
function getnextinode() used during pass1. Fsdb uses the ginode()
function which correctly does the fix, while fsck first encounters
the bad inode check-hash in pass1 where it is using the getnextinode()
function that failed to make the correction. This patch corrects
the getnextinode() function so that fsck now correctly fixes inodes
with incorrect inode check-hashs.

Reported by:  Gary Jennejohn <gljennjohn@gmail.com>
Sponsored by: Netflix
2018-12-15 17:32:47 +00:00
Edward Tomasz Napierala
04e5c6f18a Make fsck(8) use pread(2). This cuts the number of syscalls by half.
Reviewed by:	kib, mckusick
MFC after:	2 weeks
Sponsored by:	DARPA, AFRL
Differential Revision:	https://reviews.freebsd.org/D17586
2018-12-15 11:36:20 +00:00
Kirk McKusick
8f829a5cf0 Continuing efforts to provide hardening of FFS. This change adds a
check hash to the filesystem inodes. Access attempts to files
associated with an inode with an invalid check hash will fail with
EINVAL (Invalid argument). Access is reestablished after an fsck
is run to find and validate the inodes with invalid check-hashes.
This check avoids a class of filesystem panics related to corrupted
inodes. The hash is done using crc32c.

Note this check-hash is for the inode itself and not any of its
indirect blocks. Check-hash validation may be extended to also
cover indirect block pointers, but that will be a separate (and
more costly) feature.

Check hashes are added only to UFS2 and not to UFS1 as UFS1 is
primarily used in embedded systems with small memories and low-powered
processors which need as light-weight a filesystem as possible.

Reviewed by:  kib
Tested by:    Peter Holm
Sponsored by: Netflix
2018-12-11 22:14:37 +00:00
Kirk McKusick
fb14e73cb4 Normally when an attempt is made to mount a UFS/FFS filesystem whose
superblock has a check-hash error, an error message noting the
superblock check-hash failure is printed and the mount fails. The
administrator then runs fsck to repair the filesystem and when
successful, the filesystem can once again be mounted.

This approach fails if the filesystem in question is a root filesystem
from which you are trying to boot. Here, the loader fails when trying
to access the filesystem to get the kernel to boot. So it is necessary
to allow the loader to ignore the superblock check-hash error and make
a best effort to read the kernel. The filesystem may be suffiently
corrupted that the read attempt fails, but there is no harm in trying
since the loader makes no attempt to write to the filesystem.

Once the kernel is loaded and starts to run, it attempts to mount its
root filesystem. Once again, failure means that it breaks to its prompt
to ask where to get its root filesystem. Unless you have an alternate
root filesystem, you are stuck.

Since the root filesystem is initially mounted read-only, it is
safe to make an attempt to mount the root filesystem with the failed
superblock check-hash. Thus, when asked to mount a root filesystem
with a failed superblock check-hash, the kernel prints a warning
message that the root filesystem superblock check-hash needs repair,
but notes that it is ignoring the error and proceeding. It does
mark the filesystem as needing an fsck which prevents it from being
enabled for writing until fsck has been run on it. The net effect
is that the reboot fails to single user, but at least at that point
the administrator has the tools at hand to fix the problem.

Reported by:    Rick Macklem (rmacklem@)
Discussed with: Warner Losh (imp@)
Sponsored by:   Netflix
2018-12-06 00:09:39 +00:00
Kirk McKusick
8ebae128be Ensure that cylinder-group check-hashes are properly updated when first
creating them and when correcting them when they are found to be corrupted.

Reported by:  Don Lewis (truckman@)
Sponsored by: Netflix
2018-12-05 06:31:50 +00:00
Kirk McKusick
038c170fc2 Properly recover from superblock check-hash failures. Specifically,
report the check-hash failure and offer to search for and use
alternate superblocks.  Prior to this fix fsck_ffs would simply
report the check-hash failure and exit.

Reported by:  Julian H. Stacey <jhs@berklix.com>
Tested by:    Peter Holm
Sponsored by: Netflix
2018-11-25 18:09:39 +00:00
Kirk McKusick
9fc5d538fc In preparation for adding inode check-hashes, clean up and
document the libufs interface for fetching and storing inodes.
The undocumented getino / putino interface has been replaced
with a new getinode / putinode interface.

Convert the utilities that had been using the undocumented
interface to use the new documented interface.

No functional change (as for now the libufs library does not
do inode check-hashes).

Reviewed by:  kib
Tested by:    Peter Holm
Sponsored by: Netflix
2018-11-13 21:40:56 +00:00
Kirk McKusick
2c288c95d9 In preparation for adding inode check-hashes, change the fsck_ffs
inodirty() function to have a pointer to the inode being dirtied.
No functional change (as for now the parameter is ununsed).

Sponsored by: Netflix
2018-10-31 05:17:53 +00:00
Kirk McKusick
ec888383cf Continuing efforts to provide hardening of FFS, this change adds a
check hash to the superblock. If a check hash fails when an attempt
is made to mount a filesystem, the mount fails with EINVAL (Invalid
argument). This avoids a class of filesystem panics related to
corrupted superblocks. The hash is done using crc32c.

Check hases are added only to UFS2 and not to UFS1 as UFS1 is primarily
used in embedded systems with small memories and low-powered processors
which need as light-weight a filesystem as possible.

Reviewed by:  kib
Tested by:    Peter Holm
Sponsored by: Netflix
2018-10-23 21:10:06 +00:00
Kirk McKusick
7462fc7f56 Add missing newline in pwarn message.
Reported by: Mark Millard <marklmi@yahoo.com>
Approved by: re (kib)
2018-10-02 13:45:25 +00:00
Alan Somers
6040822c4e Make timespecadd(3) and friends public
The timespecadd(3) family of macros were imported from NetBSD back in
r35029. However, they were initially guarded by #ifdef _KERNEL. In the
meantime, we have grown at least 28 syscalls that use timespecs in some
way, leading many programs both inside and outside of the base system to
redefine those macros. It's better just to make the definitions public.

Our kernel currently defines two-argument versions of timespecadd and
timespecsub.  NetBSD, OpenBSD, and FreeDesktop.org's libbsd, however, define
three-argument versions.  Solaris also defines a three-argument version, but
only in its kernel.  This revision changes our definition to match the
common three-argument version.

Bump _FreeBSD_version due to the breaking KPI change.

Discussed with:	cem, jilles, ian, bde
Differential Revision:	https://reviews.freebsd.org/D14725
2018-07-30 15:46:40 +00:00
Ed Maste
d8ba45e213 Revert r313780 (UFS_ prefix) 2018-03-17 12:59:55 +00:00
Ed Maste
1e2b9afca9 Prefix UFS symbols with UFS_ to reduce namespace pollution
Followup to r313780.  Also prefix ext2's and nandfs's versions with
EXT2_ and NANDFS_.

Reported by:	kib
Reviewed by:	kib, mckusick
Sponsored by:	The FreeBSD Foundation
Differential Revision:	https://reviews.freebsd.org/D9623
2018-03-17 01:48:27 +00:00
Kirk McKusick
12487c7243 Fix a read past the end of a buffer in fsck.
To minimize the time spent scanning all of the directories in pass 2
(Check Pathnames), fsck uses a search order based on the location
of their first block. Zero length directories have no first block,
so the array being used to hold the block numbers of directory
inodes was of zero length. Thus a lookup was done past the end of
the array getting at best a random value and at worst a segment
fault.  For zero length directories, this change allocates a one
element block array and initializes it to zero. The effect is that
all zero length directories are handled first in pass 2.

Reviewed by: brooks
Differential Revision: https://reviews.freebsd.org/D14163
2018-02-21 20:32:23 +00:00
Kirk McKusick
31461aa2f1 Include files missed in 329051. 2018-02-08 23:14:24 +00:00
Kirk McKusick
068beacf21 The goal of this change is to prevent accidental foot shooting by
folks running filesystems created on check-hash enabled kernels
(which I will call "new") on a non-check-hash enabled kernels (which
I will call "old). The idea here is to detect when a filesystem is
run on an old kernel and flag the filesystem so that when it gets
moved back to a new kernel, it will not start getting a slew of
check-hash errors.

Back when the UFS version 2 filesystem was created, it added a file
flag FS_INDEXDIRS that was to be set on any filesystem that kept
some sort of on-disk indexing for directories. The idea was precisely
to solve the issue we have today. Specifically that a newer kernel
that supported indexing would be able to tell that the filesystem
had been run on an older non-indexing kernel and that the indexes
should not be used until they had been rebuilt. Since we have never
implemented on-disk directory indicies, the FS_INDEXDIRS flag is
cleared every time any UFS version 2 filesystem ever created is
mounted for writing.

This commit repurposes the FS_INDEXDIRS flag as the FS_METACKHASH
flag. Thus, the FS_METACKHASH is definitively known to have always
been cleared. The FS_INDEXDIRS flag has been moved to a new block
of flags that will always be cleared starting with this commit
(until they get used to implement some future feature which needs
to detect that the filesystem was mounted on a kernel that predates
the new feature).

If a filesystem with check-hashes enabled is mounted on an old
kernel the FS_METACKHASH flag is cleared. When that filesystem is
mounted on a new kernel it will see that the FS_METACKHASH has been
cleared and clears all of the fs_metackhash flags. To get them
re-enabled the user must run fsck (in interactive mode without the
-y flag) which will ask for each supported check hash whether it
should be rebuilt and enabled. When fsck is run in its default preen
mode, it will just ignore the check hashes so they will remain
disabled.

The kernel has always disabled any check hash functions that it
does not support, so as more types of check hashes are added, we
will get a non-surprising result. Specifically if filesystems get
moved to kernels supporting fewer of the check hashes, those that
are not supported will be disabled. If the filesystem is moved back
to a kernel with more of the check-hashes available and fsck is run
interactively to rebuild them, then their checking will resume.
Otherwise just the smaller subset will be checked.

A side effect of this commit is that filesystems running with
cylinder-group check hashes will stop having them checked until
fsck is run to re-enable them (since none of them currently have
the FS_METACKHASH flag set). So, if you want check hashes enabled
on your filesystems after booting a kernel with these changes, you
need to run fsck to enable them. Any newly created filesystems will
have check hashes enabled. If in doubt as to whether you have check
hashes emabled, run dumpfs and look at the list of enabled flags
at the end of the superblock details.
2018-02-08 23:06:58 +00:00
Kirk McKusick
26772fefc1 Use sbput(3) rather than sbwrite(3) to ensure that the updated copy of
the superblock gets written.

Reported by: Mark Johnston <markj@FreeBSD.org>
2018-02-02 00:07:38 +00:00
Kirk McKusick
dffce2150e Refactoring of reading and writing of the UFS/FFS superblock.
Specifically reading is done if ffs_sbget() and writing is done
in ffs_sbput(). These functions are exported to libufs via the
sbget() and sbput() functions which then used in the various
filesystem utilities. This work is in preparation for adding
subperblock check hashes.

No functional change intended.

Reviewed by: kib
2018-01-26 00:58:32 +00:00
Li-Wen Hsu
af89fcf725 Fix architectures where pointer and u_int have different sizes
Reviewed by:	imp
Differential Revision:	https://reviews.freebsd.org/D14049
2018-01-25 08:36:19 +00:00
Kirk McKusick
a6bbdf81b5 More throughly integrate libufs into fsck_ffs by using its cgput()
routine to write out the cylinder groups rather than recreating the
calculation of the cylinder-group check hash in fsck_ffs.

No functional change intended.
2018-01-24 23:57:40 +00:00
Kirk McKusick
72f854ce8f Correct fsck journal-recovery code to update a cylinder-group
check-hash after making changes to the cylinder group. The problem
was that the journal-recovery code was calling the libufs bwrite()
function instead of the cgput() function. The cgput() function updates
the cylinder-group check-hash before writing the cylinder group.

This change required the additions of the cgget() and cgput() functions
to the libufs API to avoid a gratuitous bcopy of every cylinder group
to be read or written. These new functions have been added to the
libufs manual pages. This was the first opportunity that I have had
to use and document the use of the EDOOFUS error code.

Reviewed by: kib
Reported by: emaste and others
2018-01-17 17:58:24 +00:00
Kirk McKusick
957fc241ec Rename cgget => cglookup to clear name space for new libufs function cgget.
No functional change.
2018-01-17 06:31:21 +00:00
David Bright
469759f8e4 Exit fsck_ffs with non-zero status when file system is not repaired.
When the fsck_ffs program cannot fully repair a file system, it will
output the message PLEASE RERUN FSCK. However, it does not exit with a
non-zero status in this case (contradicting the man page claim that it
"exits with 0 on success, and >0 if an error occurs."  The fsck
rc-script (when running "fsck -y") tests the status from fsck (which
passes along the exit status from fsck_ffs) and issues a "stop_boot"
if the status fails. However, this is not effective since fsck_ffs can
return zero even on (some) errors. Effectively, it is left to a later
step in the boot process when the file systems are mounted to detect
the still-unclean file system and stop the boot.

This change modifies fsck_ffs so that when it cannot fully repair the
file system and issues the PLEASE RERUN FSCK message it also exits
with a non-zero status.

While here, the fsck_ffs man page has also been updated to document
the failing exit status codes used by fsck_ffs. Previously, only exit
status 7 was documented. Some of these exit statuses are tested for in
the fsck rc-script, so they are clearly depended upon and deserve
documentation.

Reviewed by:	mckusick, vangyzen, jilles (manpages)
MFC after:	1 week
Sponsored by:	Dell EMC
Differential Revision:	https://reviews.freebsd.org/D13862
2018-01-15 19:25:11 +00:00
Warner Losh
3922493a21 Report CG checksum mismatches. These errors are non-fatal. The
previous behavior is preserved (the CG checksum is fixed). We're just
noisy about it now.

Reviewed by: kirk@
Sponsored by: Netflix
Differential Revision: https://reviews.freebsd.org/D13884
2018-01-14 16:55:14 +00:00
Pedro F. Giffuni
1de7b4b805 various: general adoption of SPDX licensing ID tags.
Mainly focus on files that use BSD 2-Clause license, however the tool I
was using misidentified many licenses so this was mostly a manual - error
prone - task.

The Software Package Data Exchange (SPDX) group provides a specification
to make it easier for automated tools to detect and summarize well known
opensource licenses. We are gradually adopting the specification, noting
that the tags are considered only advisory and do not, in any way,
superceed or replace the license texts.

No functional change intended.
2017-11-27 15:37:16 +00:00
Pedro F. Giffuni
8a16b7a18f General further adoption of SPDX licensing ID tags.
Mainly focus on files that use BSD 3-Clause license.

The Software Package Data Exchange (SPDX) group provides a specification
to make it easier for automated tools to detect and summarize well known
opensource licenses. We are gradually adopting the specification, noting
that the tags are considered only advisory and do not, in any way,
superceed or replace the license texts.

Special thanks to Wind River for providing access to "The Duke of
Highlander" tool: an older (2014) run over FreeBSD tree was useful as a
starting point.
2017-11-20 19:49:47 +00:00
Scott Long
7841fefb62 Rename P_OSREL_CK_CLYGRP to P_OSREL_CK_CYLGRP 2017-11-17 13:12:20 +00:00
Warner Losh
a3c15a4445 Only try to enable CK_CLYGRP if we're running on kernel newer than
1200046, the first version that supports this feature. If we set it,
then use an old kernel, we'll break the 'contract' of having
checksummed cylinder groups this flag signifies. To avoid creating
something with an inconsistent state, don't turn the flag on in these
cases. The first full fsck with a new kernel will turn this on.

Spnsored by: Netflix
Differential Revision: https://reviews.freebsd.org/D13114
2017-11-16 21:28:14 +00:00
Bryan Drewery
ea825d0274 DIRDEPS_BUILD: Update dependencies.
Sponsored by:	Dell EMC Isilon
2017-10-31 00:07:04 +00:00
Kirk McKusick
918820682e Do not report the filesystem as modified when the only change is to
update the timestamp in the superblock.

Reported by:	Peter Holm
MFC after:	1 week
2017-10-09 22:19:58 +00:00