[PATCH] debugfs: Check return value of debugfs_real_fops() for NULL

From: Matthias Kaehlcke
Date: Tue Mar 27 2018 - 19:56:40 EST


debugfs_real_fops() returns a NULL pointer when it is invoked without a
prior call to debugfs_file_get(). In code paths including this call it
is not strictly necessary to check the return value of
debugfs_real_fops(). However clang inlines debugfs_real_fops(), detects
the invalid dereferencing of the NULL pointer and drops the code path.
This leads to a bunch of objtool warnings when building with clang and
CONFIG_UNWINDER_ORC=y:

fs/debugfs/file.o: warning: objtool: full_proxy_llseek() falls through to next function full_proxy_read()
fs/debugfs/file.o: warning: objtool: full_proxy_read() falls through to next function full_proxy_write()
fs/debugfs/file.o: warning: objtool: full_proxy_write() falls through to next function full_proxy_poll()
fs/debugfs/file.o: warning: objtool: full_proxy_poll() falls through to next function full_proxy_unlocked_ioctl()
fs/debugfs/file.o: warning: objtool: full_proxy_unlocked_ioctl() falls through to next function fops_u8_open()

Check the pointer returned by debugfs_real_fops() in all code paths to
make clang and objtool happy.

Debugged-by: Josh Poimboeuf <jpoimboe@xxxxxxxxxx>
Debugged-by: Manoj Gupta <manojgupta@xxxxxxxxxxxx>
Signed-off-by: Matthias Kaehlcke <mka@xxxxxxxxxxxx>
---
fs/debugfs/file.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/fs/debugfs/file.c b/fs/debugfs/file.c
index cd12e6576b48..427e185ecc8f 100644
--- a/fs/debugfs/file.c
+++ b/fs/debugfs/file.c
@@ -183,7 +183,8 @@ static ret_type full_proxy_ ## name(proto) \
if (unlikely(r)) \
return r; \
real_fops = debugfs_real_fops(filp); \
- r = real_fops->name(args); \
+ if (real_fops) \
+ r = real_fops->name(args); \
debugfs_file_put(dentry); \
return r; \
}
@@ -217,7 +218,14 @@ static unsigned int full_proxy_poll(struct file *filp,
return POLLHUP;

real_fops = debugfs_real_fops(filp);
+ if (!real_fops) {
+ r = -ENXIO;
+ goto out;
+ }
+
r = real_fops->poll(filp, wait);
+
+out:
debugfs_file_put(dentry);
return r;
}
--
2.17.0.rc1.321.gba9d0f2565-goog