VirtualBox

Changeset 15613 in vbox


Ignore:
Timestamp:
Dec 16, 2008 11:06:27 PM (16 years ago)
Author:
vboxsync
Message:

Additions/Linux: make sure we lock user memory when we make an HGCM call

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/linux/module/vboxmod.c

    r14375 r15613  
    7171#include <iprt/asm.h>
    7272#include <iprt/assert.h>
     73#include <iprt/memobj.h>
    7374#include <linux/miscdevice.h>
    7475#include <linux/poll.h>
     
    364365}
    365366
     367/** Lock down R3 memory as needed for the HGCM call.  Copied from
     368 * HGCMInternal.cpp and SysHlp.cpp */
     369static int vboxadd_lock_hgcm_parms(void **ppvCtx, VBoxGuestHGCMCallInfo *pCallInfo)
     370{
     371    uint32_t cbParms = pCallInfo->cParms * sizeof (HGCMFunctionParameter);
     372    int rc = VINF_SUCCESS;
     373    unsigned iParm;
     374    HGCMFunctionParameter *pParm;
     375    memset (ppvCtx, 0, sizeof(void *) * pCallInfo->cParms);
     376    if (cbParms)
     377    {
     378        /* Lock user buffers. */
     379        pParm = VBOXGUEST_HGCM_CALL_PARMS(pCallInfo);
     380
     381        for (iParm = 0; iParm < pCallInfo->cParms; iParm++, pParm++)
     382        {
     383            switch (pParm->type)
     384            {
     385            case VMMDevHGCMParmType_LinAddr_Locked_In:
     386                pParm->type = VMMDevHGCMParmType_LinAddr_In;
     387                break;
     388            case VMMDevHGCMParmType_LinAddr_Locked_Out:
     389                pParm->type = VMMDevHGCMParmType_LinAddr_Out;
     390                break;
     391            case VMMDevHGCMParmType_LinAddr_Locked:
     392                pParm->type = VMMDevHGCMParmType_LinAddr;
     393                break;
     394
     395            case VMMDevHGCMParmType_LinAddr_In:
     396            case VMMDevHGCMParmType_LinAddr_Out:
     397            case VMMDevHGCMParmType_LinAddr:
     398            {
     399                RTR3PTR pv = (RTR3PTR)pParm->u.Pointer.u.linearAddr;
     400                uint32_t u32Size = pParm->u.Pointer.size;
     401                RTR0MEMOBJ MemObj;
     402                rc = RTR0MemObjLockUser(&MemObj, pv, u32Size, NIL_RTR0PROCESS);
     403                if (RT_SUCCESS(rc))
     404                    ppvCtx[iParm] = MemObj;
     405                else
     406                    ppvCtx[iParm] = NIL_RTR0MEMOBJ;
     407                break;
     408            }
     409            default:
     410                /* make gcc happy */
     411                break;
     412            }
     413            if (RT_FAILURE (rc))
     414                break;
     415        }
     416    }
     417    return RTErrConvertToErrno (rc);
     418}
     419
     420/** Unlock R3 memory after the HGCM call.  Copied from HGCMInternal.cpp and
     421 * SysHlp.cpp */
     422static void vboxadd_unlock_hgcm_parms(void **ppvCtx, VBoxGuestHGCMCallInfo *pCallInfo)
     423{
     424    unsigned iParm;
     425    /* Unlock user buffers. */
     426    HGCMFunctionParameter *pParm = VBOXGUEST_HGCM_CALL_PARMS(pCallInfo);
     427
     428    for (iParm = 0; iParm < pCallInfo->cParms; iParm++, pParm++)
     429    {
     430        if (   pParm->type == VMMDevHGCMParmType_LinAddr_In
     431            || pParm->type == VMMDevHGCMParmType_LinAddr_Out
     432            || pParm->type == VMMDevHGCMParmType_LinAddr)
     433        {
     434            if (ppvCtx[iParm] != NULL)
     435            {
     436                RTR0MEMOBJ MemObj = (RTR0MEMOBJ)ppvCtx[iParm];
     437                int rc = RTR0MemObjFree(MemObj, false);
     438                AssertRC(rc);
     439            }
     440        }
     441        else
     442            Assert(!ppvCtx[iParm]);
     443    }
     444}
     445
    366446/**
    367447 * IOCTL handler.  Make an HGCM call.
     
    376456{
    377457        VBoxGuestHGCMCallInfo *pInfo = NULL;
     458        void *apvCtx[VBOX_HGCM_MAX_PARMS];
     459        unsigned haveParms = 0;
    378460        int rc = 0;
    379         
     461   
    380462        pInfo = kmalloc(u32Size, GFP_KERNEL);
    381463        if (pInfo == NULL)
     
    392474                             u32Size));
    393475            rc = -EINVAL;
     476        }
     477        if (rc >= 0) {
     478            haveParms = 1;
     479            rc = vboxadd_lock_hgcm_parms(apvCtx, pInfo);
    394480        }
    395481        if (rc >= 0) {
     
    406492                }
    407493        }
     494        if (haveParms)
     495            vboxadd_unlock_hgcm_parms(apvCtx, pInfo);
    408496        if (pInfo != NULL)
    409497            kfree(pInfo);
     
    424512{
    425513        VBoxGuestHGCMCallInfoTimed *pInfo = NULL;
     514        void *apvCtx[VBOX_HGCM_MAX_PARMS];
     515        unsigned haveParms = 0;
    426516        int rc = 0;
    427517       
     
    440530                             u32Size));
    441531            rc = -EINVAL;
     532        }
     533        if (rc >= 0) {
     534            haveParms = 1;
     535            rc = vboxadd_lock_hgcm_parms(apvCtx, &pInfo->info);
    442536        }
    443537        if (rc >= 0) {
     
    455549                }
    456550        }
     551        if (haveParms)
     552            vboxadd_unlock_hgcm_parms(apvCtx, &pInfo->info);
    457553        if (pInfo != NULL)
    458554            kfree(pInfo);
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette