Re: [PATCH 01/19] vfs: syscall: Add fsinfo() to query filesystem information [ver #16]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Jann Horn <jannh@xxxxxxxxxx> wrote:

> > +int fsinfo_string(const char *s, struct fsinfo_context *ctx)
> ...
> Please add a check here to ensure that "ret" actually fits into the
> buffer (and use WARN_ON() if you think the check should never fire).
> Otherwise I think this is too fragile.

How about:

	int fsinfo_string(const char *s, struct fsinfo_context *ctx)
	{
		unsigned int len;
		char *p = ctx->buffer;
		int ret = 0;
		if (s) {
			len = strlen(s);
			if (len > ctx->buf_size - 1)
				len = ctx->buf_size;
			if (!ctx->want_size_only) {
				memcpy(p, s, len);
				p[len] = 0;
			}
			ret = len;
		}
		return ret;
	}

I've also added a check to eliminate the copy if userspace didn't actually
supply a buffer.

> > +       ret = vfs_statfs(path, &buf);
> > +       if (ret < 0 && ret != -ENOSYS)
> > +               return ret;
> ...
> > +       memcpy(&p->f_fsid, &buf.f_fsid, sizeof(p->f_fsid));
> 
> What's going on here? If vfs_statfs() returns -ENOSYS, we just use the
> (AFAICS uninitialized) buf.f_fsid anyway in the memcpy() below and
> return it to userspace?

Good point.  I've made the access to the buffer contingent on ret==0.  If I
don't set it, it will just be left pre-cleared.

> > +       return sizeof(*attr);
> 
> I think you meant sizeof(*info).

Yes.  I've renamed the buffer point to "p" in all cases so that it's more
obvious.

> > +       return ctx->usage;
> 
> It is kind of weird that you have to return the ctx->usage everywhere
> even though the caller already has ctx...

At this point, it's only used and returned by fsinfo_attributes() and really
is only for the use of the attribute getter function.

I could, I suppose, return the amount of data in ctx->usage and then preset it
for VSTRUCT-type objects.  Unfortunately, I can't make the getter return void
since it might have to return an error.

> > +               ctx->buffer = kvmalloc(ctx->buf_size, GFP_KERNEL);
> 
> ctx->buffer is _almost_ always pre-zeroed (see vfs_do_fsinfo() below),
> except if we have FSINFO_TYPE_OPAQUE or FSINFO_TYPE_LIST with a size
> bigger than what the attribute's ->size field said? Is that
> intentional?

Fixed.

> > +struct fsinfo_attribute {
> > +       unsigned int            attr_id;        /* The ID of the attribute */
> > +       enum fsinfo_value_type  type:8;         /* The type of the attribute's value(s) */
> > +       unsigned int            flags:8;
> > +       unsigned int            size:16;        /* - Value size (FSINFO_STRUCT) */
> > +       unsigned int            element_size:16; /* - Element size (FSINFO_LIST) */
> > +       int (*get)(struct path *path, struct fsinfo_context *params);
> > +};
> 
> Why the bitfields? It doesn't look like that's going to help you much,
> you'll just end up with 6 bytes of holes on x86-64:

Expanding them to non-bitfields will require an extra 10 bytes, making the
struct 8 bytes bigger with 4 bytes of padding.  I can do that if you'd rather.

David





[Index of Archives]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux