Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

orangefs: Fix kmemleak in orangefs_sysfs_init()

When insert and remove the orangefs module, there are kobjects memory
leaked as below:

unreferenced object 0xffff88810f95af00 (size 64):
comm "insmod", pid 783, jiffies 4294813439 (age 65.512s)
hex dump (first 32 bytes):
a0 83 af 01 81 88 ff ff 08 af 95 0f 81 88 ff ff ................
08 af 95 0f 81 88 ff ff 00 00 00 00 00 00 00 00 ................
backtrace:
[<0000000031ab7788>] kmalloc_trace+0x27/0xa0
[<000000005a6e4dfe>] orangefs_sysfs_init+0x42/0x3a0
[<00000000722645ca>] 0xffffffffa02780fe
[<000000004232d9f7>] do_one_initcall+0x87/0x2a0
[<0000000054f22384>] do_init_module+0xdf/0x320
[<000000003263bdea>] load_module+0x2f98/0x3330
[<0000000052cd4153>] __do_sys_finit_module+0x113/0x1b0
[<00000000250ae02b>] do_syscall_64+0x35/0x80
[<00000000f11c03c7>] entry_SYSCALL_64_after_hwframe+0x46/0xb0

unreferenced object 0xffff88810f95ae80 (size 64):
comm "insmod", pid 783, jiffies 4294813439 (age 65.512s)
hex dump (first 32 bytes):
c8 90 0f 02 81 88 ff ff 88 ae 95 0f 81 88 ff ff ................
88 ae 95 0f 81 88 ff ff 00 00 00 00 00 00 00 00 ................
backtrace:
[<0000000031ab7788>] kmalloc_trace+0x27/0xa0
[<000000001a4841fa>] orangefs_sysfs_init+0xc7/0x3a0
[<00000000722645ca>] 0xffffffffa02780fe
[<000000004232d9f7>] do_one_initcall+0x87/0x2a0
[<0000000054f22384>] do_init_module+0xdf/0x320
[<000000003263bdea>] load_module+0x2f98/0x3330
[<0000000052cd4153>] __do_sys_finit_module+0x113/0x1b0
[<00000000250ae02b>] do_syscall_64+0x35/0x80
[<00000000f11c03c7>] entry_SYSCALL_64_after_hwframe+0x46/0xb0

unreferenced object 0xffff88810f95ae00 (size 64):
comm "insmod", pid 783, jiffies 4294813440 (age 65.511s)
hex dump (first 32 bytes):
60 87 a1 00 81 88 ff ff 08 ae 95 0f 81 88 ff ff `...............
08 ae 95 0f 81 88 ff ff 00 00 00 00 00 00 00 00 ................
backtrace:
[<0000000031ab7788>] kmalloc_trace+0x27/0xa0
[<000000005915e797>] orangefs_sysfs_init+0x12b/0x3a0
[<00000000722645ca>] 0xffffffffa02780fe
[<000000004232d9f7>] do_one_initcall+0x87/0x2a0
[<0000000054f22384>] do_init_module+0xdf/0x320
[<000000003263bdea>] load_module+0x2f98/0x3330
[<0000000052cd4153>] __do_sys_finit_module+0x113/0x1b0
[<00000000250ae02b>] do_syscall_64+0x35/0x80
[<00000000f11c03c7>] entry_SYSCALL_64_after_hwframe+0x46/0xb0

unreferenced object 0xffff88810f95ad80 (size 64):
comm "insmod", pid 783, jiffies 4294813440 (age 65.511s)
hex dump (first 32 bytes):
78 90 0f 02 81 88 ff ff 88 ad 95 0f 81 88 ff ff x...............
88 ad 95 0f 81 88 ff ff 00 00 00 00 00 00 00 00 ................
backtrace:
[<0000000031ab7788>] kmalloc_trace+0x27/0xa0
[<000000007a14eb35>] orangefs_sysfs_init+0x1ac/0x3a0
[<00000000722645ca>] 0xffffffffa02780fe
[<000000004232d9f7>] do_one_initcall+0x87/0x2a0
[<0000000054f22384>] do_init_module+0xdf/0x320
[<000000003263bdea>] load_module+0x2f98/0x3330
[<0000000052cd4153>] __do_sys_finit_module+0x113/0x1b0
[<00000000250ae02b>] do_syscall_64+0x35/0x80
[<00000000f11c03c7>] entry_SYSCALL_64_after_hwframe+0x46/0xb0

unreferenced object 0xffff88810f95ac00 (size 64):
comm "insmod", pid 783, jiffies 4294813440 (age 65.531s)
hex dump (first 32 bytes):
e0 ff 67 02 81 88 ff ff 08 ac 95 0f 81 88 ff ff ..g.............
08 ac 95 0f 81 88 ff ff 00 00 00 00 00 00 00 00 ................
backtrace:
[<0000000031ab7788>] kmalloc_trace+0x27/0xa0
[<000000001f38adcb>] orangefs_sysfs_init+0x291/0x3a0
[<00000000722645ca>] 0xffffffffa02780fe
[<000000004232d9f7>] do_one_initcall+0x87/0x2a0
[<0000000054f22384>] do_init_module+0xdf/0x320
[<000000003263bdea>] load_module+0x2f98/0x3330
[<0000000052cd4153>] __do_sys_finit_module+0x113/0x1b0
[<00000000250ae02b>] do_syscall_64+0x35/0x80
[<00000000f11c03c7>] entry_SYSCALL_64_after_hwframe+0x46/0xb0

unreferenced object 0xffff88810f95ab80 (size 64):
comm "insmod", pid 783, jiffies 4294813441 (age 65.530s)
hex dump (first 32 bytes):
50 bf 2f 02 81 88 ff ff 88 ab 95 0f 81 88 ff ff P./.............
88 ab 95 0f 81 88 ff ff 00 00 00 00 00 00 00 00 ................
backtrace:
[<0000000031ab7788>] kmalloc_trace+0x27/0xa0
[<000000009cc7d95b>] orangefs_sysfs_init+0x2f5/0x3a0
[<00000000722645ca>] 0xffffffffa02780fe
[<000000004232d9f7>] do_one_initcall+0x87/0x2a0
[<0000000054f22384>] do_init_module+0xdf/0x320
[<000000003263bdea>] load_module+0x2f98/0x3330
[<0000000052cd4153>] __do_sys_finit_module+0x113/0x1b0
[<00000000250ae02b>] do_syscall_64+0x35/0x80
[<00000000f11c03c7>] entry_SYSCALL_64_after_hwframe+0x46/0xb0

Should add release function for each kobject_type to free the memory.

Signed-off-by: Zhang Xiaoxu <zhangxiaoxu5@huawei.com>
Signed-off-by: Mike Marshall <hubcap@omnibond.com>

authored by

Zhang Xiaoxu and committed by
Mike Marshall
1f2c0e8a d23417a5

+63 -8
+63 -8
fs/orangefs/orangefs-sysfs.c
··· 896 896 }; 897 897 ATTRIBUTE_GROUPS(orangefs_default); 898 898 899 + static struct kobject *orangefs_obj; 900 + 901 + static void orangefs_obj_release(struct kobject *kobj) 902 + { 903 + kfree(orangefs_obj); 904 + orangefs_obj = NULL; 905 + } 906 + 899 907 static struct kobj_type orangefs_ktype = { 900 908 .sysfs_ops = &orangefs_sysfs_ops, 901 909 .default_groups = orangefs_default_groups, 910 + .release = orangefs_obj_release, 902 911 }; 903 912 904 913 static struct orangefs_attribute acache_hard_limit_attribute = ··· 943 934 }; 944 935 ATTRIBUTE_GROUPS(acache_orangefs_default); 945 936 937 + static struct kobject *acache_orangefs_obj; 938 + 939 + static void acache_orangefs_obj_release(struct kobject *kobj) 940 + { 941 + kfree(acache_orangefs_obj); 942 + acache_orangefs_obj = NULL; 943 + } 944 + 946 945 static struct kobj_type acache_orangefs_ktype = { 947 946 .sysfs_ops = &orangefs_sysfs_ops, 948 947 .default_groups = acache_orangefs_default_groups, 948 + .release = acache_orangefs_obj_release, 949 949 }; 950 950 951 951 static struct orangefs_attribute capcache_hard_limit_attribute = ··· 990 972 }; 991 973 ATTRIBUTE_GROUPS(capcache_orangefs_default); 992 974 975 + static struct kobject *capcache_orangefs_obj; 976 + 977 + static void capcache_orangefs_obj_release(struct kobject *kobj) 978 + { 979 + kfree(capcache_orangefs_obj); 980 + capcache_orangefs_obj = NULL; 981 + } 982 + 993 983 static struct kobj_type capcache_orangefs_ktype = { 994 984 .sysfs_ops = &orangefs_sysfs_ops, 995 985 .default_groups = capcache_orangefs_default_groups, 986 + .release = capcache_orangefs_obj_release, 996 987 }; 997 988 998 989 static struct orangefs_attribute ccache_hard_limit_attribute = ··· 1037 1010 }; 1038 1011 ATTRIBUTE_GROUPS(ccache_orangefs_default); 1039 1012 1013 + static struct kobject *ccache_orangefs_obj; 1014 + 1015 + static void ccache_orangefs_obj_release(struct kobject *kobj) 1016 + { 1017 + kfree(ccache_orangefs_obj); 1018 + ccache_orangefs_obj = NULL; 1019 + } 1020 + 1040 1021 static struct kobj_type ccache_orangefs_ktype = { 1041 1022 .sysfs_ops = &orangefs_sysfs_ops, 1042 1023 .default_groups = ccache_orangefs_default_groups, 1024 + .release = ccache_orangefs_obj_release, 1043 1025 }; 1044 1026 1045 1027 static struct orangefs_attribute ncache_hard_limit_attribute = ··· 1084 1048 }; 1085 1049 ATTRIBUTE_GROUPS(ncache_orangefs_default); 1086 1050 1051 + static struct kobject *ncache_orangefs_obj; 1052 + 1053 + static void ncache_orangefs_obj_release(struct kobject *kobj) 1054 + { 1055 + kfree(ncache_orangefs_obj); 1056 + ncache_orangefs_obj = NULL; 1057 + } 1058 + 1087 1059 static struct kobj_type ncache_orangefs_ktype = { 1088 1060 .sysfs_ops = &orangefs_sysfs_ops, 1089 1061 .default_groups = ncache_orangefs_default_groups, 1062 + .release = ncache_orangefs_obj_release, 1090 1063 }; 1091 1064 1092 1065 static struct orangefs_attribute pc_acache_attribute = ··· 1124 1079 }; 1125 1080 ATTRIBUTE_GROUPS(pc_orangefs_default); 1126 1081 1082 + static struct kobject *pc_orangefs_obj; 1083 + 1084 + static void pc_orangefs_obj_release(struct kobject *kobj) 1085 + { 1086 + kfree(pc_orangefs_obj); 1087 + pc_orangefs_obj = NULL; 1088 + } 1089 + 1127 1090 static struct kobj_type pc_orangefs_ktype = { 1128 1091 .sysfs_ops = &orangefs_sysfs_ops, 1129 1092 .default_groups = pc_orangefs_default_groups, 1093 + .release = pc_orangefs_obj_release, 1130 1094 }; 1131 1095 1132 1096 static struct orangefs_attribute stats_reads_attribute = ··· 1157 1103 }; 1158 1104 ATTRIBUTE_GROUPS(stats_orangefs_default); 1159 1105 1106 + static struct kobject *stats_orangefs_obj; 1107 + 1108 + static void stats_orangefs_obj_release(struct kobject *kobj) 1109 + { 1110 + kfree(stats_orangefs_obj); 1111 + stats_orangefs_obj = NULL; 1112 + } 1113 + 1160 1114 static struct kobj_type stats_orangefs_ktype = { 1161 1115 .sysfs_ops = &orangefs_sysfs_ops, 1162 1116 .default_groups = stats_orangefs_default_groups, 1117 + .release = stats_orangefs_obj_release, 1163 1118 }; 1164 - 1165 - static struct kobject *orangefs_obj; 1166 - static struct kobject *acache_orangefs_obj; 1167 - static struct kobject *capcache_orangefs_obj; 1168 - static struct kobject *ccache_orangefs_obj; 1169 - static struct kobject *ncache_orangefs_obj; 1170 - static struct kobject *pc_orangefs_obj; 1171 - static struct kobject *stats_orangefs_obj; 1172 1119 1173 1120 int orangefs_sysfs_init(void) 1174 1121 {