Index: sys/fs/ext2fs/ext2_csum.c =================================================================== --- sys/fs/ext2fs/ext2_csum.c +++ sys/fs/ext2fs/ext2_csum.c @@ -201,13 +201,13 @@ dep = ep; top = EXT2_DIRENT_TAIL(ep, ip->i_e2fs->e2fs_bsize); - rec_len = dep->e2d_reclen; + rec_len = le16toh(dep->e2d_reclen); while (rec_len && !(rec_len & 0x3)) { dep = (struct ext2fs_direct_2 *)(((char *)dep) + rec_len); if ((void *)dep >= top) break; - rec_len = dep->e2d_reclen; + rec_len = le16toh(dep->e2d_reclen); } if (dep != top) @@ -263,11 +263,11 @@ struct ext2fs_htree_root_info *root; int count_offset; - if (ep->e2d_reclen == EXT2_BLOCK_SIZE(ip->i_e2fs)) + if (le16toh(ep->e2d_reclen) == EXT2_BLOCK_SIZE(ip->i_e2fs)) count_offset = 8; else if (ep->e2d_reclen == 12) { dp = (struct ext2fs_direct_2 *)(((char *)ep) + 12); - if (dp->e2d_reclen != EXT2_BLOCK_SIZE(ip->i_e2fs) - 12) + if (le16toh(dp->e2d_reclen) != EXT2_BLOCK_SIZE(ip->i_e2fs) - 12) return (NULL); root = (struct ext2fs_htree_root_info *)(((char *)dp + 12)); @@ -590,7 +590,7 @@ E2FS_REV0_INODE_SIZE, offset - E2FS_REV0_INODE_SIZE); if ((EXT2_INODE_SIZE(ip->i_e2fs) > E2FS_REV0_INODE_SIZE && - ei->e2di_extra_isize >= EXT2_INODE_CSUM_HI_EXTRA_END)) { + le16toh(ei->e2di_extra_isize) >= EXT2_INODE_CSUM_HI_EXTRA_END)) { crc = calculate_crc32c(crc, (uint8_t *)&dummy_csum, csum_size); offset += csum_size; @@ -615,12 +615,12 @@ if (!EXT2_HAS_RO_COMPAT_FEATURE(fs, EXT2F_ROCOMPAT_METADATA_CKSUM)) return (0); - provided = ei->e2di_chksum_lo; + provided = le16toh(ei->e2di_chksum_lo); calculated = ext2_ei_csum(ip, ei); if ((EXT2_INODE_SIZE(fs) > E2FS_REV0_INODE_SIZE && - ei->e2di_extra_isize >= EXT2_INODE_CSUM_HI_EXTRA_END)) { - hi = ei->e2di_chksum_hi; + le16toh(ei->e2di_extra_isize) >= EXT2_INODE_CSUM_HI_EXTRA_END)) { + hi = le16toh(ei->e2di_chksum_hi); provided |= hi << 16; } else calculated &= 0xFFFF; @@ -655,10 +655,10 @@ crc = ext2_ei_csum(ip, ei); - ei->e2di_chksum_lo = crc & 0xFFFF; + ei->e2di_chksum_lo = htole16(crc & 0xFFFF); if ((EXT2_INODE_SIZE(fs) > E2FS_REV0_INODE_SIZE && - ei->e2di_extra_isize >= EXT2_INODE_CSUM_HI_EXTRA_END)) - ei->e2di_chksum_hi = crc >> 16; + le16toh(ei->e2di_extra_isize) >= EXT2_INODE_CSUM_HI_EXTRA_END)) + ei->e2di_chksum_hi = htole16(crc >> 16); } static uint16_t Index: sys/fs/ext2fs/ext2_extattr.c =================================================================== --- sys/fs/ext2fs/ext2_extattr.c +++ sys/fs/ext2fs/ext2_extattr.c @@ -216,7 +216,7 @@ /* Check attributes magic value */ header = (struct ext2fs_extattr_dinode_header *)((char *)dinode + - E2FS_REV0_INODE_SIZE + dinode->e2di_extra_isize); + E2FS_REV0_INODE_SIZE + le16toh(dinode->e2di_extra_isize)); if (header->h_magic != EXTATTR_MAGIC) { brelse(bp); @@ -356,7 +356,7 @@ /* Check attributes magic value */ header = (struct ext2fs_extattr_dinode_header *)((char *)dinode + - E2FS_REV0_INODE_SIZE + dinode->e2di_extra_isize); + E2FS_REV0_INODE_SIZE + le16toh(dinode->e2di_extra_isize)); if (header->h_magic != EXTATTR_MAGIC) { brelse(bp); @@ -557,7 +557,7 @@ /* Check attributes magic value */ header = (struct ext2fs_extattr_dinode_header *)((char *)dinode + - E2FS_REV0_INODE_SIZE + dinode->e2di_extra_isize); + E2FS_REV0_INODE_SIZE + le16toh(dinode->e2di_extra_isize)); if (header->h_magic != EXTATTR_MAGIC) { brelse(bp); @@ -920,7 +920,7 @@ /* Check attributes magic value */ header = (struct ext2fs_extattr_dinode_header *)((char *)dinode + - E2FS_REV0_INODE_SIZE + dinode->e2di_extra_isize); + E2FS_REV0_INODE_SIZE + le16toh(dinode->e2di_extra_isize)); if (header->h_magic != EXTATTR_MAGIC) { brelse(bp); @@ -955,7 +955,7 @@ } max_size = EXT2_INODE_SIZE(fs) - E2FS_REV0_INODE_SIZE - - dinode->e2di_extra_isize; + le16toh(dinode->e2di_extra_isize); if (!EXT2_IS_LAST_ENTRY(entry)) { size = ext2_extattr_get_size(EXT2_IFIRST(header), entry, Index: sys/fs/ext2fs/ext2_htree.c =================================================================== --- sys/fs/ext2fs/ext2_htree.c +++ sys/fs/ext2fs/ext2_htree.c @@ -511,11 +511,13 @@ { uint16_t entry_len; - entry_len = EXT2_DIR_REC_LEN(last_entry->e2d_namlen); - last_entry->e2d_reclen = entry_len; + entry_len = EXT2_DIR_REC_LEN(le16toh(last_entry->e2d_namlen)); + last_entry->e2d_reclen = htole16(entry_len); last_entry = (struct ext2fs_direct_2 *)((char *)last_entry + entry_len); - new_entry->e2d_reclen = block + blksize - (char *)last_entry - csum_size; - memcpy(last_entry, new_entry, EXT2_DIR_REC_LEN(new_entry->e2d_namlen)); + new_entry->e2d_reclen = htole16(block + blksize - (char *)last_entry - + csum_size); + memcpy(last_entry, new_entry, + EXT2_DIR_REC_LEN(le16toh(new_entry->e2d_namlen))); } /* @@ -549,8 +551,8 @@ /* * Calculate name hash value for the entry which is to be added. */ - ext2_htree_hash(entry->e2d_name, entry->e2d_namlen, hash_seed, - hash_version, &entry_hash, NULL); + ext2_htree_hash(entry->e2d_name, le16toh(entry->e2d_namlen), + hash_seed, hash_version, &entry_hash, NULL); /* * Fill in directory entry sort descriptors. @@ -559,14 +561,14 @@ if (ep->e2d_ino && ep->e2d_namlen) { entry_cnt++; sort_info--; - sort_info->h_size = ep->e2d_reclen; + sort_info->h_size = le16toh(ep->e2d_reclen); sort_info->h_offset = (char *)ep - block1; - ext2_htree_hash(ep->e2d_name, ep->e2d_namlen, + ext2_htree_hash(ep->e2d_name, le16toh(ep->e2d_namlen), hash_seed, hash_version, &sort_info->h_hash, NULL); } ep = (struct ext2fs_direct_2 *) - ((char *)ep + ep->e2d_reclen); + ((char *)ep + le16toh(ep->e2d_reclen)); } /* @@ -600,7 +602,8 @@ sort_info[k].h_offset); entry_len = EXT2_DIR_REC_LEN(ep->e2d_namlen); memcpy(dest, ep, entry_len); - ((struct ext2fs_direct_2 *)dest)->e2d_reclen = entry_len; + ((struct ext2fs_direct_2 *)dest)->e2d_reclen = + htole16(entry_len); /* Mark directory entry as unused. */ ep->e2d_ino = 0; dest += entry_len; @@ -612,13 +615,13 @@ entry_len = 0; for (offset = 0; offset < blksize - csum_size; ) { ep = (struct ext2fs_direct_2 *)(block1 + offset); - offset += ep->e2d_reclen; + offset += le16toh(ep->e2d_reclen); if (ep->e2d_ino) { last = (struct ext2fs_direct_2 *) ((char *)last + entry_len); - entry_len = EXT2_DIR_REC_LEN(ep->e2d_namlen); + entry_len = EXT2_DIR_REC_LEN(le16toh(ep->e2d_namlen)); memcpy((void *)last, (void *)ep, entry_len); - last->e2d_reclen = entry_len; + last->e2d_reclen = htole16(entry_len); } } @@ -628,14 +631,14 @@ (struct ext2fs_direct_2 *)dest, entry, csum_size); /* Adjust length field of last entry of block 1. */ - last->e2d_reclen = block1 + blksize - (char *)last - csum_size; + last->e2d_reclen = htole16(block1 + blksize - (char *)last - csum_size); } else { /* Add entry to block 1. */ ext2_append_entry(block1, blksize, last, entry, csum_size); /* Adjust length field of last entry of block 2. */ ((struct ext2fs_direct_2 *)dest)->e2d_reclen = - block2 + blksize - dest - csum_size; + htole16(block2 + blksize - dest - csum_size); } if (csum_size) { @@ -679,14 +682,15 @@ root = (struct ext2fs_htree_root *)bp->b_data; dotdot = (struct ext2fs_direct_2 *)((char *)&(root->h_dotdot)); - ep = (struct ext2fs_direct_2 *)((char *)dotdot + dotdot->e2d_reclen); + ep = (struct ext2fs_direct_2 *)((char *)dotdot + + le16toh(dotdot->e2d_reclen)); dirlen = (char *)root + blksize - (char *)ep; memcpy(buf1, ep, dirlen); ep = (struct ext2fs_direct_2 *)buf1; while ((char *)ep < buf1 + dirlen) ep = (struct ext2fs_direct_2 *) - ((char *)ep + ep->e2d_reclen); - ep->e2d_reclen = buf1 + blksize - (char *)ep; + ((char *)ep + le16toh(ep->e2d_reclen)); + ep->e2d_reclen = htole16(buf1 + blksize - (char *)ep); dp->i_flag |= IN_E3INDEX; @@ -804,7 +808,7 @@ dst_node = (struct ext2fs_htree_node *)newidxblock; memset(&dst_node->h_fake_dirent, 0, sizeof(dst_node->h_fake_dirent)); - dst_node->h_fake_dirent.e2d_reclen = blksize; + dst_node->h_fake_dirent.e2d_reclen = htole32(blksize); cursize = roundup(ip->i_size, blksize); dirsize = cursize + blksize; Index: sys/fs/ext2fs/ext2_inode_cnv.c =================================================================== --- sys/fs/ext2fs/ext2_inode_cnv.c +++ sys/fs/ext2fs/ext2_inode_cnv.c @@ -49,9 +49,6 @@ */ SDT_PROBE_DEFINE2(ext2fs, , trace, inode_cnv, "int", "char*"); -#define XTIME_TO_NSEC(x) ((x & EXT3_NSEC_MASK) >> 2) -#define NSEC_TO_XTIME(t) (le32toh(t << 2) & EXT3_NSEC_MASK) - #ifdef EXT2FS_PRINT_EXTENTS void ext2_print_inode(struct inode *in) @@ -94,13 +91,19 @@ } #endif /* EXT2FS_PRINT_EXTENTS */ + +#define XTIME_TO_NSEC(x) ((le32toh(x) & EXT3_NSEC_MASK) >> 2) + /* - * raw ext2 inode to inode + * raw ext2 inode LE to host inode conversion */ int ext2_ei2i(struct ext2fs_dinode *ei, struct inode *ip) { struct m_ext2fs *fs = ip->i_e2fs; + uint32_t ei_flags_le; + uint16_t ei_extra_isize_le; + int i; if ((ip->i_number < EXT2_FIRST_INO(fs) && ip->i_number != EXT2_ROOTINO) || (ip->i_number < EXT2_ROOTINO) || @@ -109,16 +112,17 @@ return (EINVAL); } - if (ip->i_number == EXT2_ROOTINO && ei->e2di_nlink == 0) { + ip->i_nlink = le16toh(ei->e2di_nlink); + if (ip->i_number == EXT2_ROOTINO && ip->i_nlink == 0) { SDT_PROBE2(ext2fs, , trace, inode_cnv, 1, "root inode unallocated"); return (EINVAL); } - ip->i_nlink = ei->e2di_nlink; /* Check extra inode size */ + ei_extra_isize_le = le16toh(ei->e2di_extra_isize); if (EXT2_INODE_SIZE(fs) > E2FS_REV0_INODE_SIZE) { - if (E2FS_REV0_INODE_SIZE + ei->e2di_extra_isize > - EXT2_INODE_SIZE(fs) || (ei->e2di_extra_isize & 3)) { + if (E2FS_REV0_INODE_SIZE + ei_extra_isize_le > + EXT2_INODE_SIZE(fs) || (ei_extra_isize_le & 3)) { SDT_PROBE2(ext2fs, , trace, inode_cnv, 1, "bad extra inode size"); return (EINVAL); @@ -131,75 +135,83 @@ * setting i_mode to zero - why ? I can see that this might lead to * problems in an undelete. */ - ip->i_mode = ei->e2di_nlink ? ei->e2di_mode : 0; - ip->i_size = ei->e2di_size; + ip->i_mode = ip->i_nlink ? le16toh(ei->e2di_mode) : 0; + ip->i_size = le32toh(ei->e2di_size); if (S_ISREG(ip->i_mode)) - ip->i_size |= ((u_int64_t)ei->e2di_size_high) << 32; - ip->i_atime = ei->e2di_atime; - ip->i_mtime = ei->e2di_mtime; - ip->i_ctime = ei->e2di_ctime; + ip->i_size |= le64toh(ei->e2di_size_high) << 32; + ip->i_atime = le32toh(ei->e2di_atime); + ip->i_mtime = le32toh(ei->e2di_mtime); + ip->i_ctime = le32toh(ei->e2di_ctime); if (E2DI_HAS_XTIME(ip)) { ip->i_atimensec = XTIME_TO_NSEC(ei->e2di_atime_extra); ip->i_mtimensec = XTIME_TO_NSEC(ei->e2di_mtime_extra); ip->i_ctimensec = XTIME_TO_NSEC(ei->e2di_ctime_extra); - ip->i_birthtime = ei->e2di_crtime; + ip->i_birthtime = le32toh(ei->e2di_crtime); ip->i_birthnsec = XTIME_TO_NSEC(ei->e2di_crtime_extra); } ip->i_flags = 0; - ip->i_flags |= (ei->e2di_flags & EXT2_APPEND) ? SF_APPEND : 0; - ip->i_flags |= (ei->e2di_flags & EXT2_IMMUTABLE) ? SF_IMMUTABLE : 0; - ip->i_flags |= (ei->e2di_flags & EXT2_NODUMP) ? UF_NODUMP : 0; - ip->i_flag |= (ei->e2di_flags & EXT3_INDEX) ? IN_E3INDEX : 0; - ip->i_flag |= (ei->e2di_flags & EXT4_EXTENTS) ? IN_E4EXTENTS : 0; - ip->i_blocks = ei->e2di_nblock; - ip->i_facl = ei->e2di_facl; + ei_flags_le = le32toh(ei->e2di_flags); + ip->i_flags |= (ei_flags_le & EXT2_APPEND) ? SF_APPEND : 0; + ip->i_flags |= (ei_flags_le & EXT2_IMMUTABLE) ? SF_IMMUTABLE : 0; + ip->i_flags |= (ei_flags_le & EXT2_NODUMP) ? UF_NODUMP : 0; + ip->i_flag |= (ei_flags_le & EXT3_INDEX) ? IN_E3INDEX : 0; + ip->i_flag |= (ei_flags_le & EXT4_EXTENTS) ? IN_E4EXTENTS : 0; + ip->i_blocks = le32toh(ei->e2di_nblock); + ip->i_facl = le32toh(ei->e2di_facl); if (E2DI_HAS_HUGE_FILE(ip)) { - ip->i_blocks |= (uint64_t)ei->e2di_nblock_high << 32; - ip->i_facl |= (uint64_t)ei->e2di_facl_high << 32; - if (ei->e2di_flags & EXT4_HUGE_FILE) + ip->i_blocks |= (uint64_t)le16toh(ei->e2di_nblock_high) << 32; + ip->i_facl |= (uint64_t)le16toh(ei->e2di_facl_high) << 32; + if (ei_flags_le & EXT4_HUGE_FILE) ip->i_blocks = fsbtodb(ip->i_e2fs, ip->i_blocks); } - ip->i_gen = ei->e2di_gen; - ip->i_uid = ei->e2di_uid; - ip->i_gid = ei->e2di_gid; - ip->i_uid |= (uint32_t)ei->e2di_uid_high << 16; - ip->i_gid |= (uint32_t)ei->e2di_gid_high << 16; + ip->i_gen = le32toh(ei->e2di_gen); + ip->i_uid = le16toh(ei->e2di_uid); + ip->i_gid = le16toh(ei->e2di_gid); + ip->i_uid |= (uint32_t)le16toh(ei->e2di_uid_high) << 16; + ip->i_gid |= (uint32_t)le16toh(ei->e2di_gid_high) << 16; - memcpy(ip->i_data, ei->e2di_blocks, sizeof(ei->e2di_blocks)); + for (i = 0; i < EXT2_NDADDR; i++) + ip->i_db[i] = le32toh(ei->e2di_blocks[i]); + for (i = 0; i < EXT2_NIADDR; i++) + ip->i_ib[i] = le32toh(ei->e2di_blocks[EXT2_NDIR_BLOCKS + i]); /* Verify inode csum. */ return (ext2_ei_csum_verify(ip, ei)); } +#define NSEC_TO_XTIME(t) (htole32((t << 2) & EXT3_NSEC_MASK)) + /* - * inode to raw ext2 inode + * inode to raw ext2 LE inode conversion */ int ext2_i2ei(struct inode *ip, struct ext2fs_dinode *ei) { struct m_ext2fs *fs; + int i; fs = ip->i_e2fs; - ei->e2di_mode = ip->i_mode; - ei->e2di_nlink = ip->i_nlink; + ei->e2di_mode = htole16(ip->i_mode); + ei->e2di_nlink = htole16(ip->i_nlink); + ei->e2di_size = htole32(ip->i_size); + if (S_ISREG(ip->i_mode)) + ei->e2di_size_high = htole32(ip->i_size >> 32); + ei->e2di_atime = htole32(ip->i_atime); + ei->e2di_mtime = htole32(ip->i_mtime); + ei->e2di_ctime = htole32(ip->i_ctime); /* * Godmar thinks: if dtime is nonzero, ext2 says this inode has been * deleted, this would correspond to a zero link count */ - ei->e2di_dtime = ei->e2di_nlink ? 0 : ip->i_mtime; - ei->e2di_size = ip->i_size; - if (S_ISREG(ip->i_mode)) - ei->e2di_size_high = ip->i_size >> 32; - ei->e2di_atime = ip->i_atime; - ei->e2di_mtime = ip->i_mtime; - ei->e2di_ctime = ip->i_ctime; + ei->e2di_dtime = ei->e2di_nlink ? 0 : ei->e2di_mtime; if (E2DI_HAS_XTIME(ip)) { ei->e2di_ctime_extra = NSEC_TO_XTIME(ip->i_ctimensec); ei->e2di_mtime_extra = NSEC_TO_XTIME(ip->i_mtimensec); ei->e2di_atime_extra = NSEC_TO_XTIME(ip->i_atimensec); - ei->e2di_crtime = ip->i_birthtime; + ei->e2di_crtime = htole32(ip->i_birthtime); ei->e2di_crtime_extra = NSEC_TO_XTIME(ip->i_birthnsec); } + /* Keep these in host endian for a while since they change a lot */ ei->e2di_flags = 0; ei->e2di_flags |= (ip->i_flags & SF_APPEND) ? EXT2_APPEND : 0; ei->e2di_flags |= (ip->i_flags & SF_IMMUTABLE) ? EXT2_IMMUTABLE : 0; @@ -219,15 +231,23 @@ ei->e2di_nblock = dbtofsb(fs, ip->i_blocks); ei->e2di_nblock_high = dbtofsb(fs, ip->i_blocks) >> 32 & 0xffff; } - ei->e2di_facl = ip->i_facl & 0xffffffff; - ei->e2di_facl_high = ip->i_facl >> 32 & 0xffff; - ei->e2di_gen = ip->i_gen; - ei->e2di_uid = ip->i_uid & 0xffff; - ei->e2di_uid_high = ip->i_uid >> 16 & 0xffff; - ei->e2di_gid = ip->i_gid & 0xffff; - ei->e2di_gid_high = ip->i_gid >> 16 & 0xffff; + /* Catch up with the conversion */ + ei->e2di_flags = htole32(ei->e2di_flags); + ei->e2di_nblock = htole32(ei->e2di_nblock); + ei->e2di_nblock_high = htole16(ei->e2di_nblock_high); - memcpy(ei->e2di_blocks, ip->i_data, sizeof(ei->e2di_blocks)); + ei->e2di_facl = htole32(ip->i_facl & 0xffffffff); + ei->e2di_facl_high = htole16(ip->i_facl >> 32 & 0xffff); + ei->e2di_gen = htole32(ip->i_gen); + ei->e2di_uid = htole16(ip->i_uid & 0xffff); + ei->e2di_uid_high = htole16(ip->i_uid >> 16 & 0xffff); + ei->e2di_gid = htole16(ip->i_gid & 0xffff); + ei->e2di_gid_high = htole16(ip->i_gid >> 16 & 0xffff); + + for (i = 0; i < EXT2_NDADDR; i++) + ei->e2di_blocks[i] = htole32(ip->i_db[i]); + for (i = 0; i < EXT2_NIADDR; i++) + ei->e2di_blocks[EXT2_NDIR_BLOCKS + i] = htole32(ip->i_ib[i]); /* Set inode csum. */ ext2_ei_csum_set(ip, ei); Index: sys/fs/ext2fs/ext2_lookup.c =================================================================== --- sys/fs/ext2fs/ext2_lookup.c +++ sys/fs/ext2fs/ext2_lookup.c @@ -202,8 +202,8 @@ dp = (struct ext2fs_direct_2 *)&bp->b_data[skipcnt]; edp = (struct ext2fs_direct_2 *)&bp->b_data[readcnt]; while (error == 0 && uio->uio_resid > 0 && dp < edp) { - if (dp->e2d_reclen <= offsetof(struct ext2fs_direct_2, - e2d_namlen) || (caddr_t)dp + dp->e2d_reclen > + if (le16toh(dp->e2d_reclen) <= offsetof(struct ext2fs_direct_2, e2d_namlen) || + (caddr_t)dp + le16toh(dp->e2d_reclen) > (caddr_t)edp) { error = EIO; break; @@ -224,20 +224,20 @@ * because ext2fs uses a machine-independent disk * layout. */ - dstdp.d_namlen = dp->e2d_namlen; + dstdp.d_namlen = le16toh(dp->e2d_namlen); dstdp.d_type = FTTODT(dp->e2d_type); if (offsetof(struct ext2fs_direct_2, e2d_namlen) + - dstdp.d_namlen > dp->e2d_reclen) { + dstdp.d_namlen > le16toh(dp->e2d_reclen)) { error = EIO; break; } if (offset < startoffset || dp->e2d_ino == 0) goto nextentry; - dstdp.d_fileno = dp->e2d_ino; + dstdp.d_fileno = le32toh(dp->e2d_ino); dstdp.d_reclen = GENERIC_DIRSIZ(&dstdp); bcopy(dp->e2d_name, dstdp.d_name, dstdp.d_namlen); /* NOTE: d_off is the offset of the *next* entry. */ - dstdp.d_off = offset + dp->e2d_reclen; + dstdp.d_off = offset + le16toh(dp->e2d_reclen); dirent_terminate(&dstdp); if (dstdp.d_reclen > uio->uio_resid) { if (uio->uio_resid == startresid) @@ -253,14 +253,14 @@ if (cookies != NULL) { KASSERT(ncookies > 0, ("ext2_readdir: cookies buffer too small")); - *cookies = offset + dp->e2d_reclen; + *cookies = offset + le16toh(dp->e2d_reclen); cookies++; ncookies--; } nextentry: - offset += dp->e2d_reclen; + offset += le16toh(dp->e2d_reclen); dp = (struct ext2fs_direct_2 *)((caddr_t)dp + - dp->e2d_reclen); + le16toh(dp->e2d_reclen)); } bqrelse(bp); uio->uio_offset = offset; @@ -548,7 +548,8 @@ if (entryoffsetinblock + EXT2_DIR_REC_LEN(ep->e2d_namlen) > dp->i_size) { ext2_dirbad(dp, i_offset, "i_size too small"); - dp->i_size = entryoffsetinblock + EXT2_DIR_REC_LEN(ep->e2d_namlen); + dp->i_size = entryoffsetinblock + + EXT2_DIR_REC_LEN(le16toh(ep->e2d_namlen)); dp->i_flag |= IN_CHANGE | IN_UPDATE; } brelse(bp); @@ -760,14 +761,15 @@ int size = ep->e2d_reclen; if (ep->e2d_ino != 0) - size -= EXT2_DIR_REC_LEN(ep->e2d_namlen); + size -= + EXT2_DIR_REC_LEN(le16toh(ep->e2d_namlen)); else if (ext2_is_dirent_tail(ip, ep)) size -= sizeof(struct ext2fs_direct_tail); if (size > 0) { if (size >= ssp->slotneeded) { ssp->slotstatus = FOUND; ssp->slotoffset = *offp; - ssp->slotsize = ep->e2d_reclen; + ssp->slotsize = le16toh(ep->e2d_reclen); } else if (ssp->slotstatus == NONE) { ssp->slotfreespace += size; if (ssp->slotoffset == -1) @@ -775,7 +777,7 @@ if (ssp->slotfreespace >= ssp->slotneeded) { ssp->slotstatus = COMPACT; ssp->slotsize = *offp + - ep->e2d_reclen - + le16toh(ep->e2d_reclen) - ssp->slotoffset; } } @@ -785,7 +787,7 @@ * Check for a name match. */ if (ep->e2d_ino) { - namlen = ep->e2d_namlen; + namlen = le16toh(ep->e2d_namlen); if (namlen == namelen && !bcmp(name, ep->e2d_name, (unsigned)namlen)) { /* @@ -798,8 +800,8 @@ } } *prevoffp = *offp; - *offp += ep->e2d_reclen; - offset += ep->e2d_reclen; + *offp += le16toh(ep->e2d_reclen); + offset += le16toh(ep->e2d_reclen); *entryoffsetinblockp = offset; if (ep->e2d_ino) *endusefulp = *offp; @@ -846,13 +848,13 @@ char *error_msg = NULL; - if (de->e2d_reclen < EXT2_DIR_REC_LEN(1)) + if (le16toh(de->e2d_reclen) < EXT2_DIR_REC_LEN(1)) error_msg = "rec_len is smaller than minimal"; - else if (de->e2d_reclen % 4 != 0) + else if (le16toh(de->e2d_reclen) % 4 != 0) error_msg = "rec_len % 4 != 0"; - else if (de->e2d_reclen < EXT2_DIR_REC_LEN(de->e2d_namlen)) + else if (le16toh(de->e2d_reclen) < EXT2_DIR_REC_LEN(le16toh(de->e2d_namlen))) error_msg = "reclen is too small for name_len"; - else if (entryoffsetinblock + de->e2d_reclen > DIRBLKSIZ) + else if (entryoffsetinblock + le16toh(de->e2d_reclen)> DIRBLKSIZ) error_msg = "directory entry across blocks"; /* else LATER if (de->inode > dir->i_sb->u.ext2_sb.s_es->s_inodes_count) @@ -862,7 +864,8 @@ if (error_msg != NULL) { SDT_PROBE5(ext2fs, , trace, ext2_dirbadentry_error, error_msg, entryoffsetinblock, - de->e2d_ino, de->e2d_reclen, de->e2d_namlen); + le32toh(de->e2d_ino), le16toh(de->e2d_reclen), + le16toh(de->e2d_namlen)); } return error_msg == NULL ? 0 : 1; } @@ -889,13 +892,14 @@ if (EXT2_HAS_RO_COMPAT_FEATURE(dp->i_e2fs, EXT2F_ROCOMPAT_METADATA_CKSUM)) { - entry->e2d_reclen = dirblksize - sizeof(struct ext2fs_direct_tail); + entry->e2d_reclen = htole16 (dirblksize - + sizeof(struct ext2fs_direct_tail)); buf = malloc(dirblksize, M_TEMP, M_WAITOK); if (!buf) { error = ENOMEM; goto out; } - memcpy(buf, entry, EXT2_DIR_REC_LEN(entry->e2d_namlen)); + memcpy(buf, entry, EXT2_DIR_REC_LEN(htole16(entry->e2d_namlen))); ext2_init_dirent_tail(EXT2_DIRENT_TAIL(buf, dirblksize)); ext2_dirent_csum_set(dp, (struct ext2fs_direct_2 *)buf); @@ -906,7 +910,7 @@ } else { entry->e2d_reclen = dirblksize; auio.uio_offset = dp->i_offset; - auio.uio_resid = EXT2_DIR_REC_LEN(entry->e2d_namlen); + auio.uio_resid = EXT2_DIR_REC_LEN(htole16(entry->e2d_namlen)); aiov.iov_len = auio.uio_resid; aiov.iov_base = (caddr_t)entry; } @@ -951,13 +955,13 @@ panic("ext2_direnter: missing name"); #endif dp = VTOI(dvp); - newdir.e2d_ino = ip->i_number; - newdir.e2d_namlen = cnp->cn_namelen; + newdir.e2d_ino = htole32(ip->i_number); + newdir.e2d_namlen = htole16(cnp->cn_namelen); if (EXT2_HAS_INCOMPAT_FEATURE(ip->i_e2fs, EXT2F_INCOMPAT_FTYPE)) - newdir.e2d_type = DTTOFT(IFTODT(ip->i_mode)); + newdir.e2d_type = htole16(DTTOFT(IFTODT(ip->i_mode))); else - newdir.e2d_type = EXT2_FT_UNKNOWN; + newdir.e2d_type = htole16(EXT2_FT_UNKNOWN); bcopy(cnp->cn_nameptr, newdir.e2d_name, (unsigned)cnp->cn_namelen + 1); if (ext2_htree_has_idx(dp)) { @@ -1044,23 +1048,23 @@ * dp->i_offset + dp->i_count would yield the * space. */ - newentrysize = EXT2_DIR_REC_LEN(entry->e2d_namlen); + newentrysize = EXT2_DIR_REC_LEN(le16toh(entry->e2d_namlen)); ep = (struct ext2fs_direct_2 *)dirbuf; - dsize = EXT2_DIR_REC_LEN(ep->e2d_namlen); - spacefree = ep->e2d_reclen - dsize; - for (loc = ep->e2d_reclen; loc < dp->i_count; ) { + dsize = EXT2_DIR_REC_LEN(le16toh(ep->e2d_namlen)); + spacefree = le16toh(ep->e2d_reclen) - dsize; + for (loc = le16toh(ep->e2d_reclen); loc < dp->i_count; ) { nep = (struct ext2fs_direct_2 *)(dirbuf + loc); if (ep->e2d_ino) { /* trim the existing slot */ - ep->e2d_reclen = dsize; + ep->e2d_reclen = htole16(dsize); ep = (struct ext2fs_direct_2 *)((char *)ep + dsize); } else { /* overwrite; nothing there; header is ours */ spacefree += dsize; } - dsize = EXT2_DIR_REC_LEN(nep->e2d_namlen); - spacefree += nep->e2d_reclen - dsize; - loc += nep->e2d_reclen; + dsize = EXT2_DIR_REC_LEN(le16toh(nep->e2d_namlen)); + spacefree += le16toh(nep->e2d_reclen) - dsize; + loc += le16toh(nep->e2d_reclen); bcopy((caddr_t)nep, (caddr_t)ep, dsize); } /* @@ -1070,12 +1074,12 @@ if (ep->e2d_ino == 0) { if (spacefree + dsize < newentrysize) panic("ext2_direnter: compact1"); - entry->e2d_reclen = spacefree + dsize; + entry->e2d_reclen = htole16(spacefree + dsize); } else { if (spacefree < newentrysize) panic("ext2_direnter: compact2"); entry->e2d_reclen = spacefree; - ep->e2d_reclen = dsize; + ep->e2d_reclen = htole16(dsize); ep = (struct ext2fs_direct_2 *)((char *)ep + dsize); } bcopy((caddr_t)entry, (caddr_t)ep, (u_int)newentrysize); @@ -1136,7 +1140,8 @@ if (dp->i_count == 0) rep = ep; else - rep = (struct ext2fs_direct_2 *)((char *)ep + ep->e2d_reclen); + rep = (struct ext2fs_direct_2 *)((char *)ep + + le16toh(ep->e2d_reclen)); ep->e2d_reclen += rep->e2d_reclen; ext2_dirent_csum_set(dp, (struct ext2fs_direct_2 *)bp->b_data); if (DOINGASYNC(dvp) && dp->i_count != 0) @@ -1166,9 +1171,9 @@ ep->e2d_ino = ip->i_number; if (EXT2_HAS_INCOMPAT_FEATURE(ip->i_e2fs, EXT2F_INCOMPAT_FTYPE)) - ep->e2d_type = DTTOFT(IFTODT(ip->i_mode)); + ep->e2d_type = htole16(DTTOFT(IFTODT(ip->i_mode))); else - ep->e2d_type = EXT2_FT_UNKNOWN; + ep->e2d_type = htole16(EXT2_FT_UNKNOWN); ext2_dirent_csum_set(dp, (struct ext2fs_direct_2 *)bp->b_data); error = bwrite(bp); dp->i_flag |= IN_CHANGE | IN_UPDATE; @@ -1194,7 +1199,7 @@ ssize_t count; #define MINDIRSIZ (sizeof(struct dirtemplate) / 2) - for (off = 0; off < ip->i_size; off += dp->e2d_reclen) { + for (off = 0; off < ip->i_size; off += le16toh(dp->e2d_reclen)) { error = vn_rdwr(UIO_READ, ITOV(ip), (caddr_t)dp, MINDIRSIZ, off, UIO_SYSSPACE, IO_NODELOCKED | IO_NOMACCHECK, cred, NOCRED, &count, (struct thread *)0); @@ -1211,7 +1216,7 @@ if (dp->e2d_ino == 0) continue; /* accept only "." and ".." */ - namlen = dp->e2d_namlen; + namlen = htole16(dp->e2d_namlen); if (namlen > 2) return (0); if (dp->e2d_name[0] != '.') @@ -1223,7 +1228,7 @@ */ if (namlen == 1) continue; - if (dp->e2d_name[1] == '.' && dp->e2d_ino == parentino) + if (dp->e2d_name[1] == '.' && le32toh(dp->e2d_ino) == parentino) continue; return (0); }