From: David Disseldorp <ddiss@suse.de>
To: linux-fsdevel@vger.kernel.org
Cc: Martin Wilck <mwilck@suse.com>,
viro@zeniv.linux.org.uk, willy@infradead.org,
David Disseldorp <ddiss@suse.de>
Subject: [PATCH v5 3/5] gen_init_cpio: fix short read file handling
Date: Tue, 14 Dec 2021 00:20:06 +0100 [thread overview]
Message-ID: <20211213232007.26851-4-ddiss@suse.de> (raw)
In-Reply-To: <20211213232007.26851-1-ddiss@suse.de>
When processing a "file" entry, gen_init_cpio attempts to allocate a
buffer large enough to stage the entire contents of the source file.
It then attempts to fill the buffer via a single read() call and
subsequently writes out the entire buffer length, without checking that
read() returned the full length, potentially writing uninitialized
buffer memory.
Fix this by breaking up file I/O into 64k chunks and only writing the
length returned by the prior read() call.
Signed-off-by: David Disseldorp <ddiss@suse.de>
---
usr/gen_init_cpio.c | 44 +++++++++++++++++++++++++-------------------
1 file changed, 25 insertions(+), 19 deletions(-)
diff --git a/usr/gen_init_cpio.c b/usr/gen_init_cpio.c
index 0e2c8a5838b1..9a0f8c37273a 100644
--- a/usr/gen_init_cpio.c
+++ b/usr/gen_init_cpio.c
@@ -20,6 +20,7 @@
#define xstr(s) #s
#define str(s) xstr(s)
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
static unsigned int offset;
static unsigned int ino = 721;
@@ -297,9 +298,8 @@ static int cpio_mkfile(const char *name, const char *location,
unsigned int nlinks)
{
char s[256];
- char *filebuf = NULL;
struct stat buf;
- long size;
+ unsigned long size;
int file = -1;
int retval;
int rc = -1;
@@ -326,22 +326,17 @@ static int cpio_mkfile(const char *name, const char *location,
buf.st_mtime = 0xffffffff;
}
- filebuf = malloc(buf.st_size);
- if (!filebuf) {
- fprintf (stderr, "out of memory\n");
- goto error;
- }
-
- retval = read (file, filebuf, buf.st_size);
- if (retval < 0) {
- fprintf (stderr, "Can not read %s file\n", location);
+ if (buf.st_size > 0xffffffff) {
+ fprintf(stderr, "%s: Size exceeds maximum cpio file size\n",
+ location);
goto error;
}
size = 0;
for (i = 1; i <= nlinks; i++) {
/* data goes on last link */
- if (i == nlinks) size = buf.st_size;
+ if (i == nlinks)
+ size = buf.st_size;
if (name[0] == '/')
name++;
@@ -366,23 +361,34 @@ static int cpio_mkfile(const char *name, const char *location,
push_string(name);
push_pad();
- if (size) {
- if (fwrite(filebuf, size, 1, stdout) != 1) {
+ while (size) {
+ unsigned char filebuf[65536];
+ ssize_t this_read;
+ size_t this_size = MIN(size, sizeof(filebuf));
+
+ this_read = read(file, filebuf, this_size);
+ if (this_read <= 0 || this_read > this_size) {
+ fprintf(stderr, "Can not read %s file\n", location);
+ goto error;
+ }
+
+ if (fwrite(filebuf, this_read, 1, stdout) != 1) {
fprintf(stderr, "writing filebuf failed\n");
goto error;
}
- offset += size;
- push_pad();
+ offset += this_read;
+ size -= this_read;
}
+ push_pad();
name += namesize;
}
ino++;
rc = 0;
-
+
error:
- if (filebuf) free(filebuf);
- if (file >= 0) close(file);
+ if (file >= 0)
+ close(file);
return rc;
}
--
2.31.1
next prev parent reply other threads:[~2021-12-13 23:27 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-12-13 23:20 initramfs: "crc" cpio format and INITRAMFS_PRESERVE_MTIME David Disseldorp
2021-12-13 23:20 ` [PATCH v5 1/5] initramfs: refactor do_header() cpio magic checks David Disseldorp
2021-12-13 23:20 ` [PATCH v5 2/5] initramfs: add INITRAMFS_PRESERVE_MTIME Kconfig option David Disseldorp
2022-01-05 20:10 ` David Disseldorp
2021-12-13 23:20 ` David Disseldorp [this message]
2021-12-13 23:20 ` [PATCH v5 4/5] gen_init_cpio: support file checksum archiving David Disseldorp
2021-12-13 23:20 ` [PATCH v5 5/5] initramfs: support cpio extraction with file checksums David Disseldorp
2021-12-20 16:05 ` initramfs: "crc" cpio format and INITRAMFS_PRESERVE_MTIME David Disseldorp
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20211213232007.26851-4-ddiss@suse.de \
--to=ddiss@suse.de \
--cc=linux-fsdevel@vger.kernel.org \
--cc=mwilck@suse.com \
--cc=viro@zeniv.linux.org.uk \
--cc=willy@infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).