diff options
author | Dan Carpenter <dan.carpenter@oracle.com> | 2017-01-30 13:51:49 +0300 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-02-03 15:01:38 +0300 |
commit | 76bdaa161cd93d9c033bf6fe2b0a5661c8204441 (patch) | |
tree | 25ab145e0c3f01874a1bd47834694ae80032b32e | |
parent | dcdf43a01e950c9475fb325972d8f034afa19464 (diff) | |
download | linux-76bdaa161cd93d9c033bf6fe2b0a5661c8204441.tar.xz |
staging: lustre: libcfs: double copy bug
The problem is that we copy hdr.ioc_len, we verify it, then we copy it
again without checking to see if it has changed in between the two
copies.
This could result in an information leak.
Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | drivers/staging/lustre/lnet/libcfs/linux/linux-module.c | 15 |
1 files changed, 13 insertions, 2 deletions
diff --git a/drivers/staging/lustre/lnet/libcfs/linux/linux-module.c b/drivers/staging/lustre/lnet/libcfs/linux/linux-module.c index 3f5d58babc2f..075826bd3a2a 100644 --- a/drivers/staging/lustre/lnet/libcfs/linux/linux-module.c +++ b/drivers/staging/lustre/lnet/libcfs/linux/linux-module.c @@ -122,7 +122,7 @@ int libcfs_ioctl_getdata(struct libcfs_ioctl_hdr **hdr_pp, const struct libcfs_ioctl_hdr __user *uhdr) { struct libcfs_ioctl_hdr hdr; - int err = 0; + int err; if (copy_from_user(&hdr, uhdr, sizeof(hdr))) return -EFAULT; @@ -150,9 +150,20 @@ int libcfs_ioctl_getdata(struct libcfs_ioctl_hdr **hdr_pp, return -ENOMEM; if (copy_from_user(*hdr_pp, uhdr, hdr.ioc_len)) { - LIBCFS_FREE(*hdr_pp, hdr.ioc_len); err = -EFAULT; + goto free; } + + if ((*hdr_pp)->ioc_version != hdr.ioc_version || + (*hdr_pp)->ioc_len != hdr.ioc_len) { + err = -EINVAL; + goto free; + } + + return 0; + +free: + LIBCFS_FREE(*hdr_pp, hdr.ioc_len); return err; } |