|
@@ -2281,6 +2281,16 @@ static int irda_getsockopt(struct socket *sock, int level, int optname,
|
|
|
|
|
|
switch (optname) {
|
|
|
case IRLMP_ENUMDEVICES:
|
|
|
+
|
|
|
+ /* Offset to first device entry */
|
|
|
+ offset = sizeof(struct irda_device_list) -
|
|
|
+ sizeof(struct irda_device_info);
|
|
|
+
|
|
|
+ if (len < offset) {
|
|
|
+ err = -EINVAL;
|
|
|
+ goto out;
|
|
|
+ }
|
|
|
+
|
|
|
/* Ask lmp for the current discovery log */
|
|
|
discoveries = irlmp_get_discoveries(&list.len, self->mask.word,
|
|
|
self->nslots);
|
|
@@ -2291,15 +2301,9 @@ static int irda_getsockopt(struct socket *sock, int level, int optname,
|
|
|
}
|
|
|
|
|
|
/* Write total list length back to client */
|
|
|
- if (copy_to_user(optval, &list,
|
|
|
- sizeof(struct irda_device_list) -
|
|
|
- sizeof(struct irda_device_info)))
|
|
|
+ if (copy_to_user(optval, &list, offset))
|
|
|
err = -EFAULT;
|
|
|
|
|
|
- /* Offset to first device entry */
|
|
|
- offset = sizeof(struct irda_device_list) -
|
|
|
- sizeof(struct irda_device_info);
|
|
|
-
|
|
|
/* Copy the list itself - watch for overflow */
|
|
|
if (list.len > 2048) {
|
|
|
err = -EINVAL;
|