Author: jah
Date: Fri May 20 03:03:04 2016
New Revision: 300258
URL: https://svnweb.freebsd.org/changeset/base/300258

Log:
  iic_rdwr_data->nmsgs is uint32_t, so limit the allowable number of messages 
to prevent memory exhaustion and short allocations on 32-bit systems. Since 
iicrdwr is intended to be a workalike of a Linux i2c-dev call, use the same 
limit of 42 that Linux uses.
  
  Also check the return value of copyin(9) to prevent unnecessary allocation in 
the failure case.
  
  Submitted by: ngie
  Reviewed by:  kib
  MFC after:    1 week
  Differential Revision:        https://reviews.freebsd.org/D5155

Modified:
  head/sys/dev/iicbus/iic.c
  head/sys/dev/iicbus/iic.h

Modified: head/sys/dev/iicbus/iic.c
==============================================================================
--- head/sys/dev/iicbus/iic.c   Fri May 20 01:41:47 2016        (r300257)
+++ head/sys/dev/iicbus/iic.c   Fri May 20 03:03:04 2016        (r300258)
@@ -300,9 +300,16 @@ iicrdwr(struct iic_cdevpriv *priv, struc
        parent = device_get_parent(iicdev);
        error = 0;
 
+       if (d->nmsgs > IIC_RDRW_MAX_MSGS)
+               return (EINVAL);
+
        buf = malloc(sizeof(*d->msgs) * d->nmsgs, M_IIC, M_WAITOK);
 
        error = copyin(d->msgs, buf, sizeof(*d->msgs) * d->nmsgs);
+       if (error != 0) {
+               free(buf, M_IIC);
+               return (error);
+       }
 
        /* Alloc kernel buffers for userland data, copyin write data */
        usrbufs = malloc(sizeof(void *) * d->nmsgs, M_IIC, M_WAITOK | M_ZERO);
@@ -318,6 +325,8 @@ iicrdwr(struct iic_cdevpriv *priv, struc
                m->buf = NULL;
                if (error != 0)
                        continue;
+
+               /* m->len is uint16_t, so allocation size is capped at 64K. */
                m->buf = malloc(m->len, M_IIC, M_WAITOK);
                if (!(m->flags & IIC_M_RD))
                        error = copyin(usrbufs[i], m->buf, m->len);

Modified: head/sys/dev/iicbus/iic.h
==============================================================================
--- head/sys/dev/iicbus/iic.h   Fri May 20 01:41:47 2016        (r300257)
+++ head/sys/dev/iicbus/iic.h   Fri May 20 03:03:04 2016        (r300258)
@@ -56,6 +56,8 @@ struct iic_rdwr_data {
        uint32_t nmsgs;
 };
 
+#define IIC_RDRW_MAX_MSGS      42
+
 #define I2CSTART       _IOW('i', 1, struct iiccmd)     /* start condition */
 #define I2CSTOP                _IO('i', 2)                     /* stop 
condition */
 #define I2CRSTCARD     _IOW('i', 3, struct iiccmd)     /* reset the card */
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to