From 2e2c237ab90ade751753944f0ed1830b24478396 Mon Sep 17 00:00:00 2001 From: Etienne Brateau Date: Sun, 23 Jan 2022 05:17:06 +0100 Subject: ext2fs: Take cares of indiannes In ext2 data are stored in little endian to ensure portability. So enforce little endian when manipulating these bytes. Message-Id: <20220123041715.19402-8-etienne.brateau@gmail.com> --- ext2fs/balloc.c | 136 +++++++++++++++++++++++++++++------------------------ ext2fs/dir.c | 75 ++++++++++++++--------------- ext2fs/ext2_fs.h | 36 +++++++------- ext2fs/ext2fs.h | 9 ++-- ext2fs/getblk.c | 2 +- ext2fs/hyper.c | 42 ++++++++--------- ext2fs/ialloc.c | 75 ++++++++++++++--------------- ext2fs/inode.c | 140 ++++++++++++++++++++++++++++--------------------------- ext2fs/xattr.c | 80 ++++++++++++++++--------------- 9 files changed, 311 insertions(+), 284 deletions(-) diff --git a/ext2fs/balloc.c b/ext2fs/balloc.c index 8ebd11cd..337b583b 100644 --- a/ext2fs/balloc.c +++ b/ext2fs/balloc.c @@ -65,8 +65,8 @@ ext2_free_blocks (block_t block, unsigned long count) pthread_spin_lock (&global_lock); - if (block < sblock->s_first_data_block || - (block + count) > sblock->s_blocks_count) + if (block < le32toh (sblock->s_first_data_block) || + (block + count) > le32toh (sblock->s_blocks_count)) { ext2_error ("freeing blocks not in datazone - " "block = %u, count = %lu", block, count); @@ -80,24 +80,30 @@ ext2_free_blocks (block_t block, unsigned long count) { unsigned long int gcount = count; - block_group = ((block - sblock->s_first_data_block) - / sblock->s_blocks_per_group); - bit = (block - sblock->s_first_data_block) % sblock->s_blocks_per_group; - if (bit + count > sblock->s_blocks_per_group) + block_group = ((block - le32toh (sblock->s_first_data_block)) / + le32toh (sblock->s_blocks_per_group)); + bit = (block - le32toh (sblock->s_first_data_block)) % + le32toh (sblock->s_blocks_per_group); + + /* + * Check to see if we are freeing blocks accross a group + * boundary + */ + if (bit + count > le32toh (sblock->s_blocks_per_group)) { - unsigned long overflow = bit + count - sblock->s_blocks_per_group; + unsigned long overflow = bit + count - le32toh (sblock->s_blocks_per_group); gcount -= overflow; ext2_debug ("freeing blocks across group boundary - " "block = %u, count = %lu", block, count); } gdp = group_desc (block_group); - bh = disk_cache_block_ref (gdp->bg_block_bitmap); + bh = disk_cache_block_ref (le32toh (gdp->bg_block_bitmap)); - if (in_range (gdp->bg_block_bitmap, block, gcount) || - in_range (gdp->bg_inode_bitmap, block, gcount) || - in_range (block, gdp->bg_inode_table, itb_per_group) || - in_range (block + gcount - 1, gdp->bg_inode_table, itb_per_group)) + if (in_range (le32toh (gdp->bg_block_bitmap), block, gcount) || + in_range (le32toh (gdp->bg_inode_bitmap), block, gcount) || + in_range (block, le32toh (gdp->bg_inode_table), itb_per_group) || + in_range (block + gcount - 1, le32toh (gdp->bg_inode_table), itb_per_group)) ext2_panic ("freeing blocks in system zones - " "block = %u, count = %lu", block, count); @@ -108,8 +114,10 @@ ext2_free_blocks (block_t block, unsigned long count) ext2_warning ("bit already cleared for block %lu", block + i); else { - gdp->bg_free_blocks_count++; - sblock->s_free_blocks_count++; + gdp->bg_free_blocks_count = + htole16 (le16toh (gdp->bg_free_blocks_count) + 1); + sblock->s_free_blocks_count = + htole32 (le32toh (sblock->s_free_blocks_count) + 1); } } @@ -153,7 +161,7 @@ ext2_new_block (block_t goal, pthread_spin_lock (&global_lock); #ifdef XXX /* Auth check to use reserved blocks */ - if (sblock->s_free_blocks_count <= sblock->s_r_blocks_count && + if (le32toh (sblock->s_free_blocks_count) <= le32toh (sblock->s_r_blocks_count) && (!fsuser () && (sb->u.ext2_sb.s_resuid != current->fsuid) && (sb->u.ext2_sb.s_resgid == 0 || !in_group_p (sb->u.ext2_sb.s_resgid)))) @@ -170,18 +178,21 @@ repeat: /* * First, test whether the goal block is free. */ - if (goal < sblock->s_first_data_block || goal >= sblock->s_blocks_count) - goal = sblock->s_first_data_block; - i = (goal - sblock->s_first_data_block) / sblock->s_blocks_per_group; + if (goal < le32toh (sblock->s_first_data_block) + || goal >= le32toh (sblock->s_blocks_count)) + goal = le32toh (sblock->s_first_data_block); + i = (goal - le32toh (sblock->s_first_data_block)) / + le32toh (sblock->s_blocks_per_group); gdp = group_desc (i); - if (gdp->bg_free_blocks_count > 0) + if (le16toh (gdp->bg_free_blocks_count) > 0) { - j = ((goal - sblock->s_first_data_block) % sblock->s_blocks_per_group); + j = ((goal - le32toh (sblock->s_first_data_block)) + % le32toh (sblock->s_blocks_per_group)); #ifdef EXT2FS_DEBUG if (j) goal_attempts++; #endif - bh = disk_cache_block_ref (gdp->bg_block_bitmap); + bh = disk_cache_block_ref (le32toh (gdp->bg_block_bitmap)); ext2_debug ("goal is at %d:%d", i, j); @@ -204,7 +215,8 @@ repeat: else lmap = ((((unsigned long *) bh)[j >> 5]) >> ((j & 31) + 1)); - if (j < sblock->s_blocks_per_group - 32) + + if (j < le32toh (sblock->s_blocks_per_group) - 32) lmap |= (((unsigned long *) bh)[(j >> 5) + 1]) << (31 - (j & 31)); else @@ -212,7 +224,7 @@ repeat: if (lmap != 0xffffffffl) { k = ffz (lmap) + 1; - if ((j + k) < sblock->s_blocks_per_group) + if ((j + k) < le32toh (sblock->s_blocks_per_group)) { j += k; goto got_block; @@ -232,17 +244,17 @@ repeat: * cyclicly search through the rest of the groups. */ p = bh + (j >> 3); - r = memscan (p, 0, (sblock->s_blocks_per_group - j + 7) >> 3); + r = memscan (p, 0, (le32toh (sblock->s_blocks_per_group) - j + 7) >> 3); k = (r - bh) << 3; - if (k < sblock->s_blocks_per_group) + if (k < le32toh (sblock->s_blocks_per_group)) { j = k; goto search_back; } k = find_next_zero_bit ((unsigned long *) bh, - sblock->s_blocks_per_group, + le32toh (sblock->s_blocks_per_group), j); - if (k < sblock->s_blocks_per_group) + if (k < le32toh (sblock->s_blocks_per_group)) { j = k; goto got_block; @@ -264,7 +276,7 @@ repeat: if (i >= groups_count) i = 0; gdp = group_desc (i); - if (gdp->bg_free_blocks_count > 0) + if (le16toh (gdp->bg_free_blocks_count) > 0) break; } if (k >= groups_count) @@ -273,15 +285,15 @@ repeat: return 0; } assert_backtrace (bh == NULL); - bh = disk_cache_block_ref (gdp->bg_block_bitmap); - r = memscan (bh, 0, sblock->s_blocks_per_group >> 3); + bh = disk_cache_block_ref (le32toh (gdp->bg_block_bitmap)); + r = memscan (bh, 0, le32toh (sblock->s_blocks_per_group) >> 3); j = (r - bh) << 3; - if (j < sblock->s_blocks_per_group) + if (j < le32toh (sblock->s_blocks_per_group)) goto search_back; else j = find_first_zero_bit ((unsigned long *) bh, - sblock->s_blocks_per_group); - if (j >= sblock->s_blocks_per_group) + le32toh (sblock->s_blocks_per_group)); + if (j >= le32toh (sblock->s_blocks_per_group)) { disk_cache_block_deref (bh); bh = NULL; @@ -302,13 +314,14 @@ search_back: got_block: assert_backtrace (bh != NULL); - ext2_debug ("using block group %d (%d)", i, gdp->bg_free_blocks_count); + ext2_debug ("using block group %d (%d)", i, le16toh (gdp->bg_free_blocks_count)); - tmp = j + i * sblock->s_blocks_per_group + sblock->s_first_data_block; + tmp = j + i * le32toh (sblock->s_blocks_per_group) + + le32toh (sblock->s_first_data_block); - if (tmp == gdp->bg_block_bitmap || - tmp == gdp->bg_inode_bitmap || - in_range (tmp, gdp->bg_inode_table, itb_per_group)) + if (tmp == le32toh (gdp->bg_block_bitmap) || + tmp == le32toh (gdp->bg_inode_bitmap) || + in_range (tmp, le32toh (gdp->bg_inode_table), itb_per_group)) ext2_panic ("allocating block in system zone; block = %u", tmp); if (set_bit (j, bh)) @@ -340,7 +353,7 @@ got_block: *prealloc_count = 0; *prealloc_block = tmp + 1; for (k = 1; - k < prealloc_goal && (j + k) < sblock->s_blocks_per_group; k++) + k < prealloc_goal && (j + k) < le32toh (sblock->s_blocks_per_group); k++) { if (set_bit (j + k, bh)) break; @@ -354,8 +367,10 @@ got_block: pthread_spin_unlock (&modified_global_blocks_lock); } } - gdp->bg_free_blocks_count -= *prealloc_count; - sblock->s_free_blocks_count -= *prealloc_count; + gdp->bg_free_blocks_count = htole16 (le16toh (gdp->bg_free_blocks_count) - + *prealloc_count); + sblock->s_free_blocks_count = htole32 (le32toh (sblock->s_free_blocks_count) - + *prealloc_count); ext2_debug ("preallocated a further %u bits", *prealloc_count); } #endif @@ -365,7 +380,7 @@ got_block: record_global_poke (bh); bh = NULL; - if (j >= sblock->s_blocks_count) + if (j >= le32toh (sblock->s_blocks_count)) { ext2_error ("block >= blocks count - block_group = %d, block=%d", i, j); j = 0; @@ -375,11 +390,11 @@ got_block: ext2_debug ("allocating block %d; goal hits %d of %d", j, goal_hits, goal_attempts); - gdp->bg_free_blocks_count--; + gdp->bg_free_blocks_count = htole16 (le16toh (gdp->bg_free_blocks_count) - 1); disk_cache_block_ref_ptr (gdp); record_global_poke (gdp); - sblock->s_free_blocks_count--; + sblock->s_free_blocks_count = htole32 (le32toh (sblock->s_free_blocks_count) - 1); sblock_dirty = 1; sync_out: @@ -407,28 +422,29 @@ ext2_count_free_blocks () { void *bh; gdp = group_desc (i); - desc_count += gdp->bg_free_blocks_count; - bh = disk_cache_block_ref (gdp->bg_block_bitmap); + desc_count += le16toh (gdp->bg_free_blocks_count); + bh = disk_cache_block_ref (le32toh (gdp->bg_block_bitmap)); x = count_free (bh, block_size); disk_cache_block_deref (bh); printf ("group %d: stored = %d, counted = %lu", - i, gdp->bg_free_blocks_count, x); + i, le16toh (gdp->bg_free_blocks_count), x); bitmap_count += x; } printf ("ext2_count_free_blocks: stored = %u, computed = %lu, %lu", - sblock->s_free_blocks_count, desc_count, bitmap_count); + le32toh (sblock->s_free_blocks_count), + desc_count, bitmap_count); pthread_spin_unlock (&global_lock); return bitmap_count; #else - return sblock->s_free_blocks_count; + return le32toh (sblock->s_free_blocks_count); #endif } static inline int block_in_use (block_t block, unsigned char *map) { - return test_bit ((block - sblock->s_first_data_block) % - sblock->s_blocks_per_group, map); + return test_bit ((block - le32toh (sblock->s_first_data_block)) % + le32toh (sblock->s_blocks_per_group), map); } void @@ -470,8 +486,8 @@ ext2_check_blocks_bitmap () } gdp = group_desc (i); - desc_count += gdp->bg_free_blocks_count; - bh = disk_cache_block_ref (gdp->bg_block_bitmap); + desc_count += le16toh (gdp->bg_free_blocks_count); + bh = disk_cache_block_ref (le32toh (gdp->bg_block_bitmap)); if (!EXT2_HAS_RO_COMPAT_FEATURE (sblock, EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER) @@ -486,27 +502,27 @@ ext2_check_blocks_bitmap () j, i); } - if (!block_in_use (gdp->bg_block_bitmap, bh)) + if (!block_in_use (le32toh (gdp->bg_block_bitmap), bh)) ext2_error ("block bitmap for group %d is marked free", i); - if (!block_in_use (gdp->bg_inode_bitmap, bh)) + if (!block_in_use (le32toh (gdp->bg_inode_bitmap), bh)) ext2_error ("inode bitmap for group %d is marked free", i); for (j = 0; j < itb_per_group; j++) - if (!block_in_use (gdp->bg_inode_table + j, bh)) + if (!block_in_use (le32toh (gdp->bg_inode_table) + j, bh)) ext2_error ("block #%d of the inode table in group %d is marked free", j, i); x = count_free (bh, block_size); disk_cache_block_deref (bh); - if (gdp->bg_free_blocks_count != x) + if (le16toh (gdp->bg_free_blocks_count) != x) ext2_error ("wrong free blocks count for group %d," " stored = %d, counted = %lu", - i, gdp->bg_free_blocks_count, x); + i, le16toh (gdp->bg_free_blocks_count), x); bitmap_count += x; } - if (sblock->s_free_blocks_count != bitmap_count) + if (le32toh (sblock->s_free_blocks_count) != bitmap_count) ext2_error ("wrong free blocks count in super block," " stored = %lu, counted = %lu", - (unsigned long) sblock->s_free_blocks_count, bitmap_count); + (unsigned long) le32toh (sblock->s_free_blocks_count), bitmap_count); pthread_spin_unlock (&global_lock); } diff --git a/ext2fs/dir.c b/ext2fs/dir.c index bcf90469..c7c3018b 100644 --- a/ext2fs/dir.c +++ b/ext2fs/dir.c @@ -404,15 +404,15 @@ dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, for (currentoff = blockaddr, prevoff = 0; currentoff < blockaddr + DIRBLKSIZ; - prevoff = currentoff, currentoff += entry->rec_len) + prevoff = currentoff, currentoff += le16toh (entry->rec_len)) { entry = (struct ext2_dir_entry_2 *)currentoff; - if (!entry->rec_len - || entry->rec_len % EXT2_DIR_PAD + if (!le16toh (entry->rec_len) + || le16toh (entry->rec_len) % EXT2_DIR_PAD || entry->name_len > EXT2_NAME_LEN - || currentoff + entry->rec_len > blockaddr + DIRBLKSIZ - || EXT2_DIR_REC_LEN (entry->name_len) > entry->rec_len + || currentoff + le16toh (entry->rec_len) > blockaddr + DIRBLKSIZ + || EXT2_DIR_REC_LEN (entry->name_len) > le16toh (entry->rec_len) || memchr (entry->name, '\0', entry->name_len)) { ext2_warning ("bad directory entry: inode: %Ld offset: %lu", @@ -426,10 +426,10 @@ dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, size_t thisfree; /* Count how much free space this entry has in it. */ - if (entry->inode == 0) - thisfree = entry->rec_len; + if (le32toh (entry->inode) == 0) + thisfree = le16toh (entry->rec_len); else - thisfree = entry->rec_len - EXT2_DIR_REC_LEN (entry->name_len); + thisfree = le16toh (entry->rec_len) - EXT2_DIR_REC_LEN (entry->name_len); /* If this isn't at the front of the block, then it will have to be copied if we do a compression; count the @@ -445,7 +445,7 @@ dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, if (thisfree >= needed) { ds->type = CREATE; - ds->stat = entry->inode == 0 ? TAKE : SHRINK; + ds->stat = le32toh (entry->inode) == 0 ? TAKE : SHRINK; ds->entry = entry; ds->idx = idx; looking = countcopies = 0; @@ -458,12 +458,12 @@ dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, } } - if (entry->inode) + if (le32toh (entry->inode)) nentries++; if (entry->name_len == namelen && entry->name[0] == name[0] - && entry->inode + && le32toh (entry->inode) && !bcmp (entry->name, name, namelen)) break; } @@ -514,7 +514,7 @@ dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, ds->preventry = (struct ext2_dir_entry_2 *) prevoff; } - *inum = entry->inode; + *inum = le32toh (entry->inode); return 0; } @@ -551,7 +551,8 @@ diskfs_direnter_hard (struct node *dp, const char *name, struct node *np, { case TAKE: /* We are supposed to consume this slot. */ - assert_backtrace (ds->entry->inode == 0 && ds->entry->rec_len >= needed); + assert_backtrace (le32toh (ds->entry->inode) == 0 + && le16toh (ds->entry->rec_len) >= needed); new = ds->entry; break; @@ -560,12 +561,12 @@ diskfs_direnter_hard (struct node *dp, const char *name, struct node *np, /* We are supposed to take the extra space at the end of this slot. */ oldneeded = EXT2_DIR_REC_LEN (ds->entry->name_len); - assert_backtrace (ds->entry->rec_len - oldneeded >= needed); + assert_backtrace (le16toh (ds->entry->rec_len) - oldneeded >= needed); new = (struct ext2_dir_entry_2 *) ((vm_address_t) ds->entry + oldneeded); - new->rec_len = ds->entry->rec_len - oldneeded; - ds->entry->rec_len = oldneeded; + new->rec_len = htole16 (le16toh (ds->entry->rec_len) - oldneeded); + ds->entry->rec_len = htole16 (oldneeded); break; case COMPRESS: @@ -579,16 +580,16 @@ diskfs_direnter_hard (struct node *dp, const char *name, struct node *np, { struct ext2_dir_entry_2 *from = (struct ext2_dir_entry_2 *)fromoff; struct ext2_dir_entry_2 *to = (struct ext2_dir_entry_2 *) tooff; - size_t fromreclen = from->rec_len; + size_t fromreclen = le16toh (from->rec_len); - if (from->inode != 0) + if (le32toh (from->inode) != 0) { assert_backtrace (fromoff >= tooff); memmove (to, from, fromreclen); - to->rec_len = EXT2_DIR_REC_LEN (to->name_len); + to->rec_len = htole16 (EXT2_DIR_REC_LEN (to->name_len)); - tooff += to->rec_len; + tooff += le16toh (to->rec_len); } fromoff += fromreclen; } @@ -597,7 +598,7 @@ diskfs_direnter_hard (struct node *dp, const char *name, struct node *np, assert_backtrace (totfreed >= needed); new = (struct ext2_dir_entry_2 *) tooff; - new->rec_len = totfreed; + new->rec_len = htole16 (totfreed); break; case EXTEND: @@ -634,7 +635,7 @@ diskfs_direnter_hard (struct node *dp, const char *name, struct node *np, dp->dn_stat.st_size = oldsize + DIRBLKSIZ; dp->dn_set_ctime = 1; - new->rec_len = DIRBLKSIZ; + new->rec_len = htole16 (DIRBLKSIZ); break; default: @@ -645,7 +646,7 @@ diskfs_direnter_hard (struct node *dp, const char *name, struct node *np, /* NEW points to the directory entry being written, and its rec_len field is already filled in. Now fill in the rest. */ - new->inode = np->cache_id; + new->inode = htole32 (np->cache_id); #if 0 /* XXX We cannot enable this code because file types can change (and conceivably quite often) with translator settings. @@ -722,12 +723,12 @@ diskfs_dirremove_hard (struct node *dp, struct dirstat *ds) assert_backtrace (!diskfs_readonly); if (ds->preventry == 0) - ds->entry->inode = 0; + ds->entry->inode = htole32 (0); else { assert_backtrace ((vm_address_t) ds->entry - (vm_address_t) ds->preventry - == ds->preventry->rec_len); - ds->preventry->rec_len += ds->entry->rec_len; + == le16toh (ds->preventry->rec_len)); + ds->preventry->rec_len = htole16( le16toh (ds->preventry->rec_len) + ds->entry->rec_len); } dp->dn_set_mtime = 1; @@ -761,7 +762,7 @@ diskfs_dirrewrite_hard (struct node *dp, struct node *np, struct dirstat *ds) assert_backtrace (!diskfs_readonly); - ds->entry->inode = np->cache_id; + ds->entry->inode = htole32 (np->cache_id); dp->dn_set_mtime = 1; diskfs_node_disknode (dp)->info.i_flags &= ~EXT2_BTREE_FL; @@ -796,11 +797,11 @@ diskfs_dirempty (struct node *dp, struct protid *cred) for (curoff = buf; !hit && curoff < buf + dp->dn_stat.st_size; - curoff += entry->rec_len) + curoff += le16toh (entry->rec_len)) { entry = (struct ext2_dir_entry_2 *) curoff; - if (entry->inode != 0 + if (le32toh (entry->inode) != 0 && (entry->name_len > 2 || entry->name[0] != '.' || (entry->name[1] != '.' @@ -853,10 +854,10 @@ count_dirents (struct node *dp, block_t nb, char *buf) for (offinblk = buf; offinblk < buf + DIRBLKSIZ; - offinblk += entry->rec_len) + offinblk += le16toh (entry->rec_len)) { entry = (struct ext2_dir_entry_2 *) offinblk; - if (entry->inode) + if (le32toh (entry->inode)) count++; } @@ -982,7 +983,7 @@ diskfs_get_directs (struct node *dp, } for (i = 0, bufp = buf; i < entry - curentry && bufp - buf < DIRBLKSIZ; - bufp += ((struct ext2_dir_entry_2 *)bufp)->rec_len, i++) + bufp += le16toh (((struct ext2_dir_entry_2 *)bufp)->rec_len), i++) ; /* Make sure we didn't run off the end. */ assert_backtrace (bufp - buf < DIRBLKSIZ); @@ -1009,7 +1010,7 @@ diskfs_get_directs (struct node *dp, entryp = (struct ext2_dir_entry_2 *)bufp; - if (entryp->inode) + if (le32toh (entryp->inode)) { int rec_len; int name_len = entryp->name_len; @@ -1033,7 +1034,7 @@ diskfs_get_directs (struct node *dp, if (datap + rec_len > *data + allocsize) break; - userp->d_fileno = entryp->inode; + userp->d_fileno = le32toh (entryp->inode); userp->d_reclen = rec_len; userp->d_namlen = name_len; @@ -1066,7 +1067,7 @@ diskfs_get_directs (struct node *dp, i++; } - if (entryp->rec_len == 0) + if (le16toh (entryp->rec_len) == 0) { ext2_warning ("zero length directory entry: inode: %Ld offset: %zd", dp->cache_id, @@ -1074,7 +1075,7 @@ diskfs_get_directs (struct node *dp, return EIO; } - bufp += entryp->rec_len; + bufp += le16toh (entryp->rec_len); if (bufp - buf == DIRBLKSIZ) { blkno++; @@ -1084,7 +1085,7 @@ diskfs_get_directs (struct node *dp, { ext2_warning ("directory entry too long: inode: %Ld offset: %zd", dp->cache_id, - blkno * DIRBLKSIZ + bufp - buf - entryp->rec_len); + blkno * DIRBLKSIZ + bufp - buf - le16toh (entryp->rec_len)); return EIO; } } diff --git a/ext2fs/ext2_fs.h b/ext2fs/ext2_fs.h index f05abb04..daa49543 100644 --- a/ext2fs/ext2_fs.h +++ b/ext2fs/ext2_fs.h @@ -83,12 +83,12 @@ #define EXT2_ACLE_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s) / sizeof (struct ext2_acl_entry)) #define EXT2_ADDR_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s) / sizeof (__u32)) #define EXT2_BLOCK_SIZE_BITS(s) ((s)->s_log_block_size + 10) -#define EXT2_INODE_SIZE(s) (((s)->s_rev_level == EXT2_GOOD_OLD_REV) ? \ - EXT2_GOOD_OLD_INODE_SIZE : \ - (s)->s_inode_size) -#define EXT2_FIRST_INO(s) (((s)->s_rev_level == EXT2_GOOD_OLD_REV) ? \ - EXT2_GOOD_OLD_FIRST_INO : \ - (s)->s_first_ino) +#define EXT2_INODE_SIZE(s) (((s)->s_rev_level == htole32(EXT2_GOOD_OLD_REV)) ? \ + EXT2_GOOD_OLD_INODE_SIZE : \ + le16toh ((s)->s_inode_size)) +#define EXT2_FIRST_INO(s) (((s)->s_rev_level == htole32(EXT2_GOOD_OLD_REV)) ? \ + EXT2_GOOD_OLD_FIRST_INO : \ + (le32toh ((s)->s_first_ino))) /* * Macro-instructions used to manage fragments @@ -96,7 +96,7 @@ #define EXT2_MIN_FRAG_SIZE 1024 #define EXT2_MAX_FRAG_SIZE 4096 #define EXT2_MIN_FRAG_LOG_SIZE 10 -#define EXT2_FRAG_SIZE(s) (EXT2_MIN_FRAG_SIZE << (s)->s_log_frag_size) +#define EXT2_FRAG_SIZE(s) (EXT2_MIN_FRAG_SIZE << le32toh((s)->s_log_frag_size)) #define EXT2_FRAGS_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s) / EXT2_FRAG_SIZE(s)) /* @@ -139,9 +139,9 @@ struct ext2_group_desc /* * Macro-instructions used to manage group descriptors */ -#define EXT2_BLOCKS_PER_GROUP(s) ((s)->s_blocks_per_group) +#define EXT2_BLOCKS_PER_GROUP(s) (le32toh ((s)->s_blocks_per_group)) #define EXT2_DESC_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s) / sizeof (struct ext2_group)) -#define EXT2_INODES_PER_GROUP(s) ((s)->s_inodes_per_group) +#define EXT2_INODES_PER_GROUP(s) (le32toh ((s)->s_inodes_per_group)) /* * Constants relative to the data blocks @@ -435,23 +435,23 @@ struct ext2_super_block { */ #define EXT2_HAS_COMPAT_FEATURE(sb,mask) \ - ( (sb)->s_feature_compat & (mask) ) + ( (sb)->s_feature_compat & htole32 (mask) ) #define EXT2_HAS_RO_COMPAT_FEATURE(sb,mask) \ - ( (sb)->s_feature_ro_compat & (mask) ) + ( (sb)->s_feature_ro_compat & htole32 (mask) ) #define EXT2_HAS_INCOMPAT_FEATURE(sb,mask) \ - ( (sb)->s_feature_incompat & (mask) ) + ( (sb)->s_feature_incompat & htole32 (mask) ) #define EXT2_SET_COMPAT_FEATURE(sb,mask) \ - (sb)->s_feature_compat |= (mask) + (sb)->s_feature_compat |= htole32 (mask) #define EXT2_SET_RO_COMPAT_FEATURE(sb,mask) \ - (sb)->s_feature_ro_compat |= (mask) + (sb)->s_feature_ro_compat |= htole32 (mask) #define EXT2_SET_INCOMPAT_FEATURE(sb,mask) \ - (sb)->s_feature_incompat |= (mask) + (sb)->s_feature_incompat |= htole32 (mask) #define EXT2_CLEAR_COMPAT_FEATURE(sb,mask) \ - (sb)->s_feature_compat &= ~(mask) + (sb)->s_feature_compat &= ~htole32 (mask) #define EXT2_CLEAR_RO_COMPAT_FEATURE(sb,mask) \ - (sb)->s_feature_ro_compat &= ~(mask) + (sb)->s_feature_ro_compat &= ~htole32 (mask) #define EXT2_CLEAR_INCOMPAT_FEATURE(sb,mask) \ - (sb)->s_feature_incompat &= ~(mask) + (sb)->s_feature_incompat &= ~htole32 (mask) #define EXT2_FEATURE_COMPAT_DIR_PREALLOC 0x0001 #define EXT2_FEATURE_COMPAT_IMAGIC_INODES 0x0002 diff --git a/ext2fs/ext2fs.h b/ext2fs/ext2fs.h index 003e2753..88c9fe81 100644 --- a/ext2fs/ext2fs.h +++ b/ext2fs/ext2fs.h @@ -32,6 +32,7 @@ #include #include #include +#include /* Types used by the ext2 header files. */ typedef u_int32_t __u32; @@ -293,7 +294,7 @@ extern unsigned int block_size; extern unsigned int log2_block_size; /* The number of bits to scale min-blocks to get filesystem blocks. */ -#define BLOCKSIZE_SCALE (sblock->s_log_block_size) +#define BLOCKSIZE_SCALE (le32toh (sblock->s_log_block_size)) /* log2 of the number of device blocks in a filesystem block. */ extern unsigned log2_dev_blocks_per_fs_block; @@ -404,7 +405,7 @@ bptr_offs (void *ptr) #define group_desc(num) (&group_desc_image[num]) extern struct ext2_group_desc *group_desc_image; -#define inode_group_num(inum) (((inum) - 1) / sblock->s_inodes_per_group) +#define inode_group_num(inum) (((inum) - 1) / le32toh (sblock->s_inodes_per_group)) /* Forward declarations for the following functions that are usually inlined. In case inlining is disabled, or inlining is not @@ -418,11 +419,11 @@ extern void _dino_deref (struct ext2_inode *inode); EXT2FS_EI struct ext2_inode * dino_ref (ino_t inum) { - unsigned long inodes_per_group = sblock->s_inodes_per_group; + unsigned long inodes_per_group = le32toh (sblock->s_inodes_per_group); unsigned long bg_num = (inum - 1) / inodes_per_group; unsigned long group_inum = (inum - 1) % inodes_per_group; struct ext2_group_desc *bg = group_desc (bg_num); - block_t block = bg->bg_inode_table + (group_inum / inodes_per_block); + block_t block = le32toh (bg->bg_inode_table) + (group_inum / inodes_per_block); struct ext2_inode *inode = disk_cache_block_ref (block); inode += group_inum % inodes_per_block; ext2_debug ("(%llu) = %p", inum, inode); diff --git a/ext2fs/getblk.c b/ext2fs/getblk.c index 43daf6c9..00a35135 100644 --- a/ext2fs/getblk.c +++ b/ext2fs/getblk.c @@ -152,7 +152,7 @@ inode_getblk (struct node *node, int nr, int create, int zero, goal = (diskfs_node_disknode (node)->info.i_block_group * EXT2_BLOCKS_PER_GROUP (sblock)) - + sblock->s_first_data_block; + + le32toh (sblock->s_first_data_block); } *result = ext2_alloc_block (node, goal, zero); diff --git a/ext2fs/hyper.c b/ext2fs/hyper.c index 0bcf0c72..04da86a7 100644 --- a/ext2fs/hyper.c +++ b/ext2fs/hyper.c @@ -42,7 +42,7 @@ allocate_mod_map (void) global blocks are actually modified so the pager can write only them. */ { /* One bit per filesystem block. */ - mod_map_size = sblock->s_blocks_count >> 3; + mod_map_size = le32toh (sblock->s_blocks_count) >> 3; modified_global_blocks = mmap (0, mod_map_size, PROT_READ|PROT_WRITE, MAP_ANON, 0, 0); assert_backtrace (modified_global_blocks != (void *) -1); @@ -70,15 +70,15 @@ get_hypermetadata (void) if (err || read != SBLOCK_SIZE) ext2_panic ("Cannot read hypermetadata"); - if (sblock->s_magic != EXT2_SUPER_MAGIC + if (sblock->s_magic != htole16 (EXT2_SUPER_MAGIC) #ifdef EXT2FS_PRE_02B_COMPAT - && sblock->s_magic != EXT2_PRE_02B_MAGIC + && sblock->s_magic != htole16 (EXT2_PRE_02B_MAGIC) #endif ) ext2_panic ("bad magic number %#x (should be %#x)", - sblock->s_magic, EXT2_SUPER_MAGIC); + le16toh (sblock->s_magic), EXT2_SUPER_MAGIC); - log2_block_size = EXT2_MIN_BLOCK_LOG_SIZE + sblock->s_log_block_size; + log2_block_size = EXT2_MIN_BLOCK_LOG_SIZE + le32toh(sblock->s_log_block_size); block_size = 1 << log2_block_size; if (block_size > EXT2_MAX_BLOCK_SIZE) @@ -98,10 +98,10 @@ get_hypermetadata (void) ext2_panic ("block size %d isn't a power-of-two multiple of 512!", block_size); - if ((store->size >> log2_block_size) < sblock->s_blocks_count) + if ((store->size >> log2_block_size) < le32toh (sblock->s_blocks_count)) ext2_panic ("disk size (%qd bytes) too small; superblock says we need %qd", (long long int) store->size, - (long long int) sblock->s_blocks_count << log2_block_size); + (long long int) le32toh (sblock->s_blocks_count) << log2_block_size); if (log2_dev_blocks_per_fs_block != 0 && (store->size & ((1 << log2_dev_blocks_per_fs_block) - 1)) != 0) ext2_warning ("%Ld (%zd byte) device blocks " @@ -112,12 +112,12 @@ get_hypermetadata (void) /* Set these handy variables. */ inodes_per_block = block_size / EXT2_INODE_SIZE (sblock); - frag_size = EXT2_MIN_FRAG_SIZE << sblock->s_log_frag_size; + frag_size = EXT2_MIN_FRAG_SIZE << le32toh (sblock->s_log_frag_size); if (frag_size == 0) ext2_panic ("frag size is zero!"); frags_per_block = block_size / frag_size; - if (sblock->s_rev_level > EXT2_GOOD_OLD_REV) + if (le32toh (sblock->s_rev_level) > EXT2_GOOD_OLD_REV) { features = EXT2_HAS_INCOMPAT_FEATURE(sblock, EXT2_FEATURE_INCOMPAT_UNSUPPORTED); if (features) @@ -132,21 +132,21 @@ get_hypermetadata (void) features); diskfs_readonly = 1; } - if (sblock->s_inode_size != EXT2_GOOD_OLD_INODE_SIZE) - ext2_panic ("inode size %d isn't supported", sblock->s_inode_size); + if (le16toh (sblock->s_inode_size) != EXT2_GOOD_OLD_INODE_SIZE) + ext2_panic ("inode size %d isn't supported", le16toh (sblock->s_inode_size)); } groups_count = - ((sblock->s_blocks_count - sblock->s_first_data_block + - sblock->s_blocks_per_group - 1) - / sblock->s_blocks_per_group); + ((le32toh (sblock->s_blocks_count) - le32toh (sblock->s_first_data_block) + + le32toh (sblock->s_blocks_per_group) - 1) + / le32toh (sblock->s_blocks_per_group)); - itb_per_group = sblock->s_inodes_per_group / inodes_per_block; + itb_per_group = le32toh (sblock->s_inodes_per_group) / inodes_per_block; desc_per_block = block_size / sizeof (struct ext2_group_desc); addr_per_block = block_size / sizeof (block_t); db_per_group = (groups_count + desc_per_block - 1) / desc_per_block; - ext2fs_clean = sblock->s_state & EXT2_VALID_FS; + ext2fs_clean = sblock->s_state & htole16 (EXT2_VALID_FS); if (! ext2fs_clean) { ext2_warning ("FILESYSTEM NOT UNMOUNTED CLEANLY; PLEASE fsck"); @@ -183,16 +183,16 @@ map_hypermetadata (void) error_t diskfs_set_hypermetadata (int wait, int clean) { - if (clean && ext2fs_clean && !(sblock->s_state & EXT2_VALID_FS)) + if (clean && ext2fs_clean && !(sblock->s_state & htole16 (EXT2_VALID_FS))) /* The filesystem is clean, so we need to set the clean flag. */ { - sblock->s_state |= EXT2_VALID_FS; + sblock->s_state |= htole16 (EXT2_VALID_FS); sblock_dirty = 1; } - else if (!clean && (sblock->s_state & EXT2_VALID_FS)) + else if (!clean && (sblock->s_state & htole16 (EXT2_VALID_FS))) /* The filesystem just became dirty, so clear the clean flag. */ { - sblock->s_state &= ~EXT2_VALID_FS; + sblock->s_state &= htole16 (~EXT2_VALID_FS); sblock_dirty = 1; wait = 1; } @@ -221,6 +221,6 @@ diskfs_readonly_changed (int readonly) mprotect (disk_cache, disk_cache_size, PROT_READ | (readonly ? 0 : PROT_WRITE)); - if (!readonly && !(sblock->s_state & EXT2_VALID_FS)) + if (!readonly && !(sblock->s_state & htole16 (EXT2_VALID_FS))) ext2_warning ("UNCLEANED FILESYSTEM NOW WRITABLE"); } diff --git a/ext2fs/ialloc.c b/ext2fs/ialloc.c index 49122319..9ab631db 100644 --- a/ext2fs/ialloc.c +++ b/ext2fs/ialloc.c @@ -66,18 +66,18 @@ diskfs_free_node (struct node *np, mode_t old_mode) pthread_spin_lock (&global_lock); - if (inum < EXT2_FIRST_INO (sblock) || inum > sblock->s_inodes_count) + if (inum < EXT2_FIRST_INO (sblock) || inum > le32toh (sblock->s_inodes_count)) { ext2_error ("reserved inode or nonexistent inode: %Ld", inum); pthread_spin_unlock (&global_lock); return; } - block_group = (inum - 1) / sblock->s_inodes_per_group; - bit = (inum - 1) % sblock->s_inodes_per_group; + block_group = (inum - 1) / le32toh (sblock->s_inodes_per_group); + bit = (inum - 1) % le32toh (sblock->s_inodes_per_group); gdp = group_desc (block_group); - bh = disk_cache_block_ref (gdp->bg_inode_bitmap); + bh = disk_cache_block_ref (le32toh (gdp->bg_inode_bitmap)); if (!clear_bit (bit, bh)) ext2_warning ("bit already cleared for inode %Ld", inum); @@ -86,13 +86,13 @@ diskfs_free_node (struct node *np, mode_t old_mode) disk_cache_block_ref_ptr (bh); record_global_poke (bh); - gdp->bg_free_inodes_count++; + gdp->bg_free_inodes_count = htole16 (le16toh (gdp->bg_free_inodes_count) + 1); if (S_ISDIR (old_mode)) - gdp->bg_used_dirs_count--; + gdp->bg_used_dirs_count = htole16 (le16toh (gdp->bg_used_dirs_count) - 1); disk_cache_block_ref_ptr (gdp); record_global_poke (gdp); - sblock->s_free_inodes_count++; + sblock->s_free_inodes_count = htole32 (le32toh (sblock->s_free_inodes_count) + 1); } disk_cache_block_deref (bh); @@ -131,14 +131,14 @@ repeat: if (S_ISDIR (mode)) { - avefreei = sblock->s_free_inodes_count / groups_count; + avefreei = le32toh (sblock->s_free_inodes_count) / groups_count; /* I am not yet convinced that this next bit is necessary. i = inode_group_num(dir_inum); for (j = 0; j < groups_count; j++) { tmp = group_desc (i); - if ((tmp->bg_used_dirs_count << 8) < tmp->bg_free_inodes_count) + if ((le16toh (tmp->bg_used_dirs_count) << 8) < le16toh (tmp->bg_free_inodes_count)) { gdp = tmp; break; @@ -153,11 +153,12 @@ repeat: for (j = 0; j < groups_count; j++) { tmp = group_desc (j); - if (tmp->bg_free_inodes_count - && tmp->bg_free_inodes_count >= avefreei) + if (le16toh (tmp->bg_free_inodes_count) + && le16toh (tmp->bg_free_inodes_count) >= avefreei) { if (!gdp || - (tmp->bg_free_blocks_count > gdp->bg_free_blocks_count)) + (le16toh (tmp->bg_free_blocks_count) > + le16toh (gdp->bg_free_blocks_count))) { i = j; gdp = tmp; @@ -173,7 +174,7 @@ repeat: */ i = inode_group_num(dir_inum); tmp = group_desc (i); - if (tmp->bg_free_inodes_count) + if (le16toh (tmp->bg_free_inodes_count)) gdp = tmp; else { @@ -187,7 +188,7 @@ repeat: if (i >= groups_count) i -= groups_count; tmp = group_desc (i); - if (tmp->bg_free_inodes_count) + if (le16toh (tmp->bg_free_inodes_count)) { gdp = tmp; break; @@ -205,7 +206,7 @@ repeat: if (++i >= groups_count) i = 0; tmp = group_desc (i); - if (tmp->bg_free_inodes_count) + if (le16toh (tmp->bg_free_inodes_count)) { gdp = tmp; break; @@ -220,10 +221,10 @@ repeat: return 0; } - bh = disk_cache_block_ref (gdp->bg_inode_bitmap); + bh = disk_cache_block_ref (le32toh (gdp->bg_inode_bitmap)); if ((inum = - find_first_zero_bit ((unsigned long *) bh, sblock->s_inodes_per_group)) - < sblock->s_inodes_per_group) + find_first_zero_bit ((unsigned long *) bh, le32toh (sblock->s_inodes_per_group))) + < le32toh (sblock->s_inodes_per_group)) { if (set_bit (inum, bh)) { @@ -239,7 +240,7 @@ repeat: { disk_cache_block_deref (bh); bh = NULL; - if (gdp->bg_free_inodes_count != 0) + if (le16toh (gdp->bg_free_inodes_count) != 0) { ext2_error ("free inodes count corrupted in group %d", i); inum = 0; @@ -248,8 +249,8 @@ repeat: goto repeat; } - inum += i * sblock->s_inodes_per_group + 1; - if (inum < EXT2_FIRST_INO (sblock) || inum > sblock->s_inodes_count) + inum += i * le32toh (sblock->s_inodes_per_group) + 1; + if (inum < EXT2_FIRST_INO (sblock) || inum > le32toh (sblock->s_inodes_count)) { ext2_error ("reserved inode or inode > inodes count - " "block_group = %d,inode=%llu", i, inum); @@ -257,13 +258,13 @@ repeat: goto sync_out; } - gdp->bg_free_inodes_count--; + gdp->bg_free_inodes_count = htole16 (le16toh (gdp->bg_free_inodes_count) - 1); if (S_ISDIR (mode)) - gdp->bg_used_dirs_count++; + gdp->bg_used_dirs_count = htole16 (le16toh (gdp->bg_used_dirs_count) + 1); disk_cache_block_ref_ptr (gdp); record_global_poke (gdp); - sblock->s_free_inodes_count--; + sblock->s_free_inodes_count = htole32( le32toh(sblock->s_free_inodes_count) - 1); sblock_dirty = 1; sync_out: @@ -381,20 +382,20 @@ ext2_count_free_inodes () { void *bh; gdp = group_desc (i); - desc_count += gdp->bg_free_inodes_count; - bh = disk_cache_block_ref (gdp->bg_inode_bitmap); - x = count_free (bh, sblock->s_inodes_per_group / 8); + desc_count += le16toh (gdp->bg_free_inodes_count); + bh = disk_cache_block_ref (le32toh (gdp->bg_inode_bitmap)); + x = count_free (bh, le32toh (sblock->s_inodes_per_group) / 8); disk_cache_block_deref (bh); ext2_debug ("group %d: stored = %d, counted = %lu", - i, gdp->bg_free_inodes_count, x); + i, le16toh (gdp->bg_free_inodes_count), x); bitmap_count += x; } ext2_debug ("stored = %u, computed = %lu, %lu", - sblock->s_free_inodes_count, desc_count, bitmap_count); + le32toh (sblock->s_free_inodes_count), desc_count, bitmap_count); pthread_spin_unlock (&global_lock); return desc_count; #else - return sblock->s_free_inodes_count; + return le32toh (sblock->s_free_inodes_count); #endif } @@ -416,20 +417,20 @@ ext2_check_inodes_bitmap () { void *bh; gdp = group_desc (i); - desc_count += gdp->bg_free_inodes_count; - bh = disk_cache_block_ref (gdp->bg_inode_bitmap); - x = count_free (bh, sblock->s_inodes_per_group / 8); + desc_count += le16toh (gdp->bg_free_inodes_count); + bh = disk_cache_block_ref (le32toh (gdp->bg_inode_bitmap)); + x = count_free (bh, le32toh (sblock->s_inodes_per_group) / 8); disk_cache_block_deref (bh); - if (gdp->bg_free_inodes_count != x) + if (le16toh (gdp->bg_free_inodes_count) != x) ext2_error ("wrong free inodes count in group %d, " "stored = %d, counted = %lu", - i, gdp->bg_free_inodes_count, x); + i, le16toh (gdp->bg_free_inodes_count), x); bitmap_count += x; } - if (sblock->s_free_inodes_count != bitmap_count) + if (le32toh (sblock->s_free_inodes_count) != bitmap_count) ext2_error ("wrong free inodes count in super block, " "stored = %lu, counted = %lu", - (unsigned long) sblock->s_free_inodes_count, bitmap_count); + (unsigned long) le32toh (sblock->s_free_inodes_count), bitmap_count); pthread_spin_unlock (&global_lock); } diff --git a/ext2fs/inode.c b/ext2fs/inode.c index 3bfbdfdb..30219c71 100644 --- a/ext2fs/inode.c +++ b/ext2fs/inode.c @@ -130,45 +130,45 @@ diskfs_user_read_node (struct node *np, struct lookup_context *ctx) st->st_ino = np->cache_id; st->st_blksize = vm_page_size * 2; - st->st_nlink = di->i_links_count; - st->st_size = di->i_size; - st->st_gen = di->i_generation; + st->st_nlink = le16toh (di->i_links_count); + st->st_size = le32toh (di->i_size); + st->st_gen = le32toh (di->i_generation); - st->st_atim.tv_sec = di->i_atime; + st->st_atim.tv_sec = le32toh (di->i_atime); #ifdef not_yet /* ``struct ext2_inode'' doesn't do better than sec. precision yet. */ #else st->st_atim.tv_nsec = 0; #endif - st->st_mtim.tv_sec = di->i_mtime; + st->st_mtim.tv_sec = le32toh (di->i_mtime); #ifdef not_yet /* ``struct ext2_inode'' doesn't do better than sec. precision yet. */ #else st->st_mtim.tv_nsec = 0; #endif - st->st_ctim.tv_sec = di->i_ctime; + st->st_ctim.tv_sec = le32toh (di->i_ctime); #ifdef not_yet /* ``struct ext2_inode'' doesn't do better than sec. precision yet. */ #else st->st_ctim.tv_nsec = 0; #endif - st->st_blocks = di->i_blocks; + st->st_blocks = le32toh (di->i_blocks); st->st_flags = 0; - if (di->i_flags & EXT2_APPEND_FL) + if (di->i_flags & htole32 (EXT2_APPEND_FL)) st->st_flags |= UF_APPEND; - if (di->i_flags & EXT2_NODUMP_FL) + if (di->i_flags & htole32 (EXT2_NODUMP_FL)) st->st_flags |= UF_NODUMP; - if (di->i_flags & EXT2_IMMUTABLE_FL) + if (di->i_flags & htole32 (EXT2_IMMUTABLE_FL)) st->st_flags |= UF_IMMUTABLE; - if (sblock->s_creator_os == EXT2_OS_HURD) + if (sblock->s_creator_os == htole32 (EXT2_OS_HURD)) { - st->st_mode = di->i_mode | (di->i_mode_high << 16); + st->st_mode = le16toh (di->i_mode) | (le16toh (di->i_mode_high) << 16); st->st_mode &= ~S_ITRANS; - if (di->i_translator) + if (le32toh (di->i_translator)) st->st_mode |= S_IPTRANS; else { @@ -178,41 +178,41 @@ diskfs_user_read_node (struct node *np, struct lookup_context *ctx) st->st_mode |= S_IPTRANS; } - st->st_uid = di->i_uid | (di->i_uid_high << 16); - st->st_gid = di->i_gid | (di->i_gid_high << 16); + st->st_uid = le16toh (di->i_uid) | (le16toh (di->i_uid_high) << 16); + st->st_gid = le16toh (di->i_gid) | (le16toh (di->i_gid_high) << 16); - st->st_author = di->i_author; + st->st_author = le32toh (di->i_author); if (st->st_author == -1) st->st_author = st->st_uid; } else { - st->st_mode = di->i_mode & ~S_ITRANS; - st->st_uid = di->i_uid; - st->st_gid = di->i_gid; + st->st_mode = le16toh (di->i_mode) & ~S_ITRANS; + st->st_uid = le16toh (di->i_uid); + st->st_gid = le16toh (di->i_gid); st->st_author = st->st_uid; np->author_tracks_uid = 1; } /* Setup the ext2fs auxiliary inode info. */ - info->i_dtime = di->i_dtime; - info->i_flags = di->i_flags; - info->i_faddr = di->i_faddr; + info->i_dtime = le32toh (di->i_dtime); + info->i_flags = le32toh (di->i_flags); + info->i_faddr = le32toh (di->i_faddr); info->i_frag_no = di->i_frag; info->i_frag_size = di->i_fsize; info->i_osync = 0; - info->i_file_acl = di->i_file_acl; + info->i_file_acl = le32toh (di->i_file_acl); if (S_ISDIR (st->st_mode)) - info->i_dir_acl = di->i_dir_acl; + info->i_dir_acl = le32toh (di->i_dir_acl); else { info->i_dir_acl = 0; if (sizeof (off_t) >= 8) /* 64bit file size */ - st->st_size += ((off_t) di->i_size_high) << 32; + st->st_size += ((off_t) le32toh (di->i_size_high)) << 32; else { - if (di->i_size_high) /* XXX */ + if (le32toh (di->i_size_high)) /* XXX */ { dino_deref (di); ext2_warning ("cannot handle large file inode %Ld", np->cache_id); @@ -230,14 +230,18 @@ diskfs_user_read_node (struct node *np, struct lookup_context *ctx) dn->last_page_partially_writable = 0; if (S_ISCHR (st->st_mode) || S_ISBLK (st->st_mode)) - st->st_rdev = di->i_block[0]; + st->st_rdev = le32toh (di->i_block[0]); else { + /* + * NOTE! The in-memory inode i_data array is in little-endian order + * even on big-endian machines: we do NOT byteswap the block numbers! + */ memcpy (info->i_data, di->i_block, EXT2_N_BLOCKS * sizeof info->i_data[0]); st->st_rdev = 0; } - dn->info_i_translator = di->i_translator; + dn->info_i_translator = le32toh (di->i_translator); dino_deref (di); diskfs_end_catch_exception (); @@ -280,7 +284,7 @@ diskfs_user_read_node (struct node *np, struct lookup_context *ctx) static inline error_t check_high_bits (struct node *np, long l) { - if (sblock->s_creator_os == EXT2_OS_HURD) + if (sblock->s_creator_os == htole32 (EXT2_OS_HURD)) return 0; /* Linux 2.3.42 has a mount-time option (not a bit stored on disk) @@ -325,7 +329,7 @@ diskfs_validate_mode_change (struct node *np, mode_t mode) error_t diskfs_validate_author_change (struct node *np, uid_t author) { - if (sblock->s_creator_os == EXT2_OS_HURD) + if (sblock->s_creator_os == htole32 (EXT2_OS_HURD)) return 0; else /* For non-hurd filesystems, the author & owner are the same. */ @@ -372,7 +376,7 @@ write_node (struct node *np) di = dino_ref (np->cache_id); - di->i_generation = st->st_gen; + di->i_generation = htole32 (st->st_gen); /* We happen to know that the stat mode bits are the same as the ext2fs mode bits. */ @@ -380,17 +384,17 @@ write_node (struct node *np) /* Only the low 16 bits of these fields are standard across all ext2 implementations. */ - di->i_mode = st->st_mode & 0xFFFF & ~S_ITRANS; - di->i_uid = st->st_uid & 0xFFFF; - di->i_gid = st->st_gid & 0xFFFF; + di->i_mode = htole16 (st->st_mode & 0xFFFF & ~S_ITRANS); + di->i_uid = htole16 (st->st_uid & 0xFFFF); + di->i_gid = htole16 (st->st_gid & 0xFFFF); - if (sblock->s_creator_os == EXT2_OS_HURD) + if (sblock->s_creator_os == htole32 (EXT2_OS_HURD)) /* If this is a hurd-compatible filesystem, write the high bits too. */ { - di->i_mode_high = (st->st_mode >> 16) & 0xffff & ~S_ITRANS; - di->i_uid_high = st->st_uid >> 16; - di->i_gid_high = st->st_gid >> 16; - di->i_author = st->st_author; + di->i_mode_high = htole16 ((st->st_mode >> 16) & 0xffff & ~S_ITRANS); + di->i_uid_high = htole16 (st->st_uid >> 16); + di->i_gid_high = htole16 (st->st_gid >> 16); + di->i_author = htole32 (st->st_author); } else /* No hurd extensions should be turned on. */ @@ -401,20 +405,20 @@ write_node (struct node *np) assert_backtrace (np->author_tracks_uid && st->st_author == st->st_uid); } - di->i_links_count = st->st_nlink; + di->i_links_count = htole16 (st->st_nlink); - di->i_atime = st->st_atim.tv_sec; + di->i_atime = htole32(st->st_atim.tv_sec); #ifdef not_yet /* ``struct ext2_inode'' doesn't do better than sec. precision yet. */ - di->i_atime.tv_nsec = st->st_atim.tv_nsec; + di->i_atime.tv_nsec = htole32 (st->st_atim.tv_nsec); #endif - di->i_mtime = st->st_mtim.tv_sec; + di->i_mtime = htole32 (st->st_mtim.tv_sec); #ifdef not_yet - di->i_mtime.tv_nsec = st->st_mtim.tv_nsec; + di->i_mtime.tv_nsec = htole32 (st->st_mtim.tv_nsec); #endif - di->i_ctime = st->st_ctim.tv_sec; + di->i_ctime = htole32 (st->st_ctim.tv_sec); #ifdef not_yet - di->i_ctime.tv_nsec = st->st_ctim.tv_nsec; + di->i_ctime.tv_nsec = htole32 (st->st_ctim.tv_nsec); #endif /* Convert generic flags in ST->st_flags to ext2-specific flags in DI @@ -429,25 +433,25 @@ write_node (struct node *np) info->i_flags |= EXT2_NODUMP_FL; if (st->st_flags & UF_IMMUTABLE) info->i_flags |= EXT2_IMMUTABLE_FL; - di->i_flags = info->i_flags; + di->i_flags = htole32 (info->i_flags); if (st->st_mode == 0) /* Set dtime non-zero to indicate a deleted file. We don't clear i_size, i_blocks, and i_translator in this case, to give "undeletion" utilities a chance. */ - di->i_dtime = di->i_mtime; + di->i_dtime = htole32 (di->i_mtime); else { - di->i_dtime = 0; - di->i_size = st->st_size; + di->i_dtime = htole32 (0); + di->i_size = htole32 (st->st_size); if (sizeof (off_t) >= 8 && !S_ISDIR (st->st_mode)) /* 64bit file size */ - di->i_size_high = st->st_size >> 32; - di->i_blocks = st->st_blocks; + di->i_size_high = htole32 (st->st_size >> 32); + di->i_blocks = htole32 (st->st_blocks); } if (S_ISCHR(st->st_mode) || S_ISBLK(st->st_mode)) - di->i_block[0] = st->st_rdev; + di->i_block[0] = htole32 (st->st_rdev); else memcpy (di->i_block, diskfs_node_disknode (np)->info.i_data, EXT2_N_BLOCKS * sizeof di->i_block[0]); @@ -529,13 +533,13 @@ diskfs_set_statfs (struct statfs *st) { st->f_type = FSTYPE_EXT2FS; st->f_bsize = block_size; - st->f_blocks = sblock->s_blocks_count; - st->f_bfree = sblock->s_free_blocks_count; - st->f_bavail = st->f_bfree - sblock->s_r_blocks_count; - if (st->f_bfree < sblock->s_r_blocks_count) + st->f_blocks = le32toh (sblock->s_blocks_count); + st->f_bfree = le32toh (sblock->s_free_blocks_count); + st->f_bavail = st->f_bfree - le32toh (sblock->s_r_blocks_count); + if (st->f_bfree < le32toh (sblock->s_r_blocks_count)) st->f_bavail = 0; - st->f_files = sblock->s_inodes_count; - st->f_ffree = sblock->s_free_inodes_count; + st->f_files = le32toh (sblock->s_inodes_count); + st->f_ffree = le32toh (sblock->s_free_inodes_count); st->f_fsid = getpid (); st->f_namelen = 0; st->f_favail = st->f_ffree; @@ -553,7 +557,7 @@ diskfs_set_translator (struct node *np, const char *name, unsigned namelen, assert_backtrace (!diskfs_readonly); - if (sblock->s_creator_os != EXT2_OS_HURD) + if (sblock->s_creator_os != htole32 (EXT2_OS_HURD)) return EOPNOTSUPP; err = diskfs_catch_exception (); @@ -569,7 +573,7 @@ diskfs_set_translator (struct node *np, const char *name, unsigned namelen, struct ext2_inode *di; di = dino_ref (np->cache_id); - blkno = di->i_translator; + blkno = le32toh (di->i_translator); /* If a legacy translator record found, clear it */ if (blkno) @@ -577,7 +581,7 @@ diskfs_set_translator (struct node *np, const char *name, unsigned namelen, ext2_debug ("Old translator record found, clear it"); /* Clear block for translator going away. */ - di->i_translator = 0; + di->i_translator = htole32 (0); diskfs_node_disknode (np)->info_i_translator = 0; record_global_poke (di); ext2_free_blocks (blkno, 1); @@ -628,7 +632,7 @@ diskfs_set_translator (struct node *np, const char *name, unsigned namelen, return ENAMETOOLONG; di = dino_ref (np->cache_id); - blkno = di->i_translator; + blkno = le32toh (di->i_translator); if (namelen && !blkno) { @@ -648,7 +652,7 @@ diskfs_set_translator (struct node *np, const char *name, unsigned namelen, blkno = ext2_new_block ((diskfs_node_disknode (np)->info.i_block_group * EXT2_BLOCKS_PER_GROUP (sblock)) - + sblock->s_first_data_block, + + le32toh (sblock->s_first_data_block), 0, 0, 0); if (blkno == 0) { @@ -664,7 +668,7 @@ diskfs_set_translator (struct node *np, const char *name, unsigned namelen, np->dn_stat.st_mode = newmode; } - di->i_translator = blkno; + di->i_translator = htole32 (blkno); diskfs_node_disknode (np)->info_i_translator = blkno; record_global_poke (di); @@ -674,7 +678,7 @@ diskfs_set_translator (struct node *np, const char *name, unsigned namelen, else if (!namelen && blkno) { /* Clear block for translator going away. */ - di->i_translator = 0; + di->i_translator = htole32 (0); diskfs_node_disknode (np)->info_i_translator = 0; record_global_poke (di); ext2_free_blocks (blkno, 1); @@ -719,7 +723,7 @@ diskfs_get_translator (struct node *np, char **namep, unsigned *namelen) void *transloc; struct ext2_inode *di; - if (sblock->s_creator_os != EXT2_OS_HURD) + if (sblock->s_creator_os != htole32 (EXT2_OS_HURD)) return EOPNOTSUPP; err = diskfs_catch_exception (); @@ -727,7 +731,7 @@ diskfs_get_translator (struct node *np, char **namep, unsigned *namelen) return err; di = dino_ref (np->cache_id); - blkno = di->i_translator; + blkno = le32toh (di->i_translator); dino_deref (di); /* If an old translator record found, read it firstly */ diff --git a/ext2fs/xattr.c b/ext2fs/xattr.c index ff84a3b9..ab6f5600 100644 --- a/ext2fs/xattr.c +++ b/ext2fs/xattr.c @@ -91,17 +91,17 @@ xattr_entry_hash (struct ext2_xattr_header *header, if (entry->e_value_block == 0 && entry->e_value_size != 0) { - __u32 *value = (__u32 *) ((char *) header + entry->e_value_offs); - for (n = (entry->e_value_size + EXT2_XATTR_ROUND) >> + __u32 *value = (__u32 *) ((char *) header + le16toh (entry->e_value_offs)); + for (n = (le32toh (entry->e_value_size) + EXT2_XATTR_ROUND) >> EXT2_XATTR_PAD_BITS; n; n--) { hash = (hash << VALUE_HASH_SHIFT) ^ (hash >> (8 * sizeof (hash) - VALUE_HASH_SHIFT)) - ^ *value++; + ^ le32toh(*value++); } } - entry->e_hash = hash; + entry->e_hash = htole32 (hash); } @@ -127,7 +127,7 @@ xattr_entry_rehash (struct ext2_xattr_header *header, position = EXT2_XATTR_ENTRY_FIRST (header); while (!EXT2_XATTR_ENTRY_LAST (position)) { - if (position->e_hash == 0) + if (le32toh (position->e_hash) == 0) { /* Block is not shared if an entry's hash value == 0 */ hash = 0; @@ -136,12 +136,12 @@ xattr_entry_rehash (struct ext2_xattr_header *header, hash = (hash << BLOCK_HASH_SHIFT) ^ (hash >> (8 * sizeof (hash) - BLOCK_HASH_SHIFT)) - ^ position->e_hash; + ^ le32toh (position->e_hash); position = EXT2_XATTR_ENTRY_NEXT (position); } - header->h_hash = hash; + header->h_hash = htole32 (hash); } @@ -237,14 +237,14 @@ xattr_entry_get (void *block, struct ext2_xattr_entry *entry, if (value) { - if (*len < entry->e_value_size) + if (*len < le32toh (entry->e_value_size)) { return ERANGE; } - memcpy (value, block + entry->e_value_offs, entry->e_value_size); + memcpy (value, block + le16toh (entry->e_value_offs), le32toh (entry->e_value_size)); } - *len = entry->e_value_size; + *len = le32toh (entry->e_value_size); return 0; } @@ -295,13 +295,13 @@ xattr_entry_create (struct ext2_xattr_header *header, position->e_name_len = name_len; position->e_name_index = index; - position->e_value_offs = end + rest - value_size; + position->e_value_offs = htole16 (end + rest - value_size); position->e_value_block = 0; - position->e_value_size = len; + position->e_value_size = htole32 (len); strncpy (position->e_name, name, name_len); - memcpy ((char *) header + position->e_value_offs, value, len); - memset ((char *) header + position->e_value_offs + len, 0, + memcpy ((char *) header + le16toh (position->e_value_offs), value, len); + memset ((char *) header + le16toh (position->e_value_offs) + len, 0, value_size - len); return 0; @@ -325,9 +325,9 @@ xattr_entry_remove (struct ext2_xattr_header *header, struct ext2_xattr_entry *entry; /* Remove the value */ - size = EXT2_XATTR_ALIGN (position->e_value_size); + size = EXT2_XATTR_ALIGN (le32toh (position->e_value_size)); start = EXT2_XATTR_ENTRY_OFFSET (header, last) + rest; - end = position->e_value_offs; + end = le16toh (position->e_value_offs); memmove ((char *) header + start + size, (char *) header + start, end - start); @@ -337,8 +337,8 @@ xattr_entry_remove (struct ext2_xattr_header *header, entry = EXT2_XATTR_ENTRY_FIRST (header); while (!EXT2_XATTR_ENTRY_LAST (entry)) { - if (entry->e_value_offs < end) - entry->e_value_offs += size; + if (le16toh (entry->e_value_offs) < end) + entry->e_value_offs = htole16 (le16toh (entry->e_value_offs) + size); entry = EXT2_XATTR_ENTRY_NEXT (entry); } @@ -372,7 +372,7 @@ xattr_entry_replace (struct ext2_xattr_header *header, size_t old_size; size_t new_size; - old_size = EXT2_XATTR_ALIGN (position->e_value_size); + old_size = EXT2_XATTR_ALIGN (le32toh (position->e_value_size)); new_size = EXT2_XATTR_ALIGN (len); if (rest < 4 || new_size - old_size > rest - 4) @@ -385,7 +385,7 @@ xattr_entry_replace (struct ext2_xattr_header *header, struct ext2_xattr_entry *entry; start = EXT2_XATTR_ENTRY_OFFSET (header, last) + rest; - end = position->e_value_offs; + end = le16toh (position->e_value_offs); /* Remove the old value */ memmove ((char *) header + start + old_size, (char *) header + start, @@ -395,19 +395,19 @@ xattr_entry_replace (struct ext2_xattr_header *header, entry = EXT2_XATTR_ENTRY_FIRST (header); while (!EXT2_XATTR_ENTRY_LAST (entry)) { - if (entry->e_value_offs < end) - entry->e_value_offs += old_size; + if (le16toh (entry->e_value_offs) < end) + entry->e_value_offs = htole16 ( le16toh (entry->e_value_offs) + old_size); entry = EXT2_XATTR_ENTRY_NEXT (entry); } - position->e_value_offs = start - (new_size - old_size); + position->e_value_offs = htole16 (start - (new_size - old_size)); } - position->e_value_size = len; + position->e_value_size = htole32 (len); /* Write the new value */ - memcpy ((char *) header + position->e_value_offs, value, len); - memset ((char *) header + position->e_value_offs + len, 0, new_size - len); + memcpy ((char *) header + le16toh (position->e_value_offs), value, len); + memset ((char *) header + le16toh (position->e_value_offs) + len, 0, new_size - len); return 0; @@ -450,14 +450,15 @@ ext2_free_xattr_block (struct node *np) block = disk_cache_block_ref (blkno); header = EXT2_XATTR_HEADER (block); - if (header->h_magic != EXT2_XATTR_BLOCK_MAGIC || header->h_blocks != 1) + if (header->h_magic != htole32 (EXT2_XATTR_BLOCK_MAGIC) + || header->h_blocks != htole32 (1)) { ext2_warning ("Invalid extended attribute block."); err = EIO; goto cleanup; } - if (header->h_refcount == 1) + if (le32toh (header->h_refcount) == 1) { ext2_debug("free block %d", blkno); @@ -470,9 +471,9 @@ ext2_free_xattr_block (struct node *np) } else { - ext2_debug("h_refcount: %d", header->h_refcount); + ext2_debug("h_refcount: %d", le32toh (header->h_refcount)); - header->h_refcount--; + header->h_refcount = htole32 (le32toh (header->h_refcount) - 1); record_global_poke (block); } @@ -535,7 +536,8 @@ ext2_list_xattr (struct node *np, char *buffer, size_t *len) block = disk_cache_block_ref (blkno); header = EXT2_XATTR_HEADER (block); - if (header->h_magic != EXT2_XATTR_BLOCK_MAGIC || header->h_blocks != 1) + if (header->h_magic != htole32 (EXT2_XATTR_BLOCK_MAGIC) + || header->h_blocks != htole32 (1)) { ext2_warning ("Invalid extended attribute block."); err = EIO; @@ -609,7 +611,8 @@ ext2_get_xattr (struct node *np, const char *name, char *value, size_t *len) dino_deref (ei); header = EXT2_XATTR_HEADER (block); - if (header->h_magic != EXT2_XATTR_BLOCK_MAGIC || header->h_blocks != 1) + if (header->h_magic != htole32 (EXT2_XATTR_BLOCK_MAGIC) + || header->h_blocks != htole32 (1)) { ext2_warning ("Invalid extended attribute block."); err = EIO; @@ -699,7 +702,7 @@ ext2_set_xattr (struct node *np, const char *name, const char *value, assert_backtrace (!diskfs_readonly); - goal = sblock->s_first_data_block + np->dn->info.i_block_group * + goal = le32toh (sblock->s_first_data_block) + np->dn->info.i_block_group * EXT2_BLOCKS_PER_GROUP (sblock); blkno = ext2_new_block (goal, 0, 0, 0); @@ -713,15 +716,16 @@ ext2_set_xattr (struct node *np, const char *name, const char *value, memset (block, 0, block_size); header = EXT2_XATTR_HEADER (block); - header->h_magic = EXT2_XATTR_BLOCK_MAGIC; - header->h_blocks = 1; - header->h_refcount = 1; + header->h_magic = htole32 (EXT2_XATTR_BLOCK_MAGIC); + header->h_blocks = htole32 (1); + header->h_refcount = htole32 (1); } else { block = disk_cache_block_ref (blkno); header = EXT2_XATTR_HEADER (block); - if (header->h_magic != EXT2_XATTR_BLOCK_MAGIC || header->h_blocks != 1) + if (header->h_magic != htole32 (EXT2_XATTR_BLOCK_MAGIC) + || header->h_blocks != htole32 (1)) { ext2_warning ("Invalid extended attribute block."); err = EIO; @@ -761,7 +765,7 @@ ext2_set_xattr (struct node *np, const char *name, const char *value, break; } - rest -= EXT2_XATTR_ALIGN (entry->e_value_size); + rest -= EXT2_XATTR_ALIGN (le32toh (entry->e_value_size)); entry = EXT2_XATTR_ENTRY_NEXT (entry); } -- cgit v1.2.3