diff options
Diffstat (limited to 'emulators/virtualbox')
5 files changed, 621 insertions, 4 deletions
diff --git a/emulators/virtualbox/Makefile b/emulators/virtualbox/Makefile index 3538d0054d94..3d821daa23a0 100644 --- a/emulators/virtualbox/Makefile +++ b/emulators/virtualbox/Makefile @@ -7,6 +7,7 @@ PORTNAME= virtualbox DISTVERSION= 3.0.51r22902 +PORTREVISION= 2 CATEGORIES= emulators kld MASTER_SITES= http://tmp.chruetertee.ch/ \ http://freebsd.unixfreunde.de/sources/ \ @@ -142,15 +143,21 @@ BROKEN= Does not compile on FreeBSD 6.X KMK_ARCH= freebsd.x86 PLIST_SUB+= I386="" .else -.if !exists(/usr/lib32) -IGNORE= requires 32-bit libraries installed under /usr/lib32 -.endif KMK_ARCH= freebsd.${ARCH} PLIST_SUB+= I386="@comment " .endif .include <bsd.port.pre.mk> +pre-everything:: +.if ${ARCH} == "amd64" +.if !exists(/usr/lib32) + @${ECHO} 'Requires 32-bit libraries installed under /usr/lib32.' + @${ECHO} 'Do: cd /usr/src; make build32 install32; ldconfig -v -m -R /usr/lib32' + @${FALSE} +.endif +.endif + post-patch: @${ECHO} 'VBOX_PATH_APP_PRIVATE_ARCH = ${PREFIX}/lib/virtualbox' > ${WRKSRC}/LocalConfig.kmk @${ECHO} 'VBOX_PATH_SHARED_LIBS = ${PREFIX}/lib/virtualbox' >> ${WRKSRC}/LocalConfig.kmk diff --git a/emulators/virtualbox/files/patch-src-VBox-HostDrivers-VBoxNetFlt-VBoxNetFltInternal.h b/emulators/virtualbox/files/patch-src-VBox-HostDrivers-VBoxNetFlt-VBoxNetFltInternal.h new file mode 100644 index 000000000000..250a1960a7f4 --- /dev/null +++ b/emulators/virtualbox/files/patch-src-VBox-HostDrivers-VBoxNetFlt-VBoxNetFltInternal.h @@ -0,0 +1,28 @@ +Index: src/VBox/HostDrivers/VBoxNetFlt/VBoxNetFltInternal.h +=================================================================== +--- src/VBox/HostDrivers/VBoxNetFlt/VBoxNetFltInternal.h (revision 23391) ++++ src/VBox/HostDrivers/VBoxNetFlt/VBoxNetFltInternal.h (working copy) +@@ -206,6 +206,14 @@ + hook_p output; + /** Original interface flags */ + unsigned int flags; ++ /** Input queue */ ++ struct ifqueue inq; ++ /** Output queue */ ++ struct ifqueue outq; ++ /** Input task */ ++ struct task tskin; ++ /** Output task */ ++ struct task tskout; + /** The MAC address of the interface. */ + RTMAC Mac; + /** @} */ +@@ -241,6 +249,8 @@ + # endif + #elif defined(RT_OS_LINUX) + uint8_t abPadding[320]; ++#elif defined(RT_OS_FREEBSD) ++ uint8_t abPadding[320]; + #else + uint8_t abPadding[128]; + #endif diff --git a/emulators/virtualbox/files/patch-src-VBox-HostDrivers-VBoxNetFlt-freebsd-VBoxNetFlt-freebsd.c b/emulators/virtualbox/files/patch-src-VBox-HostDrivers-VBoxNetFlt-freebsd-VBoxNetFlt-freebsd.c new file mode 100644 index 000000000000..bc23fb14a545 --- /dev/null +++ b/emulators/virtualbox/files/patch-src-VBox-HostDrivers-VBoxNetFlt-freebsd-VBoxNetFlt-freebsd.c @@ -0,0 +1,375 @@ +Index: src/VBox/HostDrivers/VBoxNetFlt/freebsd/VBoxNetFlt-freebsd.c +=================================================================== +--- src/VBox/HostDrivers/VBoxNetFlt/freebsd/VBoxNetFlt-freebsd.c (revision 23391) ++++ src/VBox/HostDrivers/VBoxNetFlt/freebsd/VBoxNetFlt-freebsd.c (working copy) +@@ -43,6 +43,8 @@ + #include <sys/socket.h> + #include <sys/sockio.h> + #include <sys/syscallsubr.h> ++#include <sys/queue.h> ++#include <sys/taskqueue.h> + + #include <net/if.h> + #include <net/if_var.h> +@@ -78,8 +80,6 @@ + static ng_rcvdata_t ng_vboxnetflt_rcvdata; + static ng_disconnect_t ng_vboxnetflt_disconnect; + static int ng_vboxnetflt_mod_event(module_t mod, int event, void *data); +-static int ng_vboxnetflt_rcv_in(hook_p node, item_p item); +-static int ng_vboxnetflt_rcv_out(hook_p node, item_p item); + + /** Netgraph node type */ + #define NG_VBOXNETFLT_NODE_TYPE "vboxnetflt" +@@ -112,8 +112,8 @@ + { + .version = NG_ABI_VERSION, + .name = NG_VBOXNETFLT_NODE_TYPE, +- .mod_event = vboxnetflt_modevent, +- .constructor = ng_vboxnetflt_constructor, ++ .mod_event = vboxnetflt_modevent, ++ .constructor = ng_vboxnetflt_constructor, + .rcvmsg = ng_vboxnetflt_rcvmsg, + .shutdown = ng_vboxnetflt_shutdown, + .newhook = ng_vboxnetflt_newhook, +@@ -267,16 +267,12 @@ + if (strcmp(name, NG_VBOXNETFLT_HOOK_IN) == 0) + { + #if __FreeBSD_version >= 800000 +- NG_HOOK_SET_RCVDATA(hook, ng_vboxnetflt_rcv_in); + NG_HOOK_SET_TO_INBOUND(hook); + #endif + pThis->u.s.input = hook; + } + else if (strcmp(name, NG_VBOXNETFLT_HOOK_OUT) == 0) + { +-#if __FreeBSD_version >= 800000 +- NG_HOOK_SET_RCVDATA(hook, ng_vboxnetflt_rcv_out); +-#endif + pThis->u.s.output = hook; + } + else +@@ -310,161 +306,171 @@ + + /** + * Handle data on netgraph hooks. ++ * Frames processing is deferred to a taskqueue because this might ++ * be called with non-sleepable locks held and code paths inside ++ * the virtual switch might sleep. + */ + static int ng_vboxnetflt_rcvdata(hook_p hook, item_p item) + { + const node_p node = NG_HOOK_NODE(hook); + PVBOXNETFLTINS pThis = NG_NODE_PRIVATE(node); ++ struct ifnet *ifp = pThis->u.s.ifp; + struct mbuf *m; ++ struct m_tag *mtag; ++ bool fActive; + ++ fActive = ASMAtomicUoReadBool(&pThis->fActive); ++ ++ NGI_GET_M(item, m); ++ NG_FREE_ITEM(item); ++ ++ /* Locate tag to see if processing should be skipped for this frame */ ++ mtag = m_tag_locate(m, MTAG_VBOX, PACKET_TAG_VBOX, NULL); ++ if (mtag != NULL) ++ { ++ m_tag_unlink(m, mtag); ++ m_tag_free(mtag); ++ } ++ ++ /* ++ * Handle incoming hook. This is connected to the ++ * input path of the interface, thus handling incoming frames. ++ */ + if (pThis->u.s.input == hook) +- return ng_vboxnetflt_rcv_in(hook, item); ++ { ++ if (mtag != NULL || !fActive) ++ { ++ ether_demux(ifp, m); ++ return (0); ++ } ++ mtx_lock_spin(&pThis->u.s.inq.ifq_mtx); ++ _IF_ENQUEUE(&pThis->u.s.inq, m); ++ mtx_unlock_spin(&pThis->u.s.inq.ifq_mtx); ++ taskqueue_enqueue_fast(taskqueue_fast, &pThis->u.s.tskin); ++ } ++ /** ++ * Handle mbufs on the outgoing hook, frames going to the interface ++ */ + else if (pThis->u.s.output == hook) +- return ng_vboxnetflt_rcv_out(hook, item); ++ { ++ if (mtag != NULL || !fActive) ++ return ether_output_frame(ifp, m); ++ mtx_lock_spin(&pThis->u.s.outq.ifq_mtx); ++ _IF_ENQUEUE(&pThis->u.s.outq, m); ++ mtx_unlock_spin(&pThis->u.s.outq.ifq_mtx); ++ taskqueue_enqueue_fast(taskqueue_fast, &pThis->u.s.tskout); ++ } + else + { +- NGI_GET_M(item, m); +- NG_FREE_ITEM(item); ++ m_freem(m); + } + return (0); + } + ++static int ng_vboxnetflt_shutdown(node_p node) ++{ ++ PVBOXNETFLTINS pThis = NG_NODE_PRIVATE(node); ++ bool fActive; ++ ++ /* Prevent node shutdown if we're active */ ++ fActive = ASMAtomicUoReadBool(&pThis->fActive); ++ if (fActive) ++ return (EBUSY); ++ NG_NODE_UNREF(node); ++ return (0); ++} ++ ++static int ng_vboxnetflt_disconnect(hook_p hook) ++{ ++ return (0); ++} ++ + /** +- * Handle incoming hook. This is connected to the +- * input path of the interface, thus handling incoming frames. ++ * Input processing task, handles incoming frames + */ +-static int ng_vboxnetflt_rcv_in(hook_p hook, item_p item) ++static void vboxNetFltFreeBSDinput(void *arg, int pending) + { ++ PVBOXNETFLTINS pThis = (PVBOXNETFLTINS)arg; + struct mbuf *m, *m0; +- struct m_tag *mtag; +- const node_p node = NG_HOOK_NODE(hook); +- PVBOXNETFLTINS pThis = NG_NODE_PRIVATE(node); + struct ifnet *ifp = pThis->u.s.ifp; +- bool fActive, fDropIt = false; + unsigned int cSegs = 0; ++ bool fDropIt = false, fActive; + PINTNETSG pSG; + +- NGI_GET_M(item, m); +- NG_FREE_ITEM(item); +- +- fActive = ASMAtomicUoReadBool(&pThis->fActive); +- if (!fActive) +- goto out; +- +- mtag = m_tag_locate(m, MTAG_VBOX, PACKET_TAG_VBOX, NULL); +- if (mtag != NULL) +- { +- m_tag_unlink(m, mtag); +- m_tag_free(mtag); +- goto out; +- } + vboxNetFltRetain(pThis, true /* fBusy */); +- +- for (m0 = m; m0 != NULL; m0 = m0->m_next) ++ for (;;) + { +- if (m0->m_len > 0) +- cSegs++; +- } ++ mtx_lock_spin(&pThis->u.s.inq.ifq_mtx); ++ _IF_DEQUEUE(&pThis->u.s.inq, m); ++ mtx_unlock_spin(&pThis->u.s.inq.ifq_mtx); ++ if (m == NULL) ++ break; + ++ for (m0 = m; m0 != NULL; m0 = m0->m_next) ++ if (m0->m_len > 0) ++ cSegs++; ++ + #ifdef PADD_RUNT_FRAMES_FROM_HOST +- if (m_length(m, NULL) < 60) +- cSegs++; ++ if (m_length(m, NULL) < 60) ++ cSegs++; + #endif + +- /* Create a copy of the mbuf and hand it to the virtual switch */ +- pSG = RTMemTmpAlloc(RT_OFFSETOF(INTNETSG, aSegs[cSegs])); +- vboxNetFltFreeBSDMBufToSG(pThis, m, pSG, cSegs, 0); +- fDropIt = pThis->pSwitchPort->pfnRecv(pThis->pSwitchPort, pSG, INTNETTRUNKDIR_WIRE); +- RTMemTmpFree(pSG); ++ /* Create a copy and deliver to the virtual switch */ ++ pSG = RTMemTmpAlloc(RT_OFFSETOF(INTNETSG, aSegs[cSegs])); ++ vboxNetFltFreeBSDMBufToSG(pThis, m, pSG, cSegs, 0); ++ fDropIt = pThis->pSwitchPort->pfnRecv(pThis->pSwitchPort, pSG, INTNETTRUNKDIR_HOST); ++ RTMemTmpFree(pSG); ++ if (fDropIt) ++ m_freem(m); ++ else ++ ether_demux(ifp, m); ++ } + vboxNetFltRelease(pThis, true /* fBusy */); +- +-out: +- /* Only deliver it to the host stack if the destination weren't a guest */ +- if (fDropIt) +- { +- m_freem(m); +- return (0); +- } +- ether_demux(ifp, m); +- return (0); + } + + /** +- * Handle mbufs on the outgoing hook, frames going to the interface ++ * Output processing task, handles outgoing frames + */ +-static int ng_vboxnetflt_rcv_out(hook_p hook, item_p item) ++static void vboxNetFltFreeBSDoutput(void *arg, int pending) + { ++ PVBOXNETFLTINS pThis = (PVBOXNETFLTINS)arg; + struct mbuf *m, *m0; +- struct m_tag *mtag; +- const node_p node = NG_HOOK_NODE(hook); +- PVBOXNETFLTINS pThis = NG_NODE_PRIVATE(node); + struct ifnet *ifp = pThis->u.s.ifp; + unsigned int cSegs = 0; + bool fDropIt = false, fActive; + PINTNETSG pSG; + +- NGI_GET_M(item, m); +- NG_FREE_ITEM(item); +- +- fActive = ASMAtomicUoReadBool(&pThis->fActive); +- if (!fActive) +- return ether_output_frame(ifp, m); +- + vboxNetFltRetain(pThis, true /* fBusy */); +- /* Pass directly to interface if the packet originated from us */ +- mtag = m_tag_locate(m, MTAG_VBOX, PACKET_TAG_VBOX, NULL); +- if (mtag != NULL) ++ for (;;) + { +- m_tag_unlink(m, mtag); +- m_tag_free(mtag); +- goto out; +- } ++ mtx_lock_spin(&pThis->u.s.outq.ifq_mtx); ++ _IF_DEQUEUE(&pThis->u.s.outq, m); ++ mtx_unlock_spin(&pThis->u.s.outq.ifq_mtx); ++ if (m == NULL) ++ break; + +- for (m0 = m; m0 != NULL; m0 = m0->m_next) +- { +- if (m0->m_len > 0) +- cSegs++; +- } ++ for (m0 = m; m0 != NULL; m0 = m0->m_next) ++ if (m0->m_len > 0) ++ cSegs++; + + #ifdef PADD_RUNT_FRAMES_FROM_HOST +- if (m_length(m, NULL) < 60) +- cSegs++; ++ if (m_length(m, NULL) < 60) ++ cSegs++; + #endif +- /* Create a copy and deliver to the virtual switch */ +- pSG = RTMemTmpAlloc(RT_OFFSETOF(INTNETSG, aSegs[cSegs])); +- vboxNetFltFreeBSDMBufToSG(pThis, m, pSG, cSegs, 0); +- fDropIt = pThis->pSwitchPort->pfnRecv(pThis->pSwitchPort, pSG, INTNETTRUNKDIR_HOST); +- RTMemTmpFree(pSG); ++ /* Create a copy and deliver to the virtual switch */ ++ pSG = RTMemTmpAlloc(RT_OFFSETOF(INTNETSG, aSegs[cSegs])); ++ vboxNetFltFreeBSDMBufToSG(pThis, m, pSG, cSegs, 0); ++ fDropIt = pThis->pSwitchPort->pfnRecv(pThis->pSwitchPort, pSG, INTNETTRUNKDIR_HOST); ++ RTMemTmpFree(pSG); + +-out: ++ if (fDropIt) ++ m_freem(m); ++ else ++ ether_output_frame(ifp, m); ++ } + vboxNetFltRelease(pThis, true /* fBusy */); +- if (fDropIt) +- { +- m_freem(m); +- return (0); +- } +- +- return ether_output_frame(ifp, m); + } + +-static int ng_vboxnetflt_shutdown(node_p node) +-{ +- PVBOXNETFLTINS pThis = NG_NODE_PRIVATE(node); +- bool fActive; +- +- /* Prevent node shutdown if we're active */ +- fActive = ASMAtomicUoReadBool(&pThis->fActive); +- if (fActive) +- return (EBUSY); +- NG_NODE_UNREF(node); +- return (0); +-} +- +-static int ng_vboxnetflt_disconnect(hook_p hook) +-{ +- return (0); +-} +- + /** + * Called to deliver a frame to either the host, the wire or both. + */ +@@ -536,13 +542,23 @@ + + /* Create a new netgraph node for this instance */ + if (ng_make_node_common(&ng_vboxnetflt_typestruct, &node) != 0) +- return VERR_INTERNAL_ERROR; ++ return VERR_INTERNAL_ERROR; + + RTSpinlockAcquire(pThis->hSpinlock, &Tmp); + ASMAtomicUoWritePtr((void * volatile *)&pThis->u.s.ifp, ifp); + pThis->u.s.node = node; + bcopy(IF_LLADDR(ifp), &pThis->u.s.Mac, ETHER_ADDR_LEN); + ASMAtomicUoWriteBool(&pThis->fDisconnectedFromHost, false); ++ /* Initialize deferred input queue */ ++ bzero(&pThis->u.s.inq, sizeof(struct ifqueue)); ++ mtx_init(&pThis->u.s.inq.ifq_mtx, "vboxnetflt inq", NULL, MTX_SPIN); ++ TASK_INIT(&pThis->u.s.tskin, 0, vboxNetFltFreeBSDinput, pThis); ++ ++ /* Initialize deferred output queue */ ++ bzero(&pThis->u.s.outq, sizeof(struct ifqueue)); ++ mtx_init(&pThis->u.s.outq.ifq_mtx, "vboxnetflt outq", NULL, MTX_SPIN); ++ TASK_INIT(&pThis->u.s.tskout, 0, vboxNetFltFreeBSDoutput, pThis); ++ + RTSpinlockRelease(pThis->hSpinlock, &Tmp); + + NG_NODE_SET_PRIVATE(node, pThis); +@@ -571,7 +587,10 @@ + } + + if (ifp0 != NULL) ++ { ++ vboxNetFltOsDeleteInstance(pThis); + vboxNetFltOsInitInstance(pThis, NULL); ++ } + + return !ASMAtomicUoReadBool(&pThis->fDisconnectedFromHost); + } +@@ -579,6 +598,12 @@ + void vboxNetFltOsDeleteInstance(PVBOXNETFLTINS pThis) + { + ++ taskqueue_drain(taskqueue_fast, &pThis->u.s.tskin); ++ taskqueue_drain(taskqueue_fast, &pThis->u.s.tskout); ++ ++ mtx_destroy(&pThis->u.s.inq.ifq_mtx); ++ mtx_destroy(&pThis->u.s.outq.ifq_mtx); ++ + if (pThis->u.s.node != NULL) + ng_rmnode_self(pThis->u.s.node); + pThis->u.s.node = NULL; diff --git a/emulators/virtualbox/files/patch-src-VBox-apps-adpctl_VBoxNetAdpCtl.cpp b/emulators/virtualbox/files/patch-src-VBox-apps-adpctl_VBoxNetAdpCtl.cpp new file mode 100644 index 000000000000..955bf7a3a151 --- /dev/null +++ b/emulators/virtualbox/files/patch-src-VBox-apps-adpctl_VBoxNetAdpCtl.cpp @@ -0,0 +1,207 @@ +--- src/apps/adpctl/VBoxNetAdpCtl.cpp.r22902 2009-04-10 14:03:59.000000000 +0200 ++++ src/apps/adpctl/VBoxNetAdpCtl.cpp 2009-09-16 14:07:11.000000000 +0200 +@@ -1,4 +1,4 @@ +-/* $Id: VBoxNetAdpCtl.cpp 18864 2009-04-10 12:03:59Z vboxsync $ */ ++/* $Id: VBoxNetAdpCtl.cpp 23064 2009-09-16 12:07:11Z vboxsync $ */ + /** @file + * Apps - VBoxAdpCtl, Configuration tool for vboxnetX adapters. + */ +@@ -24,7 +24,6 @@ + /******************************************************************************* + * Header Files * + *******************************************************************************/ +-#include <assert.h> + #include <stdio.h> + #include <stdlib.h> + #include <string.h> +@@ -36,11 +35,12 @@ + # include <sys/ioccom.h> + #endif + +-/* @todo Error codes must be moved to some header file */ +-#define ADPCTLERR_NO_CTL_DEV 3 +-#define ADPCTLERR_IOCTL_FAILED 4 ++/** @todo Error codes must be moved to some header file */ ++#define ADPCTLERR_BAD_NAME 2 ++#define ADPCTLERR_NO_CTL_DEV 3 ++#define ADPCTLERR_IOCTL_FAILED 4 + +-/* @todo These are duplicates from src/VBox/HostDrivers/VBoxNetAdp/VBoxNetAdpInternal.h */ ++/** @todo These are duplicates from src/VBox/HostDrivers/VBoxNetAdp/VBoxNetAdpInternal.h */ + #define VBOXNETADP_CTL_DEV_NAME "/dev/vboxnetctl" + #define VBOXNETADP_NAME "vboxnet" + #define VBOXNETADP_MAX_NAME_LEN 32 +@@ -85,6 +85,7 @@ + pcszArg5, /* [network mask] */ + NULL /* terminator */ + }; ++ char * const envp[] = { (char*)"LC_ALL=C", NULL }; + int rc = EXIT_SUCCESS; + pid_t childPid = fork(); + switch (childPid) +@@ -94,7 +95,7 @@ + rc = EXIT_FAILURE; + break; + case 0: /* Child process. */ +- if (execv(VBOXADPCTL_IFCONFIG_PATH, (char * const*)argv) == -1) ++ if (execve(VBOXADPCTL_IFCONFIG_PATH, (char * const*)argv, envp) == -1) + rc = EXIT_FAILURE; + break; + default: /* Parent process. */ +@@ -108,15 +109,39 @@ + #define MAX_ADDRESSES 128 + #define MAX_ADDRLEN 64 + +-static bool removeAddresses(const char *pszAdapterName) ++static bool removeAddresses(char *pszAdapterName) + { +- char szCmd[1024], szBuf[1024]; ++ char szBuf[1024]; + char aszAddresses[MAX_ADDRESSES][MAX_ADDRLEN]; ++ int rc; ++ int fds[2]; ++ char * const argv[] = { VBOXADPCTL_IFCONFIG_PATH, pszAdapterName, NULL }; ++ char * const envp[] = { (char*)"LC_ALL=C", NULL }; + + memset(aszAddresses, 0, sizeof(aszAddresses)); +- snprintf(szCmd, sizeof(szCmd), VBOXADPCTL_IFCONFIG_PATH " %s", pszAdapterName); +- FILE *fp = popen(szCmd, "r"); + ++ rc = pipe(fds); ++ if (rc < 0) ++ return false; ++ ++ pid_t pid = fork(); ++ if (pid < 0) ++ return false; ++ ++ if (pid == 0) ++ { ++ /* child */ ++ close(fds[0]); ++ close(STDOUT_FILENO); ++ rc = dup2(fds[1], STDOUT_FILENO); ++ if (rc >= 0) ++ execve(VBOXADPCTL_IFCONFIG_PATH, argv, envp); ++ return false; ++ } ++ ++ /* parent */ ++ close(fds[1]); ++ FILE *fp = fdopen(fds[0], "r"); + if (!fp) + return false; + +@@ -124,9 +149,6 @@ + for (cAddrs = 0; cAddrs < MAX_ADDRESSES && fgets(szBuf, sizeof(szBuf), fp);) + { + int cbSkipWS = strspn(szBuf, " \t"); +-#if 0 /* Don't use this! assert() breaks the mac build. Use IPRT or be a rectangular building thing. */ +- assert(cbSkipWS < 20); +-#endif + char *pszWord = strtok(szBuf + cbSkipWS, " "); + /* We are concerned with IPv6 address lines only. */ + if (!pszWord || strcmp(pszWord, "inet6")) +@@ -143,11 +165,12 @@ + continue; + strncpy(aszAddresses[cAddrs++], pszWord, MAX_ADDRLEN-1); + } +- pclose(fp); ++ fclose(fp); + + for (int i = 0; i < cAddrs; i++) + { +- if (executeIfconfig(pszAdapterName, "inet6", VBOXADPCTL_DEL_CMD, aszAddresses[i]) != EXIT_SUCCESS) ++ if (executeIfconfig(pszAdapterName, "inet6", ++ VBOXADPCTL_DEL_CMD, aszAddresses[i]) != EXIT_SUCCESS) + return false; + } + +@@ -166,19 +189,41 @@ + int rc = ioctl(fd, uCmd, pData); + if (rc == -1) + { +- perror("VBoxNetAdpCtl: ioctl failed for " VBOXNETADP_CTL_DEV_NAME); ++ perror("VBoxNetAdpCtl: ioctl failed for " VBOXNETADP_CTL_DEV_NAME); + rc = ADPCTLERR_IOCTL_FAILED; + } +- ++ + close(fd); +- ++ + return rc; + } + ++int checkAdapterName(const char *pcszNameIn, char *pszNameOut) ++{ ++ int iAdapterIndex = -1; ++ ++ if ( strlen(pcszNameIn) >= VBOXNETADP_MAX_NAME_LEN ++ || sscanf(pcszNameIn, "vboxnet%d", &iAdapterIndex) != 1 ++ || iAdapterIndex < 0 || iAdapterIndex > 99 ) ++ { ++ fprintf(stderr, "Setting configuration for %s is not supported.\n", pcszNameIn); ++ return ADPCTLERR_BAD_NAME; ++ } ++ sprintf(pszNameOut, "vboxnet%d", iAdapterIndex); ++ if (strcmp(pszNameOut, pcszNameIn)) ++ { ++ fprintf(stderr, "Invalid adapter name %s.\n", pcszNameIn); ++ return ADPCTLERR_BAD_NAME; ++ } ++ ++ return 0; ++} ++ + int main(int argc, char *argv[]) + + { +- const char *pszAdapterName; ++ char szAdapterName[VBOXNETADP_MAX_NAME_LEN]; ++ char *pszAdapterName; + const char *pszAddress; + const char *pszNetworkMask = NULL; + const char *pszOption = NULL; +@@ -216,13 +261,18 @@ + pszAddress = argv[2]; + if (strcmp("remove", pszAddress) == 0) + { +- strncpy(Req.szName, pszAdapterName, sizeof(Req.szName)); ++ rc = checkAdapterName(pszAdapterName, szAdapterName); ++ if (rc) ++ return rc; ++ memset(&Req, '\0', sizeof(Req)); ++ snprintf(Req.szName, sizeof(Req.szName), "%s", szAdapterName); + return doIOCtl(VBOXNETADP_CTL_REMOVE, &Req); + } + break; + case 2: + if (strcmp("add", argv[1]) == 0) + { ++ memset(&Req, '\0', sizeof(Req)); + rc = doIOCtl(VBOXNETADP_CTL_ADD, &Req); + if (rc == 0) + puts(Req.szName); +@@ -237,11 +287,11 @@ + return 1; + } + +- if (strncmp("vboxnet", pszAdapterName, 7)) +- { +- fprintf(stderr, "Setting configuration for %s is not supported.\n", pszAdapterName); +- return 2; +- } ++ rc = checkAdapterName(pszAdapterName, szAdapterName); ++ if (rc) ++ return rc; ++ ++ pszAdapterName = szAdapterName; + + if (fRemove) + { +@@ -276,3 +326,4 @@ + } + return rc; + } ++ diff --git a/emulators/virtualbox/pkg-plist b/emulators/virtualbox/pkg-plist index 701bcf61f230..bdafc64fb6ee 100644 --- a/emulators/virtualbox/pkg-plist +++ b/emulators/virtualbox/pkg-plist @@ -592,7 +592,7 @@ include/virtualbox/xpcom/xpcom-config.h %%QT4%%@dirrmtry share/icons %%QT4%%@dirrmtry share/applications @dirrm lib/virtualbox/components -@dirrm lib/virtualbox/additions +%%GUESTADDITIONS%%@dirrm lib/virtualbox/additions @dirrm lib/virtualbox @cwd / %%KMODDIR%%/vboxdrv.ko |