void *buf;
size_t i, offset;
blk64_t curr_blk;
- int csum_size = 0;
+ int sz, csum_size = 0;
struct buffer_head *bh;
errcode_t err;
jrb->r_header.h_sequence = ext2fs_cpu_to_be32(trans->tid);
offset = sizeof(*jrb);
+ if (JFS_HAS_INCOMPAT_FEATURE(trans->journal,
+ JFS_FEATURE_INCOMPAT_64BIT))
+ sz = 8;
+ else
+ sz = 4;
+
for (i = 0; i < revoke_len; i++) {
/* Block full, write to journal */
- if (offset > trans->journal->j_blocksize - csum_size) {
+ if (offset + sz > trans->journal->j_blocksize - csum_size) {
jrb->r_count = ext2fs_cpu_to_be32(offset);
jbd2_revoke_csum_set(trans->journal, bh);
}
if (JFS_HAS_INCOMPAT_FEATURE(trans->journal,
- JFS_FEATURE_INCOMPAT_64BIT)) {
+ JFS_FEATURE_INCOMPAT_64BIT))
*((__u64 *)(&((char *)buf)[offset])) =
ext2fs_cpu_to_be64(revoke_list[i]);
- offset += 8;
-
- } else {
+ else
*((__u32 *)(&((char *)buf)[offset])) =
ext2fs_cpu_to_be32(revoke_list[i]);
- offset += 4;
- }
+ offset += sz;
}
if (offset > 0) {
{
journal_revoke_header_t *header;
int offset, max;
+ int csum_size = 0;
+ __u32 rcount;
int record_len = 4;
header = (journal_revoke_header_t *) bh->b_data;
offset = sizeof(journal_revoke_header_t);
- max = ext2fs_be32_to_cpu(header->r_count);
+ rcount = ext2fs_be32_to_cpu(header->r_count);
if (!jbd2_revoke_block_csum_verify(journal, header))
return -EINVAL;
+ if (journal_has_csum_v2or3(journal))
+ csum_size = sizeof(struct journal_revoke_tail);
+ if (rcount > journal->j_blocksize - csum_size)
+ return -EINVAL;
+ max = rcount;
+
if (JFS_HAS_INCOMPAT_FEATURE(journal, JFS_FEATURE_INCOMPAT_64BIT))
record_len = 8;
{
int csum_size = 0;
struct buffer_head *descriptor;
- int offset;
+ int sz, offset;
journal_header_t *header;
/* If we are already aborting, this all becomes a noop. We
if (journal_has_csum_v2or3(journal))
csum_size = sizeof(struct journal_revoke_tail);
+ if (JBD2_HAS_INCOMPAT_FEATURE(journal, JBD2_FEATURE_INCOMPAT_64BIT))
+ sz = 8;
+ else
+ sz = 4;
+
/* Make sure we have a descriptor with space left for the record */
if (descriptor) {
- if (offset >= journal->j_blocksize - csum_size) {
+ if (offset + sz > journal->j_blocksize - csum_size) {
flush_descriptor(journal, descriptor, offset, write_op);
descriptor = NULL;
}
*descriptorp = descriptor;
}
- if (JFS_HAS_INCOMPAT_FEATURE(journal, JFS_FEATURE_INCOMPAT_64BIT)) {
- * ((__u64 *)(&descriptor->b_data[offset])) =
- ext2fs_cpu_to_be64(record->blocknr);
- offset += 8;
-
- } else {
- * ((__u32 *)(&descriptor->b_data[offset])) =
- ext2fs_cpu_to_be32(record->blocknr);
- offset += 4;
- }
+ if (JBD2_HAS_INCOMPAT_FEATURE(journal, JBD2_FEATURE_INCOMPAT_64BIT)) {
+ * ((__be64 *)(&descriptor->b_data[offset])) =
+ cpu_to_be64(record->blocknr);
+ else
+ * ((__be32 *)(&descriptor->b_data[offset])) =
+ cpu_to_be32(record->blocknr);
+ offset += sz;
*offsetp = offset;
}
--- /dev/null
+test_filesys: recovering journal
+../e2fsck/e2fsck: Invalid argument while recovering ext3 journal of test_filesys
+
+test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
+
+test_filesys: ********** WARNING: Filesystem still has errors **********
+
+Exit status is 12
--- /dev/null
+test_filesys: recovering journal
+Pass 1: Checking inodes, blocks, and sizes
+Pass 2: Checking directory structure
+Pass 3: Checking directory connectivity
+Pass 4: Checking reference counts
+Pass 5: Checking group summary information
+test_filesys: 11/512 files (9.1% non-contiguous), 1066/2048 blocks
+Exit status is 0
--- /dev/null
+corrupt revoke r_count buffer overflow