On Mon, Mar 04, 2024 at 09:33:06AM +0100, Roberto Sassu wrote: > On Fri, 2024-03-01 at 13:00 -0600, Seth Forshee (DigitalOcean) wrote: > > On Fri, Mar 01, 2024 at 05:30:55PM +0100, Roberto Sassu wrote: > > > > +/* > > > > + * Inner implementation of vfs_caps_to_xattr() which does not return an > > > > + * error if the rootid does not map into @dest_userns. > > > > + */ > > > > +static ssize_t __vfs_caps_to_xattr(struct mnt_idmap *idmap, > > > > + struct user_namespace *dest_userns, > > > > + const struct vfs_caps *vfs_caps, > > > > + void *data, size_t size) > > > > +{ > > > > + struct vfs_ns_cap_data *ns_caps = data; > > > > + struct vfs_cap_data *caps = (struct vfs_cap_data *)ns_caps; > > > > + kuid_t rootkuid; > > > > + uid_t rootid; > > > > + > > > > + memset(ns_caps, 0, size); > > > > > > size -> sizeof(*ns_caps) (or an equivalent change) > > > > This is zeroing out the passed buffer, so it should use the size passed > > for the buffer. sizeof(*ns_caps) could potentially be more than the size > > of the buffer. > > Uhm, then maybe the problem is that you are passing the wrong argument? > > ssize_t > do_getxattr(struct mnt_idmap *idmap, struct dentry *d, > struct xattr_ctx *ctx) > { > ssize_t error; > char *kname = ctx->kname->name; > > if (is_fscaps_xattr(kname)) { > struct vfs_caps caps; > struct vfs_ns_cap_data data; > int ret; > > ret = vfs_get_fscaps(idmap, d, &caps); > if (ret) > return ret; > /* > * rootid is already in the mount idmap, so pass nop_mnt_idmap > * so that it won't be mapped. > */ > ret = vfs_caps_to_user_xattr(&nop_mnt_idmap, current_user_ns(), > &caps, &data, ctx->size); > > > ctx->size in my case is 1024 bytes. Ah, yes that definitely isn't correct. I will fix it, thanks for finding it.