Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package cramfs-tools for openSUSE:Factory checked in at 2026-10-21 21:00:19 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/cramfs-tools (Old) and /work/SRC/openSUSE:Factory/.cramfs-tools.new.2252680 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "cramfs-tools" Wed Oct 21 21:00:19 2026 rev:3 rq:1386746 version:2.2 Changes: -------- --- /work/SRC/openSUSE:Factory/cramfs-tools/cramfs-tools.changes 2024-02-26 19:47:25.530322052 +0100 +++ /work/SRC/openSUSE:Factory/.cramfs-tools.new.2252680/cramfs-tools.changes 2026-10-21 21:02:04.194527255 +0200 @@ -1,0 +2,36 @@ +Tue Oct 20 14:23:26 UTC 2026 - Martin Pluskal <[email protected]> + +- Remove leftover cramfs-tools-obey-cflags.patch, no longer + referenced since 2.2 dropped it from the spec. +- CVE-2026-8274: cramfsck path traversal via crafted dirent names, + already fixed in 2.2 (boo#1264703) +- Spec cleanup: drop obsolete Group tag, use pkgconfig(zlib), + and add missing gcc/make BuildRequires. + +------------------------------------------------------------------- +Thu Apr 23 06:43:40 UTC 2026 - Martin Hauke <[email protected]> + +- Update to version 2.2 + * README: correct stale claims, document cramfsck, list mkcramfs + options. + * cramfsck: reject directory entries that extend past their + parent's size. + * cramfsck: check I/O return values and zero the window buffer + in romfs_read. + * cramfsck: fix outbuffer NUL termination and one-byte overflow + in do_symlink + * cramfsck: use O_EXCL when creating regular files during + extraction. + * cramfsck: reject dirent names containing path separators or + traversal components. + * Add mention of a known cramfs obfuscation to the README file. + * Makefile: Obey CFLAGS. + * updating to mask errors into reported value. + * adjusting return code for errors in continue mode. + * fixing bail-outs for non-root users in diag mode. + * fix a printf warning. + * undef any existing PAGE_SIZE. +- Drop patch: + * cramfs-tools-obey-cflags.patch (upstreamed) + +------------------------------------------------------------------- Old: ---- cramfs-tools-2.1.tar.gz cramfs-tools-obey-cflags.patch New: ---- cramfs-tools-2.2.tar.gz ----------(Old B)---------- Old: - Remove leftover cramfs-tools-obey-cflags.patch, no longer referenced since 2.2 dropped it from the spec. ----------(Old E)---------- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ cramfs-tools.spec ++++++ --- /var/tmp/diff_new_pack.rZQmAx/_old 2026-10-21 21:02:04.917557654 +0200 +++ /var/tmp/diff_new_pack.rZQmAx/_new 2026-10-21 21:02:04.919557738 +0200 @@ -1,7 +1,8 @@ # # spec file for package cramfs-tools # -# Copyright (c) 2020, Martin Hauke <[email protected]> +# Copyright (c) 2026 SUSE LLC and contributors +# Copyright (c) 2020-2026, Martin Hauke <[email protected]> # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -17,16 +18,17 @@ Name: cramfs-tools -Version: 2.1 +Version: 2.2 Release: 0 Summary: Tools for CramFs (Compressed ROM File System) License: GPL-2.0-only -Group: Development/Tools/Other URL: https://github.com/npitre/cramfs-tools/ Source: https://github.com/npitre/cramfs-tools/archive/v%{version}.tar.gz#/%{name}-%{version}.tar.gz -Patch0: cramfs-tools-obey-cflags.patch +BuildRequires: gcc BuildRequires: help2man -BuildRequires: zlib-devel +BuildRequires: make +BuildRequires: pkgconfig +BuildRequires: pkgconfig(zlib) %description This package contains tools that let you construct a CramFs @@ -38,7 +40,7 @@ %autosetup -p1 %build -export CFLAGS="%optflags" +export CFLAGS="%{optflags}" %make_build help2man ./cramfsck --version-string="%{version}" --no-info > cramfsck.1 help2man ./mkcramfs --version-string="%{version}" --no-info > mkcramfs.1 ++++++ cramfs-tools-2.1.tar.gz -> cramfs-tools-2.2.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cramfs-tools-2.1/GNUmakefile new/cramfs-tools-2.2/GNUmakefile --- old/cramfs-tools-2.1/GNUmakefile 2019-09-30 17:24:28.000000000 +0200 +++ new/cramfs-tools-2.2/GNUmakefile 2026-04-22 22:43:14.000000000 +0200 @@ -1,5 +1,5 @@ CC = gcc -CFLAGS = -W -Wall -O2 -g +CFLAGS += -W -Wall -O2 -g CPPFLAGS = -I. LDLIBS = -lz PROGS = mkcramfs cramfsck diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cramfs-tools-2.1/NOTES new/cramfs-tools-2.2/NOTES --- old/cramfs-tools-2.1/NOTES 2019-09-30 17:24:28.000000000 +0200 +++ new/cramfs-tools-2.2/NOTES 2026-04-22 22:43:14.000000000 +0200 @@ -105,91 +105,3 @@ The cramfs user-space tools, including mkcramfs and cramfsck, are located at <https://github.com/npitre/cramfs-tools>. - - -Future Development -================== - -Block Size ----------- - -(Block size in cramfs refers to the size of input data that is -compressed at a time. It's intended to be somewhere around -PAGE_SIZE for cramfs_readpage's convenience.) - -The superblock ought to indicate the block size that the fs was -written for, since comments in <linux/pagemap.h> indicate that -PAGE_SIZE may grow in future (if I interpret the comment -correctly). - -Currently, mkcramfs #define's PAGE_SIZE as 4096 and uses that -for blksize, whereas Linux-2.3.39 uses its PAGE_SIZE, which in -turn is defined as PAGE_SIZE (which can be as large as 32KB on arm). -This discrepancy is a bug, though it's not clear which should be -changed. - -One option is to change mkcramfs to take its PAGE_SIZE from -<asm/page.h>. Personally I don't like this option, but it does -require the least amount of change: just change `#define -PAGE_SIZE (4096)' to `#include <asm/page.h>'. The disadvantage -is that the generated cramfs cannot always be shared between different -kernels, not even necessarily kernels of the same architecture if -PAGE_SIZE is subject to change between kernel versions -(currently possible with arm and ia64). - -The remaining options try to make cramfs more sharable. - -One part of that is addressing endianness. The two options here are -`always use little-endian' (like ext2fs) or `writer chooses -endianness; kernel adapts at runtime'. Little-endian wins because of -code simplicity and little CPU overhead even on big-endian machines. - -The cost of swabbing is changing the code to use the le32_to_cpu -etc. macros as used by ext2fs. We don't need to swab the compressed -data, only the superblock, inodes and block pointers. - - -The other part of making cramfs more sharable is choosing a block -size. The options are: - - 1. Always 4096 bytes. - - 2. Writer chooses blocksize; kernel adapts but rejects blocksize > - PAGE_SIZE. - - 3. Writer chooses blocksize; kernel adapts even to blocksize > - PAGE_SIZE. - -It's easy enough to change the kernel to use a smaller value than -PAGE_SIZE: just make cramfs_readpage read multiple blocks. - -The cost of option 1 is that kernels with a larger PAGE_SIZE -value don't get as good compression as they can. - -The cost of option 2 relative to option 1 is that the code uses -variables instead of #define'd constants. The gain is that people -with kernels having larger PAGE_SIZE can make use of that if -they don't mind their cramfs being inaccessible to kernels with -smaller PAGE_SIZE values. - -Option 3 is easy to implement if we don't mind being CPU-inefficient: -e.g. get readpage to decompress to a buffer of size MAX_BLKSIZE (which -must be no larger than 32KB) and discard what it doesn't need. -Getting readpage to read into all the covered pages is harder. - -The main advantage of option 3 over 1, 2, is better compression. The -cost is greater complexity. Probably not worth it, but I hope someone -will disagree. (If it is implemented, then I'll re-use that code in -e2compr.) - - -Another cost of 2 and 3 over 1 is making mkcramfs use a different -block size, but that just means adding and parsing a -b option. - - -Inode Size ----------- - -It might make sense to expand the inode a little from its current -12 bytes. Inodes other than the root inode are followed by filename, -so the expansion doesn't even have to be a multiple of 4 bytes. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cramfs-tools-2.1/README new/cramfs-tools-2.2/README --- old/cramfs-tools-2.1/README 2019-09-30 17:24:28.000000000 +0200 +++ new/cramfs-tools-2.2/README 2026-04-22 22:43:14.000000000 +0200 @@ -25,8 +25,10 @@ mkcramfs simply truncates to 8 bits, which is a potential security issue. -Hard links are supported, but hard linked files -will still have a link count of 1 in the cramfs image. +Hard links are not preserved. mkcramfs deduplicates files with +identical content, but two names for the same on-disk inode in the +source tree become two separate (content-shared) entries in the +image, and the kernel always reports a link count of 1. Cramfs directories have no `.' or `..' entries. Directories (like every other file on cramfs) always have a link count of 1. (There's @@ -51,15 +53,54 @@ with mkcramfs -X (or -X twice for target systems with a MMU for which a greater alignment is necessary). This implies -x as described above. -Currently, cramfs must be written and read with architectures of the -same endianness, and can be read only by kernels with PAGE_SIZE -== 4096. At least the latter of these is a bug, but it hasn't been -decided what the best fix is. For the moment if you have larger pages -you can just change the #define in mkcramfs.c, so long as you don't -mind the filesystem becoming unreadable to future kernels. - +The on-disk layout is host-endian: the kernel does not swab, and +refuses to mount an image whose endianness does not match the CPU. +For cross-builds, mkcramfs -B / -L forces the output endianness so +that a host of one endianness can produce an image for a target of +the other. + +The on-disk block size is fixed at 4096 bytes. On systems with a +larger PAGE_SIZE you can change the #define in mkcramfs.c, with the +caveat that the resulting image will only be readable on kernels +configured for the same PAGE_SIZE. + + +Tools +----- + +This repository provides two user-space tools: + + mkcramfs <dir> <image> + Build a cramfs image from a directory tree. Options: + -e N set edition number (part of fsid) + -n NAME set filesystem name + -i FILE insert FILE as a pre-built image + -D FILE use FILE as a device table + -p pad the first 512 bytes for boot code + -q squash ownership to root + -z emit explicit holes (requires kernel >= 2.3.39) + -x use extended block pointers; skip compression for + blocks that would grow (requires kernel >= 4.15) + -X align read-only ELF segments for XIP (implies -x); + pass twice for MMU-grade alignment + -B / -L force big- or little-endian output + -E treat warnings as errors + -s (accepted for compatibility, ignored) + -v verbose + + cramfsck [-v] [-c] [-x DIR] <image> + Check a cramfs image and optionally extract it. -x DIR + extracts the image below DIR. -v prints each inode as it is + visited; -c continues past recoverable errors and reports an + aggregate exit code at the end. Hacker Notes ------------ -See fs/cramfs/README for filesystem layout and implementation notes. +See NOTES in this directory for filesystem layout and implementation +notes. The equivalent file in the Linux kernel tree lives at +Documentation/filesystems/cramfs.rst (historically fs/cramfs/README). + +Altered cramfs inode representations exist in the field, presumably as an +attempt by some vendor at obfuscating their firmware images. Please see +https://github.com/npitre/cramfs-tools/issues/10 for details. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cramfs-tools-2.1/cramfsck.c new/cramfs-tools-2.2/cramfsck.c --- old/cramfs-tools-2.1/cramfsck.c 2019-09-30 17:24:28.000000000 +0200 +++ new/cramfs-tools-2.2/cramfsck.c 2026-04-22 22:43:14.000000000 +0200 @@ -77,6 +77,9 @@ static char *filename; /* ROM image filename */ struct cramfs_super super; /* just find the cramfs superblock once */ static int opt_verbose = 0; /* 1 = verbose (-v), 2+ = very verbose (-vv) */ +static int opt_continue = 0; /* 1 = continue on error for diagnositc / recovery */ +static int log_errors_continue = 0; /* number of errors we encountered */ +static int log_errors_result = FSCK_OK; #ifdef INCLUDE_FS_TESTS static int opt_extract = 0; /* extract cramfs (-x) */ static char *extract_dir = "/"; /* extraction directory (-x) */ @@ -96,7 +99,8 @@ static unsigned long read_buffer_block = ~0UL; /* Uncompressing data structures... */ -static char outbuffer[PAGE_SIZE*2]; +/* +1 so that do_symlink's trailing NUL never falls one byte past the end */ +static char outbuffer[PAGE_SIZE*2 + 1]; static z_stream stream; /* Prototypes */ @@ -112,6 +116,7 @@ " -h print this help\n" " -x dir extract into dir\n" " -v be more verbose\n" + " -c continue on failure\n" " file file to test\n", progname); exit(status); @@ -131,7 +136,12 @@ } fprintf(stderr, "\n"); va_end(arg_ptr); - exit(status); + if (opt_continue > 0) { + log_errors_continue++; + log_errors_result |= status; + } else { + exit(status); + } } static void test_super(int *start, size_t *length) { @@ -294,9 +304,19 @@ { unsigned int block = offset >> ROMBUFFER_BITS; if (block != read_buffer_block) { + ssize_t n; + read_buffer_block = block; - lseek(fd, block << ROMBUFFER_BITS, SEEK_SET); - read(fd, read_buffer, ROMBUFFERSIZE * 2); + /* Zero first so that any region past EOF reads as zero + rather than stale bytes from a previous window. */ + memset(read_buffer, 0, sizeof(read_buffer)); + if (lseek(fd, block << ROMBUFFER_BITS, SEEK_SET) == (off_t)-1) { + die(FSCK_ERROR, 1, "lseek failed: %s", filename); + } + n = read(fd, read_buffer, ROMBUFFERSIZE * 2); + if (n < 0) { + die(FSCK_ERROR, 1, "read failed: %s", filename); + } } return read_buffer + (offset & ROMBUFFERMASK); } @@ -546,6 +566,9 @@ int newlen = child->namelen << 2; size = sizeof(struct cramfs_inode) + newlen; + if (size > count) { + die(FSCK_UNCORRECTED, 0, "directory entry extends past parent size"); + } count -= size; offset += sizeof(struct cramfs_inode); @@ -558,6 +581,13 @@ if ((pathlen + newlen) - strlen(newpath) > 3) { die(FSCK_UNCORRECTED, 0, "bad filename length"); } + { + const char *name = newpath + pathlen; + if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0 || + strchr(name, '/') != NULL) { + die(FSCK_UNCORRECTED, 0, "bad filename: %s", name); + } + } expand_fs(newpath, child); offset += newlen; @@ -591,7 +621,7 @@ print_node('f', i, path); } if (opt_extract) { - fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, i->mode); + fd = open(path, O_WRONLY | O_CREAT | O_EXCL, i->mode); if (fd < 0) { die(FSCK_ERROR, 1, "open failed: %s", path); } @@ -635,6 +665,7 @@ free(str); /* once again with verbose on */ read_block(offset, 0, i->size); + outbuffer[size] = 0; } if (opt_extract) { if (symlink(outbuffer, path) < 0) { @@ -744,7 +775,7 @@ progname = argv[0]; /* command line options */ - while ((c = getopt(argc, argv, "hx:v")) != EOF) { + while ((c = getopt(argc, argv, "hx:vc")) != EOF) { switch (c) { case 'h': usage(FSCK_OK); @@ -759,6 +790,9 @@ case 'v': opt_verbose++; break; + case 'c': + opt_continue++; + break; } } @@ -776,7 +810,15 @@ printf("%s: OK\n", filename); } - exit(FSCK_OK); + if ((opt_verbose > 0) && (opt_continue > 0) && (log_errors_continue > 0)) { + printf("%s: extraction with %d errors encountered\n", filename, log_errors_continue); + } + + if (log_errors_continue > 0) { + exit(log_errors_result); + } else { + exit(FSCK_OK); + } } /* diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cramfs-tools-2.1/mkcramfs.c new/cramfs-tools-2.2/mkcramfs.c --- old/cramfs-tools-2.1/mkcramfs.c 2019-09-30 17:24:28.000000000 +0200 +++ new/cramfs-tools-2.2/mkcramfs.c 2026-04-22 22:43:14.000000000 +0200 @@ -81,6 +81,7 @@ #define PAD_SIZE 512 /* The kernel assumes PAGE_SIZE as block size. */ +#undef PAGE_SIZE #define PAGE_SIZE (4096) /* @@ -1546,7 +1547,7 @@ /* Write the superblock now that we can fill in all of the fields. */ write_superblock(root_entry, rom_image+opt_pad, offset); if (opt_verbose) - printf("Super block: %ld bytes\n", sizeof(struct cramfs_super)); + printf("Super block: %zd bytes\n", sizeof(struct cramfs_super)); /* Put the checksum in. */ crc = crc32(0L, Z_NULL, 0);
