aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChengyu Song <csong84@gatech.edu>2015-04-14 18:43:44 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2015-04-14 19:48:58 -0400
commite2ac55b6a8e337fac7cc59c6f452caac92ab5ee6 (patch)
tree5f169fe79554f618b350761d7e428be64d7b084a
parent762515a8e9c7ead55539cf96a63dec2363b1df50 (diff)
ocfs2: incorrect check for debugfs returns
debugfs_create_dir and debugfs_create_file may return -ENODEV when debugfs is not configured, so the return value should be checked against ERROR_VALUE as well, otherwise the later dereference of the dentry pointer would crash the kernel. This patch tries to solve this problem by fixing certain checks. However, I have that found other call sites are protected by #ifdef CONFIG_DEBUG_FS. In current implementation, if CONFIG_DEBUG_FS is defined, then the above two functions will never return any ERROR_VALUE. So another possibility to fix this is to surround all the buggy checks/functions with the same #ifdef CONFIG_DEBUG_FS. But I'm not sure if this would break any functionality, as only OCFS2_FS_STATS declares dependency on DEBUG_FS. Signed-off-by: Chengyu Song <csong84@gatech.edu> Cc: Mark Fasheh <mfasheh@suse.com> Cc: Joel Becker <jlbec@evilplan.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--fs/ocfs2/cluster/heartbeat.c42
-rw-r--r--fs/ocfs2/dlmglue.c2
-rw-r--r--fs/ocfs2/super.c9
3 files changed, 37 insertions, 16 deletions
diff --git a/fs/ocfs2/cluster/heartbeat.c b/fs/ocfs2/cluster/heartbeat.c
index 16eff45727ee..8e19b9d7aba8 100644
--- a/fs/ocfs2/cluster/heartbeat.c
+++ b/fs/ocfs2/cluster/heartbeat.c
@@ -1312,7 +1312,9 @@ static int o2hb_debug_init(void)
1312 int ret = -ENOMEM; 1312 int ret = -ENOMEM;
1313 1313
1314 o2hb_debug_dir = debugfs_create_dir(O2HB_DEBUG_DIR, NULL); 1314 o2hb_debug_dir = debugfs_create_dir(O2HB_DEBUG_DIR, NULL);
1315 if (!o2hb_debug_dir) { 1315 if (IS_ERR_OR_NULL(o2hb_debug_dir)) {
1316 ret = o2hb_debug_dir ?
1317 PTR_ERR(o2hb_debug_dir) : -ENOMEM;
1316 mlog_errno(ret); 1318 mlog_errno(ret);
1317 goto bail; 1319 goto bail;
1318 } 1320 }
@@ -1325,7 +1327,9 @@ static int o2hb_debug_init(void)
1325 sizeof(o2hb_live_node_bitmap), 1327 sizeof(o2hb_live_node_bitmap),
1326 O2NM_MAX_NODES, 1328 O2NM_MAX_NODES,
1327 o2hb_live_node_bitmap); 1329 o2hb_live_node_bitmap);
1328 if (!o2hb_debug_livenodes) { 1330 if (IS_ERR_OR_NULL(o2hb_debug_livenodes)) {
1331 ret = o2hb_debug_livenodes ?
1332 PTR_ERR(o2hb_debug_livenodes) : -ENOMEM;
1329 mlog_errno(ret); 1333 mlog_errno(ret);
1330 goto bail; 1334 goto bail;
1331 } 1335 }
@@ -1338,7 +1342,9 @@ static int o2hb_debug_init(void)
1338 sizeof(o2hb_live_region_bitmap), 1342 sizeof(o2hb_live_region_bitmap),
1339 O2NM_MAX_REGIONS, 1343 O2NM_MAX_REGIONS,
1340 o2hb_live_region_bitmap); 1344 o2hb_live_region_bitmap);
1341 if (!o2hb_debug_liveregions) { 1345 if (IS_ERR_OR_NULL(o2hb_debug_liveregions)) {
1346 ret = o2hb_debug_liveregions ?
1347 PTR_ERR(o2hb_debug_liveregions) : -ENOMEM;
1342 mlog_errno(ret); 1348 mlog_errno(ret);
1343 goto bail; 1349 goto bail;
1344 } 1350 }
@@ -1352,7 +1358,9 @@ static int o2hb_debug_init(void)
1352 sizeof(o2hb_quorum_region_bitmap), 1358 sizeof(o2hb_quorum_region_bitmap),
1353 O2NM_MAX_REGIONS, 1359 O2NM_MAX_REGIONS,
1354 o2hb_quorum_region_bitmap); 1360 o2hb_quorum_region_bitmap);
1355 if (!o2hb_debug_quorumregions) { 1361 if (IS_ERR_OR_NULL(o2hb_debug_quorumregions)) {
1362 ret = o2hb_debug_quorumregions ?
1363 PTR_ERR(o2hb_debug_quorumregions) : -ENOMEM;
1356 mlog_errno(ret); 1364 mlog_errno(ret);
1357 goto bail; 1365 goto bail;
1358 } 1366 }
@@ -1366,7 +1374,9 @@ static int o2hb_debug_init(void)
1366 sizeof(o2hb_failed_region_bitmap), 1374 sizeof(o2hb_failed_region_bitmap),
1367 O2NM_MAX_REGIONS, 1375 O2NM_MAX_REGIONS,
1368 o2hb_failed_region_bitmap); 1376 o2hb_failed_region_bitmap);
1369 if (!o2hb_debug_failedregions) { 1377 if (IS_ERR_OR_NULL(o2hb_debug_failedregions)) {
1378 ret = o2hb_debug_failedregions ?
1379 PTR_ERR(o2hb_debug_failedregions) : -ENOMEM;
1370 mlog_errno(ret); 1380 mlog_errno(ret);
1371 goto bail; 1381 goto bail;
1372 } 1382 }
@@ -2000,7 +2010,8 @@ static int o2hb_debug_region_init(struct o2hb_region *reg, struct dentry *dir)
2000 2010
2001 reg->hr_debug_dir = 2011 reg->hr_debug_dir =
2002 debugfs_create_dir(config_item_name(&reg->hr_item), dir); 2012 debugfs_create_dir(config_item_name(&reg->hr_item), dir);
2003 if (!reg->hr_debug_dir) { 2013 if (IS_ERR_OR_NULL(reg->hr_debug_dir)) {
2014 ret = reg->hr_debug_dir ? PTR_ERR(reg->hr_debug_dir) : -ENOMEM;
2004 mlog_errno(ret); 2015 mlog_errno(ret);
2005 goto bail; 2016 goto bail;
2006 } 2017 }
@@ -2013,7 +2024,9 @@ static int o2hb_debug_region_init(struct o2hb_region *reg, struct dentry *dir)
2013 O2HB_DB_TYPE_REGION_LIVENODES, 2024 O2HB_DB_TYPE_REGION_LIVENODES,
2014 sizeof(reg->hr_live_node_bitmap), 2025 sizeof(reg->hr_live_node_bitmap),
2015 O2NM_MAX_NODES, reg); 2026 O2NM_MAX_NODES, reg);
2016 if (!reg->hr_debug_livenodes) { 2027 if (IS_ERR_OR_NULL(reg->hr_debug_livenodes)) {
2028 ret = reg->hr_debug_livenodes ?
2029 PTR_ERR(reg->hr_debug_livenodes) : -ENOMEM;
2017 mlog_errno(ret); 2030 mlog_errno(ret);
2018 goto bail; 2031 goto bail;
2019 } 2032 }
@@ -2025,7 +2038,9 @@ static int o2hb_debug_region_init(struct o2hb_region *reg, struct dentry *dir)
2025 sizeof(*(reg->hr_db_regnum)), 2038 sizeof(*(reg->hr_db_regnum)),
2026 O2HB_DB_TYPE_REGION_NUMBER, 2039 O2HB_DB_TYPE_REGION_NUMBER,
2027 0, O2NM_MAX_NODES, reg); 2040 0, O2NM_MAX_NODES, reg);
2028 if (!reg->hr_debug_regnum) { 2041 if (IS_ERR_OR_NULL(reg->hr_debug_regnum)) {
2042 ret = reg->hr_debug_regnum ?
2043 PTR_ERR(reg->hr_debug_regnum) : -ENOMEM;
2029 mlog_errno(ret); 2044 mlog_errno(ret);
2030 goto bail; 2045 goto bail;
2031 } 2046 }
@@ -2037,7 +2052,9 @@ static int o2hb_debug_region_init(struct o2hb_region *reg, struct dentry *dir)
2037 sizeof(*(reg->hr_db_elapsed_time)), 2052 sizeof(*(reg->hr_db_elapsed_time)),
2038 O2HB_DB_TYPE_REGION_ELAPSED_TIME, 2053 O2HB_DB_TYPE_REGION_ELAPSED_TIME,
2039 0, 0, reg); 2054 0, 0, reg);
2040 if (!reg->hr_debug_elapsed_time) { 2055 if (IS_ERR_OR_NULL(reg->hr_debug_elapsed_time)) {
2056 ret = reg->hr_debug_elapsed_time ?
2057 PTR_ERR(reg->hr_debug_elapsed_time) : -ENOMEM;
2041 mlog_errno(ret); 2058 mlog_errno(ret);
2042 goto bail; 2059 goto bail;
2043 } 2060 }
@@ -2049,13 +2066,16 @@ static int o2hb_debug_region_init(struct o2hb_region *reg, struct dentry *dir)
2049 sizeof(*(reg->hr_db_pinned)), 2066 sizeof(*(reg->hr_db_pinned)),
2050 O2HB_DB_TYPE_REGION_PINNED, 2067 O2HB_DB_TYPE_REGION_PINNED,
2051 0, 0, reg); 2068 0, 0, reg);
2052 if (!reg->hr_debug_pinned) { 2069 if (IS_ERR_OR_NULL(reg->hr_debug_pinned)) {
2070 ret = reg->hr_debug_pinned ?
2071 PTR_ERR(reg->hr_debug_pinned) : -ENOMEM;
2053 mlog_errno(ret); 2072 mlog_errno(ret);
2054 goto bail; 2073 goto bail;
2055 } 2074 }
2056 2075
2057 ret = 0; 2076 return 0;
2058bail: 2077bail:
2078 debugfs_remove_recursive(reg->hr_debug_dir);
2059 return ret; 2079 return ret;
2060} 2080}
2061 2081
diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c
index 11849a44dc5a..23adcbf374d3 100644
--- a/fs/ocfs2/dlmglue.c
+++ b/fs/ocfs2/dlmglue.c
@@ -2954,7 +2954,7 @@ static int ocfs2_dlm_init_debug(struct ocfs2_super *osb)
2954 osb->osb_debug_root, 2954 osb->osb_debug_root,
2955 osb, 2955 osb,
2956 &ocfs2_dlm_debug_fops); 2956 &ocfs2_dlm_debug_fops);
2957 if (!dlm_debug->d_locking_state) { 2957 if (IS_ERR_OR_NULL(dlm_debug->d_locking_state)) {
2958 ret = -EINVAL; 2958 ret = -EINVAL;
2959 mlog(ML_ERROR, 2959 mlog(ML_ERROR,
2960 "Unable to create locking state debugfs file.\n"); 2960 "Unable to create locking state debugfs file.\n");
diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c
index 26675185b886..fb43de586791 100644
--- a/fs/ocfs2/super.c
+++ b/fs/ocfs2/super.c
@@ -1112,7 +1112,7 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent)
1112 1112
1113 osb->osb_debug_root = debugfs_create_dir(osb->uuid_str, 1113 osb->osb_debug_root = debugfs_create_dir(osb->uuid_str,
1114 ocfs2_debugfs_root); 1114 ocfs2_debugfs_root);
1115 if (!osb->osb_debug_root) { 1115 if (IS_ERR_OR_NULL(osb->osb_debug_root)) {
1116 status = -EINVAL; 1116 status = -EINVAL;
1117 mlog(ML_ERROR, "Unable to create per-mount debugfs root.\n"); 1117 mlog(ML_ERROR, "Unable to create per-mount debugfs root.\n");
1118 goto read_super_error; 1118 goto read_super_error;
@@ -1122,7 +1122,7 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent)
1122 osb->osb_debug_root, 1122 osb->osb_debug_root,
1123 osb, 1123 osb,
1124 &ocfs2_osb_debug_fops); 1124 &ocfs2_osb_debug_fops);
1125 if (!osb->osb_ctxt) { 1125 if (IS_ERR_OR_NULL(osb->osb_ctxt)) {
1126 status = -EINVAL; 1126 status = -EINVAL;
1127 mlog_errno(status); 1127 mlog_errno(status);
1128 goto read_super_error; 1128 goto read_super_error;
@@ -1606,8 +1606,9 @@ static int __init ocfs2_init(void)
1606 } 1606 }
1607 1607
1608 ocfs2_debugfs_root = debugfs_create_dir("ocfs2", NULL); 1608 ocfs2_debugfs_root = debugfs_create_dir("ocfs2", NULL);
1609 if (!ocfs2_debugfs_root) { 1609 if (IS_ERR_OR_NULL(ocfs2_debugfs_root)) {
1610 status = -ENOMEM; 1610 status = ocfs2_debugfs_root ?
1611 PTR_ERR(ocfs2_debugfs_root) : -ENOMEM;
1611 mlog(ML_ERROR, "Unable to create ocfs2 debugfs root.\n"); 1612 mlog(ML_ERROR, "Unable to create ocfs2 debugfs root.\n");
1612 goto out4; 1613 goto out4;
1613 } 1614 }