Author: brooks
Date: Tue Mar 27 21:14:39 2018
New Revision: 331654
URL: https://svnweb.freebsd.org/changeset/base/331654

Log:
  Don't access userspace directly from the kernel in nxge(4).
  
  Update to what the previous code seemed to be doing via the correct
  interfaces.  Further issues exist in xge_ioctl_registers(), but this is
  debugging code in a driver that has few users and they don't appear to
  be crashes or leaks.
  
  Reviewed by:  jhb (prior version)
  MFC after:    1 week
  Sponsored by: DARPA, AFRL
  Differential Revision:        https://reviews.freebsd.org/D14848

Modified:
  head/sys/dev/nxge/if_nxge.c

Modified: head/sys/dev/nxge/if_nxge.c
==============================================================================
--- head/sys/dev/nxge/if_nxge.c Tue Mar 27 21:06:18 2018        (r331653)
+++ head/sys/dev/nxge/if_nxge.c Tue Mar 27 21:14:39 2018        (r331654)
@@ -1364,11 +1364,15 @@ int
 xge_ioctl_stats(xge_lldev_t *lldev, struct ifreq *ifreqp)
 {
        xge_hal_status_e status = XGE_HAL_OK;
-       char *data = (char *)ifreqp->ifr_data;
+       char cmd, mode;
        void *info = NULL;
        int retValue = EINVAL;
 
-       switch(*data) {
+       cmd = fubyte(ifreqp->ifr_data);
+       if (cmd == -1)
+               return (EFAULT);
+
+       switch(cmd) {
            case XGE_QUERY_STATS:
                mtx_lock(&lldev->mtx_drv);
                status = xge_hal_stats_hw(lldev->devh,
@@ -1496,8 +1500,8 @@ xge_ioctl_stats(xge_lldev_t *lldev, struct ifreq *ifre
            case XGE_SET_BUFFER_MODE_1:
            case XGE_SET_BUFFER_MODE_2:
            case XGE_SET_BUFFER_MODE_5:
-               *data = (*data == XGE_SET_BUFFER_MODE_1) ? 'Y':'N';
-               if(copyout(data, ifreqp->ifr_data, sizeof(data)) == 0)
+               mode = (cmd == XGE_SET_BUFFER_MODE_1) ? 'Y':'N';
+               if(copyout(&mode, ifreqp->ifr_data, sizeof(mode)) == 0)
                    retValue = 0;
                break;
            default:
@@ -1518,10 +1522,17 @@ xge_ioctl_stats(xge_lldev_t *lldev, struct ifreq *ifre
 int
 xge_ioctl_registers(xge_lldev_t *lldev, struct ifreq *ifreqp)
 {
-       xge_register_t *data = (xge_register_t *)ifreqp->ifr_data;
+       xge_register_t tmpdata;
+       xge_register_t *data;
        xge_hal_status_e status = XGE_HAL_OK;
        int retValue = EINVAL, offset = 0, index = 0;
+       int error;
        u64 val64 = 0;
+
+       error = copyin(ifreqp->ifr_data, &tmpdata, sizeof(tmpdata));
+       if (error != 0)
+               return (error);
+       data = &tmpdata;
 
        /* Reading a register */
        if(strcmp(data->option, "-r") == 0) {
_______________________________________________
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