In the Linux kernel, the following vulnerability has been resolved:
btrfs: fix memory leak in _addinode_ref()
Line 1169 (#3) allocates a memory chunk for victimname by kmalloc(), but when the function returns in line 1184 (#4) victimname allocated by line 1169 (#3) is not freed, which will lead to a memory leak. There is a similar snippet of code in this function as allocating a memory chunk for victim_name in line 1104 (#1) as well as releasing the memory in line 1116 (#2).
We should kfree() victimname when the return value of backrefin_log() is less than zero and before the function returns in line 1184 (#4).
1057 static inline int _addinoderef(struct btrfstranshandle *trans, 1058 struct btrfsroot *root, 1059 struct btrfspath *path, 1060 struct btrfsroot *logroot, 1061 struct btrfsinode *dir, 1062 struct btrfsinode *inode, 1063 u64 inodeobjectid, u64 parentobjectid, 1064 u64 refindex, char *name, int namelen, 1065 int *search_done) 1066 {
1104 victimname = kmalloc(victimnamelen, GFPNOFS); // #1: kmalloc (victimname-1) 1105 if (!victimname) 1106 return -ENOMEM;
1112 ret = backrefinlog(logroot, &searchkey, 1113 parentobjectid, victimname, 1114 victimnamelen); 1115 if (ret < 0) { 1116 kfree(victimname); // #2: kfree (victimname-1) 1117 return ret; 1118 } else if (!ret) {
1169 victimname = kmalloc(victimnamelen, GFPNOFS); // #3: kmalloc (victimname-2) 1170 if (!victimname) 1171 return -ENOMEM;
1180 ret = backrefinlog(logroot, &searchkey, 1181 parentobjectid, victimname, 1182 victimnamelen); 1183 if (ret < 0) { 1184 return ret; // #4: missing kfree (victim_name-2) 1185 } else if (!ret) {
1241 return 0; 1242 }