[gfs2-utils] 03/03: Make sure i_bh is set after lgfs2_gfs_inode_get()
by pagure@pagure.io
This is an automated email from the git hooks/post-receive script.
andyp pushed a commit to branch master
in repository gfs2-utils.
commit 7ec698b481bdb56c672e691be29f6ba77470beff
Author: Andrew Price <anprice(a)redhat.com>
AuthorDate: Fri Oct 15 12:36:27 2021 +0100
Make sure i_bh is set after lgfs2_gfs_inode_get()
This function accepts a char * instead of a bh and users expect i_bh to
be set as it is in lgfs2_inode_get(). Fixes a segfault when checking
gfs1 filesystems. This is kind of a temporary measure as i_bh should be
removed in future in favour of separately managed i/o.
Signed-off-by: Andrew Price <anprice(a)redhat.com>
---
gfs2/convert/gfs2_convert.c | 1 +
gfs2/fsck/metawalk.c | 4 +++-
2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/gfs2/convert/gfs2_convert.c b/gfs2/convert/gfs2_convert.c
index 99a2fa76..beb71af2 100644
--- a/gfs2/convert/gfs2_convert.c
+++ b/gfs2/convert/gfs2_convert.c
@@ -867,6 +867,7 @@ static int adjust_inode(struct gfs2_sbd *sbp, struct gfs2_buffer_head *bh)
log_crit(_("Error reading inode: %s\n"), strerror(errno));
return -1;
}
+ inode->i_bh = bh;
inode_was_gfs1 = (inode->i_num.in_formal_ino == inode->i_num.in_addr);
/* Fix the inode number: */
diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c
index 4f36fe63..deaa1ed8 100644
--- a/gfs2/fsck/metawalk.c
+++ b/gfs2/fsck/metawalk.c
@@ -284,8 +284,10 @@ struct gfs2_inode *fsck_inode_get(struct gfs2_sbd *sdp, struct rgrp_tree *rgd,
ip = lgfs2_gfs_inode_get(sdp, bh->b_data);
else
ip = lgfs2_inode_get(sdp, bh);
- if (ip)
+ if (ip) {
ip->i_rgd = rgd;
+ ip->i_bh = bh;
+ }
return ip;
}
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
2 years, 8 months
[gfs2-utils] 02/03: libgfs2: Avoid potential gfs/gfs2 superblock
update clash
by pagure@pagure.io
This is an automated email from the git hooks/post-receive script.
andyp pushed a commit to branch master
in repository gfs2-utils.
commit 8cea89ce70357634586acd420e8a9142dead6e59
Author: Andrew Price <anprice(a)redhat.com>
AuthorDate: Wed Oct 6 15:30:28 2021 +0100
libgfs2: Avoid potential gfs/gfs2 superblock update clash
gfs1's sb_jindex_di field is at the same offset as gfs2's sb_master_dir.
Writing both in lgfs2_sb_out() means that one can overwrite the other
when the values are different. To avoid that possibility, make them a
union and add unit tests that cover this scenario.
Signed-off-by: Andrew Price <anprice(a)redhat.com>
---
gfs2/libgfs2/check_libgfs2.c | 2 +
gfs2/libgfs2/check_ondisk.c | 155 +++++++++++++++++++++++++++++++++++++++++++
gfs2/libgfs2/checks.am | 2 +-
gfs2/libgfs2/libgfs2.h | 7 +-
4 files changed, 163 insertions(+), 3 deletions(-)
diff --git a/gfs2/libgfs2/check_libgfs2.c b/gfs2/libgfs2/check_libgfs2.c
index 0cfe08f2..a5d9df52 100644
--- a/gfs2/libgfs2/check_libgfs2.c
+++ b/gfs2/libgfs2/check_libgfs2.c
@@ -5,6 +5,7 @@
void print_it(const char *label, const char *fmt, const char *fmt2, ...) {}
extern Suite *suite_meta(void);
+extern Suite *suite_ondisk(void);
extern Suite *suite_rgrp(void);
int main(void)
@@ -12,6 +13,7 @@ int main(void)
int failures;
SRunner *runner = srunner_create(suite_meta());
+ srunner_add_suite(runner, suite_ondisk());
srunner_add_suite(runner, suite_rgrp());
srunner_run_all(runner, CK_ENV);
diff --git a/gfs2/libgfs2/check_ondisk.c b/gfs2/libgfs2/check_ondisk.c
new file mode 100644
index 00000000..6c8dd065
--- /dev/null
+++ b/gfs2/libgfs2/check_ondisk.c
@@ -0,0 +1,155 @@
+#include <check.h>
+#include "libgfs2.h"
+
+Suite *suite_ondisk(void);
+
+START_TEST(check_sb_in)
+{
+ char buf[sizeof(struct gfs2_sb)];
+ char namechk[GFS2_LOCKNAME_LEN];
+ struct gfs2_sbd sbd;
+ char uuidchk[sizeof(sbd.sd_uuid)];
+
+ memset(buf, 0x5a, sizeof(buf));
+ memset(namechk, 0x5a, GFS2_LOCKNAME_LEN);
+ memset(uuidchk, 0x5a, sizeof(sbd.sd_uuid));
+ memset(&sbd, 0, sizeof(sbd));
+
+ lgfs2_sb_in(&sbd, buf);
+ /* Compare each field individually to find exactly where any bugs are */
+ ck_assert(sbd.sd_fs_format == 0x5a5a5a5a);
+ ck_assert(sbd.sd_multihost_format == 0x5a5a5a5a);
+ ck_assert(sbd.sd_flags == 0x5a5a5a5a);
+ ck_assert(sbd.sd_bsize == 0x5a5a5a5a);
+ ck_assert(sbd.sd_bsize_shift == 0x5a5a5a5a);
+ ck_assert(sbd.sd_seg_size == 0x5a5a5a5a);
+ ck_assert(sbd.sd_meta_dir.in_formal_ino == 0x5a5a5a5a5a5a5a5a);
+ ck_assert(sbd.sd_meta_dir.in_addr == 0x5a5a5a5a5a5a5a5a);
+ ck_assert(sbd.sd_root_dir.in_formal_ino == 0x5a5a5a5a5a5a5a5a);
+ ck_assert(sbd.sd_root_dir.in_addr == 0x5a5a5a5a5a5a5a5a);
+ ck_assert(memcmp(sbd.sd_lockproto, namechk, GFS2_LOCKNAME_LEN) == 0);
+ ck_assert(memcmp(sbd.sd_locktable, namechk, GFS2_LOCKNAME_LEN) == 0);
+ ck_assert(sbd.sd_jindex_di.in_formal_ino == 0x5a5a5a5a5a5a5a5a);
+ ck_assert(sbd.sd_jindex_di.in_addr == 0x5a5a5a5a5a5a5a5a);
+ ck_assert(sbd.sd_rindex_di.in_formal_ino == 0x5a5a5a5a5a5a5a5a);
+ ck_assert(sbd.sd_rindex_di.in_addr == 0x5a5a5a5a5a5a5a5a);
+ ck_assert(sbd.sd_quota_di.in_formal_ino == 0x5a5a5a5a5a5a5a5a);
+ ck_assert(sbd.sd_quota_di.in_addr == 0x5a5a5a5a5a5a5a5a);
+ ck_assert(sbd.sd_license_di.in_formal_ino == 0x5a5a5a5a5a5a5a5a);
+ ck_assert(sbd.sd_license_di.in_addr == 0x5a5a5a5a5a5a5a5a);
+ ck_assert(memcmp(sbd.sd_uuid, uuidchk, sizeof(sbd.sd_uuid)) == 0);
+}
+END_TEST
+
+START_TEST(check_sb1_out)
+{
+ char namechk[GFS2_LOCKNAME_LEN];
+ char buf[sizeof(struct gfs_sb)];
+ struct gfs2_sbd sbd;
+ struct gfs_sb *sb;
+
+ memset(namechk, 0x5a, GFS2_LOCKNAME_LEN);
+
+ /* 1. If only the gfs1 fields are set, the sb must be filled */
+ memset(buf, 0, sizeof(buf));
+ memset(&sbd, 0, sizeof(sbd));
+
+ sbd.sd_fs_format = 0x5a5a5a51;
+ sbd.sd_multihost_format = 0x5a5a5a52;
+ sbd.sd_flags = 0x5a5a5a53;
+ sbd.sd_bsize = 0x5a5a5a54;
+ sbd.sd_bsize_shift = 0x5a5a5a55;
+ sbd.sd_seg_size = 0x5a5a5a56;
+ sbd.sd_jindex_di.in_formal_ino = 0x5a5a5a5a5a5a5a57;
+ sbd.sd_jindex_di.in_addr = 0x5a5a5a5a5a5a5a58;
+ sbd.sd_rindex_di.in_formal_ino = 0x5a5a5a5a5a5a5a59;
+ sbd.sd_rindex_di.in_addr = 0x5a5a5a5a5a5a5a5a;
+ sbd.sd_root_dir.in_formal_ino = 0x5a5a5a5a5a5a5a5b;
+ sbd.sd_root_dir.in_addr = 0x5a5a5a5a5a5a5a5c;
+ memset(sbd.sd_lockproto, 0x5a, sizeof(sbd.sd_lockproto));
+ memset(sbd.sd_locktable, 0x5a, sizeof(sbd.sd_locktable));
+ sbd.sd_quota_di.in_formal_ino = 0x5a5a5a5a5a5a5a5d;
+ sbd.sd_quota_di.in_addr = 0x5a5a5a5a5a5a5a5e;
+ sbd.sd_license_di.in_formal_ino = 0x5a5a5a5a5a5a5a5f;
+ sbd.sd_license_di.in_addr = 0x5a5a5a5a5a5a5a50;
+
+ lgfs2_sb_out(&sbd, buf);
+
+ sb = (struct gfs_sb *)buf;
+ ck_assert(be32_to_cpu(sb->sb_fs_format) == 0x5a5a5a51);
+ ck_assert(be32_to_cpu(sb->sb_multihost_format) == 0x5a5a5a52);
+ ck_assert(be32_to_cpu(sb->sb_flags) == 0x5a5a5a53);
+ ck_assert(be32_to_cpu(sb->sb_bsize) == 0x5a5a5a54);
+ ck_assert(be32_to_cpu(sb->sb_bsize_shift) == 0x5a5a5a55);
+ ck_assert(be32_to_cpu(sb->sb_seg_size) == 0x5a5a5a56);
+ ck_assert(be64_to_cpu(sb->sb_jindex_di.no_formal_ino) == 0x5a5a5a5a5a5a5a57);
+ ck_assert(be64_to_cpu(sb->sb_jindex_di.no_addr) == 0x5a5a5a5a5a5a5a58);
+ ck_assert(be64_to_cpu(sb->sb_rindex_di.no_formal_ino) == 0x5a5a5a5a5a5a5a59);
+ ck_assert(be64_to_cpu(sb->sb_rindex_di.no_addr) == 0x5a5a5a5a5a5a5a5a);
+ ck_assert(be64_to_cpu(sb->sb_root_di.no_formal_ino) == 0x5a5a5a5a5a5a5a5b);
+ ck_assert(be64_to_cpu(sb->sb_root_di.no_addr) == 0x5a5a5a5a5a5a5a5c);
+ ck_assert(memcmp(sb->sb_lockproto, namechk, GFS2_LOCKNAME_LEN) == 0);
+ ck_assert(memcmp(sb->sb_locktable, namechk, GFS2_LOCKNAME_LEN) == 0);
+ ck_assert(be64_to_cpu(sb->sb_quota_di.no_formal_ino) == 0x5a5a5a5a5a5a5a5d);
+ ck_assert(be64_to_cpu(sb->sb_quota_di.no_addr) == 0x5a5a5a5a5a5a5a5e);
+ ck_assert(be64_to_cpu(sb->sb_license_di.no_formal_ino) == 0x5a5a5a5a5a5a5a5f);
+ ck_assert(be64_to_cpu(sb->sb_license_di.no_addr) == 0x5a5a5a5a5a5a5a50);
+}
+END_TEST
+
+START_TEST(check_sb2_out)
+{
+ char buf[sizeof(struct gfs2_sb)];
+ char namechk[GFS2_LOCKNAME_LEN];
+ struct gfs2_sbd sbd;
+ struct gfs2_sb *sb;
+ char uuidchk[sizeof(sbd.sd_uuid)];
+
+ memset(namechk, 0x5a, GFS2_LOCKNAME_LEN);
+ memset(uuidchk, 0x5a, sizeof(sbd.sd_uuid));
+
+ /* 2. If only the gfs2 fields are set, the sb must be filled */
+ memset(buf, 0, sizeof(buf));
+ memset(&sbd, 0, sizeof(sbd));
+
+ sbd.sd_fs_format = 0x5a5a5a50;
+ sbd.sd_multihost_format = 0x5a5a5a51;
+ sbd.sd_bsize = 0x5a5a5a52;
+ sbd.sd_bsize_shift = 0x5a5a5a53;
+ sbd.sd_meta_dir.in_formal_ino = 0x5a5a5a5a5a5a5a54;
+ sbd.sd_meta_dir.in_addr = 0x5a5a5a5a5a5a5a55;
+ sbd.sd_root_dir.in_formal_ino = 0x5a5a5a5a5a5a5a56;
+ sbd.sd_root_dir.in_addr = 0x5a5a5a5a5a5a5a57;
+ memset(sbd.sd_lockproto, 0x5a, sizeof(sbd.sd_lockproto));
+ memset(sbd.sd_locktable, 0x5a, sizeof(sbd.sd_locktable));
+ memset(sbd.sd_uuid, 0x5a, sizeof(sbd.sd_uuid));
+
+ lgfs2_sb_out(&sbd, buf);
+
+ sb = (struct gfs2_sb *)buf;
+ ck_assert(be32_to_cpu(sb->sb_fs_format) == 0x5a5a5a50);
+ ck_assert(be32_to_cpu(sb->sb_multihost_format) == 0x5a5a5a51);
+ ck_assert(be32_to_cpu(sb->sb_bsize) == 0x5a5a5a52);
+ ck_assert(be32_to_cpu(sb->sb_bsize_shift) == 0x5a5a5a53);
+ ck_assert(be64_to_cpu(sb->sb_master_dir.no_formal_ino) == 0x5a5a5a5a5a5a5a54);
+ ck_assert(be64_to_cpu(sb->sb_master_dir.no_addr) == 0x5a5a5a5a5a5a5a55);
+ ck_assert(be64_to_cpu(sb->sb_root_dir.no_formal_ino) == 0x5a5a5a5a5a5a5a56);
+ ck_assert(be64_to_cpu(sb->sb_root_dir.no_addr) == 0x5a5a5a5a5a5a5a57);
+ ck_assert(memcmp(sb->sb_lockproto, namechk, GFS2_LOCKNAME_LEN) == 0);
+ ck_assert(memcmp(sb->sb_locktable, namechk, GFS2_LOCKNAME_LEN) == 0);
+ ck_assert(memcmp(sb->sb_uuid, uuidchk, sizeof(sb->sb_uuid)) == 0);
+}
+END_TEST
+
+Suite *suite_ondisk(void)
+{
+ Suite *s = suite_create("ondisk.c");
+
+ TCase *tc_meta = tcase_create("On-disk structure parsing checks");
+ tcase_add_test(tc_meta, check_sb_in);
+ tcase_add_test(tc_meta, check_sb1_out);
+ tcase_add_test(tc_meta, check_sb2_out);
+ suite_add_tcase(s, tc_meta);
+
+ return s;
+}
diff --git a/gfs2/libgfs2/checks.am b/gfs2/libgfs2/checks.am
index 2a2b7538..18d719ab 100644
--- a/gfs2/libgfs2/checks.am
+++ b/gfs2/libgfs2/checks.am
@@ -7,7 +7,7 @@ check_libgfs2_SOURCES = \
rgrp.c check_rgrp.c \
crc32c.c \
gfs2_disk_hash.c \
- ondisk.c \
+ ondisk.c check_ondisk.c \
buf.c \
device_geometry.c \
fs_ops.c \
diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
index 41f83b94..2b816f3c 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
@@ -325,10 +325,13 @@ struct gfs2_sbd {
uint32_t sd_fs_format;
uint32_t sd_multihost_format;
uint32_t sd_flags; /* gfs1 */
- struct lgfs2_inum sd_meta_dir;
+ /* gfs1's sb_jindex_di is gfs2's sb_master_dir */
+ union {
+ struct lgfs2_inum sd_meta_dir;
+ struct lgfs2_inum sd_jindex_di; /* gfs1 */
+ };
struct lgfs2_inum sd_root_dir;
struct lgfs2_inum sd_rindex_di; /* gfs1 */
- struct lgfs2_inum sd_jindex_di; /* gfs1 */
struct lgfs2_inum sd_quota_di; /* gfs1 */
struct lgfs2_inum sd_license_di; /* gfs1 */
uint32_t sd_bsize_shift;
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
2 years, 8 months
[gfs2-utils] 01/03: gfs2_edit: Fix segfault in hexdump()
by pagure@pagure.io
This is an automated email from the git hooks/post-receive script.
andyp pushed a commit to branch master
in repository gfs2-utils.
commit fc8280d33774e67ef60f58e9c66c7842a46df124
Author: Andrew Price <anprice(a)redhat.com>
AuthorDate: Tue Oct 5 10:54:55 2021 +0100
gfs2_edit: Fix segfault in hexdump()
The S_ISDIR check wasn't in the correct level of parentheses so the
condition could be evaluated when di == NULL, causing a segfault.
Split that clause out to make it more clear and correct the parentheses.
Signed-off-by: Andrew Price <anprice(a)redhat.com>
---
gfs2/edit/hexedit.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/gfs2/edit/hexedit.c b/gfs2/edit/hexedit.c
index 302f0843..798639b5 100644
--- a/gfs2/edit/hexedit.c
+++ b/gfs2/edit/hexedit.c
@@ -624,12 +624,15 @@ static int hexdump(uint64_t startaddr, uint64_t len, int trunc_zeros,
}
if (m && cursor_line) {
const uint32_t block_type = m->mh_type;
+ int isdir;
+
+ isdir = ((block_type == GFS2_METATYPE_DI) &&
+ (((struct gfs2_dinode*)bh->b_data)->di_height ||
+ S_ISDIR(be32_to_cpu(di->di_mode))));
if (block_type == GFS2_METATYPE_IN ||
- block_type == GFS2_METATYPE_LD ||
- ((block_type == GFS2_METATYPE_DI) &&
- ((struct gfs2_dinode*)bh->b_data)->di_height) ||
- S_ISDIR(be32_to_cpu(di->di_mode))) {
+ block_type == GFS2_METATYPE_LD || isdir) {
+
ptroffset = edit_row[dmode] * 16 +
edit_col[dmode];
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
2 years, 8 months
[gfs2-utils] branch master updated (626f14bf -> 7ec698b4)
by pagure@pagure.io
This is an automated email from the git hooks/post-receive script.
andyp pushed a change to branch master
in repository gfs2-utils.
from 626f14bf libgfs2: Add NULL-checking for ip->i_bh in inode_put()
new fc8280d3 gfs2_edit: Fix segfault in hexdump()
new 8cea89ce libgfs2: Avoid potential gfs/gfs2 superblock update clash
new 7ec698b4 Make sure i_bh is set after lgfs2_gfs_inode_get()
The 3 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
Summary of changes:
gfs2/convert/gfs2_convert.c | 1 +
gfs2/edit/hexedit.c | 11 +--
gfs2/fsck/metawalk.c | 4 +-
gfs2/libgfs2/check_libgfs2.c | 2 +
gfs2/libgfs2/check_ondisk.c | 155 +++++++++++++++++++++++++++++++++++++++++++
gfs2/libgfs2/checks.am | 2 +-
gfs2/libgfs2/libgfs2.h | 7 +-
7 files changed, 174 insertions(+), 8 deletions(-)
create mode 100644 gfs2/libgfs2/check_ondisk.c
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
2 years, 8 months
[gfs2-utils] branch master updated: libgfs2: Add NULL-checking for
ip->i_bh in inode_put()
by pagure@pagure.io
This is an automated email from the git hooks/post-receive script.
andyp pushed a commit to branch master
in repository gfs2-utils.
The following commit(s) were added to refs/heads/master by this push:
new 626f14bf libgfs2: Add NULL-checking for ip->i_bh in inode_put()
626f14bf is described below
commit 626f14bfad3eeff2f2ae05c5ffa3da9c7ac8e4e1
Author: Andrew Price <anprice(a)redhat.com>
AuthorDate: Fri Sep 24 12:34:25 2021 +0100
libgfs2: Add NULL-checking for ip->i_bh in inode_put()
Fixes a segfault in fsck.gfs2 when checking gfs1 filesystems and defends
against any other code that might call inode_put() on an inode without a
bh set.
Signed-off-by: Andrew Price <anprice(a)redhat.com>
---
gfs2/libgfs2/fs_ops.c | 23 +++++++++--------------
1 file changed, 9 insertions(+), 14 deletions(-)
diff --git a/gfs2/libgfs2/fs_ops.c b/gfs2/libgfs2/fs_ops.c
index eb695a3e..449873b9 100644
--- a/gfs2/libgfs2/fs_ops.c
+++ b/gfs2/libgfs2/fs_ops.c
@@ -93,21 +93,16 @@ void inode_put(struct gfs2_inode **ip_in)
uint64_t block = ip->i_num.in_addr;
struct gfs2_sbd *sdp = ip->i_sbd;
- if (ip->i_bh->b_modified) {
- lgfs2_dinode_out(ip, ip->i_bh->b_data);
- if (!ip->bh_owned && is_system_inode(sdp, block))
- fprintf(stderr, "Warning: Change made to inode "
- "were discarded.\n");
- /* This is for debugging only: a convenient place to set
- a breakpoint. This means a system inode was modified but
- not written. That's not fatal: some places like
- adjust_inode in gfs2_convert will do this on purpose.
- It can also point out a coding problem, but we don't
- want to raise alarm in the users either. */
+ if (ip->i_bh != NULL) {
+ if (ip->i_bh->b_modified) {
+ lgfs2_dinode_out(ip, ip->i_bh->b_data);
+ if (!ip->bh_owned && is_system_inode(sdp, block))
+ fprintf(stderr, "Warning: Changes made to inode were discarded.\n");
+ }
+ if (ip->bh_owned)
+ brelse(ip->i_bh);
+ ip->i_bh = NULL;
}
- if (ip->bh_owned)
- brelse(ip->i_bh);
- ip->i_bh = NULL;
free(ip);
*ip_in = NULL; /* make sure the memory isn't accessed again */
}
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
2 years, 8 months