git: e23954bd42fe - main - hexdump: Do not trust st_size if it equals zero.

From: Xin LI <delphij_at_FreeBSD.org>
Date: Thu, 04 Jan 2024 08:23:11 UTC
The branch main has been updated by delphij:

URL: https://cgit.FreeBSD.org/src/commit/?id=e23954bd42fe4331b67ba8f6446bcccf751096f1

commit e23954bd42fe4331b67ba8f6446bcccf751096f1
Author:     Ricardo Branco <rbranco@suse.de>
AuthorDate: 2024-01-03 20:17:58 +0000
Commit:     Xin LI <delphij@FreeBSD.org>
CommitDate: 2024-01-04 08:16:50 +0000

    hexdump: Do not trust st_size if it equals zero.
    
    Fix for hexdump -s not being able to skip files residing in
    pseudo-filesystems that advertise a zero size value.
    
    Historically, many pseudofs-based filesystems (e.g., procfs) report
    a va_size of 0 for numerous files classified as regular files.
    Typically, the contents of these files are generated on demand
    from kernel data as sbuf(9) strings at the time they are read.
    Accurately reporting the size of these files is challenging, as it
    often involves generating their contents. These pseudofs implementations
    frequently report the size as 0. This is a historical behavior and also
    aligns with Linux behavior. To maintain compatibility, we have chosen
    to preserve the existing behavior and address it in the userland
    application, rather than modifying it in the kernel (by updating the
    correct value for va_size).
    
    PR:             bin/276106
    MFC after:      1 week
---
 usr.bin/hexdump/display.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/usr.bin/hexdump/display.c b/usr.bin/hexdump/display.c
index 2bef03626fe2..77de580983ca 100644
--- a/usr.bin/hexdump/display.c
+++ b/usr.bin/hexdump/display.c
@@ -391,13 +391,14 @@ doskip(const char *fname, int statok)
 	if (statok) {
 		if (fstat(fileno(stdin), &sb))
 			err(1, "%s", fname);
-		if (S_ISREG(sb.st_mode) && skip > sb.st_size) {
+		if (S_ISREG(sb.st_mode) && skip > sb.st_size && sb.st_size > 0) {
 			address += sb.st_size;
 			skip -= sb.st_size;
 			return;
 		}
 	}
-	if (!statok || S_ISFIFO(sb.st_mode) || S_ISSOCK(sb.st_mode)) {
+	if (!statok || S_ISFIFO(sb.st_mode) || S_ISSOCK(sb.st_mode) || \
+	    (S_ISREG(sb.st_mode) && sb.st_size == 0)) {
 		noseek();
 		return;
 	}