diff options
author | Chengyu Song <csong84@gatech.edu> | 2015-04-14 18:43:44 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-04-14 19:48:58 -0400 |
commit | e2ac55b6a8e337fac7cc59c6f452caac92ab5ee6 (patch) | |
tree | 5f169fe79554f618b350761d7e428be64d7b084a | |
parent | 762515a8e9c7ead55539cf96a63dec2363b1df50 (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.c | 42 | ||||
-rw-r--r-- | fs/ocfs2/dlmglue.c | 2 | ||||
-rw-r--r-- | fs/ocfs2/super.c | 9 |
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(®->hr_item), dir); | 2012 | debugfs_create_dir(config_item_name(®->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; |
2058 | bail: | 2077 | bail: |
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 | } |