d_real() is about to be able to fail for D_REAL_DATA. So switch bpf_real_data_inode() from d_real_inode() to d_real_data_inode() and return NULL if the data can't be resolved. The kfunc is already KF_SLEEPABLE | KF_RET_NULL and its documentation says it may return NULL. So programs already have to deal with NULL and the verifier enforces that. Note that this is the caller that most easily ends up with a file whose data was never looked up. lsm.s/file_open runs before ovl_open() and lsm.s/file_receive sees O_PATH files passed via SCM_RIGHTS. Spell that out in the documentation. This is a no-op until d_real() can actually fail. Signed-off-by: Christian Brauner (Amutable) --- fs/bpf_fs_kfuncs.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/fs/bpf_fs_kfuncs.c b/fs/bpf_fs_kfuncs.c index 35ccd98a4de64..ab24e6bcd64c4 100644 --- a/fs/bpf_fs_kfuncs.c +++ b/fs/bpf_fs_kfuncs.c @@ -491,11 +491,20 @@ __bpf_kfunc int bpf_sock_read_xattr(struct socket *sock, const char *name__str, * inode itself is returned; for any file on a non-union filesystem the inode * attached to @file is returned. * - * Return: The inode hosting @file's data, or NULL. + * The union/overlay may have to look up the data first, e.g., when @file was + * opened with O_PATH or the program runs before the file is opened. If that + * fails NULL is returned. + * + * Return: The inode hosting @file's data, or NULL if it can't be resolved. */ __bpf_kfunc struct inode *bpf_real_data_inode(struct file *file) { - return d_real_inode(file_dentry(file)); + struct inode *inode; + + inode = d_real_data_inode(file_dentry(file)); + if (IS_ERR(inode)) + return NULL; + return inode; } __bpf_kfunc_end_defs(); -- 2.53.0