diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..8b99065 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,52 @@ +name: build + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +jobs: + build: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + include: + - cc: gcc + extra: "" + - cc: clang + extra: "" + - cc: gcc + extra: "--enable-warnings" + - cc: gcc + extra: "--enable-io-failure-emulation" + env: + CC: ${{ matrix.cc }} + steps: + - uses: actions/checkout@v4 + + - name: Install build dependencies + run: | + sudo apt-get update + sudo apt-get install -y --no-install-recommends \ + autoconf automake libtool pkg-config \ + libcom-err-dev uuid-dev \ + build-essential + + - name: Bootstrap + run: ./autogen.sh + + - name: Configure + run: ./configure ${{ matrix.extra }} + + - name: Build + run: make -j"$(nproc)" + + - name: Smoke test + run: | + set -e + dd if=/dev/zero of=smoke.img bs=1M count=64 status=none + ./mkreiserfs/mkreiserfs -f -q smoke.img + ./fsck/reiserfsck --check -f -q -y smoke.img + ./debugreiserfs/debugreiserfs -S smoke.img \ No newline at end of file diff --git a/configure.ac b/configure.ac index f3f1a65..59af87b 100644 --- a/configure.ac +++ b/configure.ac @@ -108,6 +108,15 @@ if test "x$ac_cv_func_register_printf_specifier" != xyes -a \ fi +dnl -Wall -Wextra is clean as of this release; keep it opt-in so that +dnl distributions building with -Werror are not surprised by a future +dnl compiler adding a new diagnostic. +AC_ARG_ENABLE([warnings], + [AS_HELP_STRING([--enable-warnings], [build with -Wall -Wextra])]) +if test "$enable_warnings" = "yes" ; then + CFLAGS="$CFLAGS -Wall -Wextra" +fi + dnl Never enable this. It is for debugging only AC_ARG_ENABLE([io-failure-emulation], [AS_HELP_STRING([--enable-io-failure-emulation], [Never use this. It is for debugging only])]) diff --git a/debugreiserfs/debugreiserfs.c b/debugreiserfs/debugreiserfs.c index 5ee9d48..00cc3c6 100644 --- a/debugreiserfs/debugreiserfs.c +++ b/debugreiserfs/debugreiserfs.c @@ -4,6 +4,7 @@ */ #include "debugreiserfs.h" +#include "misc.h" #include reiserfs_filsys_t fs; @@ -264,13 +265,13 @@ static char *parse_options(struct debugreiserfs_data *data, != EOF) { switch (c) { case 'a': /* -r will read this, -n and -N will write to it */ - asprintf(&data->map_file, "%s", optarg); + xasprintf(&data->map_file, "%s", optarg); break; case 'b': /* will load bitmap from a file and read only blocks marked in it. This is for -p and -k */ - asprintf(&data->input_bitmap, "%s", optarg); + xasprintf(&data->input_bitmap, "%s", optarg); data->scan_area = EXTERN_BITMAP; break; @@ -338,7 +339,7 @@ static char *parse_options(struct debugreiserfs_data *data, break; case 'r': - asprintf(&data->recovery_file, "%s", optarg); + xasprintf(&data->recovery_file, "%s", optarg); data->mode = DO_RECOVER; break; @@ -379,7 +380,7 @@ static char *parse_options(struct debugreiserfs_data *data, break; case 'B': /*disabled for a while */ - asprintf(&badblocks_file, "%s", optarg); + xasprintf(&badblocks_file, "%s", optarg); data->mode = DO_EXTRACT_BADBLOCKS; break; case 'q': diff --git a/debugreiserfs/scan.c b/debugreiserfs/scan.c index dcf05dd..fa094ff 100644 --- a/debugreiserfs/scan.c +++ b/debugreiserfs/scan.c @@ -4,6 +4,7 @@ */ #include "debugreiserfs.h" +#include "misc.h" #include #include #include @@ -253,7 +254,7 @@ static struct saved_name *scan_for_key(const struct reiserfs_key *key) char *name; struct saved_name *new, *name_in; - asprintf(&name, "%u_%u", get_key_dirid(key), get_key_objectid(key)); + xasprintf(&name, "%u_%u", get_key_dirid(key), get_key_objectid(key)); new = obstack_alloc(&name_store, sizeof(struct saved_name) + strlen(name)); @@ -591,7 +592,7 @@ static void flush_map(reiserfs_filsys_t fs, __u32 v32; if (!map_file(fs)) - asprintf(&map_file(fs), "%s", ".map"); + xasprintf(&map_file(fs), "%s", ".map"); //reiserfs_warning (stderr, "Saving maps into %s\n", map_file (fs)); fp = fopen(map_file(fs), "a"); @@ -814,7 +815,7 @@ static void make_map(const void *nodep, VISIT value, int level) if (value == leaf || value == postorder) { while (name) { if (map_file(fs)) { - asprintf(&file_name, "%s.%d", map_file(fs), + xasprintf(&file_name, "%s.%d", map_file(fs), ++nr); reiserfs_warning(log_to, "%d - (%d): [%K]:\"%s\": stored in the %s\n", @@ -1006,7 +1007,7 @@ void do_scan(reiserfs_filsys_t fs) int type; char *answer = 0; size_t n = 0; - struct reiserfs_key key = { 0, 0, }; + struct reiserfs_key key = { 0 }; unsigned long done, total; if (debug_mode(fs) == DO_LOOK_FOR_NAME) { diff --git a/debugreiserfs/unpack.c b/debugreiserfs/unpack.c index b0969ff..ecbbcb1 100644 --- a/debugreiserfs/unpack.c +++ b/debugreiserfs/unpack.c @@ -514,11 +514,13 @@ void unpack_partition(int fd, int jfd) case '1': fread(c, 1, 1, stdin); /* that was 100%, read in first 0 */ + /* fall through */ case '2': case '4': case '6': case '8': fread(c, 1, 1, stdin); + /* fall through */ case '0': fread(c + 1, 1, 1, stdin); /* read % */ diff --git a/fsck/fsck.h b/fsck/fsck.h index cc016e4..7924e13 100644 --- a/fsck/fsck.h +++ b/fsck/fsck.h @@ -52,18 +52,18 @@ int main(int argc, char *argv[]); * options */ -#define OPT_INTERACTIVE 1 << 0 -#define OPT_ADJUST_FILE_SIZE 1 << 1 /* not default yet */ -#define OPT_QUIET 1 << 2 /* no "speed" info */ -#define OPT_SILENT 1 << 3 /* no complains about found corruptions */ -#define OPT_BACKGROUND 1 << 4 -#define OPT_SKIP_JOURNAL 1 << 5 -#define OPT_HASH_DEFINED 1 << 6 -#define OPT_SAVE_PASSES_DUMP 1 << 7 -#define OPT_SAVE_ROLLBACK 1 << 8 -#define OPT_YES 1 << 9 -#define BADBLOCKS_FILE 1 << 10 -#define OPT_FORCE 1 << 11 +#define OPT_INTERACTIVE 1U << 0 +#define OPT_ADJUST_FILE_SIZE 1U << 1 /* not default yet */ +#define OPT_QUIET 1U << 2 /* no "speed" info */ +#define OPT_SILENT 1U << 3 /* no complains about found corruptions */ +#define OPT_BACKGROUND 1U << 4 +#define OPT_SKIP_JOURNAL 1U << 5 +#define OPT_HASH_DEFINED 1U << 6 +#define OPT_SAVE_PASSES_DUMP 1U << 7 +#define OPT_SAVE_ROLLBACK 1U << 8 +#define OPT_YES 1U << 9 +#define BADBLOCKS_FILE 1U << 10 +#define OPT_FORCE 1U << 11 /* pass0.c */ extern reiserfs_bitmap_t *leaves_bitmap; diff --git a/fsck/lost+found.c b/fsck/lost+found.c index da1f489..4377684 100644 --- a/fsck/lost+found.c +++ b/fsck/lost+found.c @@ -4,6 +4,7 @@ */ #include "fsck.h" +#include "misc.h" void erase_name(int len); void print_name(char *name, int len); @@ -180,7 +181,7 @@ static __u64 _look_for_lost(reiserfs_filsys_t fs, int link_lost_dirs) (&ih->ih_key)); } - asprintf(&lost_name, "%u_%u", + xasprintf(&lost_name, "%u_%u", get_key_dirid(&tmp_ih.ih_key), get_key_objectid(&tmp_ih.ih_key)); diff --git a/fsck/main.c b/fsck/main.c index 5063504..4edc8b6 100644 --- a/fsck/main.c +++ b/fsck/main.c @@ -4,6 +4,7 @@ */ #include "fsck.h" +#include "misc.h" #include #include #include @@ -198,7 +199,7 @@ static char *parse_options(struct fsck_data *data, int argc, char *argv[]) break; #endif case 'd': /* --create-passes-dump */ - asprintf(&data->rebuild.passes_dump_file_name, "%s", + xasprintf(&data->rebuild.passes_dump_file_name, "%s", optarg); data->options |= OPT_SAVE_PASSES_DUMP; break; @@ -208,7 +209,7 @@ static char *parse_options(struct fsck_data *data, int argc, char *argv[]) break; case 'h': /* --hash: suppose that this hash was used on a filesystem */ - asprintf(&data->rebuild.defined_hash, "%s", optarg); + xasprintf(&data->rebuild.defined_hash, "%s", optarg); if (name2func(data->rebuild.defined_hash) == NULL) reiserfs_panic ("reiserfsck: Unknown hash is specified: %s", @@ -221,12 +222,12 @@ static char *parse_options(struct fsck_data *data, int argc, char *argv[]) break; case 'R': /* preparing rollback data */ - asprintf(&data->rebuild.rollback_file, "%s", optarg); + xasprintf(&data->rebuild.rollback_file, "%s", optarg); data->options |= OPT_SAVE_ROLLBACK; break; case 'B': /* list of phisically corrupted blocks */ - asprintf(&badblocks_file, "%s", optarg); + xasprintf(&badblocks_file, "%s", optarg); data->options |= BADBLOCKS_FILE; break; @@ -916,25 +917,29 @@ static void rebuild_tree(reiserfs_filsys_t fs) "reiserfsck --rebuild-tree started at %s" "###########\n", ctime(&t)); + /* Deliberate cascade: each pass falls into the next so that a rebuild + always runs every stage from the requested starting point on. */ switch (where_to_start_from(fs)) { case START_FROM_THE_BEGINNING: reset_super_block(fs); pass_0(fs); - + /* fall through */ case START_FROM_PASS_1: reset_super_block(fs); pass_1(fs); - + /* fall through */ case START_FROM_PASS_2: pass_2(fs); - + /* fall through */ case START_FROM_SEMANTIC: pass_3_semantic(fs); + /* fall through */ /* if --lost+found is set - link unaccessed directories to lost+found directory */ case START_FROM_LOST_FOUND: pass_3a_look_for_lost(fs); + /* fall through */ case START_FROM_PASS_4: /* 4. look for unaccessed items in the leaves */ @@ -1267,7 +1272,7 @@ static int open_devices_for_rollback(char *file_name, struct fsck_data *data) fs = getmem(sizeof(*fs)); fs->fs_dev = fd; fs->fs_vp = data; - asprintf(&fs->fs_file_name, "%s", file_name); + xasprintf(&fs->fs_file_name, "%s", file_name); if (data->journal_dev_name && strcmp(data->journal_dev_name, file_name)) { fs->fs_journal_dev = open(data->journal_dev_name, @@ -1454,7 +1459,8 @@ int main(int argc, char *argv[]) if (auto_check(fs)) break; data->mode = FSCK_FIX_FIXABLE; - case FSCK_CHECK: + /* fall through */ + case FSCK_CHECK: /* and FSCK_FIX_FIXABLE */ case FSCK_FIX_FIXABLE: check_fs(fs); break; diff --git a/fsck/pass2.c b/fsck/pass2.c index 60bccce..ea521e3 100644 --- a/fsck/pass2.c +++ b/fsck/pass2.c @@ -4,6 +4,7 @@ */ #include "fsck.h" +#include "misc.h" /* on pass2 we take leaves which could not be inserted into tree during pass1 and insert each item separately. It is possible that @@ -74,7 +75,7 @@ static __u64 link_one(struct relocated *file) struct reiserfs_key obj_key; __u64 len = 0; - asprintf(&name, "%lu,%lu", file->old_dir_id, file->new_objectid); + xasprintf(&name, "%lu,%lu", file->old_dir_id, file->new_objectid); set_key_dirid(&obj_key, file->old_dir_id); set_key_objectid(&obj_key, file->new_objectid); @@ -118,15 +119,12 @@ void linked_already(const struct reiserfs_key *new_key /*, link_func_t link_func void link_relocated_files(void) { struct relocated *tmp; - int count; - count = 0; while (relocated_list) { link_one(relocated_list); tmp = relocated_list; relocated_list = relocated_list->next; freemem(tmp); - count++; } } @@ -369,7 +367,7 @@ static void put_directory_item_into_tree(struct item_head *comingih, char *item) " badly hashed entry", i, namelen, name, &comingih->ih_key); - asprintf(&buf, "%.*s", namelen, name); + xasprintf(&buf, "%.*s", namelen, name); /* 1 for fsck is important: if there is no any items of this directory in the tree yet - new item will be inserted marked not reached */ diff --git a/fsck/semantic_check.c b/fsck/semantic_check.c index 92f18b9..b168456 100644 --- a/fsck/semantic_check.c +++ b/fsck/semantic_check.c @@ -3,6 +3,7 @@ */ #include "fsck.h" +#include "misc.h" static struct reiserfs_key *trunc_links = NULL; static __u32 links_num = 0; @@ -366,7 +367,7 @@ start_again: memcpy(dir_item, ih_item_body(bh, ih), get_ih_item_len(ih)); /* next item key */ - if (PATH_LAST_POSITION(&path) == (B_NR_ITEMS(bh) - 1) && + if (PATH_LAST_POSITION(&path) + 1 == B_NR_ITEMS(bh) && (rdkey = uget_rkey(&path))) copy_key(key, rdkey); else { @@ -559,7 +560,7 @@ static int check_semantic_pass(struct reiserfs_key *key, } namelen = name_in_entry_length(&tmp_ih, deh, i); - asprintf(&name, "%.*s", namelen, name_in_entry(deh, i)); + xasprintf(&name, "%.*s", namelen, name_in_entry(deh, i)); entry_len = entry_length(&tmp_ih, deh, i); get_object_key(deh, &object_key, &entry_key, &tmp_ih); @@ -634,6 +635,7 @@ static int check_semantic_pass(struct reiserfs_key *key, ("check_semantic_pass: Name \"%.*s\" in directory %K points to " "nowhere\n", namelen, name, &tmp_ih.ih_key); + /* fall through */ case LOOP_FOUND: if (fsck_mode(fs) == FSCK_FIX_FIXABLE) { reiserfs_remove_entry(fs, &entry_key); diff --git a/fsck/semantic_rebuild.c b/fsck/semantic_rebuild.c index 3cc00bb..5ab4da2 100644 --- a/fsck/semantic_rebuild.c +++ b/fsck/semantic_rebuild.c @@ -4,6 +4,7 @@ */ #include "fsck.h" +#include "misc.h" int screen_width; static int screen_curr_pos; @@ -639,7 +640,7 @@ static char *get_next_directory_item(struct reiserfs_key *key, /* on return this memcpy(dir_item, ih_item_body(bh, ih), get_ih_item_len(ih)); /* next item key */ - if (PATH_LAST_POSITION(&path) == (B_NR_ITEMS(bh) - 1) && + if (PATH_LAST_POSITION(&path) + 1 == B_NR_ITEMS(bh) && (rdkey = uget_rkey(&path))) copy_key(key, rdkey); else { @@ -923,7 +924,7 @@ start_again: /* when directory was relocated */ } namelen = name_in_entry_length(&tmp_ih, deh, i); - asprintf(&name, "%.*s", namelen, name_in_entry(deh, i)); + xasprintf(&name, "%.*s", namelen, name_in_entry(deh, i)); entry_len = entry_length(&tmp_ih, deh, i); diff --git a/fsck/ufile.c b/fsck/ufile.c index f93d0d6..e0ef955 100644 --- a/fsck/ufile.c +++ b/fsck/ufile.c @@ -13,8 +13,8 @@ static int do_items_have_the_same_type(const struct item_head *ih, static int are_items_in_the_same_node(const struct reiserfs_path *path) { - return (PATH_LAST_POSITION(path) < - B_NR_ITEMS(PATH_PLAST_BUFFER(path)) - 1) ? 1 : 0; + return (PATH_LAST_POSITION(path) + 1 < + B_NR_ITEMS(PATH_PLAST_BUFFER(path))) ? 1 : 0; } static void cut_last_unfm_pointer(struct reiserfs_path *path, diff --git a/include/misc.h b/include/misc.h index 45fde6a..a8dd4ca 100644 --- a/include/misc.h +++ b/include/misc.h @@ -36,10 +36,10 @@ void check_memory_msg(void); void die(const char *fmt, ...) __attribute__ ((format(printf, 1, 2))); +int xasprintf(char **ret, const char *fmt, ...) __attribute__ ((format(printf, 2, 3))); void *getmem(int size); void *mem_alloc(int size); void freemem(void *p); -void checkmem(const char *p, int size); void *expandmem(void *p, int size, int by); unsigned int get_mem_size(const char *p); void check_and_free_mem(void); diff --git a/include/reiserfs_fs.h b/include/reiserfs_fs.h index a128017..2f508c7 100644 --- a/include/reiserfs_fs.h +++ b/include/reiserfs_fs.h @@ -32,6 +32,7 @@ #ifndef REISERFSPROGS_FS_H #define REISERFSPROGS_FS_H +#include #include #include "swab.h" @@ -174,7 +175,12 @@ struct reiserfs_super_block_v1 { #define SB_SIZE_V1 (sizeof(struct reiserfs_super_block_v1)) /* 76 bytes */ -#define sb_jp(sb) (&((sb)->s_v1.sb_journal)) +/* &(sb)->s_v1.sb_journal would take the address of a member inside a + packed struct, which is legal here (offset 12) but trips + -Waddress-of-packed-member on every use. Spell it out instead. */ +#define sb_jp(sb) ((struct journal_params *) \ + ((char *)(sb) + offsetof(struct reiserfs_super_block, s_v1) + \ + offsetof(struct reiserfs_super_block_v1, sb_journal))) /* values for sb_version field of struct reiserfs_super_block. sb_version is only reliable on filesystem with non-standard journal */ @@ -636,6 +642,12 @@ struct item_head { /* size of item header */ #define IH_SIZE (sizeof(struct item_head)) +/* Address of the packed ih_format field, computed without forming a pointer + to a member of a packed struct (which trips -Waddress-of-packed-member). + ih_format is naturally aligned, so dereferencing the result is fine. */ +#define ih_format_ptr(ih) \ + ((__le16 *)((char *)(ih) + offsetof(struct item_head, ih_format))) + /* set/get fields of item head on disk with these defines */ #define get_ih_entry_count(ih) get_le16 (ih, u.ih2_entry_count) #define set_ih_entry_count(ih,val) set_le16 (ih, u.ih2_entry_count, val) @@ -1061,7 +1073,7 @@ struct reiserfs_path { }; #define INITIALIZE_REISERFS_PATH(var) \ -struct reiserfs_path var = {ILLEGAL_PATH_ELEMENT_OFFSET, } +struct reiserfs_path var = { .path_length = ILLEGAL_PATH_ELEMENT_OFFSET } /* Get path element by path and path position. */ #define PATH_OFFSET_PELEMENT(p_s_path,n_offset) ((p_s_path)->path_elements +(n_offset)) diff --git a/include/reiserfs_lib.h b/include/reiserfs_lib.h index 2156380..d1266fc 100644 --- a/include/reiserfs_lib.h +++ b/include/reiserfs_lib.h @@ -172,17 +172,17 @@ typedef int (*reiserfs_file_iterate_direct_fn)(reiserfs_filsys_t fs, const char *body, size_t len, void *data); int reiserfs_iterate_file_data(reiserfs_filsys_t fs, - const struct reiserfs_key const *short_key, + const struct reiserfs_key *short_key, reiserfs_file_iterate_indirect_fn indirect_fn, reiserfs_file_iterate_direct_fn direct_fn, void *data); typedef int (*reiserfs_iterate_dir_fn)(reiserfs_filsys_t fs, - const struct reiserfs_key const *dir_short_key, + const struct reiserfs_key *dir_short_key, const char *name, size_t len, __u32 deh_dirid, __u32 deh_objectid, void *data); int reiserfs_iterate_dir(reiserfs_filsys_t fs, - const struct reiserfs_key const *dir_short_key, + const struct reiserfs_key *dir_short_key, const reiserfs_iterate_dir_fn callback, void *data); diff --git a/lib/io.c b/lib/io.c index bcd5478..26113a5 100644 --- a/lib/io.c +++ b/lib/io.c @@ -7,7 +7,7 @@ #include #include -#include +#include void check_memory_msg(void) { @@ -585,8 +585,8 @@ static void erase_rollback_file(char *rollback_file) int open_rollback_file(char *rollback_file, FILE * log) { - char string[28]; struct stat buf; + char string[sizeof(ROLLBACK_FILE_START_MAGIC)] = { 0 }; if (rollback_file == NULL) return -1; @@ -603,8 +603,8 @@ int open_rollback_file(char *rollback_file, FILE * log) return -1; } - fread(string, 28, 1, s_rollback_file); - if (!strcmp(string, ROLLBACK_FILE_START_MAGIC)) { + fread(string, sizeof(ROLLBACK_FILE_START_MAGIC) - 1, 1, s_rollback_file); + if (strcmp(string, ROLLBACK_FILE_START_MAGIC) != 0) { fprintf(stderr, "Specified file (%s) does not look like a rollback file\n", rollback_file); @@ -775,8 +775,9 @@ void do_fsck_rollback(int fd_device, int fd_journal_device, FILE * progress) printf("\n"); if (log_file) - fprintf(log_file, "rollback: (%u) blocks restored\n", - count_rollbacked); + fprintf(log_file, + "rollback: (%u) blocks restored, %u skipped\n", + count_rollbacked, count_failed); } /* diff --git a/lib/misc.c b/lib/misc.c index 090f5dd..6fe2d1b 100644 --- a/lib/misc.c +++ b/lib/misc.c @@ -9,10 +9,11 @@ #include #include +#include #include #include #include -#include +#include #include #include #include @@ -33,125 +34,117 @@ void die(const char *fmt, ...) va_list args; va_start(args, fmt); - vsprintf(buf, fmt, args); + vsnprintf(buf, sizeof(buf), fmt, args); va_end(args); fprintf(stderr, "\n%s\n", buf); abort(); } -#define MEM_BEGIN "_mem_begin_" -#define MEM_END "mem_end" -#define MEM_FREED "__free_" -#define CONTROL_SIZE (strlen (MEM_BEGIN) + 1 + sizeof (int) + strlen (MEM_END) + 1) +/* + * Small size-tracking allocator. Every block handed out by getmem()/ + * mem_alloc()/expandmem() is preceded by a header recording its usable + * size. get_mem_size() reports it back and expandmem() uses it to grow + * in place without the caller having to remember the old size. + * + * The header is over-aligned so the returned pointer keeps malloc's + * alignment guarantees for any type. + */ +union mem_header { + struct { + size_t size; + } h; + max_align_t align; +}; + +/* asprintf() wrapper: allocation failure is fatal, matching the rest of + this file (die()). Use it where the old code ignored asprintf()'s + return value and then dereferenced the pointer. */ +int xasprintf(char **ret, const char *fmt, ...) +{ + va_list args; + int rc; + + va_start(args, fmt); + rc = vasprintf(ret, fmt, args); + va_end(args); + + if (rc < 0) + die("xasprintf: out of memory"); + + return rc; +} + +#define MEM_HEADER_SIZE (sizeof(union mem_header)) + +static union mem_header *mem_header_of(const void *p) +{ + return (union mem_header *)((char *)p - MEM_HEADER_SIZE); +} unsigned int get_mem_size(const char *p) { - const char *begin; - - begin = p - strlen(MEM_BEGIN) - 1 - sizeof(int); - return *(int *)(begin + strlen(MEM_BEGIN) + 1); + return mem_header_of(p)->h.size; } -void checkmem(const char *p, int size) +void *mem_alloc(int size) { - const char *begin; - const char *end; + union mem_header *hdr; + char *mem; - begin = p - strlen(MEM_BEGIN) - 1 - sizeof(int); - if (strcmp(begin, MEM_BEGIN)) - die("checkmem: memory corrupted - invalid head sign"); + if (size < 0) + die("mem_alloc: negative size (%d)", size); - if (*(int *)(begin + strlen(MEM_BEGIN) + 1) != size) - die("checkmem: memory corrupted - invalid size"); + hdr = malloc(MEM_HEADER_SIZE + (size_t) size); + if (!hdr) + die("mem_alloc: no more memory (%d)", size); - end = begin + size + CONTROL_SIZE - strlen(MEM_END) - 1; - if (strcmp(end, MEM_END)) - die("checkmem: memory corrupted - invalid end sign"); + hdr->h.size = size; + mem = (char *)hdr + MEM_HEADER_SIZE; + + return mem; } void *getmem(int size) { char *mem; - if ((mem = mem_alloc(size)) == NULL) - die("getmem: no more memory (%d)", size); - + mem = mem_alloc(size); memset(mem, 0, size); -// checkmem (mem, size); - - return mem; -} - -void *mem_alloc(int size) -{ - char *p; - char *mem; - - p = (char *)malloc(CONTROL_SIZE + size); - if (!p) - die("getmem: no more memory (%d)", size); - - /* Write the MEM_BEGIN magic in the beginning of allocated memory. */ - strcpy(p, MEM_BEGIN); - p += strlen(MEM_BEGIN) + 1; - /* Write the size after the magic. */ - *(int *)p = size; - p += sizeof(int); - mem = p; - p += size; - strcpy(p, MEM_END); return mem; } void *expandmem(void *vp, int size, int by) { - int allocated; - char *mem, *p = vp; - int expand_by = by; + union mem_header *hdr; + char *mem; + size_t old_size = vp ? (size_t) mem_header_of(vp)->h.size : 0; + size_t new_size = old_size + by; - if (p) { - checkmem(p, size); - allocated = CONTROL_SIZE + size; - p -= (strlen(MEM_BEGIN) + 1 + sizeof(int)); - } else { - allocated = 0; - /* add control bytes to the new allocated area */ - expand_by += CONTROL_SIZE; - } - p = realloc(p, allocated + expand_by); - if (!p) + if (by < 0) + die("expandmem: negative increment (%d)", by); + + hdr = realloc(vp ? mem_header_of(vp) : NULL, MEM_HEADER_SIZE + new_size); + if (!hdr) die("expandmem: no more memory (%d)", size); - if (!vp) { - strcpy(p, MEM_BEGIN); - } - mem = p + strlen(MEM_BEGIN) + 1 + sizeof(int); - *(int *)(p + strlen(MEM_BEGIN) + 1) = size + by; - /* fill new allocated area by 0s */ + mem = (char *)hdr + MEM_HEADER_SIZE; + hdr->h.size = new_size; + + /* fill the newly allocated area with 0s */ if (by > 0) - memset(mem + size, 0, by); - strcpy(mem + size + by, MEM_END); -// checkmem (mem, size + by); + memset(mem + old_size, 0, by); return mem; } void freemem(void *vp) { - char *p = vp; - int size; - - if (!p) + if (!vp) return; - size = get_mem_size(vp); - checkmem(p, size); - p -= (strlen(MEM_BEGIN) + 1 + sizeof(int)); - strcpy(p, MEM_FREED); - strcpy(p + size + CONTROL_SIZE - strlen(MEM_END) - 1, MEM_FREED); - free(p); + free(mem_header_of(vp)); } typedef int (*func_t) (const char *); @@ -714,13 +707,18 @@ int prepare_dma_check(dma_info_t *dma_info) } while ((dirent = readdir(dir)) != NULL) { + int n; + if (strncmp(dirent->d_name, ".", 1) == 0 || strncmp(dirent->d_name, "..", 2) == 0) continue; - memset(buf, 0, 256); - strncat(buf, "/dev/", 5); - strncat(buf, dirent->d_name, - strlen(dirent->d_name)); + + /* "/dev/" + name; skip names that do not fit + rather than truncating into a wrong path */ + n = snprintf(buf, sizeof(buf), "/dev/%s", + dirent->d_name); + if (n < 0 || (size_t) n >= sizeof(buf)) + continue; if (stat(buf, &st)) break; diff --git a/lib/progbar.c b/lib/progbar.c index 8052635..90bb190 100644 --- a/lib/progbar.c +++ b/lib/progbar.c @@ -15,7 +15,7 @@ void progbar_init(struct progbar *ctx, const char *units, FILE * fp) memset(bar, '=', sizeof(bar) - 1); if (!spaces[0]) memset(spaces, ' ', sizeof(spaces) - 1); - strncpy(ctx->units, units, sizeof(ctx->units)); + snprintf(ctx->units, sizeof(ctx->units), "%s", units); ctx->file = fp; } diff --git a/mkreiserfs/mkreiserfs.c b/mkreiserfs/mkreiserfs.c index 463eb8e..225eaaa 100644 --- a/mkreiserfs/mkreiserfs.c +++ b/mkreiserfs/mkreiserfs.c @@ -122,7 +122,11 @@ static void make_super_block(reiserfs_filsys_t fs) reiserfs_warning(stderr, "\nSpecified LABEL is longer then 16 " "characters, will be truncated\n\n"); - strncpy(fs->fs_ondisk_sb->s_label, LABEL, 16); + /* on-disk label is a fixed 16-byte field; keep it + NUL-terminated for the userspace readers below */ + snprintf(fs->fs_ondisk_sb->s_label, + sizeof(fs->fs_ondisk_sb->s_label), + "%s", LABEL); } set_sb_v2_flag(fs->fs_ondisk_sb, reiserfs_attrs_cleared); } @@ -643,7 +647,7 @@ int main(int argc, char **argv) break; case 'B': /* --badblock-list */ - asprintf(&badblocks_file, "%s", optarg); + xasprintf(&badblocks_file, "%s", optarg); break; case 'h': /* --hash */ diff --git a/reiserfscore/do_balan.c b/reiserfscore/do_balan.c index 79a5e72..4cc3d91 100644 --- a/reiserfscore/do_balan.c +++ b/reiserfscore/do_balan.c @@ -1538,7 +1538,7 @@ void do_balance(struct tree_balance *tb, /* tree_balance structure insert_ptr[0] = (struct buffer_head *)body; /* we must prepare insert_key */ - if (PATH_H_B_ITEM_ORDER(tb->tb_path, 0) /*LAST_POSITION (tb->tb_path) */ + if ((int)PATH_H_B_ITEM_ORDER(tb->tb_path, 0) /*LAST_POSITION (tb->tb_path) */ /*item_pos */ == -1) { /* get delimiting key from buffer in tree */ copy_key(&insert_key[0].ih_key, diff --git a/reiserfscore/hashes.c b/reiserfscore/hashes.c index a8044da..f1fac4d 100644 --- a/reiserfscore/hashes.c +++ b/reiserfscore/hashes.c @@ -22,7 +22,7 @@ // r5 // -#include +#include #define DELTA 0x9E3779B9 #define FULLROUNDS 10 /* 32 is overkill, 16 is strong crypto */ @@ -190,29 +190,3 @@ u32 r5_hash(const signed char *msg, int len) } return a; } - -#if 0 - -#include - -int main(void) -{ - char *name = 0; - size_t n = 0; - - while (1) { - getline(&name, &n, stdin); - if (!strcmp(name, "\n")) - break; - name[strlen(name) - 1] = 0; - printf("tea %lu\n, r5 %lu\nyura %lu\n", - keyed_hash(name, strlen(name)) & 0x7fffff80, - r5_hash(name, strlen(name)) & 0x7fffff80, - yura_hash(name, strlen(name)) & 0x7fffff80); - free(name); - name = 0; - n = 0; - } -} - -#endif diff --git a/reiserfscore/includes.h b/reiserfscore/includes.h index 31fad42..9e192d3 100644 --- a/reiserfscore/includes.h +++ b/reiserfscore/includes.h @@ -15,8 +15,6 @@ #include #include #include -#include +#include #include -#include -#include #include diff --git a/reiserfscore/journal.c b/reiserfscore/journal.c index 9113d0c..111c43a 100644 --- a/reiserfscore/journal.c +++ b/reiserfscore/journal.c @@ -506,7 +506,7 @@ int reiserfs_open_journal(reiserfs_filsys_t fs, const char *j_filename, if (fs->fs_journal_dev == -1) return -1; - asprintf(&fs->fs_j_file_name, "%s", j_filename); + xasprintf(&fs->fs_j_file_name, "%s", j_filename); if (get_jp_journal_size(sb_jp(sb)) < JOURNAL_MIN_SIZE) { reiserfs_warning(stderr, "Journal of (%lu) block size found on " @@ -694,7 +694,7 @@ int reiserfs_create_journal(reiserfs_filsys_t fs, const char *j_device, /* journ return 0; } - asprintf(&fs->fs_j_file_name, "%s", j_device); + xasprintf(&fs->fs_j_file_name, "%s", j_device); if (len < JOURNAL_MIN_SIZE + 1) { reiserfs_warning(stderr, diff --git a/reiserfscore/node_formats.c b/reiserfscore/node_formats.c index c6eb900..a380f2c 100644 --- a/reiserfscore/node_formats.c +++ b/reiserfscore/node_formats.c @@ -610,7 +610,7 @@ int find_hash_in_use(const char *name, int namelen, __u32 offset, char *code2name(unsigned int code) { - if (code >= HASH_AMOUNT || code < 0) + if (code >= HASH_AMOUNT) return NULL; return hashes[code].name; } @@ -1031,22 +1031,22 @@ int name_length(const char *name, int key_format) /* key format is stored in 12 bits starting from 0-th of item_head's ih2_format*/ __u16 get_ih_key_format(const struct item_head * ih) { - get_bit_field_XX(16, &ih->ih_format, 0, 12); + get_bit_field_XX(16, ih_format_ptr(ih), 0, 12); } __u16 get_ih_flags(const struct item_head *ih) { - get_bit_field_XX(16, &ih->ih_format, 12, 4); + get_bit_field_XX(16, ih_format_ptr(ih), 12, 4); } void set_ih_key_format(struct item_head *ih, __u16 val) { - set_bit_field_XX(16, &ih->ih_format, val, 0, 12); + set_bit_field_XX(16, ih_format_ptr(ih), val, 0, 12); } void set_ih_flags(struct item_head *ih, __u16 val) { - set_bit_field_XX(16, &ih->ih_format, val, 12, 4); + set_bit_field_XX(16, ih_format_ptr(ih), val, 12, 4); } /* access to fields of stat data (both v1 and v2) */ diff --git a/reiserfscore/reiserfslib.c b/reiserfscore/reiserfslib.c index 6535379..97ffaa1 100644 --- a/reiserfscore/reiserfslib.c +++ b/reiserfscore/reiserfslib.c @@ -82,7 +82,7 @@ reiserfs_filsys_t reiserfs_open(const char *filename, int flags, fs = getmem(sizeof(*fs)); fs->fs_dev = fd; fs->fs_vp = vp; - asprintf(&fs->fs_file_name, "%s", filename); + xasprintf(&fs->fs_file_name, "%s", filename); /* reiserfs super block is either in 16-th or in 2-nd 4k block of the device */ @@ -215,7 +215,7 @@ reiserfs_filsys_t reiserfs_create(const char *filename, } fs->fs_blocksize = block_size; - asprintf(&fs->fs_file_name, "%s", filename); + xasprintf(&fs->fs_file_name, "%s", filename); fs->fs_format = version; if (new_format) @@ -664,7 +664,7 @@ struct reiserfs_key *uget_rkey(const struct reiserfs_path *path) struct reiserfs_key *reiserfs_next_key(const struct reiserfs_path *path) { - if (get_item_pos(path) < B_NR_ITEMS(get_bh(path)) - 1) + if (get_item_pos(path) + 1 < B_NR_ITEMS(get_bh(path))) return leaf_key(get_bh(path), get_item_pos(path) + 1); return uget_rkey(path); @@ -1054,7 +1054,7 @@ int reiserfs_add_entry(reiserfs_filsys_t fs, const struct reiserfs_key *dir, const char *name, int name_len, const struct reiserfs_key *key, __u16 fsck_need) { - struct item_head entry_ih = { {0,}, }; + struct item_head entry_ih = { 0 }; char *entry; int retval; INITIALIZE_REISERFS_PATH(path); @@ -1458,7 +1458,7 @@ void add_badblock_list(reiserfs_filsys_t fs, int replace) } int reiserfs_iterate_file_data(reiserfs_filsys_t fs, - const struct reiserfs_key const *short_key, + const struct reiserfs_key *short_key, reiserfs_file_iterate_indirect_fn indirect_fn, reiserfs_file_iterate_direct_fn direct_fn, void *data) @@ -1555,7 +1555,7 @@ fail: } int reiserfs_iterate_dir(reiserfs_filsys_t fs, - const struct reiserfs_key const *dir_short_key, + const struct reiserfs_key *dir_short_key, const reiserfs_iterate_dir_fn callback, void *data) { INITIALIZE_REISERFS_PATH(path); diff --git a/reiserfsprogs.spec b/reiserfsprogs.spec index 40f5032..a0480ba 100644 --- a/reiserfsprogs.spec +++ b/reiserfsprogs.spec @@ -1,4 +1,4 @@ -%define reiserfsprogsversion 3.6.23 +%define reiserfsprogsversion 3.6.25 Vendor: Hans Reiser Distribution: Hans Reiser diff --git a/resize_reiserfs/resize_reiserfs.c b/resize_reiserfs/resize_reiserfs.c index 54ec06a..91d1f45 100644 --- a/resize_reiserfs/resize_reiserfs.c +++ b/resize_reiserfs/resize_reiserfs.c @@ -48,9 +48,11 @@ static long long int calc_new_fs_size(unsigned long count, case 'G': case 'g': bytes *= 1024; + /* fall through */ case 'M': case 'm': bytes *= 1024; + /* fall through */ case 'K': case 'k': bytes *= 1024; @@ -58,7 +60,7 @@ static long long int calc_new_fs_size(unsigned long count, blocks = bytes / bs; - return rel ? count + blocks : blocks; + return rel ? (long long int)count + blocks : blocks; } /* print some fs parameters */ @@ -215,6 +217,7 @@ int main(int argc, char *argv[]) reiserfs_exit(1, "Missing argument to -j option"); jdevice_name = optarg; + break; case 'f': opt_force = 1; break; @@ -292,7 +295,7 @@ int main(int argc, char *argv[]) block_count_new = bytes_count_str ? calc_new_fs_size(get_sb_block_count(sb), fs->fs_blocksize, bytes_count_str) : - count_blocks(devname, fs->fs_blocksize); + (long long int)count_blocks(devname, fs->fs_blocksize); if (resizer_check_fs_size(fs, block_count_new)) return 1; diff --git a/tune/tune.c b/tune/tune.c index e860910..b017cd8 100644 --- a/tune/tune.c +++ b/tune/tune.c @@ -6,6 +6,7 @@ #define _GNU_SOURCE #include "tune.h" +#include "misc.h" #include #include @@ -487,11 +488,11 @@ int main(int argc, char **argv) Force++; break; case 'b': /* --add-badblocks */ - asprintf(&badblocks_file, "%s", optarg); + xasprintf(&badblocks_file, "%s", optarg); Bads = 1; break; case 'B': /* --badblocks */ - asprintf(&badblocks_file, "%s", optarg); + xasprintf(&badblocks_file, "%s", optarg); Bads = 2; break; case 'u': @@ -675,7 +676,11 @@ int main(int argc, char **argv) if (strlen(LABEL) > 16) message ("Specified LABEL is longer then 16 characters, will be truncated\n"); - strncpy(fs->fs_ondisk_sb->s_label, LABEL, 16); + /* on-disk label is a fixed 16-byte field; keep it + NUL-terminated for the userspace readers below */ + snprintf(fs->fs_ondisk_sb->s_label, + sizeof(fs->fs_ondisk_sb->s_label), + "%s", LABEL); need_dirty = 1; } if (Max_mnt_count &&