Re: [driver-core:debugfs_cleanup 4/5] fs/d_path.c:59 prepend() warn: unsigned 'p->len' is never less than zero.

2022-01-01 Thread Al Viro
On Sat, Jan 01, 2022 at 02:08:54PM +0100, Greg Kroah-Hartman wrote:
> On Fri, Dec 31, 2021 at 07:35:07PM +0000, Al Viro wrote:
> > On Sat, Jan 01, 2022 at 01:08:41AM +0800, kernel test robot wrote:
> > > tree:   
> > > https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git 
> > > debugfs_cleanup
> > > head:   a04bbe0a2c7e98669e11a47f94e53dd8228bbeba
> > > commit: e95d5bed5d58c2f5352969369827e7135fa2261e [4/5] fs: make 
> > > d_path-like functions all have unsigned size
> > > config: i386-randconfig-m031-20211228 
> > > (https://download.01.org/0day-ci/archive/20220101/202201010156.bjvo7gaw-...@intel.com/config)
> > > compiler: gcc-9 (Debian 9.3.0-22) 9.3.0
> > > 
> > > If you fix the issue, kindly add following tag as appropriate
> > > Reported-by: kernel test robot 
> > > 
> > > smatch warnings:
> > > fs/d_path.c:59 prepend() warn: unsigned 'p->len' is never less than zero.
> > 
> > What do you mean, "unsigned p->len"?
> > 
> > ->len really *can* be negative - that's how running out of buffer is 
> > indicated.
> > 
> > Greg, I stand by the comment I made back in July - this kind of "hardening" 
> > is
> > useless; there's no legitimate reason to pass a huge buffer length, 
> > especially
> > since there's a limit on the length of pathname any syscall would accept.
> > See https://www.spinics.net/lists/linux-fsdevel/msg200370.html for the
> > variant I would prefer.
> 
> Sorry, yes, I agree with you, but never deleted this commit from this
> "scratch" branch of mine.  I'll go rebase the branch and purge it from
> the system so that 0-day doesn't hit it anymore, sorry for the noise.

OK...  I'll probably throw something along the lines of "negative => EINVAL,
positive greater than 32Kb - adjust the buffer and length to the last 32Kb
of what had been passed" into the misc queue.
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [driver-core:debugfs_cleanup 4/5] fs/d_path.c:59 prepend() warn: unsigned 'p->len' is never less than zero.

2021-12-31 Thread Al Viro
On Sat, Jan 01, 2022 at 01:08:41AM +0800, kernel test robot wrote:
> tree:   
> https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git 
> debugfs_cleanup
> head:   a04bbe0a2c7e98669e11a47f94e53dd8228bbeba
> commit: e95d5bed5d58c2f5352969369827e7135fa2261e [4/5] fs: make d_path-like 
> functions all have unsigned size
> config: i386-randconfig-m031-20211228 
> (https://download.01.org/0day-ci/archive/20220101/202201010156.bjvo7gaw-...@intel.com/config)
> compiler: gcc-9 (Debian 9.3.0-22) 9.3.0
> 
> If you fix the issue, kindly add following tag as appropriate
> Reported-by: kernel test robot 
> 
> smatch warnings:
> fs/d_path.c:59 prepend() warn: unsigned 'p->len' is never less than zero.

What do you mean, "unsigned p->len"?

->len really *can* be negative - that's how running out of buffer is indicated.

Greg, I stand by the comment I made back in July - this kind of "hardening" is
useless; there's no legitimate reason to pass a huge buffer length, especially
since there's a limit on the length of pathname any syscall would accept.
See https://www.spinics.net/lists/linux-fsdevel/msg200370.html for the
variant I would prefer.
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH 2/2] binder: Use receive_fd() to receive file from another process

2021-04-16 Thread Al Viro
On Fri, Apr 16, 2021 at 05:30:41PM +, Al Viro wrote:
> On Fri, Apr 16, 2021 at 05:58:15PM +0200, Christian Brauner wrote:
> 
> > They could probably refactor this but I'm not sure why they'd bother. If
> > they fail processing any of those files they end up aborting the
> > whole transaction.
> > (And the original code didn't check the error code btw.)
> 
> Wait a sec...  What does aborting the transaction do to descriptor table?
> 
> Oh, lovely...
> 
> binder_apply_fd_fixups() is deeply misguided.  What it should do is
>   * go through t->fd_fixups, reserving descriptor numbers and
> putting them into t->buffer (and I'd probably duplicate them into
> struct binder_txn_fd_fixup).  Cleanup in case of failure: go through
> the list, releasing the descriptors we'd already reserved, doing
> fput() on fixup->file in all entries and freeing the entries as
> we go.
>   * On success, go through the list, doing fd_install() and
> freeing the entries.

Something like this:

diff --git a/drivers/android/binder.c b/drivers/android/binder.c
index c119736ca56a..b0c5f7e625f3 100644
--- a/drivers/android/binder.c
+++ b/drivers/android/binder.c
@@ -2195,6 +2195,7 @@ static int binder_translate_fd(u32 fd, binder_size_t 
fd_offset,
fixup->offset = fd_offset;
trace_binder_transaction_fd_send(t, fd, fixup->offset);
list_add_tail(&fixup->fixup_entry, &t->fd_fixups);
+   fixup->target_fd = -1;
 
return ret;
 
@@ -3707,25 +3708,10 @@ static int binder_wait_for_work(struct binder_thread 
*thread,
return ret;
 }
 
-/**
- * binder_apply_fd_fixups() - finish fd translation
- * @proc: binder_proc associated @t->buffer
- * @t: binder transaction with list of fd fixups
- *
- * Now that we are in the context of the transaction target
- * process, we can allocate and install fds. Process the
- * list of fds to translate and fixup the buffer with the
- * new fds.
- *
- * If we fail to allocate an fd, then free the resources by
- * fput'ing files that have not been processed and ksys_close'ing
- * any fds that have already been allocated.
- */
-static int binder_apply_fd_fixups(struct binder_proc *proc,
+static int binder_reserve_fds(struct binder_proc *proc,
  struct binder_transaction *t)
 {
-   struct binder_txn_fd_fixup *fixup, *tmp;
-   int ret = 0;
+   struct binder_txn_fd_fixup *fixup;
 
list_for_each_entry(fixup, &t->fd_fixups, fixup_entry) {
int fd = get_unused_fd_flags(O_CLOEXEC);
@@ -3734,42 +3720,55 @@ static int binder_apply_fd_fixups(struct binder_proc 
*proc,
binder_debug(BINDER_DEBUG_TRANSACTION,
 "failed fd fixup txn %d fd %d\n",
 t->debug_id, fd);
-   ret = -ENOMEM;
-   break;
+   return -ENOMEM;
}
binder_debug(BINDER_DEBUG_TRANSACTION,
 "fd fixup txn %d fd %d\n",
 t->debug_id, fd);
trace_binder_transaction_fd_recv(t, fd, fixup->offset);
-   fd_install(fd, fixup->file);
-   fixup->file = NULL;
+   fixup->target_fd = fd;
if (binder_alloc_copy_to_buffer(&proc->alloc, t->buffer,
fixup->offset, &fd,
-   sizeof(u32))) {
-   ret = -EINVAL;
-   break;
-   }
+   sizeof(u32)))
+   return -EINVAL;
}
-   list_for_each_entry_safe(fixup, tmp, &t->fd_fixups, fixup_entry) {
-   if (fixup->file) {
-   fput(fixup->file);
-   } else if (ret) {
-   u32 fd;
-   int err;
-
-   err = binder_alloc_copy_from_buffer(&proc->alloc, &fd,
-   t->buffer,
-   fixup->offset,
-   sizeof(fd));
-   WARN_ON(err);
-   if (!err)
-   binder_deferred_fd_close(fd);
+   return 0;
+}
+
+/**
+ * binder_apply_fd_fixups() - finish fd translation
+ * @proc: binder_proc associated @t->buffer
+ * @t: binder transaction with list of fd fixups
+ *
+ * Now that we are in the context of the transaction target
+ * process, we can allocate fds. Process the list of fds to
+ * translate and fixup the buffer with the new fds.
+ *
+ * If we fail to al

Re: [PATCH 2/2] binder: Use receive_fd() to receive file from another process

2021-04-16 Thread Al Viro
On Fri, Apr 16, 2021 at 05:58:15PM +0200, Christian Brauner wrote:

> They could probably refactor this but I'm not sure why they'd bother. If
> they fail processing any of those files they end up aborting the
> whole transaction.
> (And the original code didn't check the error code btw.)

Wait a sec...  What does aborting the transaction do to descriptor table?

Oh, lovely...

binder_apply_fd_fixups() is deeply misguided.  What it should do is
* go through t->fd_fixups, reserving descriptor numbers and
putting them into t->buffer (and I'd probably duplicate them into
struct binder_txn_fd_fixup).  Cleanup in case of failure: go through
the list, releasing the descriptors we'd already reserved, doing
fput() on fixup->file in all entries and freeing the entries as
we go.
* On success, go through the list, doing fd_install() and
freeing the entries.

That's it.  No rereading from the buffer, no binder_deferred_fd_close()
crap, etc.

Again, YOU CAN NOT UNDO fd_install().  Ever.  Kernel can not decide it
shouldn't have put something in descriptor table and take it back.
You can't unring that bell.
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH 2/2] binder: Use receive_fd() to receive file from another process

2021-04-16 Thread Al Viro
On Fri, Apr 16, 2021 at 06:00:38PM +0200, Christian Brauner wrote:

> (dma_buf_fd() seems like another good candidate. But again, I don't have
> any plans to shove this down anyone's throat.)

Sure, there are candidates for such a helper.  Just as there are legitimate
users of anon_inode_getfd().

However, it is *NOT* something we can use as a vehicle for some hooks (pardon
the obscenity); it won't be consistently used in all cases - it simply is not
feasible for many of the fd_install() users.

Incidentally, looking at the user of receive_fd_user(), I would say that it
would be easier to follow in this form:
case VDUSE_IOTLB_GET_ENTRY: {
struct vduse_iotlb_entry entry;
struct vhost_iotlb_map *map;
struct vduse_iova_domain *domain = dev->domain;
struct file *f = NULL;

if (copy_from_user(&entry, argp, sizeof(entry)))
return -EFAULT;
entry.fd = get_unused_fd_flags(perm_to_file_flags(entry.perm));
if (entry.fd < 0)
return entry.fd;
spin_lock(&domain->iotlb_lock);
map = vhost_iotlb_itree_first(domain->iotlb,
  entry.start, entry.start + 1);
if (map) {
struct vdpa_map_file *map_file = map->opaque;

f = get_file(map_file->file);
entry.offset = map_file->offset;
entry.start = map->start;
entry.last = map->last;
entry.perm = map->perm;
}
spin_unlock(&domain->iotlb_lock);
if (!f) {
put_unused_fd(entry.fd);
return -EINVAL;
}
if (copy_to_user(argp, &entry, sizeof(entry))) {
put_unused_fd(entry.fd);
fput(f);
return -EFAULT;
}
// point of no return
fd_install(entry.fd, f);
return 0;
}
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH 2/2] binder: Use receive_fd() to receive file from another process

2021-04-16 Thread Al Viro
On Fri, Apr 16, 2021 at 05:13:10PM +0200, Christian Brauner wrote:

> My point here was more that the _file_ has already been opened _before_
> that call to io_uring_add_task_file(). But any potential non-trivial
> side-effects of opening that file that you correctly pointed out in an
> earlier mail has already happened by that time.

The file comes from io_uring_get_file(), the entire thing is within the
io_ring_ctx constructor and the only side effect there is ->ring_sock
creation.  And that stays until the io_ring_ctx is freed.  I'm _not_
saying I like io_uring style in general, BTW - in particular,
->ring_sock->file handling is a kludge (as is too much of interation
with AF_UNIX machinery there).  But from side effects POV we are fine
there.

> Granted there are more
> obvious examples, e.g. the binder stuff.
> 
>   int fd = get_unused_fd_flags(O_CLOEXEC);
> 
>   if (fd < 0) {
>   binder_debug(BINDER_DEBUG_TRANSACTION,
>"failed fd fixup txn %d fd %d\n",
>t->debug_id, fd);
>   ret = -ENOMEM;
>   break;
>   }
>   binder_debug(BINDER_DEBUG_TRANSACTION,
>"fd fixup txn %d fd %d\n",
>t->debug_id, fd);
>   trace_binder_transaction_fd_recv(t, fd, fixup->offset);
>   fd_install(fd, fixup->file);
>   fixup->file = NULL;
>   if (binder_alloc_copy_to_buffer(&proc->alloc, t->buffer,
>   fixup->offset, &fd,
>   sizeof(u32))) {
>   ret = -EINVAL;
>   break;
>   }

... and it's actually broken, since this
/* All copies must be 32-bit aligned and 32-bit size */
if (!check_buffer(alloc, buffer, buffer_offset, bytes))
return -EINVAL;
in binder_alloc_copy_to_buffer() should've been done *before*
fd_install().  If anything, it's an example of the situation when
fd_receive() would be wrong...
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH 2/2] binder: Use receive_fd() to receive file from another process

2021-04-16 Thread Al Viro
On Fri, Apr 16, 2021 at 03:42:52PM +0200, Christian Brauner wrote:
> > > are drivers/dma-buf/sw_sync.c and drivers/dma-buf/sync_file.c, etc.
> > 
> > FWIW, pretty much all ioctls that return descriptor as part of a structure
> > stored to user-supplied address tend to be that way; some don't have any
> > other output fields (in which case they probably would've been better off
> > with just passing the descriptor as return value of ioctl(2)).  Those
> > might be served by that receive_fd_user() helper; anything that has several
> > outputs won't be.  The same goes for anything that has hard-to-undo
> > operations as part of what they need to do:
> > reserve fd
> > set file up
> > do hard-to-undo stuff
> > install into descriptor table
> > is the only feasible order of operations - reservation can fail, so
> > it must go before the hard-to-undo part and install into descriptor
> > table can't be undone at all, so it must come last.  Looks like
> > e.g. drivers/virt/nitro_enclaves/ne_misc_dev.c case might be of
> > that sort...
> 
> If receive_fd() or your receive_fd_user() proposal can replace a chunk

My what proposal?  The thing is currently in linux/file.h, put there
by Kees half a year ago...

> of open-coded places in modules where the split between reserving the
> file descriptor and installing it is pointless it's probably already
> worth it.

A helper for use in some of the simplest cases, with big fat warnings
not to touch if the things are not entirely trivial - sure, why not,
same as we have anon_inode_getfd().  But that's a convenience helper,
not a general purpose primitive.

> Random example from io_uring where the file is already opened
> way before (which yes, isn't a module afaik but another place where we
> have that pattern):
> 
> static int io_uring_install_fd(struct io_ring_ctx *ctx, struct file *file)
> {
>   int ret, fd;
> 
>   fd = get_unused_fd_flags(O_RDWR | O_CLOEXEC);
>   if (fd < 0)
>   return fd;
> 
>   ret = io_uring_add_task_file(ctx);

Huh?  It's
ret = io_uring_add_task_file(ctx, file);
in the mainline and I don't see how that sucker could work without having
file passed to it.

>   if (ret) {
>   put_unused_fd(fd);
>   return ret;
>   }
>   fd_install(fd, file);
>   return fd;
> }

... and that's precisely the situation where we have something that is
not obvious how to undo; look into io_uring_add_task_file()...

We have three things to do: (1) reserve a descriptor, (2) 
io_uring_add_task_file(),
(3) install the file.  (1) and (2) may fail, (1) is trivial to undo, (2) might 
be
not, (3) is impossible to undo.  So I'd say that in this particular case
io_uring is being perfectly reasonable...
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH 2/2] binder: Use receive_fd() to receive file from another process

2021-04-15 Thread Al Viro
On Fri, Apr 16, 2021 at 05:19:50AM +, Al Viro wrote:
> On Thu, Apr 01, 2021 at 12:40:34PM +0200, Christian Brauner wrote:

> > and see whether all of them can be switched to simply using
> > receive_fd(). I did a completely untested rough sketch to illustrate
> > what I meant by using binder and devpts Xie seems to have just picked
> > those two. But the change is obviously only worth it if all or nearly
> > all callers can be switched over without risk of regression.
> > It would most likely simplify quite a few codepaths though especially in
> > the error paths since we can get rid of put_unused_fd() cleanup.
> > 
> > But it requires buy in from others obviously.
> 
> Opening a file can have non-trivial side effects; reserving a descriptor
> can't.  Moreover, if you look at the second hit in your list, you'll see
> that we do *NOT* want that combined thing there - fd_install() is
> completely irreversible, so we can't do that until we made sure the
> reply (struct vtpm_proxy_new_dev) has been successfully copied to
> userland.  No, your receive_fd_user() does not cover that.
> 
> There's a bunch of other cases like that - the next ones on your list
> are drivers/dma-buf/sw_sync.c and drivers/dma-buf/sync_file.c, etc.

FWIW, pretty much all ioctls that return descriptor as part of a structure
stored to user-supplied address tend to be that way; some don't have any
other output fields (in which case they probably would've been better off
with just passing the descriptor as return value of ioctl(2)).  Those
might be served by that receive_fd_user() helper; anything that has several
outputs won't be.  The same goes for anything that has hard-to-undo
operations as part of what they need to do:
reserve fd
set file up
do hard-to-undo stuff
install into descriptor table
is the only feasible order of operations - reservation can fail, so
it must go before the hard-to-undo part and install into descriptor
table can't be undone at all, so it must come last.  Looks like
e.g. drivers/virt/nitro_enclaves/ne_misc_dev.c case might be of
that sort...
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH 2/2] binder: Use receive_fd() to receive file from another process

2021-04-15 Thread Al Viro
On Thu, Apr 01, 2021 at 12:40:34PM +0200, Christian Brauner wrote:
> My suggestion was to look at all the places were we currently open-code
> this in drivers/:
> 
> drivers/android/binder.c:   int fd = 
> get_unused_fd_flags(O_CLOEXEC);
> drivers/char/tpm/tpm_vtpm_proxy.c:  fd = get_unused_fd_flags(O_RDWR);
> drivers/dma-buf/dma-buf.c:  fd = get_unused_fd_flags(flags);
> drivers/dma-buf/sw_sync.c:  int fd = get_unused_fd_flags(O_CLOEXEC);
> drivers/dma-buf/sync_file.c:int fd = get_unused_fd_flags(O_CLOEXEC);
> drivers/gpio/gpiolib-cdev.c:fd = get_unused_fd_flags(O_RDONLY | 
> O_CLOEXEC);
> drivers/gpio/gpiolib-cdev.c:fd = get_unused_fd_flags(O_RDONLY | 
> O_CLOEXEC);
> drivers/gpio/gpiolib-cdev.c:fd = get_unused_fd_flags(O_RDONLY | 
> O_CLOEXEC);
> drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c: fd = 
> get_unused_fd_flags(O_CLOEXEC);
> drivers/gpu/drm/drm_atomic_uapi.c:  fence_state->fd = 
> get_unused_fd_flags(O_CLOEXEC);
> drivers/gpu/drm/drm_lease.c:fd = get_unused_fd_flags(cl->flags & 
> (O_CLOEXEC | O_NONBLOCK));
> drivers/gpu/drm/drm_syncobj.c:  fd = get_unused_fd_flags(O_CLOEXEC);
> drivers/gpu/drm/drm_syncobj.c:  int fd = get_unused_fd_flags(O_CLOEXEC);
> drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c:   out_fence_fd = 
> get_unused_fd_flags(O_CLOEXEC);
> drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c: out_fence_fd = 
> get_unused_fd_flags(O_CLOEXEC);
> drivers/gpu/drm/msm/msm_gem_submit.c:   out_fence_fd = 
> get_unused_fd_flags(O_CLOEXEC);
> drivers/gpu/drm/virtio/virtgpu_ioctl.c: out_fence_fd = 
> get_unused_fd_flags(O_CLOEXEC);
> drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c:out_fence_fd = 
> get_unused_fd_flags(O_CLOEXEC);
> drivers/infiniband/core/rdma_core.c:new_fd = 
> get_unused_fd_flags(O_CLOEXEC);
> drivers/media/mc/mc-request.c:  fd = get_unused_fd_flags(O_CLOEXEC);
> drivers/misc/cxl/api.c: rc = get_unused_fd_flags(flags);
> drivers/scsi/cxlflash/ocxl_hw.c:rc = get_unused_fd_flags(flags);
> drivers/scsi/cxlflash/ocxl_hw.c:dev_err(dev, "%s: 
> get_unused_fd_flags failed rc=%d\n",
> drivers/tty/pty.c:  fd = get_unused_fd_flags(flags);
> drivers/vfio/vfio.c:ret = get_unused_fd_flags(O_CLOEXEC);
> drivers/virt/nitro_enclaves/ne_misc_dev.c:  enclave_fd = 
> get_unused_fd_flags(O_CLOEXEC);
> 
> and see whether all of them can be switched to simply using
> receive_fd(). I did a completely untested rough sketch to illustrate
> what I meant by using binder and devpts Xie seems to have just picked
> those two. But the change is obviously only worth it if all or nearly
> all callers can be switched over without risk of regression.
> It would most likely simplify quite a few codepaths though especially in
> the error paths since we can get rid of put_unused_fd() cleanup.
> 
> But it requires buy in from others obviously.

Opening a file can have non-trivial side effects; reserving a descriptor
can't.  Moreover, if you look at the second hit in your list, you'll see
that we do *NOT* want that combined thing there - fd_install() is
completely irreversible, so we can't do that until we made sure the
reply (struct vtpm_proxy_new_dev) has been successfully copied to
userland.  No, your receive_fd_user() does not cover that.

There's a bunch of other cases like that - the next ones on your list
are drivers/dma-buf/sw_sync.c and drivers/dma-buf/sync_file.c, etc.

So I would consider receive_fd() as an attractive nuisance if it
is ever suggested (and available) for wide use...
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH RFC PKS/PMEM 33/58] fs/cramfs: Utilize new kmap_thread()

2020-10-13 Thread Al Viro
On Tue, Oct 13, 2020 at 08:36:43PM +0100, Matthew Wilcox wrote:

> static inline void copy_to_highpage(struct page *to, void *vfrom, unsigned 
> int size)
> {
>   char *vto = kmap_atomic(to);
> 
>   memcpy(vto, vfrom, size);
>   kunmap_atomic(vto);
> }
> 
> in linux/highmem.h ?

You mean, like
static void memcpy_from_page(char *to, struct page *page, size_t offset, size_t 
len)
{
char *from = kmap_atomic(page);
memcpy(to, from + offset, len);
kunmap_atomic(from);
}

static void memcpy_to_page(struct page *page, size_t offset, const char *from, 
size_t len)
{
char *to = kmap_atomic(page);
memcpy(to + offset, from, len);
kunmap_atomic(to);
}

static void memzero_page(struct page *page, size_t offset, size_t len)
{
char *addr = kmap_atomic(page);
memset(addr + offset, 0, len);
kunmap_atomic(addr);
}

in lib/iov_iter.c?  FWIW, I don't like that "highpage" in the name and
highmem.h as location - these make perfect sense regardless of highmem;
they are normal memory operations with page + offset used instead of
a pointer...
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[git pull] uaccess comedi compat

2020-06-03 Thread Al Viro
comedi compat ioctls done saner (killing the single biggest pile
of __get_user/__put_user outside of arch/* in process).

The following changes since commit 8f3d9f354286745c751374f5f1fcafee6b3f3136:

  Linux 5.7-rc1 (2020-04-12 12:35:55 -0700)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs.git uaccess.comedi

for you to fetch changes up to bac42fb21259783cb748ae54227a5e755340a396:

  comedi: get rid of compat_alloc_user_space() mess in COMEDI_CMD{,TEST} compat 
(2020-05-29 10:06:01 -0400)


Al Viro (10):
  comedi: move compat ioctl handling to native fops
  comedi: get rid of indirection via translated_ioctl()
  comedi: get rid of compat_alloc_user_space() mess in COMEDI_CHANINFO 
compat
  comedi: get rid of compat_alloc_user_space() mess in COMEDI_RANGEINFO 
compat
  comedi: get rid of compat_alloc_user_space() mess in COMEDI_INSN compat
  comedi: get rid of compat_alloc_user_space() mess in COMEDI_INSNLIST 
compat
  comedi: lift copy_from_user() into callers of __comedi_get_user_cmd()
  comedi: do_cmdtest_ioctl(): lift copyin/copyout into the caller
  comedi: do_cmd_ioctl(): lift copyin/copyout into the caller
  comedi: get rid of compat_alloc_user_space() mess in COMEDI_CMD{,TEST} 
compat

 drivers/staging/comedi/Makefile  |   1 -
 drivers/staging/comedi/comedi_compat32.c | 455 -
 drivers/staging/comedi/comedi_compat32.h |  28 --
 drivers/staging/comedi/comedi_fops.c | 564 +--
 drivers/staging/comedi/comedi_internal.h |   2 +-
 drivers/staging/comedi/range.c   |  17 +-
 6 files changed, 467 insertions(+), 600 deletions(-)
 delete mode 100644 drivers/staging/comedi/comedi_compat32.c
 delete mode 100644 drivers/staging/comedi/comedi_compat32.h
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH v2 2/3] binder: do not initialize locals passed to copy_from_user()

2020-03-05 Thread Al Viro
On Thu, Mar 05, 2020 at 10:03:25AM +0100, Rasmus Villemoes wrote:

> Does copy_from_user guarantee to zero-initialize the remaining buffer if
> copying fails partway through?

That's guaranteed, short of raw_copy_from_user() being completely broken.
What raw_copy_from_user() implementation must guarantee is that if
raw_copy_from_user(to, from, N) returns N - n, then
* 0 <= n <= N
* all attempted reads had been within the range [from .. from + N - 1]
* all stores had been to the range [to .. to + n - 1] and every byte
within that range had been overwritten
* for all k in [0 .. n - 1], the value stored at to[k] by the end of
the call is equal to the value that would've been possible to read from
from[k] at some point during the call.  In particular, for all bytes in
range [from .. from + n - 1] there had been a successful read of some
object containing that byte.
* if everything in [from .. from + N - 1] is readable, the call
will copy the entire range into [to .. to + N - 1] and return 0.

Provided that, copy_from_user() will leave no uninitialized data in
destination object in any case, success or no success.
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH] staging: wfx: add gcc extension __force cast

2019-11-11 Thread Al Viro
On Mon, Nov 11, 2019 at 08:28:52PM +, Al Viro wrote:

> So it smells like a remote buffer overrun, little-endian or not.
> And at that point I would start looking for driver original authors with
> some rather pointed questions about the validation of data and lack
> thereof.
> 
> BTW, if incoming packets are fixed-endian, I would expect more bugs on
> big-endian hosts - wfx_tx_confirm_cb() does things like
> tx_info->status.tx_time =
> arg->media_delay - arg->tx_queue_delay;
> with media_delay and tx_queue_delay both being 32bit fields in the
> incoming packet.  So another question to the authors (or documentation,
> or direct experiments) is what endianness do various fields in the incoming
> data have.  We can try and guess, but...

More fun:
int hif_read_mib(struct wfx_dev *wdev, int vif_id, u16 mib_id, void *val, 
size_t val_len)
{
int ret;
struct hif_msg *hif;
int buf_len = sizeof(struct hif_cnf_read_mib) + val_len;
struct hif_req_read_mib *body = wfx_alloc_hif(sizeof(*body), &hif);
struct hif_cnf_read_mib *reply = kmalloc(buf_len, GFP_KERNEL);

OK, allocated request and reply buffers, by the look of it; request one
being struct hif_msg with struct hif_req_read_mib for payload
and reply - struct hif_cnf_read_mib {
uint32_t   status;
uint16_t   mib_id;
uint16_t   length;
uint8_tmib_data[];
} with val_len bytes in mib_data.

body->mib_id = cpu_to_le16(mib_id);
wfx_fill_header(hif, vif_id, HIF_REQ_ID_READ_MIB, sizeof(*body));

Filled request, {.len = cpu_to_le16(4 + 4),
 .id = HIF_REQ_ID_READ_MIB,
 .interface = vif_id,
 .body = {
.mib_id = cpu_to_le16(mib_id)
}
}
Note that mib_id is host-endian here; what we send is little-endian.

ret = wfx_cmd_send(wdev, hif, reply, buf_len, false);
send it, get reply

if (!ret && mib_id != reply->mib_id) {
Wha...?  Now we are comparing two bytes at offset 4 into reply with a 
host-endian
value?  Oh, well...

dev_warn(wdev->dev, "%s: confirmation mismatch request\n", 
__func__);
ret = -EIO;
}
if (ret == -ENOMEM)
dev_err(wdev->dev, "buffer is too small to receive %s (%zu < 
%d)\n",
get_mib_name(mib_id), val_len, reply->length);
if (!ret)
memcpy(val, &reply->mib_data, reply->length);
What.  The.  Hell?

We are copying data from the reply.  Into caller-supplied object.
With length taken from the same reply and no validation even
attempted?  Not even "um, maybe we shouldn't copy more than the caller
told us to copy, especially since that's as much as there is in the
source of that memcpy"?

And that's besides the endianness questions.  Note that getting the
endianness wrong here is just about certain to blow up - small value
will be misinterpreted by factor of 256.

In any case, even if this is talking to firmware on a card, that's
an unhealthy degree of trust, especially since the same function
does consider the possibility of bogus replies.
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH] staging: wfx: add gcc extension __force cast

2019-11-11 Thread Al Viro
On Mon, Nov 11, 2019 at 01:51:33PM +, Jules Irenge wrote:
> 
> > NAK.  force-cast (and it's not a gcc extension, BTW - it's sparse) is 
> > basically
> > "I know better; the code is right, so STFU already".  *IF* 
> > counters.count_...
> > is really little-endian 32bit, then why isn't it declared that way?  And if
> > it's host-endian, you've just papered over a real bug here.
> > 
> > As a general rule "fix" doesn't mean "tell it to shut up"...
> > 
> 
> Thanks for the comments, I have updated  but I have a mixed mind on the 
> __le32. I have to read more about it. 
> 
> I would appreciate if you can comment again on the update.

>From the look at the driver, it seems that all these counters are a part of
structure that is read from the hardware and only used as little-endian.
So just declare all fields in struct hif_mib_extended_count_table as
__le32; easy enough.  Looking a bit further, the same goes for
struct hif_mib_bcn_filter_table ->num_of_info_elmts
struct hif_mib_keep_alive_period ->keep_alive_period (__le16)
struct hif_mib_template_frame ->frame_length (__le16)
struct hif_mib_set_association_mode ->basic_rate_set (__le32)
struct hif_req_update_ie ->num_i_es (__le16)
struct hif_req_write_mib ->mib_id, ->length (__le16 both)
struct hif_req_read_mib ->mib_id (__le16)
struct hif_req_configuration ->length (__le16)

With those annotated we are left with

drivers/staging/wfx/bh.c:73:35: warning: incorrect type in argument 1 
(different base types)
drivers/staging/wfx/bh.c:73:35:expected restricted __le16 const [usertype] 
*p
drivers/staging/wfx/bh.c:73:35:got unsigned short [usertype] *
drivers/staging/wfx/bh.c:106:41: warning: cast to restricted __le32
drivers/staging/wfx/bh.c:175:22: warning: cast to restricted __le16
drivers/staging/wfx/hwio.c:199:16: warning: cast from restricted __le32
drivers/staging/wfx/hwio.c:199:14: warning: incorrect type in assignment 
(different base types)
drivers/staging/wfx/hwio.c:199:14:expected unsigned int [usertype]
drivers/staging/wfx/hwio.c:199:14:got restricted __le32 [usertype]
drivers/staging/wfx/hif_tx.c:36:18: warning: incorrect type in assignment 
(different base types)
drivers/staging/wfx/hif_tx.c:36:18:expected unsigned short [usertype] len
drivers/staging/wfx/hif_tx.c:36:18:got restricted __le16 [usertype]
drivers/staging/wfx/data_tx.c:646:22: warning: incorrect type in assignment 
(different base types)
drivers/staging/wfx/data_tx.c:646:22:expected unsigned short [usertype] len
drivers/staging/wfx/data_tx.c:646:22:got restricted __le16 [usertype]
drivers/staging/wfx/hif_tx_mib.h:111:27: warning: incorrect type in initializer 
(different base types)
drivers/staging/wfx/hif_tx_mib.h:111:27:expected unsigned int [usertype] 
enable
drivers/staging/wfx/hif_tx_mib.h:111:27:got restricted __le32 [usertype]
drivers/staging/wfx/hif_tx_mib.h:112:30: warning: incorrect type in initializer 
(different base types)
drivers/staging/wfx/hif_tx_mib.h:112:30:expected unsigned int [usertype] 
bcn_count
drivers/staging/wfx/hif_tx_mib.h:112:30:got restricted __le32 [usertype]
drivers/staging/wfx/hif_tx_mib.h:34:38: warning: incorrect type in initializer 
(different base types)
drivers/staging/wfx/hif_tx_mib.h:34:38:expected unsigned char [usertype] 
wakeup_period_max
drivers/staging/wfx/hif_tx_mib.h:34:38:got restricted __le16 [usertype]
drivers/staging/wfx/main.c:108:39: warning: incorrect type in initializer 
(different base types)
drivers/staging/wfx/main.c:108:39:expected restricted __le16 [usertype] 
rx_highest
drivers/staging/wfx/main.c:108:39:got int
drivers/staging/wfx/./traces.h:155:1: warning: incorrect type in argument 1 
(different base types)
drivers/staging/wfx/./traces.h:155:1:expected restricted __le16 const 
[usertype] *p
drivers/staging/wfx/./traces.h:155:1:got unsigned short [usertype] *
drivers/staging/wfx/./traces.h:155:1: warning: incorrect type in argument 1 
(different base types)
drivers/staging/wfx/./traces.h:155:1:expected restricted __le16 const 
[usertype] *p
drivers/staging/wfx/./traces.h:155:1:got unsigned short [usertype] *


and that's where the real bugs start to show up; leaving the misbegotten
forest of macros in misbegotten tracing shite aside, we have this:

static const struct ieee80211_supported_band wfx_band_2ghz = {
.channels = wfx_2ghz_chantable,
.n_channels = ARRAY_SIZE(wfx_2ghz_chantable),
.bitrates = wfx_rates,
.n_bitrates = ARRAY_SIZE(wfx_rates),
.ht_cap = {
// Receive caps
.cap = IEEE80211_HT_CAP_GRN_FLD | IEEE80211_HT_CAP_SGI_20 |
   IEEE80211_HT_CAP_MAX_AMSDU | (1 << 
IEEE80211_HT_CAP_RX_STBC_SHIFT),
.ht_supported = 1,
.ampdu_factor = IEEE80211_HT_MAX_AMPDU_16K,
.ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE,
.mcs = {
.rx_mask = { 0xFF }, // MCS0 to MCS7
  

Re: [PATCH] staging: wfx: add gcc extension __force cast

2019-11-09 Thread Al Viro
On Fri, Nov 08, 2019 at 11:38:37PM +, Jules Irenge wrote:
> Add gcc extension __force and __le32 cast to fix warning issued by Sparse 
> tool."warning: cast to restricted __le32"
>
> Signed-off-by: Jules Irenge 
> ---
>  drivers/staging/wfx/debug.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/staging/wfx/debug.c b/drivers/staging/wfx/debug.c
> index 0a9ca109039c..aa7b2dd691b9 100644
> --- a/drivers/staging/wfx/debug.c
> +++ b/drivers/staging/wfx/debug.c
> @@ -72,7 +72,7 @@ static int wfx_counters_show(struct seq_file *seq, void *v)
>   return -EIO;
>  
>  #define PUT_COUNTER(name) \
> - seq_printf(seq, "%24s %d\n", #name ":", 
> le32_to_cpu(counters.count_##name))
> + seq_printf(seq, "%24s %d\n", #name ":", le32_to_cpu((__force 
> __le32)(counters.count_##name)))

NAK.  force-cast (and it's not a gcc extension, BTW - it's sparse) is basically
"I know better; the code is right, so STFU already".  *IF* counters.count_...
is really little-endian 32bit, then why isn't it declared that way?  And if
it's host-endian, you've just papered over a real bug here.

As a general rule "fix" doesn't mean "tell it to shut up"...
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH] staging: comedi: Capitalize macro name to fix camelcase checkpatch warning

2019-10-06 Thread Al Viro
On Sun, Oct 06, 2019 at 07:49:03PM +0100, Jules Irenge wrote:

[mA vs. MA]

Table 5.  SI prefixes
Factor  NameSymbol

10^6megaM

10^-3   milli   m

Confusing one for another (especially for electrical units) can be...
spectacular.  FYI, 1mA is more or less what you get if you lick
the terminals of a 9V battery; 1MA is about 30 times the current
in typical lightning strike...
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH] staging: exfat: cleanup braces for if/else statements

2019-09-03 Thread Al Viro
On Tue, Sep 03, 2019 at 06:47:32PM +0200, Valentin Vidic wrote:
> + } else if (uni == 0x) {
>   skip = TRUE;

While we are at it, could you get rid of that 'TRUE' macro?
Or added

#define THE_TRUTH_AND_THATS_CUTTIN_ME_OWN_THROAT true

if you want to properly emphasize it...
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH v2 03/24] erofs: add super block operations

2019-07-20 Thread Al Viro
On Sun, Jul 21, 2019 at 11:08:42AM +0800, Gao Xiang wrote:

> It is for debugging use as you said below, mainly for our internal
> testers whose jobs are
> to read kmsg logs and catch kernel problems. sb->s_id (device number)
> maybe not
> straight-forward for them compared with dev_name...

Huh? ->s_id is something like "sdb7" - it's bdev_name(), not a device
number...

> The initial purpose of erofs_mount_private was to passing multi private
> data from erofs_mount
> to erofs_read_super, which was written before fs_contest was introduced.

That has nothing to do with fs_context (well, other than fs_context conversions
affecting the code very close to that).

> I agree with you, it seems better to just use s_id in community and
> delete erofs_mount_private stuffs...
> Yet I don't look into how to use new fs_context, could I keep using
> legacy mount interface and fix them all?

Sure.

> I guess if I don't misunderstand, that is another suggestion -- in
> short, leave all destructors to .kill_sb() and
> cleanup fill_super().

Just be careful with that iput() there - AFAICS, if fs went live (i.e.
if ->s_root is non-NULL), you really need it done only from put_super();
OTOH, for the case of NULL ->s_root ->put_super() won't be called at all,
so in that case you need it directly in ->kill_sb().
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH v2 03/24] erofs: add super block operations

2019-07-20 Thread Al Viro
On Thu, Jul 11, 2019 at 10:57:34PM +0800, Gao Xiang wrote:
> This commit adds erofs super block operations, including (u)mount,
> remount_fs, show_options, statfs, in addition to some private
> icache management functions.

Could you explain what's the point of this

> + /* save the device name to sbi */
> + sbi->dev_name = __getname();
> + if (!sbi->dev_name) {
> + err = -ENOMEM;
> + goto err_devname;
> + }
> +
> + snprintf(sbi->dev_name, PATH_MAX, "%s", dev_name);
> + sbi->dev_name[PATH_MAX - 1] = '\0';

... and this?

> +struct erofs_mount_private {
> + const char *dev_name;
> + char *options;
> +};
> +
> +/* support mount_bdev() with options */
> +static int erofs_fill_super(struct super_block *sb,
> + void *_priv, int silent)
> +{
> + struct erofs_mount_private *priv = _priv;
> +
> + return erofs_read_super(sb, priv->dev_name,
> + priv->options, silent);
> +}
> +
> +static struct dentry *erofs_mount(
> + struct file_system_type *fs_type, int flags,
> + const char *dev_name, void *data)
> +{
> + struct erofs_mount_private priv = {
> + .dev_name = dev_name,
> + .options = data
> + };
> +
> + return mount_bdev(fs_type, flags, dev_name,
> + &priv, erofs_fill_super);
> +}

AFAICS, the only use of sbi->dev_name is debugging printks and
all of those have sb->s_id available, with device name stored
in there.  Which makes the whole thing bloody weird - what's
wrong with simply passing data to mount_bdev (instead of
&priv), folding erofs_read_super() into erofs_fill_super(),
replacing sbi->dev_name with sb->s_id and killing sbi->dev_name,
along with the associated allocation, freeing, handling of
allocation failure, etc.?

For drivers/staging location that would be (compile-tested only)
the diff below.  I suspect that you could simplify fill_super
a bit further if you added ->kill_sb() along the lines of

sbi = EROFS(sb);
#ifdef EROFS_FS_HAS_MANAGED_CACHE
if (sbi && !sb->s_root)
iput(sbi->managed_cache);
#endif
kill_block_super(sb);
kfree(sbi);
and took freeing sbi out of your ->put_super().  Then fill_super()
would simply return -E... on all failure exits, leaving all cleanup
to ->kill_sb().  E.g. initialization of the same ->managed_cache
would become
#ifdef EROFS_FS_HAS_MANAGED_CACHE
inode = erofs_init_managed_cache(sb);
if (IS_ERR(inode))
return PTR_ERR(inode);
sbi->managed_cache = inode;
#endif
etc.  Matter of taste, but IME if destructor parallels the cleanups on failure
exits in constructor it often makes sense to make use of that and kill the
duplication...  Anyway, that's a separate store; sbi->dev_name is a lot more
obvious one.


diff --git a/drivers/staging/erofs/internal.h b/drivers/staging/erofs/internal.h
index 382258fc124d..16bab07e69d8 100644
--- a/drivers/staging/erofs/internal.h
+++ b/drivers/staging/erofs/internal.h
@@ -117,8 +117,6 @@ struct erofs_sb_info {
u8 volume_name[16]; /* volume name */
u32 requirements;
 
-   char *dev_name;
-
unsigned int mount_opt;
unsigned int shrinker_run_no;
 
diff --git a/drivers/staging/erofs/super.c b/drivers/staging/erofs/super.c
index cadbcc11702a..a6ee69d0ce45 100644
--- a/drivers/staging/erofs/super.c
+++ b/drivers/staging/erofs/super.c
@@ -367,15 +367,14 @@ static struct inode *erofs_init_managed_cache(struct 
super_block *sb)
 
 #endif
 
-static int erofs_read_super(struct super_block *sb,
-   const char *dev_name,
+static int erofs_fill_super(struct super_block *sb,
void *data, int silent)
 {
struct inode *inode;
struct erofs_sb_info *sbi;
int err = -EINVAL;
 
-   infoln("read_super, device -> %s", dev_name);
+   infoln("read_super, device -> %s", sb->s_id);
infoln("options -> %s", (char *)data);
 
if (unlikely(!sb_set_blocksize(sb, EROFS_BLKSIZ))) {
@@ -453,20 +452,10 @@ static int erofs_read_super(struct super_block *sb,
goto err_iget;
}
 
-   /* save the device name to sbi */
-   sbi->dev_name = __getname();
-   if (!sbi->dev_name) {
-   err = -ENOMEM;
-   goto err_devname;
-   }
-
-   snprintf(sbi->dev_name, PATH_MAX, "%s", dev_name);
-   sbi->dev_name[PATH_MAX - 1] = '\0';
-
erofs_register_super(sb);
 
if (!silent)
-   infoln("mounted on %s with opts: %s.", dev_name,
+   infoln("mounted on %s with opts: %s.", sb->s_id,
   (char *)data);
return 0;
/*
@@ -474,9 +463,6 @@ static int erofs_read_super(struct super_block *sb,
 * the following name convention, thus new features
 * can be integrated easily without renaming labels.
 */
-err_devname:
-   dput(sb->s_root);
-   sb->s_root = NULL;

Re: Procedure questions - new filesystem driver..

2019-07-08 Thread Al Viro
On Mon, Jul 08, 2019 at 08:37:42PM -0400, Valdis Klētnieks wrote:
> I have an out-of-tree driver for the exfat file system that I beaten into 
> shape
> for upstreaming. The driver works, and passes sparse and checkpatch (except
> for a number of line-too-long complaints).
> 
> Do you want this taken straight to the fs/ tree, or through drivers/staging?

First of all, post it...
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH V2] staging: fieldbus: anybus-s: force endiannes annotation

2019-04-30 Thread Al Viro
On Tue, Apr 30, 2019 at 09:32:20AM -0400, Sven Van Asbroeck wrote:
> On Tue, Apr 30, 2019 at 12:19 AM Al Viro  wrote:
> >
> > ... not that there's much sense keeping ->fieldbus_type in host-endian,
> > while we are at it.
> 
> Interesting! Suppose we make device->fieldbus_type bus-endian.
> Then the endinan-ness conversion either needs to happen in
> bus_match() (and we'd have to convert endianness each time
> this function is called).
> Or, we make driver->fieldbus_type bus-endian also, then there
> is no need for conversion... but the driver writer has to remember
> to specify this in bus endianness:
> 
> static struct anybuss_client_driver profinet_driver = {
> .probe = ...,
> .fieldbus_type = endian convert?? (0x0089),
> };
> 
> Which pushes bus implementation details onto the
> client driver writer? Also, how to convert a constant
> to a specific endianness in a static initializer?

cpu_to_be16() or htons() - either will be fine there.
On little-endian you'll get
htons(0x0089) =>
___htons(0x0089) =>
__cpu_to_be16(0x0089) =>
((__force __be16)__swab16((0x0089))) =>
((__be16)(__builtin_constant_p((__u16)((0x0089))) ?
___constant_swab16((0x0089)) : __fswab16((0x0089))) =>
((__be16)(__builtin_constant_p((__u16)((0x0089))) ?
((__u16)__u16)((0x0089)) & (__u16)0x00ffU) << 8) |
 (((__u16)((0x0089)) & (__u16)0xff00U) >> 8))) :
__fswab16((0x0089)))
and once the preprocessor has produced that, from compiler POV we have
a constant expression as argument of __builtin_constant_p(), so it
evaluates as true, reducing the whole thing to
((__be16)(((__u16)__u16)((0x0089)) & (__u16)0x00ffU) << 8) |
 (((__u16)((0x0089)) & (__u16)0xff00U) >> 8))) )
i.e. (__be16)0x8900.  On big-endian expansion will be different,
resulting in (__be16)0x0089...

IOW, you can use endianness convertors in static initializers; things
like
struct sockaddr_in addr = {.sin_addr.s_addr = htonl(0x7f01),
 .sin_port = htons(25),
 .sin_family = AF_INET};
are fine kernel-side (from the compiler POV, that is - something
trying to speak SMTP in the kernel code would obviously be a bad sign).

As for having to remember - sparse will complain about endianness mismatches
in initializer...
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH V2] staging: fieldbus: anybus-s: force endiannes annotation

2019-04-29 Thread Al Viro
On Tue, Apr 30, 2019 at 05:33:10AM +0200, Nicholas Mc Guire wrote:

> ok - my bad thn - I had assumed that using __force is reasonable
> if the handling is correct and its a localized conversoin only 
> like var = be16_to_cpu(var) which evaded introducing additinal
> variables just to have different types but no different function.

If compiler can't recognize that in

T1 v1;
T2 v2;

code using v1, but not v2
v2 = f(v1);
code using v2, but not v1

it can use the same memory for v1 and v2, file a bug against the
compiler.  Or stop using that toy altogether - that kind of
optimizations is early 60s stuff and any real compiler will
handle that.  Both gcc and clang certainly do handle that.

Another thing they handle is figuring out that be16_to_cpu()
et.al. are pure functions, so

f(be16_to_cpu(n));
no modifications of n
g(be16_to_cpu(n));

doesn't need to have le16_to_cpu recalculated.  IOW, that particular
code could as well have been
dev_info(dev, "Fieldbus type: %04X", be16_to_cpu(fieldbus_type));
...
cd->client->fieldbus_type = be16_to_cpu(fieldbus_type);

... not that there's much sense keeping ->fieldbus_type in host-endian,
while we are at it.
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH V2] staging: fieldbus: anybus-s: force endiannes annotation

2019-04-29 Thread Al Viro
On Tue, Apr 30, 2019 at 04:22:38AM +0200, Nicholas Mc Guire wrote:
> On Mon, Apr 29, 2019 at 10:03:36AM -0400, Sven Van Asbroeck wrote:
> > On Mon, Apr 29, 2019 at 2:11 AM Nicholas Mc Guire  wrote:
> > >
> > > V2: As requested by Sven Van Asbroeck  make the
> > > impact of the patch clear in the commit message.
> > 
> > Thank you, but did you miss my comment about creating a local variable
> > instead? See:
> > https://lkml.org/lkml/2019/4/28/97
> 
> Did not miss it - I just don't think that makes it any more
> understandable - the __force __be16 makes it clear I believe
> that this is correct, sparse does not like this though - so tell
> sparse.

... to STFU, 'cause you know better.  The trouble is, how do we
(or yourself a year or two later) know *why* it is correct?
Worse, how do we (or yourself, etc.) know if a change about to be
done to the code won't invalidate the proof of yours?

> The local variable would need to be explained as it is
> functionally not necessary - therefor I find it more confusing
> that using  __force here.

What's confusing is mixing host- and fixed-endian values in the
same variable at different times.  Treat those as unrelated
types that happen to have the same sizeof.

Quite a few of __force instances in the tree should be taken out
and shot.  Don't add to their number.
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH v3 12/26] compat_ioctl: move more drivers to compat_ptr_ioctl

2019-04-25 Thread Al Viro
On Thu, Apr 25, 2019 at 05:55:23PM +0200, Arnd Bergmann wrote:
> On Thu, Apr 25, 2019 at 5:35 PM Al Viro  wrote:
> >
> > On Thu, Apr 25, 2019 at 12:21:53PM -0300, Mauro Carvalho Chehab wrote:
> >
> > > If I understand your patch description well, using compat_ptr_ioctl
> > > only works if the driver is not for s390, right?
> >
> > No; s390 is where "oh, just set ->compat_ioctl same as ->unlocked_ioctl
> > and be done with that; compat_ptr() is a no-op anyway" breaks.  IOW,
> > s390 is the reason for having compat_ptr_ioctl() in the first place;
> > that thing works on all biarch architectures, as long as all stuff
> > handled by ->ioctl() takes pointer to arch-independent object as
> > argument.  IOW,
> > argument ignored => OK
> > any arithmetical type => no go, compat_ptr() would bugger it
> > pointer to int => OK
> > pointer to string => OK
> > pointer to u64 => OK
> > pointer to struct {u64 addr; char s[11];} => OK
> 
> To be extra pedantic, the 'struct {u64 addr; char s[11];} '
> case is also broken on x86, because sizeof (obj) is smaller
> on i386, even though the location of the members are
> the same. i.e. you can copy_from_user() this, but not
> copy_to_user(), which overwrites 4 bytes after the end of
> the 20-byte user structure.

D'oh!  FWIW, it might be worth putting into Documentation/ somewhere;
basically, what is and what isn't biarch-neutral.

Or arch-neutral, for that matter - it's very close.  The only real
exception, IIRC, is an extra twist on m68k, where int behaves
like x86 long long - its alignment is only half its size, so
sizeof(struct {char c; int x;}) is 6, not 8 as everywhere
else.  Irrelevant for biarch, thankfully (until somebody gets insane
enough to implement 64bit coldfire, kernel port for it *and* biarch
support for m68k binaries on that thing, that is)...
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH v3 12/26] compat_ioctl: move more drivers to compat_ptr_ioctl

2019-04-25 Thread Al Viro
On Thu, Apr 25, 2019 at 12:21:53PM -0300, Mauro Carvalho Chehab wrote:

> If I understand your patch description well, using compat_ptr_ioctl
> only works if the driver is not for s390, right?

No; s390 is where "oh, just set ->compat_ioctl same as ->unlocked_ioctl
and be done with that; compat_ptr() is a no-op anyway" breaks.  IOW,
s390 is the reason for having compat_ptr_ioctl() in the first place;
that thing works on all biarch architectures, as long as all stuff
handled by ->ioctl() takes pointer to arch-independent object as
argument.  IOW,
argument ignored => OK
any arithmetical type => no go, compat_ptr() would bugger it
pointer to int => OK
pointer to string => OK
pointer to u64 => OK
pointer to struct {u64 addr; char s[11];} => OK
pointer to long => needs explicit handler
pointer to struct {void *addr; char s[11];} => needs explicit handler
pointer to struct {int x; u64 y;} => needs explicit handler on amd64
For "just use ->unlocked_ioctl for ->ioctl" we have
argument ignored => OK
any arithmetical type => OK
any pointer => instant breakage on s390, in addtion to cases that break
with compat_ptr_ioctl().

Probably some form of that ought to go into commit message for 
compat_ptr_ioctl()
introduction...
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH] tty: Fix WARNING in tty_set_termios

2019-01-25 Thread Al Viro
On Fri, Jan 25, 2019 at 04:29:05PM -0700, Shuah Khan wrote:
> tty_set_termios() has the following WARMN_ON which can be triggered with a
> syscall to invoke TIOCGETD __NR_ioctl.
> 
> WARN_ON(tty->driver->type == TTY_DRIVER_TYPE_PTY &&
> tty->driver->subtype == PTY_TYPE_MASTER);
> Reference: 
> https://syzkaller.appspot.com/bug?id=2410d22f1d8e5984217329dd0884b01d99e3e48d
> 
> A simple change would have been to print error message instead of WARN_ON.
> However, the callers assume that tty_set_termios() always returns 0 and
> don't check return value. The complete solution is fixing all the callers
> to check error and bail out to fix the WARN_ON.
> 
> This fix changes tty_set_termios() to return error and all the callers
> to check error and bail out. The reproducer is used to reproduce the
> problem and verify the fix.

> --- a/drivers/bluetooth/hci_ldisc.c
> +++ b/drivers/bluetooth/hci_ldisc.c
> @@ -321,6 +321,8 @@ void hci_uart_set_flow_control(struct hci_uart *hu, bool 
> enable)
>   status = tty_set_termios(tty, &ktermios);
>   BT_DBG("Disabling hardware flow control: %s",
>  status ? "failed" : "success");
> + if (status)
> + return;

Can that ldisc end up set on pty master?  And does it make any sense there?

> diff --git a/drivers/tty/serdev/serdev-ttyport.c 
> b/drivers/tty/serdev/serdev-ttyport.c
> index fa1672993b4c..29b51370deac 100644
> --- a/drivers/tty/serdev/serdev-ttyport.c
> +++ b/drivers/tty/serdev/serdev-ttyport.c
> @@ -136,7 +136,9 @@ static int ttyport_open(struct serdev_controller *ctrl)
>   ktermios.c_cflag |= CRTSCTS;
>   /* Hangups are not supported so make sure to ignore carrier detect. */
>   ktermios.c_cflag |= CLOCAL;
> - tty_set_termios(tty, &ktermios);
> + ret = tty_set_termios(tty, &ktermios);

How can _that_ happen to pty master?

> diff --git a/net/nfc/nci/uart.c b/net/nfc/nci/uart.c
> index 78fe622eba65..9978c21ce34d 100644
> --- a/net/nfc/nci/uart.c
> +++ b/net/nfc/nci/uart.c
> @@ -447,6 +447,7 @@ void nci_uart_set_config(struct nci_uart *nu, int 
> baudrate, int flow_ctrl)
>   else
>   new_termios.c_cflag &= ~CRTSCTS;
>  
> + /* FIXME tty_set_termios() could return error */

Ditto for this one.

IOW, I don't believe that this patch makes any sense.  If anything,
we need to prevent unconditional tty_set_termios() on the path
that *does* lead to calling it for pty.
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH 0/5] binderfs: debug galore

2019-01-18 Thread Al Viro
On Fri, Jan 18, 2019 at 03:53:39PM +0100, Christian Brauner wrote:
> Hey everyone,
> 
> Al gave me a really helpful review of binderfs and pointed out a range
> of bugs. The most obvious and serious ones have fortunately already been
> taken care of by patches sitting in Greg's char-misc-linus tree. The
> others are hopefully all covered in this patchset.

BTW, binderfs_binder_device_create() looks rather odd - it would be easier
to do this:
inode_lock(d_inode(root));
/* look it up */
dentry = lookup_one_len(name, root, strlen(name));
if (IS_ERR(dentry)) {
/* some kind of error (ENOMEM, permissions) - report */
inode_unlock(d_inode(root));
ret = PTR_ERR(dentry);
goto err;
}
if (d_really_is_positive(dentry)) {
/* already exists */
dput(dentry);
inode_unlock(d_inode(root));
ret = -EEXIST;
goto err;
}
inode->i_private = device;
... and from that point on - as in your variant.  Another thing in there:
name = kmalloc(name_len, GFP_KERNEL);
if (!name)
goto err;

strscpy(name, req->name, name_len);
is an odd way to go; more straightforward would be
req->name[BINDERFS_MAX_NAME] = '\0';/* NUL-terminate */
name = kmemdup(req->name, sizeof(req->name), GEP_KERNEL);
if (!name)

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH 3/5] binderfs: rework binderfs_fill_super()

2019-01-18 Thread Al Viro
On Fri, Jan 18, 2019 at 03:53:42PM +0100, Christian Brauner wrote:
>  static int binderfs_fill_super(struct super_block *sb, void *data, int 
> silent)
>  {
> + int ret;
>   struct binderfs_info *info;
> - int ret = -ENOMEM;
>   struct inode *inode = NULL;
>   struct ipc_namespace *ipc_ns = current->nsproxy->ipc_ns;
>  
> @@ -495,13 +495,14 @@ static int binderfs_fill_super(struct super_block *sb, 
> void *data, int silent)
>   sb->s_op = &binderfs_super_ops;
>   sb->s_time_gran = 1;
>  
> - info = kzalloc(sizeof(struct binderfs_info), GFP_KERNEL);
> - if (!info)
> - goto err_without_dentry;
> + sb->s_fs_info = kzalloc(sizeof(struct binderfs_info), GFP_KERNEL);
> + if (!sb->s_fs_info)
> + return -ENOMEM;
> + info = sb->s_fs_info;

... and that's when you should grab ipcns reference and stick it into
info->ipc_ns, to match the logics in binderfs_kill_super().

Otherwise the failure above

>   ret = binderfs_parse_mount_opts(data, &info->mount_opts);
>   if (ret)
> - goto err_without_dentry;
> + return ret;

... or here leaves you with an ipcns leak.

Destructor does
if ->s_fs_info is non-NULL
release ->s_fs_info->ipc_ns
free ->s_fs_info
so constructor should not leave object in a state when ipcns is already
grabbed, but not stored in ->s_fs_info->ipc_ns (including the case of
allocation failure leaving it with NULL ->s_fs_info).
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH 2/5] binderfs: prevent renaming the control dentry

2019-01-18 Thread Al Viro
On Fri, Jan 18, 2019 at 03:53:41PM +0100, Christian Brauner wrote:
> We don't allow to unlink it since it is crucial for binderfs to be useable
> but if we allow to rename it we make the unlink trivial to bypass. So
> prevent renaming too and simply treat the control dentry as immutable.
> 
> Take the opportunity and turn the check for the control dentry into a
> separate helper is_binderfs_control_device() since it's now used in two
> places.
> Additionally, replace the custom rename dance we did with call to
> simple_rename().

Umm...

> +static inline bool is_binderfs_control_device(const struct inode *inode,
> +   const struct dentry *dentry)
> +{
> + return BINDERFS_I(inode)->control_dentry == dentry;
> +}

What do you need an inode for?

static inline struct binderfs_info *BINDERFS_I(const struct inode *inode) 
{
return inode->i_sb->s_fs_info;
}

so it looks like all you care about is the superblock.  Which can be
had simply as dentry->d_sb...

Besides, what's the point of calling is_binderfs_device() in ->rename()?
If your directory methods are given dentries from another filesystem,
the kernel is already FUBAR.  So your rename should simply do
if (is_binderfs_control_device(old_dentry) ||
is_binderfs_control_device(new_dentry))
return -EPERM;
return simple_rename(..);
and that's it...
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH v2] binder: fix use-after-free due to ksys_close() during fdget()

2018-12-14 Thread Al Viro
On Fri, Dec 14, 2018 at 12:38:15PM -0800, Todd Kjos wrote:
> 44d8047f1d8 ("binder: use standard functions to allocate fds")
> exposed a pre-existing issue in the binder driver.
> 
> fdget() is used in ksys_ioctl() as a performance optimization.
> One of the rules associated with fdget() is that ksys_close() must
> not be called between the fdget() and the fdput(). There is a case
> where this requirement is not met in the binder driver which results
> in the reference count dropping to 0 when the device is still in
> use. This can result in use-after-free or other issues.
> 
> If userpace has passed a file-descriptor for the binder driver using
> a BINDER_TYPE_FDA object, then kys_close() is called on it when
> handling a binder_ioctl(BC_FREE_BUFFER) command. This violates
> the assumptions for using fdget().
> 
> The problem is fixed by deferring the fd close using task_work_add()
> so ksys_close() is called after returning from binder_ioctl().
> 
> Fixes: 44d8047f1d87a ("binder: use standard functions to allocate fds")
> Suggested-by: Al Viro 
> Signed-off-by: Todd Kjos 

Umm...  IMO you are making it more brittle than needed.  Descriptors
(as in, integers serving as indices in file descriptor tables) are
sensitive to a lot of things and generally you don't want to pass
them around, at least not without a lot more context than you do.

References to struct file are much more robust.  And frankly, ksys_close()
is best not touched - what you want is basically a version of __close_fd()
that would grab a reference to struct file before filp_close() and
passed that reference to you.  Then your delayed ksys_close() would turn
into (equally delayed) fput().

Something like
int rip_fd(int fd, struct file **res)
{
struct files_struct *files = current->files;
struct file *file;
struct fdtable *fdt;

spin_lock(&files->file_lock);
fdt = files_fdtable(files);
if (fd >= fdt->max_fds)
goto out_unlock;
file = fdt->fd[fd];
if (!file)
goto out_unlock;
rcu_assign_pointer(fdt->fd[fd], NULL);
__put_unused_fd(files, fd);
spin_unlock(&files->file_lock);
get_file(file);
*res = file;
return filp_close(file, files);

out_unlock:
spin_unlock(&files->file_lock);
*res = NULL;
return -ENOENT;
}

used as
error = rip_fd(fd, &file);
/* we are committed to arranging fput(file) now, error or not */

Frankly, the main objection to exporting that would be to avoid encouraging
the "we'll just pass the number around" kind of braindamage.  In case of
binder you are locked into that braindamage by an atrocious userland API
design and warnings along the lines of "use that and you *will* have
to explain yourself; yes, we will be watching" might suffice to prevent
additional uses...
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH v2] binder: fix use-after-free due to fdget() optimization

2018-12-05 Thread Al Viro
On Wed, Dec 05, 2018 at 04:21:55PM -0800, Todd Kjos wrote:

> > How about grabbing the references to all victims (*before* screwing with
> > ksys_close()), sticking them into a structure with embedded callback_head
> > and using task_work_add() on it, the callback doing those fput()?
> >
> > The callback would trigger before the return to userland, so observable
> > timing of the final close wouldn't be changed.  And it would avoid the
> > kludges like this.
> 
> I'll rework it according to your suggestion. I had hoped to do this in a way
> that doesn't require adding calls to non-exported functions since we are
> trying to clean up binder (I hear you snickering) to be a better citizen and
> not rely on internal functions that drivers shouldn't be using. I presume
> there are no plans to export task_work_add()...

Er...  Your variant critically depends upon binder being non-modular; if it
*was* built as a module, you could
* lose the timeslice just after your fput()
* have another process hit the final fput() *and* close the struct file
* now that module refcount is not pinned by anything, get rmmod remove
your module
* have the process in binder_ioctl() regain the timeslice and find the
code under it gone.

That's one of the reasons why such kludges are brittle as hell - normally you
are guaranteed that once fdget() has succeeded, the final fput() won't happen
until fdput().  With everything that guarantees in terms of code/data not going
away under you.  This patch relies upon the lack of accesses to anything
sensitive after that fput() added into binder_ioctl().  Which is actually
true, but only because the driver is not modular...

At least this variant (task_work_add()-based) doesn't depend on anything
subtle - the lack of exports is the only problem there (IOW, it would've
worked in a module if not for that).
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH v2] binder: fix use-after-free due to fdget() optimization

2018-12-05 Thread Al Viro
On Wed, Dec 05, 2018 at 01:16:01PM -0800, Todd Kjos wrote:
> 44d8047f1d87a ("binder: use standard functions to allocate fds")
> exposed a pre-existing issue in the binder driver.
> 
> fdget() is used in ksys_ioctl() as a performance optimization.
> One of the rules associated with fdget() is that ksys_close() must
> not be called between the fdget() and the fdput(). There is a case
> where this requirement is not met in the binder driver (and possibly
> other drivers) which results in the reference count dropping to 0
> when the device is still in use. This can result in use-after-free
> or other issues.
> 
> This was observed with the following sequence of events:
> 
> Task A and task B are connected via binder; task A has /dev/binder open at
> file descriptor number X. Both tasks are single-threaded.
> 
> 1. task B sends a binder message with a file descriptor array
>(BINDER_TYPE_FDA) containing one file descriptor to task A
> 2. task A reads the binder message with the translated file
>descriptor number Y
> 3. task A uses dup2(X, Y) to overwrite file descriptor Y with
>the /dev/binder file
> 4. task A unmaps the userspace binder memory mapping; the reference
>count on task A's /dev/binder is now 2
> 5. task A closes file descriptor X; the reference count on task
>A's /dev/binder is now 1
> 6. task A forks off a child, task C, duplicating the file descriptor
>table; the reference count on task A's /dev/binder is now 2
> 7. task A invokes the BC_FREE_BUFFER command on file descriptor X
>to release the incoming binder message
> 8. fdget() in ksys_ioctl() suppresses the reference count increment,
>since the file descriptor table is not shared
> 9. the BC_FREE_BUFFER handler removes the file descriptor table
>entry for X and decrements the reference count of task A's
>/dev/binder file to 1
> 10.task C calls close(X), which drops the reference count of
>task A's /dev/binder to 0 and frees it
> 11.task A continues processing of the ioctl and accesses some
>property of e.g. the binder_proc => KASAN-detectable UAF
> 
> Fixed by using get_file() / fput() in binder_ioctl().

Note that this patch does *not* remove the nasty trap caused by the garbage
in question - struct file can be freed before we even return from
->unlocked_ioctl().  Could you describe in details the desired behaviour
of this interface?

How about grabbing the references to all victims (*before* screwing with
ksys_close()), sticking them into a structure with embedded callback_head
and using task_work_add() on it, the callback doing those fput()?

The callback would trigger before the return to userland, so observable
timing of the final close wouldn't be changed.  And it would avoid the
kludges like this.

Of course, the proper fix would require TARDIS and set of instruments for
treating severe case of retrocranial inversion, so that this "ABI" would've
never existed, but...
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH v2 05/17] compat_ioctl: move more drivers to generic_compat_ioctl_ptrarg

2018-09-14 Thread Al Viro
On Fri, Sep 14, 2018 at 01:35:06PM -0700, Darren Hart wrote:
 
> Acked-by: Darren Hart (VMware) 
> 
> As for a longer term solution, would it be possible to init fops in such
> a way that the compat_ioctl call defaults to generic_compat_ioctl_ptrarg
> so we don't have to duplicate this boilerplate for every ioctl fops
> structure?

Bad idea, that...  Because several years down the road somebody will add
an ioctl that takes an unsigned int for argument.  Without so much as looking
at your magical mystery macro being used to initialize file_operations.

FWIW, I would name that helper in more blunt way - something like
compat_ioctl_only_compat_pointer_ioctls_here()...
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH] staging: speakup: fix wraparound in uaccess length check

2018-07-12 Thread Al Viro
On Fri, Jul 13, 2018 at 12:29:36AM +0200, Jann Horn wrote:
> From: Samuel Thibault 
> 
> From: Samuel Thibault 
> 
> If softsynthx_read() is called with `count < 3`, `count - 3` wraps, causing
> the loop to copy as much data as available to the provided buffer. If
> softsynthx_read() is invoked through sys_splice(), this causes an
> unbounded kernel write; but even when userspace just reads from it
> normally, a small size could cause userspace crashes.

Or you could try this (completely untested, though):

diff --git a/drivers/staging/speakup/speakup_soft.c 
b/drivers/staging/speakup/speakup_soft.c
index a61bc41b82d7..198936ed0b54 100644
--- a/drivers/staging/speakup/speakup_soft.c
+++ b/drivers/staging/speakup/speakup_soft.c
@@ -192,13 +192,10 @@ static int softsynth_close(struct inode *inode, struct 
file *fp)
return 0;
 }
 
-static ssize_t softsynthx_read(struct file *fp, char __user *buf, size_t count,
-  loff_t *pos, int unicode)
+static ssize_t softsynthx_read_iter(struct kiocb *iocb, struct iov_iter *to, 
int unicode)
 {
int chars_sent = 0;
-   char __user *cp;
char *init;
-   u16 ch;
int empty;
unsigned long flags;
DEFINE_WAIT(wait);
@@ -211,7 +208,7 @@ static ssize_t softsynthx_read(struct file *fp, char __user 
*buf, size_t count,
if (!synth_buffer_empty() || speakup_info.flushing)
break;
spin_unlock_irqrestore(&speakup_info.spinlock, flags);
-   if (fp->f_flags & O_NONBLOCK) {
+   if (iocb->ki_flags & IOCB_NOWAIT) {
finish_wait(&speakup_event, &wait);
return -EAGAIN;
}
@@ -224,11 +221,14 @@ static ssize_t softsynthx_read(struct file *fp, char 
__user *buf, size_t count,
}
finish_wait(&speakup_event, &wait);
 
-   cp = buf;
init = get_initstring();
 
/* Keep 3 bytes available for a 16bit UTF-8-encoded character */
-   while (chars_sent <= count - 3) {
+   while (iov_iter_count(to)) {
+   u_char s[3];
+   int l, n;
+   u16 ch;
+
if (speakup_info.flushing) {
speakup_info.flushing = 0;
ch = '\x18';
@@ -244,60 +244,47 @@ static ssize_t softsynthx_read(struct file *fp, char 
__user *buf, size_t count,
spin_unlock_irqrestore(&speakup_info.spinlock, flags);
 
if ((!unicode && ch < 0x100) || (unicode && ch < 0x80)) {
-   u_char c = ch;
-
-   if (copy_to_user(cp, &c, 1))
-   return -EFAULT;
-
-   chars_sent++;
-   cp++;
+   s[0] = ch;
+   l = 1;
} else if (unicode && ch < 0x800) {
-   u_char s[2] = {
-   0xc0 | (ch >> 6),
-   0x80 | (ch & 0x3f)
-   };
-
-   if (copy_to_user(cp, s, sizeof(s)))
-   return -EFAULT;
-
-   chars_sent += sizeof(s);
-   cp += sizeof(s);
+   s[0] = 0xc0 | (ch >> 6);
+   s[1] = 0x80 | (ch & 0x3f);
+   l = 2;
} else if (unicode) {
-   u_char s[3] = {
-   0xe0 | (ch >> 12),
-   0x80 | ((ch >> 6) & 0x3f),
-   0x80 | (ch & 0x3f)
-   };
-
-   if (copy_to_user(cp, s, sizeof(s)))
-   return -EFAULT;
-
-   chars_sent += sizeof(s);
-   cp += sizeof(s);
+   s[0] = 0xe0 | (ch >> 12);
+   s[1] = 0x80 | ((ch >> 6) & 0x3f);
+   s[2] = 0x80 | (ch & 0x3f);
+   l = 3;
}
-
+   n = copy_to_iter(s, l, to);
+   if (n != l) {
+   iov_iter_revert(to, n);
+   spin_lock_irqsave(&speakup_info.spinlock, flags);
+   break;
+   }
+   chars_sent += l;
spin_lock_irqsave(&speakup_info.spinlock, flags);
}
-   *pos += chars_sent;
+   iocb->ki_pos += chars_sent;
empty = synth_buffer_empty();
spin_unlock_irqrestore(&speakup_info.spinlock, flags);
if (empty) {
speakup_start_ttys();
-   *pos = 0;
+   iocb->ki_pos = 0;
}
return chars_sent;
 }
 
-static ssize_t softsynth_read(struct file *fp, char __user *buf, size_t count,
+static ssize_t softsynth_read_iter(struct kiocb *iocb, struct iov_iter *to)
  loff_t *pos)
 {
-   return softsynthx_read(fp, buf, count

Re: simplify procfs code for seq_file instances V3

2018-05-16 Thread Al Viro
On Wed, May 16, 2018 at 11:43:04AM +0200, Christoph Hellwig wrote:
> We currently have hundreds of proc files that implement plain, read-only
> seq_file based interfaces.  This series consolidates them using new
> procfs helpers that take the seq_operations or simple show callback
> directly.
> 
> A git tree is available at:
> 
> git://git.infradead.org/users/hch/misc.git proc_create.3

Pulled, but the last bit is a bleeding atrocity in need of followup
cleanup.
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: simplify procfs code for seq_file instances V2

2018-05-06 Thread Al Viro
On Sun, May 06, 2018 at 08:19:49PM +0300, Alexey Dobriyan wrote:
> +++ b/fs/proc/internal.h
> @@ -48,8 +48,8 @@ struct proc_dir_entry {
>   const struct seq_operations *seq_ops;
>   int (*single_show)(struct seq_file *, void *);
>   };
> - unsigned int state_size;
>   void *data;
> + unsigned int state_size;
>   unsigned int low_ino;
>   nlink_t nlink;
>   kuid_t uid;

Makes sense

> @@ -62,9 +62,9 @@ struct proc_dir_entry {
>   umode_t mode;
>   u8 namelen;
>  #ifdef CONFIG_64BIT
> -#define SIZEOF_PDE_INLINE_NAME   (192-139)
> +#define SIZEOF_PDE_INLINE_NAME   (192-155)
>  #else
> -#define SIZEOF_PDE_INLINE_NAME   (128-87)
> +#define SIZEOF_PDE_INLINE_NAME   (128-95)

>  #endif
>   char inline_name[SIZEOF_PDE_INLINE_NAME];
>  } __randomize_layout;

*UGH*

Both to the original state and that kind of "adjustments".
Incidentally, with __bugger_layout in there these expressions
are simply wrong.

If nothing else, I would suggest turning the last one into
char inline_name[];
in hope that layout won't get... randomized that much and
used

#ifdef CONFIG_64BIT
#define PDE_SIZE 192
#else
#define PDE_SIZE 128
#endif

union __proc_dir_entry {
char pad[PDE_SIZE];
struct proc_dir_entry real;
};

#define SIZEOF_PDE_INLINE_NAME (PDE_SIZE - offsetof(struct proc_dir_entry, 
inline_name))

for constants, adjusted sizeof and sizeof_field when creating
proc_dir_entry_cache and turned proc_root into

union __proc_dir_entry __proc_root = { .real = {
.low_ino= PROC_ROOT_INO,
.namelen= 5,
.mode   = S_IFDIR | S_IRUGO | S_IXUGO,
.nlink  = 2,
.refcnt = REFCOUNT_INIT(1),
.proc_iops  = &proc_root_inode_operations,
.proc_fops  = &proc_root_operations,
.parent = &__proc_root.real,
.subdir = RB_ROOT,
.name   = __proc_root.real.inline_name,
.inline_name= "/proc",
}};

#define proc_root __proc_root.real
(or actually used __proc_root.real in all of a 6 places where it remains).

> diff --git a/fs/proc/proc_net.c b/fs/proc/proc_net.c
> index baf1994289ce..7d94fa005b0d 100644
> --- a/fs/proc/proc_net.c
> +++ b/fs/proc/proc_net.c
> @@ -40,7 +40,7 @@ static struct net *get_proc_net(const struct inode *inode)
>  
>  static int seq_open_net(struct inode *inode, struct file *file)
>  {
> - size_t state_size = PDE(inode)->state_size;
> + unsigned int state_size = PDE(inode)->state_size;
>   struct seq_net_private *p;
>   struct net *net;


You and your "size_t is evil" crusade...
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: KASAN: use-after-free Read in remove_wait_queue

2018-02-12 Thread Al Viro
On Mon, Feb 12, 2018 at 06:11:02PM +0100, Dmitry Vyukov wrote:

> The commit on which it was triggered already includes this fix. So
> there must be another bug.

Any chance of bisecting it?
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH] Staging: netlogic: platform_net: Fixed '(' at the EOL

2018-01-14 Thread Al Viro
On Sun, Jan 14, 2018 at 11:47:11PM +0530, Naveen Panwar wrote:
> Removed '(' from the end of line, coding style issue.

The one and only reason for warnings is that they point to
places more likely to be dodgy.  There is no inherent value
in having e.g. checkpatch.pl STFU, all wanking about uniformity
of style nonwithstanding.

If you end up figuring out how to manipulate some code so that
some warning would go away, something is wrong.  Either the
warning is bogus (which it might very well be - the point of
a warning is "might be worth looking here" and considering
the... level of sophistication of some of those, you can't
expect to get no false alarms) or there *is* something
dodgy in the vicinity.  Dodgy beyond the "this heuristic
triggers", that is.

The first thing to do when dealing with any warning is to
look around and see if it has caught something interesting.
In this case the warning points to excessively long expressions.
With your patch they *still* are just as long, but split in
more unnatural way, making checkpatch.pl miss them.

All of them appear to have the same form - CPHYSADDR applied to
nlm_mmio_base result.  Moreover, looking around that file
shows that all uses of CPHYSADDR and nlm_mmio_base in it
are parts of such expressions.

Most of those expressions are too long and hard to read, so
cleaning them up would probably be a good idea.  And seeing
that composition of these functions keeps occuring in that
sucker, making that composition an inlined helper appears
to be called for.

So
static inline  something( offset)
{
return CPHYSADDR(nlm_mmio_base(offset));
}

and turn those into

gmac4_addr = ioremap(something(NETLOGIC_IO_GMAC_4_OFFSET), 0xfff);

void __iomem *gmac0_addr = ioremap(something(NETLOGIC_IO_GMAC_0_OFFSET),
   0xfff);
 
gpio_addr = ioremap(something(NETLOGIC_IO_GPIO_OFFSET), 0xfff);

ndata0.mii_addr = ioremap(something(NETLOGIC_IO_GMAC_0_OFFSET), 0xfff);

and turn
res->start = CPHYSADDR(nlm_mmio_base(offset));
in xlr_resource_init() into
res->start = something(offset);
as well.  What should the types be?  Result is either fed to ioremap(), or
stored in struct resource 'start' field.  The latter is resource_size_t;
the former varies among the architectures.  Some take resource_size_t,
some - phys_addr_t, some - unsigned long.  On mips (that driver appears to
be mips-only) ioremap takes phys_addr_t; the difference is cosmetical,
anyway, since resource_size_t is typedefed to phys_addr_t on all architectures.

So let it return phys_addr_t.  As for the argument type, looks like it's
an explicit constant or, in case of xlr_resource_init(), an int.  Grepping
shows that all constants involved do fit into int, so we arrive at

static inline phys_addr_t something(int offset)
{
return CPHYSADDR(nlm_mmio_base(offset));
}

probably best placed just before the first use.  OTOH, nlm_mmio_base() is
declared as taking uint32_t, so that might be a better fit for argument.
All constants fed there are between 0 and 2^31, so the only question is
what values does xlr_resource_init() get passed in 'offset' argument.
Callers are
xlr_resource_init(&xlr_net1_res[mac * 2],
  xlr_gmac_offsets[mac + 4],
  xlr_gmac_irqs[mac + 4]);
xlr_resource_init(&xlr_net0_res[0], xlr_gmac_offsets[0],
  xlr_gmac_irqs[0]);
xlr_resource_init(&xlr_net0_res[mac * 2],
  xlr_gmac_offsets[mac],  
xlr_gmac_irqs[mac]);
xlr_resource_init(&xlr_net0_res[mac * 2], xlr_gmac_offsets[mac],
  xlr_gmac_irqs[mac]);

so in all cases we have xlr_gmac_offsets[] passed.  What's
going on with that array?  Initialized as
static u32 xlr_gmac_offsets[] = {
NETLOGIC_IO_GMAC_0_OFFSET, NETLOGIC_IO_GMAC_1_OFFSET,
NETLOGIC_IO_GMAC_2_OFFSET, NETLOGIC_IO_GMAC_3_OFFSET,
NETLOGIC_IO_GMAC_4_OFFSET, NETLOGIC_IO_GMAC_5_OFFSET,
NETLOGIC_IO_GMAC_6_OFFSET, NETLOGIC_IO_GMAC_7_OFFSET
};
and never modified, apparently.  OK, that pretty much settles it -
xlr_resource_init() should be getting u32 instead of int.  It's harmless
(the constants here are in the same range), but the things will be easier
for reader that way:

static inline phys_addr_t something(u32 offset)
{
return CPHYSADDR(nlm_mmio_base(offset));
}

static void xlr_resource_init(struct resource *res, u32 offset, int irq)
{
res->name = "gmac";

res->start = something(offset);

While we are at it, 'irq' argument appears to be always taken from
xlr_gmac_irqs[], which is also u32.  So I'd probably do 
static void xlr_resource_init(struct resource *res, u32 offset, u32 irq)
instead.

Now, what do we call that helper?  Definition of CPHYSADDR is
/*
 * Returns the physical

Re: [PATCH v2] binder: fix proc->files use-after-free

2017-11-17 Thread Al Viro
On Thu, Nov 16, 2017 at 09:56:50AM -0800, Todd Kjos wrote:

> +static struct files_struct *binder_get_files_struct(struct binder_proc *proc)
> +{
> + return get_files_struct(proc->tsk);
> +}

Hell, _no_.  You should never, ever use the result of get_files_struct() for
write access.  It's strictly for "let me look at other process' descriptor
table".  The whole reason for proc->files is that we want to keep a reference
that *could* be used for modifying the damn thing.  And such can be obtained
only by the process itself.

The rules are:
* you can use current->files both for read and write
* you can use get_files_struct(current) to get a reference that
can be used for modifying the damn thing.  Then it can be passed to
any other process and used by it.
* you can use get_files_struct(some_other_task) to get a reference
that can be used for examining the descriptor table of that other task.

Violation of those rules means an exploitable race.  Here's the logics
fdget() and friends are based on: "I'm going to do something to file
refered by descriptor N.  If my descriptor table is not shared, all
struct file references in it will stay around - I'm not changing it,
nobody else has it as their ->current, so any additional references
to that descriptor table will *not* be used for modifying it.
In other words, I don't need to bump the refcount of struct file I'm
about to work with - the reference from my descriptor table will keep
it alive".

Your patch breaks those assumptions.  NAK.
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH] staging: pi433: fix missing break in switch statement.

2017-11-09 Thread Al Viro
On Thu, Nov 09, 2017 at 05:19:55PM +, Colin King wrote:
> From: Colin Ian King 
> 
> The PI433_IOC_WR_RX_CFG case is missing a break and will fall through
> to the default case and errorenously return -EINVAL. Fix this by
> adding in missing break.

Folded and pushed...
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH] lustre: check copy_from_iter/copy_to_iter return code

2017-07-13 Thread Al Viro
On Thu, Jul 13, 2017 at 10:57:59PM +0200, Arnd Bergmann wrote:

> Thanks for testing it!
> 
> That means we did not copy any data and the kernel continues with
> an uninitialized buffer, right? The problem may be the definition of
> 
> struct kib_immediate_msg {
> struct lnet_hdr ibim_hdr;/* portals header */
> char ibim_payload[0]; /* piggy-backed payload */
> } WIRE_ATTR;
> 
> The check that Al added will try to ensure that we don't write
> beyond the size of the ibim_payload[] array, which unfortunately
> is defined as a zero-byte array, so I can see why it will now
> fail. However, it's already broken in mainline now, with or without
> my patch.
> 
> Are you able to come up with a fix that avoids the warning in
> 'allmodconfig' and makes the function do something reasonable
> again?

Might make sense to try and use valid C99 for "array of indefinite
size as the last member", i.e.
struct kib_immediate_msg {
 struct lnet_hdr ibim_hdr;/* portals header */
 char ibim_payload[]; /* piggy-backed payload */
} WIRE_ATTR;

Zero-sized array as the last member is gcc hack predating that;
looks like gcc gets confused into deciding that it knows the distance
from the end of object...

Said that, are we really guaranteed the IBLND_MSG_SIZE bytes
in there?
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH 001/001] drivers/staging/vt6656/main_usb.c: checkpatch warning

2017-03-31 Thread Al Viro
On Fri, Mar 31, 2017 at 08:52:50PM -0700, Joe Perches wrote:

> > MILD SUGGESTION: don't spell the function name out in format strings;
> > "this_function: foo is %d", n
> > might be better off as
> > "%s: foo is %d", __func__, n
> > in case you ever move it to another function or rename your function.
> 
> Thank you sir, may I have another.
> 
> checkpatch messages are single line.

Too bad... Incidentally, being able to get more detailed explanation of
a warning might be a serious improvement, especially if it contains
the rationale.  Hell, something like TeX handling of errors might be
a good idea - warning printed, offered actions include 'give more help',
'continue', 'exit', 'from now on suppress this kind of warning', 'from
now on just dump this kind of warning into log and keep going', 'from
now on dump all warnings into log and keep going'.

And yes, I'm serious about having something like "mild suggestion" as
possible severity - people are using that thing to look for potential
improvements to make and 'such and such change might be useful for such
and such reasons' is a lot more useful than 'this needs to be thus because
it must be thus or I'll keep warning'.
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH 001/001] drivers/staging/vt6656/main_usb.c: checkpatch warning

2017-03-31 Thread Al Viro
On Fri, Mar 31, 2017 at 08:36:22PM -0700, Joe Perches wrote:
> On Sat, 2017-04-01 at 04:32 +0100, Al Viro wrote:
> > On Fri, Mar 31, 2017 at 06:59:19PM -0700, Chewie Lin wrote:
> > > Replace string with formatted arguments in the dev_warn() call. It removes
> > > the checkpatch warning:
> > > 
> > >   WARNING: Prefer using "%s", __func__ to embedded function names
> []
> > Again, checkpatch warning is badly written
> 
> In your opinion, what wording would be better?

MILD SUGGESTION: don't spell the function name out in format strings;
"this_function: foo is %d", n
might be better off as
"%s: foo is %d", __func__, n
in case you ever move it to another function or rename your function.
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH 001/001] drivers/staging/vt6656/main_usb.c: checkpatch warning

2017-03-31 Thread Al Viro
On Fri, Mar 31, 2017 at 06:59:19PM -0700, Chewie Lin wrote:
> Replace string with formatted arguments in the dev_warn() call. It removes
> the checkpatch warning:
> 
>   WARNING: Prefer using "%s", __func__ to embedded function names
>   #417: FILE: main_usb.c:417:
>   +"usb_device_reset fail status=%d\n", status);
> 
>   total: 0 errors, 1 warnings, 1058 lines checked
> 
> And after fix:
> 
>   main_usb.c has no obvious style problems and is ready for submission.


> -  "usb_device_reset fail status=%d\n", status);
> +  "%s=%d\n", "usb_device_reset fail status", status);

Would you mind explaining the meaning of that warning?  Incidentally, why not
  "%se_reset fail status=%d\n", "usb_devic", status);
- it would produce the identical output and silences checkpatch even more
reliably.  Discuss.

Sarcasm aside, when you are proposing a change, there are several questions you
really must ask yourself and be able to answer.  First and foremost, of course,
is
* Why is it an improvement?
If the answer to that was "it makes a warning go away", the next questions are
* What are we warned about?
* What is problematic in the original variant?
* Is the replacement free from the problem we had in the original?
and if the answer to any of that is "I don't know", the next step is _not_
"send it anyway".  "Try to figure out" might be a good idea, with usual
heuristics regarding the reading comprehension ("if a sentence remains
a mystery, see if there are any unfamiliar words skipped at the first reading
and find what they mean", etc.) applying.

In this particular case the part you've apparently skipped was, indeed,
critical - "__func__".  I am not trying to defend the quality of checkpatch -
the warning is badly worded, the tool is badly written and more often than
not its suggestions reflect nothing but authors' arbitrary preferences.

This one, however, does have some rationale behind it.  Namely, if some
debugging output contains the name of a function that has produced it,
having that name spelled out in format string is not a good idea.  If
that code gets moved elsewhere one would have to replace the name in format
string or face confusing messages refering to the function where that
code used to be.  Since __func__ is interpreted as a constant string
initialized with the name of the function it's used in, it is possible
to avoid spelling the function name out - instead of
"my_function: pink elephants; reduce the daily intake to %d glasses\n", n
one could use
"%s: pink elephants; reduce the daily intake to %d glasses\n", __func__, n
producing the same output and avoiding the need to adjust anything when
the whole thing is moved to another function.  It's not particularly big
deal, but it's a more or less reasonable suggestion.

Your change, of course, has achieved only one thing - it has moved the
explicitly spelled out function name out of format string.  It's still
just as explicitly spelled out, still would need to be adjusted if moved
to another function and the whole thing has become harder to read and
understand since you've buried other parts of message in the place where
it's harder to follow.

Again, checkpatch warning is badly written, but the main problem with
your posting is not that you had been confused by checkpatch - it's
that you have posted it based on an incomprehensible message with no better
rationale than "it shuts checkpatch up, dunno why and what about".
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [Outreachy kernel] [PATCH] staging: android: Replace strcpy with strlcpy

2017-03-11 Thread Al Viro
On Sat, Mar 11, 2017 at 09:47:30PM +0100, Julia Lawall wrote:
> 
> 
> On Sun, 12 Mar 2017, simran singhal wrote:
> 
> > Replace strcpy with strlcpy as strcpy does not check for buffer
> > overflow.
> > This is found using Flawfinder.
> >
> > Signed-off-by: simran singhal 
> > ---
> >  drivers/staging/android/ashmem.c | 3 ++-
> >  1 file changed, 2 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/staging/android/ashmem.c 
> > b/drivers/staging/android/ashmem.c
> > index 7cbad0d..eb2f4ef 100644
> > --- a/drivers/staging/android/ashmem.c
> > +++ b/drivers/staging/android/ashmem.c
> > @@ -548,7 +548,8 @@ static int set_name(struct ashmem_area *asma, void 
> > __user *name)
> > if (unlikely(asma->file))
> > ret = -EINVAL;
> > else
> > -   strcpy(asma->name + ASHMEM_NAME_PREFIX_LEN, local_name);
> > +   strlcpy(asma->name + ASHMEM_NAME_PREFIX_LEN, local_name,
> > +   sizeof(asma->name + ASHMEM_NAME_PREFIX_LEN));
> 
> There is a parenthesis in the wrong place.

Worse - moving parenthesis to just after asma->name would result in
interestingly bogus value (size + amount skipped instead of size -
amount skipped).

Folks, blind changes in name of security are seriously counterproductive;
fortunately, in this particular case overflow prevention is taken care
of by earlier code (source of strcpy is a local array of size that
isn't enough to cause trouble and it is NUL-terminated), so that
particular strlcpy() is simply pointless, but if not for that...
Variant with sizeof(asma->name) + ASHMEM_NAME_PREFIX_LEN would've
invited an overflow *and* made it harder to spot in the future -
"it uses strlcpy, no worries about overflows here"...
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH] staging: android: Replace strcpy with strlcpy

2017-03-11 Thread Al Viro
On Sun, Mar 12, 2017 at 02:10:01AM +0530, simran singhal wrote:
> Replace strcpy with strlcpy as strcpy does not check for buffer
> overflow.
> This is found using Flawfinder.
> 
> Signed-off-by: simran singhal 
> ---
>  drivers/staging/android/ashmem.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/staging/android/ashmem.c 
> b/drivers/staging/android/ashmem.c
> index 7cbad0d..eb2f4ef 100644
> --- a/drivers/staging/android/ashmem.c
> +++ b/drivers/staging/android/ashmem.c
> @@ -548,7 +548,8 @@ static int set_name(struct ashmem_area *asma, void __user 
> *name)
>   if (unlikely(asma->file))
>   ret = -EINVAL;
>   else
> - strcpy(asma->name + ASHMEM_NAME_PREFIX_LEN, local_name);
> + strlcpy(asma->name + ASHMEM_NAME_PREFIX_LEN, local_name,
> + sizeof(asma->name + ASHMEM_NAME_PREFIX_LEN));

Trivial C quiz: given

struct ashmem_area {
char name[ASHMEM_FULL_NAME_LEN];
struct list_head unpinned_list;
struct file *file;
size_t size;
unsigned long prot_mask;
};
static int set_name(struct ashmem_area *asma, void __user *name)

what, in your opinion, would be
1) type of asma->name
2) type of asma->name + ASHMEM_NAME_PREFIX_LEN
3) value of sizeof(asma->name + ASHMEM_NAME_PREFIX_LEN)
As a bonus question,
4) what is the value of this kind of patches?


1) NFUZRZ_SHYY_ANZR_YRA-ryrzrag neenl bs pune
2) cbvagre gb pune
3) fvmr bs n cbvagre
4) fbpvbybtvpny - ernql-znqr vyyhfgengvbaf bs crevyf bs
pnetb phyg.
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH]staging: fbtft: Fix sparse warnings about endianness

2017-02-14 Thread Al Viro
On Tue, Feb 14, 2017 at 09:18:25AM -0800, Greg KH wrote:
> On Tue, Feb 14, 2017 at 04:53:10PM +0800, maomao xu wrote:
> > Fixed sparse warnings about endianness. E.g.:
> > 
> > warning: incorrect type in assignment (different base types)
> 
> Why are these lines indented?
> 
> > Signed-off-by: maomao xu 
> > 
> > diff --git a/drivers/staging/fbtft/fbtft-io.c 
> > b/drivers/staging/fbtft/fbtft-io.c
> > index d868405..ffb9a3b 100644
> > --- a/drivers/staging/fbtft/fbtft-io.c
> > +++ b/drivers/staging/fbtft/fbtft-io.c
> > @@ -71,7 +71,7 @@ int fbtft_write_spi_emulate_9(struct fbtft_par *par, void 
> > *buf, size_t len)
> > src++;
> > }
> > tmp |= ((*src & 0x0100) ? 1 : 0);
> > -   *(u64 *)dst = cpu_to_be64(tmp);
> > +   *(__be64 *)dst = cpu_to_be64(tmp);
> 
> Really?  That seems very odd.  I need a maintainer's ack for this before
> I can take it...

If anything, I would turn the inner loop into
tmp = 0;
for (j = 0; j < 7; j++) {
tmp <<= 9;
tmp |= *src++ & 0x1ff;
}
tmp <<= 1;
there - the whole thing looks like an obfuscated "take an array of 9-bit
values, each stored in host-endian 16bit, repack them into octets".
Which architecture is that supposed to run on?  Anything that doesn't like
unaligned stores won't be happy with that code...

Another interesting part is that we have size = len / 2 and verify that len
is a multiple of 8.  I.e. that size is only guaranteed to be a multiple
of 4.  Each pass through the outer loop consumes 8 16bit values and decrements
size by 8, so if len is e.g. 24 we'll end up accepting that, get size equal
to 12, pass through the outer loop twice and chew through 32 bytes of buf...
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCHv4 2/8] Fixed variables not being consistently lower case

2016-12-25 Thread Al Viro
On Sun, Dec 25, 2016 at 10:34:54PM +, Jonathan Cameron wrote:
> 
> 
> On 25 December 2016 20:14:09 GMT+00:00, Al Viro  
> wrote:
> >On Sun, Dec 25, 2016 at 01:41:06PM -0600, Scott Matheina wrote:
> >> Across the file, variables were sometimes upper case, some times
> >> lower case, this fix addresses a few of the instances with this
> >> inconsistency.
> >
> >NAK.  Go learn C and don't come back until you've done that.  If
> >somebody
> >has told you that you can contribute without knowing the language,
> >they'd
> >lied - you really can't.  And I would *STRONGLY* recommend to stay away
> >from drivers/staging while you are learning C - it's like trying to use
> >a public restroom wall as a sex-ed textbook.
> 
> Please can we keep things polite.

In case you have not realized it,
* Scott is -><- that close to joining the select group of kooks who
get filtered out within days of getting a new account.  At this point he
probably still can spend a while learning what needs to be learnt and
reappear with less inane patches after a while, with everything getting
forgotten.  A week more of the same kind of postings will almost certainly
cement the reputation of clue-resistant noise source beyond any chance of
repair.
* I am 100% sure that he has not learnt C - hadn't even started doing
so.  This, BTW, is not a value judgement of any kind; it's just a highly
likely conclusion based on what he'd been posting.  This particular patch,
for example, changes identifiers in a bunch of places, none of which happens
to be a declaration.  The reasons why that cannot be correct become obvious
to anyone who had opened _any_ textbook after a few pages.  Or tried to
write and run any program in C.  Again, it's not "should" - it's really one
of the first things that gets learnt ("you need to declare all variables
explicitly and the names are case-sensitive").
* One really cannot produce any useful patches without understanding
the language.  As this (and previous) patch series sent by Scott has
demonstrated, BTW.  Learning C is a hard prerequisite for doing any development
in a project written in C, including the kernel.  Fortunately, it is not
hard to do.
* Trying to do that purely by osmosis is not the best way, but it's
doable.  HOWEVER, trying to do that by osmosis when swimming in drivers/staging
is really on par with using a WC wall as sex ed tutorial.  Results will be
awkward, painful and won't satisfy anybody.  Very odd ideas of how the things
work are also practically guaranteed.

drivers/staging can serve as a playground for learning how to
produce patches, but only if you already know the language.  Otherwise
it really, really must be avoided - it's full of unidiomatic and very
badly written C.  It serves as quarantine barracks for much more serious
reasons than anything checkpatch.pl is capable of picking.  Directing the
folks new to kernel development towards that pile of code is not particularly
kind, but potentially useful.  Doing that to those who are still learning C
goes far beyond "not kind".  I can't stress it enough - don't go there if
you are still learning the language.
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCHv4 2/8] Fixed variables not being consistently lower case

2016-12-25 Thread Al Viro
On Sun, Dec 25, 2016 at 01:41:06PM -0600, Scott Matheina wrote:
> Across the file, variables were sometimes upper case, some times
> lower case, this fix addresses a few of the instances with this
> inconsistency.

NAK.  Go learn C and don't come back until you've done that.  If somebody
has told you that you can contribute without knowing the language, they'd
lied - you really can't.  And I would *STRONGLY* recommend to stay away
from drivers/staging while you are learning C - it's like trying to use
a public restroom wall as a sex-ed textbook.

While we are at it, it might be a good idea to check if the kernel
builds after your changes and see what errors are produced.
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH 0/8] Sparse warning fixes in Lustre.

2016-12-07 Thread Al Viro
On Wed, Dec 07, 2016 at 05:41:26PM -0500, Oleg Drokin wrote:
> This set of fixes aims at sparse warnings.

Speaking of the stuff sparse catches there: class_process_proc_param().
I've tried to describe what I think of that Fine Piece Of Software
several times, but I had to give up - my command of obscenity is not
up to the task, neither in English nor in Russian.  Please, take it
out.  Preferably - along with the ->ldo_process_config()/->process_config()
thing.
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [RFC 0/6] Module for tracking/accounting shared memory buffers

2016-10-11 Thread Al Viro
On Tue, Oct 11, 2016 at 04:50:04PM -0700, Ruchi Kandoi wrote:

> memtrack maintains a per-process list of shared buffer references, which is
> exported to userspace as /proc/[pid]/memtrack.  Buffers can be optionally
> "tagged" with a short string: for example, Android userspace would use this
> tag to identify whether buffers were allocated on behalf of the camera stack,
> GL, etc.  memtrack also exports the VMAs associated with these buffers so
> that pages already included in the process's mm counters aren't 
> double-counted.
> 
> Shared-buffer allocators can hook into memtrack by embedding
> struct memtrack_buffer in their buffer metadata, calling
> memtrack_buffer_{init,remove} at buffer allocation and free time, and
> memtrack_buffer_{install,uninstall} when a userspace process takes or
> drops a reference to the buffer.  For fd-backed buffers like dma-bufs, hooks 
> in
> fdtable.c and fork.c automatically notify memtrack when references are added 
> or
> removed from a process's fd table.
> 
> This patchstack adds memtrack hooks into dma-buf and ion.  If there's upstream
> interest in memtrack, it can be extended to other memory allocators as well,
> such as GEM implementations.

No, with a side of Hell, No.  Not to mention anything else,
* descriptor tables do not belong to any specific task_struct and
actions done by one show up in all who share that thing.
* shared descriptor table does not imply belonging to the same
group.
* shared descriptor table can become unshared at any point, invisibly
for that Fine Piece Of Software.
* while we are at it, blocking allocation under several spinlocks
(and with interrupts disabled, for good measure) is generally considered
a bloody bad idea.

That - just from the quick look through that patchset.  Bringing task_struct
into the API is already sufficient for a NAK.
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH] staging/ion: Add support to get ion handle from dma buf

2016-01-06 Thread Al Viro
On Wed, Jan 06, 2016 at 10:21:33AM -0800, Linus Torvalds wrote:
> On Wed, Jan 6, 2016 at 1:06 AM, Dan Carpenter  
> wrote:
> > It's not really necessary to CC linux-kernel.  No one reads it.

Some of us still do.

> > I only send patches there when there isn't another public mailing
> > list available.
> 
> Actually, cc'ing lkml is still often a good idea, because it's a great
> archiving point.

*nod*
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH] staging: most: add __iomem for io_base and registers

2016-01-02 Thread Al Viro
On Sat, Jan 02, 2016 at 08:30:21PM +, Hugo Camboulive wrote:
> This removes a few Sparse warnings.

> + g.dim2 = (struct dim2_regs __iomem *)dim_base_address;

> -u8 dim_startup(void *dim_base_address, u32 mlb_clock);
> +u8 dim_startup(void __iomem *dim_base_address, u32 mlb_clock);

Umm...  Why not have it take struct dim2_regs __iomem * as argument, and
to hell with that cast?
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH v2] staging: rtl8723au: Fix sparse errors in rtl8723a_cmd.c

2015-10-06 Thread Al Viro
On Tue, Oct 06, 2015 at 12:32:28AM -0400, Jacob Kiefer wrote:

>  int rtl8723a_set_rssi_cmd(struct rtw_adapter *padapter, u8 *param)
>  {
> - *((u32 *)param) = cpu_to_le32(*((u32 *)param));
> + __le32 leparam;
> 
> - FillH2CCmd(padapter, RSSI_SETTING_EID, 3, param);
> + leparam = cpu_to_le32(*((u32 *)param));
> +
> + FillH2CCmd(padapter, RSSI_SETTING_EID, 3, (u8 *)&leparam);

Why not fill the thing we are passing already with little-endian?  There's
only one caller, after all...

>  int rtl8723a_set_raid_cmd(struct rtw_adapter *padapter, u32 mask, u8 arg)
>  {
>   u8 buf[5];
> + __le32 lemask;
> 
>   memset(buf, 0, 5);
> - mask = cpu_to_le32(mask);
> - memcpy(buf, &mask, 4);
> + lemask = cpu_to_le32(mask);
> + memcpy(buf, &lemask, 4);
>   buf[4]  = arg;
> 
>   FillH2CCmd(padapter, MACID_CONFIG_EID, 5, buf);

Ugh...
struct macid_config_eid {__le32 mask; u8 arg;} buf = {
.mask = cpu_to_le32(mask), .arg = arg
};

FillH2CCmd(padapter, MACID_CONFIG_EID, 5, &buf);

Why bother with memcpy/memset/whatnot when all you are trying to do is to
initialize a temporary structure?  And no, it's not going to have any gaps...
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


use of opaque subject lines

2015-02-05 Thread Al Viro
On Mon, Feb 02, 2015 at 08:13:10PM +0100, Andreas Ruprecht wrote:

> On a serious note: I do understand what you're getting at, I don't take
> that personally (and I will send a v2 addressing the things above), but
> honestly, this kind of answer might just be a real turn-off for other
> people trying to get into kernel development...
> 
> I don't want to start a whole new 'attitude in the kernel community'
> discussion, but I can't just let this go like that, sorry.

Just during the last 12 hours or so, I've seen the following l-k traffic:

Subject: [PATCH] usb: host/sl811-hcd: fix sparse warning
Subject: [PATCH] usb: gadget: function/f_sourcesink: fix sparse warning
Subject: [PATCH] tty: vt/vt: fix sparse warning
Subject: [PATCH] scsi: fix sparse warnings
Subject: [PATCH] bfa: bfa_core: fix sparse warning
Subject: [PATCH] scsi: fix sparse warning
Subject: [PATCH] xen/acpi-processor: fix sparse warning
Subject: [PATCH] scsi: initio: fix sparse warnings
Subject: [PATCH] scsi: dc395x: fix sparse warning
Subject: [PATCH] scsi: eata: fix sparse warning
Subject: [PATCH] scsi: qla1280: fix sparse warnings
Subject: [PATCH] scsi: ips: fix sparse warnings
Subject: [PATCH] fbdev: via/via_clock: fix sparse warning
Subject: [PATCH] usb: gadget: fix sparse warnings
Subject: [PATCH] usb: gadget: fix sparse warnings
Subject: [PATCH] usb: gadget: function/uvc_v4l2.c: fix sparse warnings
Subject: [PATCH] xen-netback: fix sparse warning
Subject: [PATCH] thermal: int340x: fix sparse warning
Subject: [PATCH] vxge: fix sparse warning
Subject: Re: [PATCH] xen-netback: fix sparse warning
Subject: [PATCH] ixgbe: fix sparse warnings
Subject: [PATCH] samsung-laptop: fix sparse warning
Subject: [PATCH] x86: thinkpad_acpi.c: fix sparse warning
Subject: [PATCH] Sony-laptop: fix sparse warning

one of those is an ACK from maintainer, the rest are (AFAICS) all "make
something static", all with rather poor commit messages and subjects.  Not
threaded, either (that would've somewhat mitigated one of the problems).

Bad attitude?  I'd say that _this_ is one.  l-k is high-traffic list;
postings like that mean extra strain on those who are trying at least to
skim through it and they are not easy on those who are trying to read the
commit logs.  And it's trivial to mitigate - choose less opaque subjects,
for starters.  Because these are about as opaque as it gets: essentially,
it's "sparse had drawn my attention to $FILE; I've fixed that problem by
making it STFU".  Readers would like more information to filter upon?
Tough luck, open the damn mail and look into it.  One after another, after
another, to the tune of dozens per night.  All with the commit messages
pretty much of the form "$TOOL has produced $MESSAGE; with diff below it
doesn't".

It's physically impossible to read through all l-k traffic; the rate is too
high for that.  Is making it possible to do minimal triage too much to ask for?
I'm not blaming anyone for going after the low-hanging fruit like that to
get some experience on simple stuff, but as it is, it reinforces seriously
bad habits while creating considerable PITA for list readers.  And yes,
we'd all done our share of lousy commit messages, but this pretty much
teaches newbies to do that all the time.

Sigh...  Folks, please
* Use descriptive subject lines at least somewhere in a thread.
* Describe what the thing does, besides "makes $TOOL to STFU".
* Remember, you don't fix warnings - you deal with the problem
(if any) in the code those warnings had pointed to.  And if there isn't
a problem (i.e. the warning was a false positive) you might be annotating
the code to tell the dumb tool what's going on there.  Which is a different
genre, and needs different mindset when reviewing (it's easy to obfuscate
a _real_ problem away - away from the $TOOL's ability to spot it, that
is).
* Remember that said tools are nowhere near strong AI; the
same warning can come from very different underlying problems.  These
warnigns are heuristics - such-and-such looking code has high chances of
needing attention.  Give at least some indication what the problem _is_ - e.g.
the sparse warnings that has spawned this flood might come from
1) function really is used only in the file it's defined in,
never intended to be used elsewhere, ought to be static to avoid namespace
pollution
2) function is used elsewhere, and its uses elsewhere have explicit
externs right at the point of use.  Dangerous, since there's no practical
way for compiler (gcc, sparse, lint, whatever) to verify that there's no
type mismatch.  Ought to have extern placed in some header included both by
the file where it's defined and by all files where it's used, with externs
at the point of use removed.  Need to be careful about the choice of header
and location in it.
3) function _is_ declared in a common header, but it's either not
included by the file where it actually lives, *or* is included only on
some architectures an

Re: [PATCH] staging: lustre: osc: Fix sparse warning about osc_init

2015-02-02 Thread Al Viro
On Mon, Feb 02, 2015 at 02:36:43PM +0100, Andreas Ruprecht wrote:
> When running sparse on the osc/ subdirectory, it shows the
> following warning:
> 
> andreas@workbox:~/linux-next$ make C=1 M=drivers/staging/lustre/lustre/osc/
> [...]
> drivers/staging/lustre/lustre/osc/osc_request.c:3335:12: warning:
> symbol 'osc_init' was not declared. Should it be static?
> [...]
> 
> As this is the module init function, it can (and should) be declared
> static.
> 
> Signed-off-by: Andreas Ruprecht 

For pity sake, folks, could you at least try to produce less meaningless
commit summaries?  "Fix sparse warning" says nothing whatsoever about
what's getting done.  The role of sparse in that is simple - it has
provided a tip to look at that declaration.  That's all; it might as well
had been offered by a guy puking at the next stall in the loo after big
party.  And no, sparse alone is not sufficient to prove that it could be
made static - it might be used somewhere else with explicit extern, its
declaration might've been in a header that didn't get included here, or
under slightly incorrect ifdefs, etc.  Such things need to be investigated
manually, not that it was hard to do.  OK, in this case the tip had panned
out; it can be made static (quick grep shows that) and it's better off
that way - less namespace pollution, makes life easier when doing analysis
of that code, etc.

_That_ is the point of this patch, not making the holy oracle shut the bleeding
fuck up.  If you want to credit sparse (or that guy puking in the next stall,
or whatever had drawn your attention to the function in question) - great,
do so inside the commit message.  _AFTER_ having described what the patch
does ("make osc_init() static" or equivalent thereof), please.  Ideally -
with something like "it's never used outside of osc_request.c" after summary
line (strictly speaking, something that serves as module_init might very well
be called elsewhere in the module explicitly; not common, but possible).
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH] staging: lustre: Fix the warning messages about casting without __user macro

2014-12-09 Thread Al Viro
On Tue, Dec 09, 2014 at 10:56:12PM -0800, Shalin Mehta wrote:
> From: Shalin Mehta 
> 
> This issue is showed up while compiling with sparse. The iov_base in struct 
> iovec struct explicitly declares that the assigned value should be user space 
> pointer with __user macro. Where as here, the __user macro isn't used while 
> casting.

... and pointers are not user space ones at all.  Which is to say, quit
messing with casts; it's not struct iovec.  Proper fix is to replace
it here (and in almost all places throughout drivers/staging/lustre) with
struct kvec.  And yes, such a patch had been sent.  Still not applied,
AFAICS...
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH] staging:lustre:lnet: Incorrect type in assignment

2014-12-02 Thread Al Viro
On Mon, Dec 01, 2014 at 02:53:52PM +0800, sunwxg wrote:
> From: Sun Wang 
> 
> Incorrect type when assign value to varible iov_base.

Oh, for pity sake...  Folks, these struct iovec in there are bloody wrong.
It's not iovec at all.  There are exactly two declarations in the whole
drivers/staging/lustre where struct iovec should not be struct kvec.  As for
everything else, see below.

commit 82fa028f2b462743aeeb9b973d02733801b2f8e6
Author: Al Viro 
Date:   Sat Nov 29 12:24:20 2014 -0500

lustre: don't use iovec instead of kvec

    Signed-off-by: Al Viro 

diff --git a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h 
b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h
index 7e89b3b..99fb52a 100644
--- a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h
+++ b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h
@@ -752,9 +752,9 @@ int lnet_fail_nid(lnet_nid_t nid, unsigned int threshold);
 void lnet_counters_get(lnet_counters_t *counters);
 void lnet_counters_reset(void);
 
-unsigned int lnet_iov_nob(unsigned int niov, struct iovec *iov);
-int lnet_extract_iov(int dst_niov, struct iovec *dst,
-int src_niov, struct iovec *src,
+unsigned int lnet_iov_nob(unsigned int niov, struct kvec *iov);
+int lnet_extract_iov(int dst_niov, struct kvec *dst,
+int src_niov, struct kvec *src,
  unsigned int offset, unsigned int len);
 
 unsigned int lnet_kiov_nob(unsigned int niov, lnet_kiov_t *iov);
@@ -762,17 +762,17 @@ int lnet_extract_kiov(int dst_niov, lnet_kiov_t *dst,
  int src_niov, lnet_kiov_t *src,
  unsigned int offset, unsigned int len);
 
-void lnet_copy_iov2iov(unsigned int ndiov, struct iovec *diov,
+void lnet_copy_iov2iov(unsigned int ndiov, struct kvec *diov,
   unsigned int doffset,
-   unsigned int nsiov, struct iovec *siov,
+   unsigned int nsiov, struct kvec *siov,
unsigned int soffset, unsigned int nob);
-void lnet_copy_kiov2iov(unsigned int niov, struct iovec *iov,
+void lnet_copy_kiov2iov(unsigned int niov, struct kvec *iov,
unsigned int iovoffset,
 unsigned int nkiov, lnet_kiov_t *kiov,
 unsigned int kiovoffset, unsigned int nob);
 void lnet_copy_iov2kiov(unsigned int nkiov, lnet_kiov_t *kiov,
unsigned int kiovoffset,
-unsigned int niov, struct iovec *iov,
+unsigned int niov, struct kvec *iov,
 unsigned int iovoffset, unsigned int nob);
 void lnet_copy_kiov2kiov(unsigned int ndkiov, lnet_kiov_t *dkiov,
 unsigned int doffset,
@@ -781,10 +781,10 @@ void lnet_copy_kiov2kiov(unsigned int ndkiov, lnet_kiov_t 
*dkiov,
 
 static inline void
 lnet_copy_iov2flat(int dlen, void *dest, unsigned int doffset,
-  unsigned int nsiov, struct iovec *siov, unsigned int soffset,
+  unsigned int nsiov, struct kvec *siov, unsigned int soffset,
   unsigned int nob)
 {
-   struct iovec diov = {/*.iov_base = */ dest, /*.iov_len = */ dlen};
+   struct kvec diov = {/*.iov_base = */ dest, /*.iov_len = */ dlen};
 
lnet_copy_iov2iov(1, &diov, doffset,
  nsiov, siov, soffset, nob);
@@ -795,17 +795,17 @@ lnet_copy_kiov2flat(int dlen, void *dest, unsigned int 
doffset,
unsigned int nsiov, lnet_kiov_t *skiov,
unsigned int soffset, unsigned int nob)
 {
-   struct iovec diov = {/* .iov_base = */ dest, /* .iov_len = */ dlen};
+   struct kvec diov = {/* .iov_base = */ dest, /* .iov_len = */ dlen};
 
lnet_copy_kiov2iov(1, &diov, doffset,
   nsiov, skiov, soffset, nob);
 }
 
 static inline void
-lnet_copy_flat2iov(unsigned int ndiov, struct iovec *diov, unsigned int 
doffset,
+lnet_copy_flat2iov(unsigned int ndiov, struct kvec *diov, unsigned int doffset,
   int slen, void *src, unsigned int soffset, unsigned int nob)
 {
-   struct iovec siov = {/*.iov_base = */ src, /*.iov_len = */slen};
+   struct kvec siov = {/*.iov_base = */ src, /*.iov_len = */slen};
 
lnet_copy_iov2iov(ndiov, diov, doffset,
  1, &siov, soffset, nob);
@@ -816,7 +816,7 @@ lnet_copy_flat2kiov(unsigned int ndiov, lnet_kiov_t *dkiov,
unsigned int doffset, int slen, void *src,
unsigned int soffset, unsigned int nob)
 {
-   struct iovec siov = {/* .iov_base = */ src, /* .iov_len = */ slen};
+   struct kvec siov = {/* .iov_base = */ src, /* .iov_len = */ slen};
 
lnet_copy_iov2kiov(ndiov, dkiov, doffset,
   1, &siov, soffset, nob);
diff --git a/drivers/staging/lustre/include/linux/lnet/lib-types.h 
b/drivers/staging/lustre/include/linux/lnet/lib-types.h

Re: [PATCH] staging: lustre: fix pointer declarations

2014-11-26 Thread Al Viro
On Tue, Nov 25, 2014 at 09:44:21PM +0100, Zahari Doychev wrote:
> This patch fixes pointer declarations from void * to void __user * in order
> to remove some sparse warnings.

_Are_ those userland addresses, though?  Quick grep shows that in the
only caller of lnet_copy_iov2flat() we have something called ibmsg passed
as the second argument *AND* *RIGHT* *BEFORE* *THAT* *CALL* *WE* *HAVE*
ibmsg = tx->tx_msg;
ibmsg->ibm_u.immediate.ibim_hdr = *hdr;
Go ahead, explain how does that manage to work if ibmsg is a userland pointer.
Either you have discovered an exploitable hole (direct store to userland
address), or it's not a userland pointer, after all.

Al, sick and tired of the "remove some warnings" as the sole rationale for
patches, without even an attempt to figure out what those warnings are
about.  Magic box makes noises, magic box must be appeased...
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH] staging: lustre: socklnd: sparse warning fix

2014-11-16 Thread Al Viro
> the same value casted the same way few lines below:
>   csum = ksocknal_csum(~0, (void *)tx->tx_iov[0].iov_base,
> 
> then it seems like a typo in LASSERT() that is got fixed
> 
>  drivers/staging/lustre/lnet/klnds/socklnd/socklnd_lib-linux.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_lib-linux.c 
> b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_lib-linux.c
> index 245c9d7..ebd400d 100644
> --- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_lib-linux.c
> +++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_lib-linux.c
> @@ -390,7 +390,7 @@ ksocknal_lib_csum_tx(ksock_tx_t *tx)
>   __u32   csum;
>   void*base;
>  
> - LASSERT(tx->tx_iov[0].iov_base == (void *)&tx->tx_msg);
> + LASSERT((void *)tx->tx_iov[0].iov_base == &tx->tx_msg);

Turn tx_iov into struct kvec * instead.
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH v3.18-rc2] staging: android: logger: Fix log corruption regression

2014-10-27 Thread Al Viro
On Mon, Oct 27, 2014 at 06:51:43PM +, Daniel Thompson wrote:
> Since commit cd678fce4280 ("switch logger to ->write_iter()"), any
> attempt to write to the log results in the log data being written over
> its own metadata, thus rendering the log unreadable.
> 
> The problem was first detected when I ran an Android userspace on the
> v3.18-rc1 kernel. However the issue can also be observed with a
> non-Android userspace by using echo/cat to write to/from /dev/log_main .
> 
> This patch resolves the problem by using a temporary to track the status
> of not-yet-committed writes to the log buffer.
> 
> Signed-off-by: Daniel Thompson 
> Cc: Al Viro 

Applied
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH resend] staging, lustre: fix a sparse error

2014-10-12 Thread Al Viro
On Fri, Oct 10, 2014 at 11:21:16AM +0800, WANG Chao wrote:

> I think __user annotation is for no dereferencing in kernel space. In
> this case, I think it's fine to override this error by __force. Because
> they're pointers with identical target types.

Umm...  The real question seems to be whether iovec is the right type in
the first place.  Does ->tx_iov ever contain a vector with _userland_
pointers?  If not, it ought to be struct kvec * instead.
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [RFC PATCH] vsnprintf: Remove use of %n and convert existing uses

2013-09-11 Thread Al Viro
On Wed, Sep 11, 2013 at 05:04:17PM -0700, Joe Perches wrote:
> On Thu, 2013-09-12 at 08:40 +0900, Tetsuo Handa wrote:
> > Joe Perches wrote:
> > > - seq_printf(m, "%s%d%n", con->name, con->index, &len);
> > > + len = seq_printf(m, "%s%d", con->name, con->index);
> > 
> > Isn't len always 0 or -1 ?
> 
> Right.  Well you're no fun...
> 
> These uses would seem broken anyway because the
> seq_printf isn't itself tested for correctness.
> 
> Hmm.
> 
> Also, there's a large amount of code that appears
> to do calculations with pos or len like:
> 
>   pos += seq_printf(handle, fmt. ...)

... and most of that code proceeds to ignore pos completely.
Note that ->show() is *NOT* supposed to return the number of
characters it has/would like to have produced.  Just return
0 and be done with that; overflows are dealt with just fine.
The large amount, BTW, is below 100 lines, AFAICS, in rather
few files.

> There are very few that seem to use it correctly
> like netfilter.

> Suggestions?

Just bury the cargo-culting crap.  All those += seq_printf() should
be simply calling it.  The *only* reason to look at the return
value is "if we'd already overflown the buffer, I'd rather skipped
the costly generation of the rest of the record".  In that case
seq_printf() returning -1 means "skip it, nothing else will fit and
caller will be repeating with bigger buffer anyway".
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel