On Wed, Jun 03, 2020 at 07:47:14PM +0200, glider@xxxxxxxxxx wrote: > Under certain circumstances (we found this out running Docker on a > Clang-built kernel with CONFIG_INIT_STACK_ALL) ovl_copy_xattr() may > return uninitialized value of |error| from ovl_copy_xattr(). If we are returning uninitialized value of error, doesn't that mean that somewhere in the function we are returning without setting error. And that probably means that's a bug and we should fix it? I am wondering if this is triggered by loop finishing because all the xattr on the file are ovl_is_private_xattr(). In that case, we will come out of the loop without setting error. This is in fact success and we should return 0 instead of some random error? Thanks Vivek > It is then returned by ovl_create() to lookup_open(), which casts it to > an invalid dentry pointer, that can be further read or written by the > lookup_open() callers. > > Signed-off-by: Alexander Potapenko <glider@xxxxxxxxxx> > Cc: Kees Cook <keescook@xxxxxxxxxxxx> > Cc: Roy Yang <royyang@xxxxxxxxxx> > Cc: <stable@xxxxxxxxxxxxxxx> # 4.1 > > --- > > It's unclear to me whether error should be initially 0 or some error > code (both seem to work), but I thought returning an error makes sense, > as the situation wasn't anticipated by the code authors. > > The bug seem to date back to at least v4.1 where the annotation has been > introduced (i.e. the compilers started noticing error could be used > before being initialized). I hovever didn't try to prove that the > problem is actually reproducible on such ancient kernels. We've seen it > on a real machine running v4.4 as well. > --- > fs/overlayfs/copy_up.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c > index 9709cf22cab3..428d43e2d016 100644 > --- a/fs/overlayfs/copy_up.c > +++ b/fs/overlayfs/copy_up.c > @@ -47,7 +47,7 @@ int ovl_copy_xattr(struct dentry *old, struct dentry *new) > { > ssize_t list_size, size, value_size = 0; > char *buf, *name, *value = NULL; > - int uninitialized_var(error); > + int error = -EINVAL; > size_t slen; > > if (!(old->d_inode->i_opflags & IOP_XATTR) || > -- > 2.27.0.rc2.251.g90737beb825-goog >