[LU-7940] Null pointer may be passed to function ldiskfs_flex_group_add() that may dereference it Created: 29/Mar/16  Updated: 10/Mar/18

Status: Open
Project: Lustre
Component/s: None
Affects Version/s: Lustre 2.9.0
Fix Version/s: None

Type: Bug Priority: Minor
Reporter: Dmitry Eremin (Inactive) Assignee: WC Triage
Resolution: Unresolved Votes: 0
Labels: kw

Severity: 3
Rank (Obsolete): 9223372036854775807

 Description   
1574		int ldiskfs_group_add(struct super_block *sb, struct ldiskfs_new_group_data *input)
1575		{
1576			struct ldiskfs_new_flex_group_data flex_gd;
1577			struct ldiskfs_sb_info *sbi = LDISKFS_SB(sb);
1578			struct ldiskfs_super_block *es = sbi->s_es;
1579			int reserved_gdb = ldiskfs_bg_has_super(sb, input->group) ?
1580				le16_to_cpu(es->s_reserved_gdt_blocks) : 0;
1581			struct inode *inode = NULL;
1582			int gdb_off;
1583			int err;
1584			__u16 bg_flags = 0;
1585		 
1586			gdb_off = input->group % LDISKFS_DESC_PER_BLOCK(sb);
1587		 
1588			if (gdb_off == 0 && !LDISKFS_HAS_RO_COMPAT_FEATURE(sb,
1589							LDISKFS_FEATURE_RO_COMPAT_SPARSE_SUPER)) {
1590				ldiskfs_warning(sb, "Can't resize non-sparse filesystem further");
1591				return -EPERM;
1592			}
1593		 
1594			if (ldiskfs_blocks_count(es) + input->blocks_count <
1595			    ldiskfs_blocks_count(es)) {...}
1599		 
1600			if (le32_to_cpu(es->s_inodes_count) + LDISKFS_INODES_PER_GROUP(sb) <
1601			    le32_to_cpu(es->s_inodes_count)) {...}
1605		 
1606			if (reserved_gdb || gdb_off == 0) {
1607				if (!LDISKFS_HAS_COMPAT_FEATURE(sb,
1608							     LDISKFS_FEATURE_COMPAT_RESIZE_INODE)
1609				    || !le16_to_cpu(es->s_reserved_gdt_blocks)) {...}
1614				inode = ldiskfs_iget(sb, LDISKFS_RESIZE_INO);
1615				if (IS_ERR(inode)) {
1616					ldiskfs_warning(sb, "Error opening resize inode");
1617					return PTR_ERR(inode);
1618				}
1619			}
1620		 
1621		 
1622			err = verify_group_input(sb, input);
1623			if (err)
1624				goto out;
1625		 
1626			err = ldiskfs_alloc_flex_bg_array(sb, input->group + 1);
1627			if (err)
1628				goto out;
1629		 
1630			err = ldiskfs_mb_alloc_groupinfo(sb, input->group + 1);
1631			if (err)
1632				goto out;
1633		 
1634			flex_gd.count = 1;
1635			flex_gd.groups = input;
1636			flex_gd.bg_flags = &bg_flags;
1637			err = ldiskfs_flex_group_add(sb, inode, &flex_gd);
1638		out:
1639			iput(inode);
1640			return err;
1641		} /* ldiskfs_group_add */

TRACEBACK

  • An event which alters the program's state, leading to the defect
    resize.c:1581: 'inode' has been assigned a NULL value.
  • A condition which occurs, leading to the defect
    resize.c:1588: gdb_off==0&& ! ( (LDISKFS_SB(sb) ->s_es->s_feature_ro_compat& ( (_le32) (_u32) (1) ) ) !=0) is false
  • A condition which occurs, leading to the defect
    resize.c:1606: reserved_gdb||gdb_off==0 is false
    • An event which alters the program's state, leading to the defect
      resize.c:1637: 'inode' is dereferenced by passing argument 2 to function 'ldiskfs_flex_group_add'.
    • An event which alters the program's state, leading to the defect
      resize.c:1411: 'resize_inode' is passed to function 'ldiskfs_flex_group_add'.
      • An event which alters the program's state, leading to the defect
        resize.c:1457: 'resize_inode' is dereferenced by passing argument 4 to function 'ldiskfs_add_new_descs'.
      • An event which alters the program's state, leading to the defect
        resize.c:1152: 'resize_inode' is passed to function 'ldiskfs_add_new_descs'.
      • A condition which occurs, leading to the defect
        resize.c:1180: ldiskfs_bg_num_gdb(sb, group) is false
      • A condition which occurs, leading to the defect
        resize.c:1180: !err&&reserved_gdb&&ldiskfs_bg_num_gdb(sb, group) is false
        • An event which alters the program's state, leading to the defect
          resize.c:1185: 'resize_inode' is dereferenced by passing argument 2 to function 'add_new_gdb'.
        • An event which alters the program's state, leading to the defect
          resize.c:753: 'inode' is passed to function 'add_new_gdb'.
        • An event which alters the program's state, leading to the defect
          resize.c:756: 'inode' is explicitly dereferenced.


 Comments   
Comment by Dmitry Eremin (Inactive) [ 29/Mar/16 ]

The same issue in int ldiskfs_resize_fs(struct super_block *sb, ldiskfs_fsblk_t n_blocks_count):

  • Null pointer 'resize_inode' that comes from line 1875 may be passed to function and can be dereferenced there by passing argument 2 to function 'ldiskfs_flex_group_add' at line 2004.
    • An event which alters the program's state, leading to the defect
      resize.c:1875: 'resize_inode' has been assigned a NULL value.
    • A condition which occurs, leading to the defect
      resize.c:1923: ( (LDISKFS_SB(sb) ->s_es->s_feature_compat& ( (_le32) (_u32) (16) ) ) !=0) is false
    • A condition which occurs, leading to the defect
      resize.c:1947: !resize_inode is true
    • A condition which occurs, leading to the defect
      resize.c:1951: resize_inode is false
    • A condition which occurs, leading to the defect
      resize.c:1955: n_blocks_count_retry is false
    • A condition which occurs, leading to the defect
      resize.c:1947: ( !resize_inode&& !meta_bg) ||n_blocks_count==o_blocks_count is false
    • A condition which occurs, leading to the defect
      resize.c:1993: Entering loop, because ldiskfs_setup_next_flex_gd(sb, flex_gd, n_blocks_count, flexbg_size) is true
    • A condition which occurs, leading to the defect
      resize.c:1996: last_update_time is false
    • A condition which occurs, leading to the defect
      resize.c:2002: ldiskfs_alloc_group_tables(sb, flex_gd, flexbg_size) !=0 is false
      • An event which alters the program's state, leading to the defect
        resize.c:2004: 'resize_inode' is dereferenced by passing argument 2 to function 'ldiskfs_flex_group_add'.
Generated at Sat Feb 10 02:13:14 UTC 2024 using Jira 9.4.14#940014-sha1:734e6822bbf0d45eff9af51f82432957f73aa32c.