From 4e955dc4b6fff43956d47c0286bb698e03f14b11 Mon Sep 17 00:00:00 2001 From: Patrick J Volkerding Date: Fri, 31 Jan 2020 20:46:25 +0000 Subject: Fri Jan 31 20:46:25 UTC 2020 a/util-linux-2.35.1-x86_64-1.txz: Upgraded. a/zerofree-1.1.1-x86_64-1.txz: Added. Also queued up for the next installer build. Thanks to bifferos. ap/sudo-1.8.31-x86_64-1.txz: Upgraded. This update fixes a security issue: In Sudo before 1.8.31, if pwfeedback is enabled in /etc/sudoers, users can trigger a stack-based buffer overflow in the privileged sudo process. (pwfeedback is a default setting in some Linux distributions; however, it is not the default for upstream or in Slackware, and would exist only if enabled by an administrator.) The attacker needs to deliver a long string to the stdin of getln() in tgetpass.c. For more information, see: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-18634 (* Security fix *) n/NetworkManager-1.22.6-x86_64-1.txz: Upgraded. n/openldap-client-2.4.49-x86_64-1.txz: Upgraded. xfce/Thunar-1.8.11-x86_64-1.txz: Removed. xfce/thunar-1.8.12-x86_64-1.txz: Added. Changed package name from "Thunar" to "thunar" to follow upstream's naming. --- source/a/zerofree/sparsify.c | 274 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 274 insertions(+) create mode 100644 source/a/zerofree/sparsify.c (limited to 'source/a/zerofree/sparsify.c') diff --git a/source/a/zerofree/sparsify.c b/source/a/zerofree/sparsify.c new file mode 100644 index 000000000..4c52e0075 --- /dev/null +++ b/source/a/zerofree/sparsify.c @@ -0,0 +1,274 @@ +/* + * sparsify - a tool to make files on an ext2 filesystem sparse + * + * Copyright (C) 2004-2012 R M Yorston + * + * This file may be redistributed under the terms of the GNU General Public + * License, version 2. + */ +#include +#include +#include +#include + +#define USAGE "usage: %s [-n] [-v] filesystem filename ...\n" + +/* initially assume pre-ext4 API version */ +#define API 140 + +#if defined(BLOCK_FLAG_READ_ONLY) +#undef API +#define API 141 +#endif + +#if defined(EXT2_FLAG_64BITS) +#undef API +#define API 142 +#endif + +struct process_data { + unsigned char *buf; + int verbose; + int dryrun; + blk_t count; + blk_t blocks; + blk_t total_blocks; + int old_percent; +}; + +static int process(ext2_filsys fs, blk_t *blocknr, e2_blkcnt_t blockcnt, + blk_t ref_block, int ref_offset, void *priv) +{ + struct process_data *p; + errcode_t errcode; + int i, group; + int ret = 0; + + p = (struct process_data *)priv; + + p->blocks++; + if ( blockcnt >= 0 ) { + errcode = io_channel_read_blk(fs->io, *blocknr, 1, p->buf); + if ( errcode ) { + return BLOCK_ABORT; + } + + for ( i=0; i < fs->blocksize; ++i ) { + if ( p->buf[i] ) { + break; + } + } + + if ( i == fs->blocksize ) { + p->count++; + + if ( !p->dryrun ) { + ext2fs_unmark_block_bitmap(fs->block_map, *blocknr); + group = ext2fs_group_of_blk(fs, *blocknr); +#if API >= 142 + ext2fs_bg_free_blocks_count_set(fs, group, + ext2fs_bg_free_blocks_count(fs, group)+1); + ext2fs_free_blocks_count_add(fs->super, (blk64_t)1); +#else + fs->group_desc[group].bg_free_blocks_count++; + fs->super->s_free_blocks_count++; +#endif +#if API >= 141 + ext2fs_group_desc_csum_set(fs, group); +#endif + *blocknr = 0; + ret = BLOCK_CHANGED; + } + } + + if ( p->verbose ) { + double percent; + + percent = 100.0 * (double)p->blocks/(double)p->total_blocks; + + if ( (int)(percent*10) != p->old_percent ) { + fprintf(stderr, "\r%4.1f%%", percent); + p->old_percent = (int)(percent*10); + } + } + } + + return ret; +} + +int main(int argc, char **argv) +{ + int verbose = 0; + int dryrun = 0; + errcode_t ret; + int flags; + int superblock = 0; + int open_flags = EXT2_FLAG_RW; + int iter_flags = 0; + int blocksize = 0; + ext2_filsys fs = NULL; + struct ext2_inode inode; + ext2_ino_t root, cwd, inum; + int i, c; + struct process_data pdata; + + while ( (c=getopt(argc, argv, "nv")) != -1 ) { + switch (c) { + case 'n' : + dryrun = 1; +#if defined(BLOCK_FLAG_READ_ONLY) + iter_flags |= BLOCK_FLAG_READ_ONLY; +#endif + break; + case 'v' : + verbose = 1; + break; + default : + fprintf(stderr, USAGE, argv[0]); + return 1; + } + } + + if ( argc < optind+2 ) { + fprintf(stderr, USAGE, argv[0]); + return 1; + } + + ret = ext2fs_check_if_mounted(argv[optind], &flags); + if ( ret ) { + fprintf(stderr, "%s: failed to determine filesystem mount state %s\n", + argv[0], argv[optind]); + return 1; + } + + if ( flags & EXT2_MF_MOUNTED ) { + fprintf(stderr, "%s: filesystem %s is mounted\n", + argv[0], argv[optind]); + return 1; + } + + ret = ext2fs_open(argv[optind], open_flags, superblock, blocksize, + unix_io_manager, &fs); + if ( ret ) { + fprintf(stderr, "%s: failed to open filesystem %s\n", + argv[0], argv[optind]); + return 1; + } + + pdata.buf = (unsigned char *)malloc(fs->blocksize); + if ( pdata.buf == NULL ) { + fprintf(stderr, "%s: out of memory (surely not?)\n", argv[0]); + return 1; + } + + ret = ext2fs_read_inode_bitmap(fs); + if ( ret ) { + fprintf(stderr, "%s: error while reading inode bitmap\n", argv[0]); + return 1; + } + + ret = ext2fs_read_block_bitmap(fs); + if ( ret ) { + fprintf(stderr, "%s: error while reading block bitmap\n", argv[0]); + return 1; + } + + root = cwd = EXT2_ROOT_INO; + + for ( i=optind+1; isuper->s_feature_ro_compat & EXT4_FEATURE_RO_COMPAT_HUGE_FILE) + && (inode.i_flags & EXT4_HUGE_FILE_FL) ) { + fprintf(stderr, "%s: unable to process %s, it's huge\n", + argv[0], argv[i]); + continue; + } +#endif + + if ( verbose ) { + printf("processing %s\n", argv[i]); + } + + pdata.verbose = verbose; + pdata.dryrun = dryrun; + pdata.count = pdata.blocks = 0; + pdata.total_blocks = inode.i_blocks/(fs->blocksize >> 9); + pdata.old_percent = 1000; + ret = ext2fs_block_iterate2(fs, inum, iter_flags, NULL, + process, &pdata); + if ( ret ) { + fprintf(stderr, "%s: failed to process file %s\n", argv[0], + argv[i]); + continue; + } + + if ( pdata.count && !dryrun ) { + ext2fs_mark_bb_dirty(fs); + ext2fs_mark_super_dirty(fs); + + ret = ext2fs_read_inode(fs, inum, &inode); + if ( ret ) { + fprintf(stderr, "%s: failed to open inode (%s)\n", argv[0], + argv[i]); + continue; + } + +#if API >= 141 + ret = ext2fs_iblk_sub_blocks(fs, &inode, (blk64_t)pdata.count); + if ( ret ) { + fprintf(stderr, "%s: failed to update block count (%s)\n", + argv[0], argv[i]); + continue; + } +#else + inode.i_blocks -= pdata.count * (fs->blocksize >> 9); +#endif + + ret = ext2fs_write_inode(fs, inum, &inode); + if ( ret ) { + fprintf(stderr, "%s: failed to write inode (%s)\n", + argv[0], argv[i]); + continue; + } + } + + if ( verbose ) { + printf("\r%d/%d/%d %s\n", pdata.count, pdata.blocks, + pdata.total_blocks, argv[i]); + } + } + + ret = ext2fs_close(fs); + if ( ret ) { + fprintf(stderr, "%s: error while closing filesystem\n", argv[0]); + return 1; + } + + return 0; +} -- cgit v1.2.3-65-gdbad