diff options
author | Dan Carpenter <dan.carpenter@oracle.com> | 2017-01-30 05:51:49 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-02-03 07:01:38 -0500 |
commit | 76bdaa161cd93d9c033bf6fe2b0a5661c8204441 (patch) | |
tree | 25ab145e0c3f01874a1bd47834694ae80032b32e | |
parent | dcdf43a01e950c9475fb325972d8f034afa19464 (diff) |
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, | |||
122 | const struct libcfs_ioctl_hdr __user *uhdr) | 122 | const struct libcfs_ioctl_hdr __user *uhdr) |
123 | { | 123 | { |
124 | struct libcfs_ioctl_hdr hdr; | 124 | struct libcfs_ioctl_hdr hdr; |
125 | int err = 0; | 125 | int err; |
126 | 126 | ||
127 | if (copy_from_user(&hdr, uhdr, sizeof(hdr))) | 127 | if (copy_from_user(&hdr, uhdr, sizeof(hdr))) |
128 | return -EFAULT; | 128 | return -EFAULT; |
@@ -150,9 +150,20 @@ int libcfs_ioctl_getdata(struct libcfs_ioctl_hdr **hdr_pp, | |||
150 | return -ENOMEM; | 150 | return -ENOMEM; |
151 | 151 | ||
152 | if (copy_from_user(*hdr_pp, uhdr, hdr.ioc_len)) { | 152 | if (copy_from_user(*hdr_pp, uhdr, hdr.ioc_len)) { |
153 | LIBCFS_FREE(*hdr_pp, hdr.ioc_len); | ||
154 | err = -EFAULT; | 153 | err = -EFAULT; |
154 | goto free; | ||
155 | } | 155 | } |
156 | |||
157 | if ((*hdr_pp)->ioc_version != hdr.ioc_version || | ||
158 | (*hdr_pp)->ioc_len != hdr.ioc_len) { | ||
159 | err = -EINVAL; | ||
160 | goto free; | ||
161 | } | ||
162 | |||
163 | return 0; | ||
164 | |||
165 | free: | ||
166 | LIBCFS_FREE(*hdr_pp, hdr.ioc_len); | ||
156 | return err; | 167 | return err; |
157 | } | 168 | } |
158 | 169 | ||