Commit 671f9ae6 authored by Oleg Dzhimiev's avatar Oleg Dzhimiev

builds in Kubuntu 20.04

parent 6e0687d7
......@@ -4,7 +4,7 @@ This layer provides official support for Elphel Inc. reconfigurable cameras.
## Compatibility
Compatible with Kubuntu 16.04 (which uses glibc 2.29)
Compatible with Kubuntu 20.04 (which uses glibc 2.31)
## Supported boards/machines
Camera boards to be supported by this layer:
......
......@@ -12,6 +12,9 @@ PREFERRED_VERSION_linux-xlnx = "4.%"
PREFERRED_VERSION_php = "5.%"
#PREFERRED_VERSION_php = "7.%"
# Qemu preferred version for Kubuntu 20.04
QEMUVERSION = "4.1%"
# Machine definition known by ezynq and xilinx u-boot
UBOOT_MACHINE = "elphel393_config"
......@@ -43,4 +46,4 @@ IMAGE_BOOT_FILES += " \
${PRODUCTION_DEVICETREE} \
${PRODUCTION_KERNEL} \
"
HOSTTOOLS += " ping scp"
\ No newline at end of file
HOSTTOOLS += " ping scp"
SUMMARY = "Qemu helper scripts"
LICENSE = "GPLv2"
RDEPENDS_${PN} = "nativesdk-qemu \
nativesdk-python3-shell nativesdk-python3-fcntl nativesdk-python3-logging \
"
PR = "r9"
LIC_FILES_CHKSUM = "file://${WORKDIR}/tunctl.c;endline=4;md5=ff3a09996bc5fff6bc5d4e0b4c28f999 \
file://${COREBASE}/scripts/runqemu;beginline=5;endline=10;md5=ac2b489a58739c7628a2604698db5e7f"
SRC_URI = "file://${COREBASE}/scripts/runqemu \
file://${COREBASE}/scripts/runqemu-addptable2image \
file://${COREBASE}/scripts/runqemu-gen-tapdevs \
file://${COREBASE}/scripts/runqemu-ifup \
file://${COREBASE}/scripts/runqemu-ifdown \
file://${COREBASE}/scripts/oe-find-native-sysroot \
file://${COREBASE}/scripts/runqemu-extract-sdk \
file://${COREBASE}/scripts/runqemu-export-rootfs \
file://tunctl.c \
"
S = "${WORKDIR}"
inherit nativesdk
do_compile() {
${CC} tunctl.c -o tunctl
}
do_install() {
install -d ${D}${bindir}
install -m 0755 ${WORKDIR}${COREBASE}/scripts/oe-* ${D}${bindir}/
install -m 0755 ${WORKDIR}${COREBASE}/scripts/runqemu* ${D}${bindir}/
install tunctl ${D}${bindir}/
}
SUMMARY = "Helper utilities needed by the runqemu script"
LICENSE = "GPLv2"
RDEPENDS_${PN} = "qemu-system-native"
PR = "r1"
LIC_FILES_CHKSUM = "file://${WORKDIR}/tunctl.c;endline=4;md5=ff3a09996bc5fff6bc5d4e0b4c28f999"
SRC_URI = "file://tunctl.c"
S = "${WORKDIR}"
inherit native
do_compile() {
${CC} ${CFLAGS} ${LDFLAGS} -Wall tunctl.c -o tunctl
}
do_install() {
install -d ${D}${bindir}
install tunctl ${D}${bindir}/
}
DEPENDS += "qemu-system-native"
addtask addto_recipe_sysroot after do_populate_sysroot before do_build
/* Copyright 2002 Jeff Dike
* Licensed under the GPL
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <pwd.h>
#include <grp.h>
#include <net/if.h>
#include <sys/ioctl.h>
#include <linux/if_tun.h>
/* TUNSETGROUP appeared in 2.6.23 */
#ifndef TUNSETGROUP
#define TUNSETGROUP _IOW('T', 206, int)
#endif
static void Usage(char *name, int status)
{
fprintf(stderr, "Create: %s [-b] [-u owner] [-g group] [-t device-name] "
"[-f tun-clone-device]\n", name);
fprintf(stderr, "Delete: %s -d device-name [-f tun-clone-device]\n\n",
name);
fprintf(stderr, "The default tun clone device is /dev/net/tun - some systems"
" use\n/dev/misc/net/tun instead\n\n");
fprintf(stderr, "-b will result in brief output (just the device name)\n");
exit(status);
}
int main(int argc, char **argv)
{
struct ifreq ifr;
struct passwd *pw;
struct group *gr;
uid_t owner = -1;
gid_t group = -1;
int tap_fd, opt, delete = 0, brief = 0;
char *tun = "", *file = "/dev/net/tun", *name = argv[0], *end;
while((opt = getopt(argc, argv, "bd:f:t:u:g:h")) > 0){
switch(opt) {
case 'b':
brief = 1;
break;
case 'd':
delete = 1;
tun = optarg;
break;
case 'f':
file = optarg;
break;
case 'u':
pw = getpwnam(optarg);
if(pw != NULL){
owner = pw->pw_uid;
break;
}
owner = strtol(optarg, &end, 0);
if(*end != '\0'){
fprintf(stderr, "'%s' is neither a username nor a numeric uid.\n",
optarg);
Usage(name, 1);
}
break;
case 'g':
gr = getgrnam(optarg);
if(gr != NULL){
group = gr->gr_gid;
break;
}
group = strtol(optarg, &end, 0);
if(*end != '\0'){
fprintf(stderr, "'%s' is neither a groupname nor a numeric group.\n",
optarg);
Usage(name, 1);
}
break;
case 't':
tun = optarg;
break;
case 'h':
Usage(name, 0);
break;
default:
Usage(name, 1);
}
}
argv += optind;
argc -= optind;
if(argc > 0)
Usage(name, 1);
if((tap_fd = open(file, O_RDWR)) < 0){
fprintf(stderr, "Failed to open '%s' : ", file);
perror("");
exit(1);
}
memset(&ifr, 0, sizeof(ifr));
ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
strncpy(ifr.ifr_name, tun, sizeof(ifr.ifr_name) - 1);
if(ioctl(tap_fd, TUNSETIFF, (void *) &ifr) < 0){
perror("TUNSETIFF");
exit(1);
}
if(delete){
if(ioctl(tap_fd, TUNSETPERSIST, 0) < 0){
perror("disabling TUNSETPERSIST");
exit(1);
}
printf("Set '%s' nonpersistent\n", ifr.ifr_name);
}
else {
/* emulate behaviour prior to TUNSETGROUP */
if(owner == -1 && group == -1) {
owner = geteuid();
}
if(owner != -1) {
if(ioctl(tap_fd, TUNSETOWNER, owner) < 0){
perror("TUNSETOWNER");
exit(1);
}
}
if(group != -1) {
if(ioctl(tap_fd, TUNSETGROUP, group) < 0){
perror("TUNSETGROUP");
exit(1);
}
}
if(ioctl(tap_fd, TUNSETPERSIST, 1) < 0){
perror("enabling TUNSETPERSIST");
exit(1);
}
if(brief)
printf("%s\n", ifr.ifr_name);
else {
printf("Set '%s' persistent and owned by", ifr.ifr_name);
if(owner != -1)
printf(" uid %d", owner);
if(group != -1)
printf(" gid %d", group);
printf("\n");
}
}
return(0);
}
inherit native
require qemu.inc
SRC_URI_append = " \
file://0010-fix-libcap-header-issue-on-some-distro.patch \
file://0011-cpus.c-Add-error-messages-when-qemi_cpu_kick_thread-.patch \
"
EXTRA_OEMAKE_append = " LD='${LD}' AR='${AR}' OBJCOPY='${OBJCOPY}' LDFLAGS='${LDFLAGS}'"
LDFLAGS_append = " -fuse-ld=bfd"
do_install_append() {
${@bb.utils.contains('PACKAGECONFIG', 'gtk+', 'make_qemu_wrapper', '', d)}
}
BPN = "qemu"
DEPENDS = "glib-2.0-native zlib-native"
require qemu-native.inc
EXTRA_OECONF_append = " --target-list=${@get_qemu_usermode_target_list(d)} --disable-tools --disable-blobs --disable-guest-agent"
PACKAGECONFIG ??= ""
BPN = "qemu"
require qemu-native.inc
# As some of the files installed by qemu-native and qemu-system-native
# are the same, we depend on qemu-native to get the full installation set
# and avoid file clashes
DEPENDS = "glib-2.0-native zlib-native pixman-native qemu-native bison-native"
EXTRA_OECONF_append = " --target-list=${@get_qemu_system_target_list(d)}"
PACKAGECONFIG ??= "fdt alsa kvm"
# Handle distros such as CentOS 5 32-bit that do not have kvm support
PACKAGECONFIG_remove = "${@'kvm' if not os.path.exists('/usr/include/linux/kvm.h') else ''}"
do_install_append() {
install -Dm 0755 ${WORKDIR}/powerpc_rom.bin ${D}${datadir}/qemu
# The following is also installed by qemu-native
rm -f ${D}${datadir}/qemu/trace-events-all
rm -rf ${D}${datadir}/qemu/keymaps
rm -rf ${D}${datadir}/icons/
}
# possible arch values are:
# aarch64 arm armeb alpha cris i386 x86_64 m68k microblaze
# mips mipsel mips64 mips64el ppc ppc64 ppc64abi32 ppcemb
# riscv32 riscv64 sparc sparc32 sparc32plus
def get_qemu_target_list(d):
import bb
archs = d.getVar('QEMU_TARGETS').split()
tos = d.getVar('HOST_OS')
softmmuonly = ""
for arch in ['ppcemb', 'lm32']:
if arch in archs:
softmmuonly += arch + "-softmmu,"
archs.remove(arch)
linuxuseronly = ""
for arch in ['armeb', 'alpha', 'ppc64abi32', 'sparc32plus', 'aarch64_be']:
if arch in archs:
linuxuseronly += arch + "-linux-user,"
archs.remove(arch)
if 'linux' not in tos:
return softmmuonly + ''.join([arch + "-softmmu" + "," for arch in archs]).rstrip(',')
return softmmuonly + linuxuseronly + ''.join([arch + "-linux-user" + "," + arch + "-softmmu" + "," for arch in archs]).rstrip(',')
def get_qemu_usermode_target_list(d):
return ",".join(filter(lambda i: "-linux-user" in i, get_qemu_target_list(d).split(',')))
def get_qemu_system_target_list(d):
return ",".join(filter(lambda i: "-linux-user" not in i, get_qemu_target_list(d).split(',')))
SUMMARY = "Fast open source processor emulator"
DESCRIPTION = "QEMU is a hosted virtual machine monitor: it emulates the \
machine's processor through dynamic binary translation and provides a set \
of different hardware and device models for the machine, enabling it to run \
a variety of guest operating systems"
HOMEPAGE = "http://qemu.org"
LICENSE = "GPLv2 & LGPLv2.1"
RDEPENDS_${PN}-ptest = "bash make"
require qemu-targets.inc
inherit pkgconfig ptest
LIC_FILES_CHKSUM = "file://COPYING;md5=441c28d2cf86e15a37fa47e15a72fbac \
file://COPYING.LIB;endline=24;md5=8c5efda6cf1e1b03dcfd0e6c0d271c7f"
SRC_URI = "https://download.qemu.org/${BPN}-${PV}.tar.xz \
file://powerpc_rom.bin \
file://run-ptest \
file://0001-qemu-Add-missing-wacom-HID-descriptor.patch \
file://0002-Add-subpackage-ptest-which-runs-all-unit-test-cases-.patch \
file://0003-qemu-Add-addition-environment-space-to-boot-loader-q.patch \
file://0004-qemu-disable-Valgrind.patch \
file://0005-qemu-native-set-ld.bfd-fix-cflags-and-set-some-envir.patch \
file://0006-chardev-connect-socket-to-a-spawned-command.patch \
file://0007-apic-fixup-fallthrough-to-PIC.patch \
file://0008-linux-user-Fix-webkitgtk-hangs-on-32-bit-x86-target.patch \
file://0009-Fix-webkitgtk-builds.patch \
file://0010-configure-Add-pkg-config-handling-for-libgcrypt.patch \
file://0011-linux-user-remove-host-stime-syscall.patch \
file://CVE-2019-15890.patch \
file://CVE-2019-12068.patch \
file://CVE-2020-1711.patch \
file://CVE-2019-20382.patch \
file://CVE-2020-7039-1.patch \
file://CVE-2020-7039-2.patch \
file://CVE-2020-7039-3.patch \
file://CVE-2020-7211.patch \
file://CVE-2020-11869.patch \
file://CVE-2020-13765.patch \
file://CVE-2020-10702.patch \
file://CVE-2020-16092.patch \
file://CVE-2020-10756.patch \
file://CVE-2020-15863.patch \
file://CVE-2020-14364.patch \
"
UPSTREAM_CHECK_REGEX = "qemu-(?P<pver>\d+(\.\d+)+)\.tar"
SRC_URI[md5sum] = "cdf2b5ca52b9abac9bacb5842fa420f8"
SRC_URI[sha256sum] = "656e60218689bdeec69903087fd7582d5d3e72238d02f4481d8dc6d79fd909c6"
COMPATIBLE_HOST_mipsarchn32 = "null"
COMPATIBLE_HOST_mipsarchn64 = "null"
do_install_append() {
# Prevent QA warnings about installed ${localstatedir}/run
if [ -d ${D}${localstatedir}/run ]; then rmdir ${D}${localstatedir}/run; fi
}
do_compile_ptest() {
make buildtest-TESTS
}
do_install_ptest() {
cp -rL ${B}/tests ${D}${PTEST_PATH}
find ${D}${PTEST_PATH}/tests -type f -name "*.[Sshcod]" | xargs -i rm -rf {}
cp ${S}/tests/Makefile.include ${D}${PTEST_PATH}/tests
# Don't check the file genreated by configure
sed -i -e '/wildcard config-host.mak/d' \
-e '$ {/endif/d}' ${D}${PTEST_PATH}/tests/Makefile.include
}
# QEMU_TARGETS is overridable variable
QEMU_TARGETS ?= "arm aarch64 i386 mips mipsel mips64 mips64el ppc ppc64 riscv32 riscv64 sh4 x86_64"
EXTRA_OECONF = " \
--prefix=${prefix} \
--bindir=${bindir} \
--includedir=${includedir} \
--libdir=${libdir} \
--mandir=${mandir} \
--datadir=${datadir} \
--docdir=${docdir}/${BPN} \
--sysconfdir=${sysconfdir} \
--libexecdir=${libexecdir} \
--localstatedir=${localstatedir} \
--with-confsuffix=/${BPN} \
--disable-strip \
--disable-werror \
--extra-cflags='${CFLAGS}' \
${PACKAGECONFIG_CONFARGS} \
"
export LIBTOOL="${HOST_SYS}-libtool"
B = "${WORKDIR}/build"
EXTRA_OECONF_append = " --python=${HOSTTOOLS_DIR}/python3"
do_configure_prepend_class-native() {
# Append build host pkg-config paths for native target since the host may provide sdl
BHOST_PKGCONFIG_PATH=$(PATH=/usr/bin:/bin pkg-config --variable pc_path pkg-config || echo "")
if [ ! -z "$BHOST_PKGCONFIG_PATH" ]; then
export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:$BHOST_PKGCONFIG_PATH
fi
}
do_configure() {
${S}/configure ${EXTRA_OECONF}
}
do_install () {
export STRIP=""
oe_runmake 'DESTDIR=${D}' install
}
# The following fragment will create a wrapper for qemu-mips user emulation
# binary in order to work around a segmentation fault issue. Basically, by
# default, the reserved virtual address space for 32-on-64 bit is set to 4GB.
# This will trigger a MMU access fault in the virtual CPU. With this change,
# the qemu-mips works fine.
# IMPORTANT: This piece needs to be removed once the root cause is fixed!
do_install_append() {
if [ -e "${D}/${bindir}/qemu-mips" ]; then
create_wrapper ${D}/${bindir}/qemu-mips \
QEMU_RESERVED_VA=0x0
fi
}
# END of qemu-mips workaround
make_qemu_wrapper() {
gdk_pixbuf_module_file=`pkg-config --variable=gdk_pixbuf_cache_file gdk-pixbuf-2.0`
for tool in `ls ${D}${bindir}/qemu-system-*`; do
create_wrapper $tool \
GDK_PIXBUF_MODULE_FILE=$gdk_pixbuf_module_file \
FONTCONFIG_PATH=/etc/fonts \
GTK_THEME=Adwaita
done
}
# Disable kvm/virgl/mesa on targets that do not support it
PACKAGECONFIG_remove_darwin = "kvm virglrenderer glx gtk+"
PACKAGECONFIG_remove_mingw32 = "kvm virglrenderer glx gtk+"
PACKAGECONFIG[sdl] = "--enable-sdl,--disable-sdl,libsdl2"
PACKAGECONFIG[virtfs] = "--enable-virtfs --enable-attr,--disable-virtfs,libcap attr,"
PACKAGECONFIG[aio] = "--enable-linux-aio,--disable-linux-aio,libaio,"
PACKAGECONFIG[xfs] = "--enable-xfsctl,--disable-xfsctl,xfsprogs,"
PACKAGECONFIG[xen] = "--enable-xen,--disable-xen,xen,xen-libxenstore xen-libxenctrl xen-libxenguest"
PACKAGECONFIG[vnc-sasl] = "--enable-vnc --enable-vnc-sasl,--disable-vnc-sasl,cyrus-sasl,"
PACKAGECONFIG[vnc-jpeg] = "--enable-vnc --enable-vnc-jpeg,--disable-vnc-jpeg,jpeg,"
PACKAGECONFIG[vnc-png] = "--enable-vnc --enable-vnc-png,--disable-vnc-png,libpng,"
PACKAGECONFIG[libcurl] = "--enable-curl,--disable-curl,curl,"
PACKAGECONFIG[nss] = "--enable-smartcard,--disable-smartcard,nss,"
PACKAGECONFIG[curses] = "--enable-curses,--disable-curses,ncurses,"
PACKAGECONFIG[gtk+] = "--enable-gtk,--disable-gtk,gtk+3 gettext-native"
PACKAGECONFIG[vte] = "--enable-vte,--disable-vte,vte gettext-native"
PACKAGECONFIG[libcap-ng] = "--enable-cap-ng,--disable-cap-ng,libcap-ng,"
PACKAGECONFIG[ssh] = "--enable-libssh,--disable-libssh,libssh,"
PACKAGECONFIG[gcrypt] = "--enable-gcrypt,--disable-gcrypt,libgcrypt,"
PACKAGECONFIG[nettle] = "--enable-nettle,--disable-nettle,nettle"
PACKAGECONFIG[libusb] = "--enable-libusb,--disable-libusb,libusb1"
PACKAGECONFIG[fdt] = "--enable-fdt,--disable-fdt,dtc"
PACKAGECONFIG[alsa] = "--audio-drv-list='oss alsa',,alsa-lib"
PACKAGECONFIG[glx] = "--enable-opengl,--disable-opengl,mesa"
PACKAGECONFIG[lzo] = "--enable-lzo,--disable-lzo,lzo"
PACKAGECONFIG[numa] = "--enable-numa,--disable-numa,numactl"
PACKAGECONFIG[gnutls] = "--enable-gnutls,--disable-gnutls,gnutls"
PACKAGECONFIG[bzip2] = "--enable-bzip2,--disable-bzip2,bzip2"
PACKAGECONFIG[bluez] = "--enable-bluez,--disable-bluez,bluez5"
PACKAGECONFIG[libiscsi] = "--enable-libiscsi,--disable-libiscsi"
PACKAGECONFIG[kvm] = "--enable-kvm,--disable-kvm"
PACKAGECONFIG[virglrenderer] = "--enable-virglrenderer,--disable-virglrenderer,virglrenderer"
# spice will be in meta-networking layer
PACKAGECONFIG[spice] = "--enable-spice,--disable-spice,spice"
# usbredir will be in meta-networking layer
PACKAGECONFIG[usb-redir] = "--enable-usb-redir,--disable-usb-redir,usbredir"
PACKAGECONFIG[snappy] = "--enable-snappy,--disable-snappy,snappy"
PACKAGECONFIG[glusterfs] = "--enable-glusterfs,--disable-glusterfs,glusterfs"
INSANE_SKIP_${PN} = "arch"
FILES_${PN} += "${datadir}/icons"
From 4655dc18074e0be9d239f51dac32b61435da8549 Mon Sep 17 00:00:00 2001
From: Richard Purdie <richard.purdie@linuxfoundation.org>
Date: Thu, 27 Nov 2014 14:04:29 +0000
Subject: [PATCH] qemu: Add missing wacom HID descriptor
The USB wacom device is missing a HID descriptor which causes it
to fail to operate with recent kernels (e.g. 3.17).
This patch adds a HID desriptor to the device, based upon one from
real wcom device.
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Upstream-Status: Submitted
2014/11/27
---
hw/usb/dev-wacom.c | 94 +++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 93 insertions(+), 1 deletion(-)
diff --git a/hw/usb/dev-wacom.c b/hw/usb/dev-wacom.c
index 8c43db93..3ff8ca28 100644
--- a/hw/usb/dev-wacom.c
+++ b/hw/usb/dev-wacom.c
@@ -74,6 +74,89 @@ static const USBDescStrings desc_strings = {
[STR_SERIALNUMBER] = "1",
};
+static const uint8_t qemu_tablet_hid_report_descriptor[] = {
+ 0x05, 0x01, /* Usage Page (Generic Desktop) */
+ 0x09, 0x02, /* Usage (Mouse) */
+ 0xa1, 0x01, /* Collection (Application) */
+ 0x85, 0x01, /* Report ID (1) */
+ 0x09, 0x01, /* Usage (Pointer) */
+ 0xa1, 0x00, /* Collection (Physical) */
+ 0x05, 0x09, /* Usage Page (Button) */
+ 0x19, 0x01, /* Usage Minimum (1) */
+ 0x29, 0x05, /* Usage Maximum (5) */
+ 0x15, 0x00, /* Logical Minimum (0) */
+ 0x25, 0x01, /* Logical Maximum (1) */
+ 0x95, 0x05, /* Report Count (5) */
+ 0x75, 0x01, /* Report Size (1) */
+ 0x81, 0x02, /* Input (Data, Variable, Absolute) */
+ 0x95, 0x01, /* Report Count (1) */
+ 0x75, 0x03, /* Report Size (3) */
+ 0x81, 0x01, /* Input (Constant) */
+ 0x05, 0x01, /* Usage Page (Generic Desktop) */
+ 0x09, 0x30, /* Usage (X) */
+ 0x09, 0x31, /* Usage (Y) */
+ 0x15, 0x81, /* Logical Minimum (-127) */
+ 0x25, 0x7f, /* Logical Maximum (127) */
+ 0x75, 0x08, /* Report Size (8) */
+ 0x95, 0x02, /* Report Count (2) */
+ 0x81, 0x06, /* Input (Data, Variable, Relative) */
+ 0xc0, /* End Collection */
+ 0xc0, /* End Collection */
+ 0x05, 0x0d, /* Usage Page (Digitizer) */
+ 0x09, 0x01, /* Usage (Digitizer) */
+ 0xa1, 0x01, /* Collection (Application) */
+ 0x85, 0x02, /* Report ID (2) */
+ 0xa1, 0x00, /* Collection (Physical) */
+ 0x06, 0x00, 0xff, /* Usage Page (Vendor 0xff00) */
+ 0x09, 0x01, /* Usage (Digitizer) */
+ 0x15, 0x00, /* Logical Minimum (0) */
+ 0x26, 0xff, 0x00, /* Logical Maximum (255) */
+ 0x75, 0x08, /* Report Size (8) */
+ 0x95, 0x08, /* Report Count (8) */
+ 0x81, 0x02, /* Input (Data, Variable, Absolute) */
+ 0xc0, /* End Collection */
+ 0x09, 0x01, /* Usage (Digitizer) */
+ 0x85, 0x02, /* Report ID (2) */
+ 0x95, 0x01, /* Report Count (1) */
+ 0xb1, 0x02, /* FEATURE (2) */
+ 0xc0, /* End Collection */
+ 0x06, 0x00, 0xff, /* Usage Page (Vendor 0xff00) */
+ 0x09, 0x01, /* Usage (Digitizer) */
+ 0xa1, 0x01, /* Collection (Application) */
+ 0x85, 0x02, /* Report ID (2) */
+ 0x05, 0x0d, /* Usage Page (Digitizer) */
+ 0x09, 0x22, /* Usage (Finger) */
+ 0xa1, 0x00, /* Collection (Physical) */
+ 0x06, 0x00, 0xff, /* Usage Page (Vendor 0xff00) */
+ 0x09, 0x01, /* Usage (Digitizer) */
+ 0x15, 0x00, /* Logical Minimum (0) */
+ 0x26, 0xff, 0x00, /* Logical Maximum */
+ 0x75, 0x08, /* Report Size (8) */
+ 0x95, 0x02, /* Report Count (2) */
+ 0x81, 0x02, /* Input (Data, Variable, Absolute) */
+ 0x05, 0x01, /* Usage Page (Generic Desktop) */
+ 0x09, 0x30, /* Usage (X) */
+ 0x35, 0x00, /* Physical Minimum */
+ 0x46, 0xe0, 0x2e, /* Physical Maximum */
+ 0x26, 0xe0, 0x01, /* Logical Maximum */
+ 0x75, 0x10, /* Report Size (16) */
+ 0x95, 0x01, /* Report Count (1) */
+ 0x81, 0x02, /* Input (Data, Variable, Absolute) */
+ 0x09, 0x31, /* Usage (Y) */
+ 0x46, 0x40, 0x1f, /* Physical Maximum */
+ 0x26, 0x40, 0x01, /* Logical Maximum */
+ 0x81, 0x02, /* Input (Data, Variable, Absolute) */
+ 0x06, 0x00, 0xff, /* Usage Page (Vendor 0xff00) */
+ 0x09, 0x01, /* Usage (Digitizer) */
+ 0x26, 0xff, 0x00, /* Logical Maximum */
+ 0x75, 0x08, /* Report Size (8) */
+ 0x95, 0x0d, /* Report Count (13) */
+ 0x81, 0x02, /* Input (Data, Variable, Absolute) */
+ 0xc0, /* End Collection */
+ 0xc0, /* End Collection */
+};
+
+
static const USBDescIface desc_iface_wacom = {
.bInterfaceNumber = 0,
.bNumEndpoints = 1,
@@ -91,7 +174,7 @@ static const USBDescIface desc_iface_wacom = {
0x00, /* u8 country_code */
0x01, /* u8 num_descriptors */
0x22, /* u8 type: Report */
- 0x6e, 0, /* u16 len */
+ sizeof(qemu_tablet_hid_report_descriptor), 0, /* u16 len */
},
},
},
@@ -271,6 +354,15 @@ static void usb_wacom_handle_control(USBDevice *dev, USBPacket *p,
}
switch (request) {
+ case InterfaceRequest | USB_REQ_GET_DESCRIPTOR:
+ switch (value >> 8) {
+ case 0x22:
+ memcpy(data, qemu_tablet_hid_report_descriptor,
+ sizeof(qemu_tablet_hid_report_descriptor));
+ p->actual_length = sizeof(qemu_tablet_hid_report_descriptor);
+ break;
+ }
+ break;
case WACOM_SET_REPORT:
if (s->mouse_grabbed) {
qemu_remove_mouse_event_handler(s->eh_entry);
From 67751f3a23e3db3012f391b3b3b73a4484488ce9 Mon Sep 17 00:00:00 2001
From: Juro Bystricky <juro.bystricky@intel.com>
Date: Thu, 31 Aug 2017 11:06:56 -0700
Subject: [PATCH] Add subpackage -ptest which runs all unit test cases for
qemu.
Upstream-Status: Pending
Signed-off-by: Kai Kang <kai.kang@windriver.com>
Signed-off-by: Juro Bystricky <juro.bystricky@intel.com>
---
tests/Makefile.include | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/tests/Makefile.include b/tests/Makefile.include
index fd7fdb86..83b7f409 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -1183,4 +1183,12 @@ all: $(QEMU_IOTESTS_HELPERS-y)
-include $(wildcard tests/*.d)
-include $(wildcard tests/libqos/*.d)
+buildtest-TESTS: $(check-unit-y)
+
+runtest-TESTS:
+ for f in $(check-unit-y); do \
+ nf=$$(echo $$f | sed 's/tests\//\.\//g'); \
+ $$nf; \
+ done
+
endif
From 235b94f1188597873c8776b019fed49947983392 Mon Sep 17 00:00:00 2001
From: Jason Wessel <jason.wessel@windriver.com>
Date: Fri, 28 Mar 2014 17:42:43 +0800
Subject: [PATCH] qemu: Add addition environment space to boot loader
qemu-system-mips
Upstream-Status: Inappropriate - OE uses deep paths
If you create a project with very long directory names like 128 characters
deep and use NFS, the kernel arguments will be truncated. The kernel will
accept longer strings such as 1024 bytes, but the qemu boot loader defaulted
to only 256 bytes. This patch expands the limit.
Signed-off-by: Jason Wessel <jason.wessel@windriver.com>
Signed-off-by: Roy Li <rongqing.li@windriver.com>
---
hw/mips/mips_malta.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c
index 20e019bf..d150b01c 100644
--- a/hw/mips/mips_malta.c
+++ b/hw/mips/mips_malta.c
@@ -60,7 +60,7 @@
#define ENVP_ADDR 0x80002000l
#define ENVP_NB_ENTRIES 16
-#define ENVP_ENTRY_SIZE 256
+#define ENVP_ENTRY_SIZE 1024
/* Hardware addresses */
#define FLASH_ADDRESS 0x1e000000ULL
From 3ad7a375015d47fdf5016e03e11fa93440d6d8bd Mon Sep 17 00:00:00 2001
From: Ross Burton <ross.burton@intel.com>
Date: Tue, 20 Oct 2015 22:19:08 +0100
Subject: [PATCH] qemu: disable Valgrind
There isn't an option to enable or disable valgrind support, so disable it to avoid non-deterministic builds.
Upstream-Status: Inappropriate
Signed-off-by: Ross Burton <ross.burton@intel.com>
---
configure | 9 ---------
1 file changed, 9 deletions(-)
diff --git a/configure b/configure
index 714e7fb6..dad4fc59 100755
--- a/configure
+++ b/configure
@@ -5335,15 +5335,6 @@ fi
# check if we have valgrind/valgrind.h
valgrind_h=no
-cat > $TMPC << EOF
-#include <valgrind/valgrind.h>
-int main(void) {
- return 0;
-}
-EOF
-if compile_prog "" "" ; then
- valgrind_h=yes
-fi
########################################
# check if environ is declared
From 80e6070bcdfe636b103a13598e6c38ad0d0e7624 Mon Sep 17 00:00:00 2001
From: Stephen Arnold <sarnold@vctlabs.com>
Date: Sun, 12 Jun 2016 18:09:56 -0700
Subject: [PATCH] qemu-native: set ld.bfd, fix cflags, and set some environment
Upstream-Status: Pending
---
configure | 4 ----
1 file changed, 4 deletions(-)
diff --git a/configure b/configure
index dad4fc59..685bbe5e 100755
--- a/configure
+++ b/configure
@@ -5971,10 +5971,6 @@ write_c_skeleton
if test "$gcov" = "yes" ; then
CFLAGS="-fprofile-arcs -ftest-coverage -g $CFLAGS"
LDFLAGS="-fprofile-arcs -ftest-coverage $LDFLAGS"
-elif test "$fortify_source" = "yes" ; then
- CFLAGS="-O2 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 $CFLAGS"
-elif test "$debug" = "no"; then
- CFLAGS="-O2 $CFLAGS"
fi
if test "$have_asan" = "yes"; then
From ad853601e75f6d0dd09672bcca05fbe4fac766a4 Mon Sep 17 00:00:00 2001
From: Alistair Francis <alistair.francis@xilinx.com>
Date: Thu, 21 Dec 2017 11:35:16 -0800
Subject: [PATCH] chardev: connect socket to a spawned command
The command is started in a shell (sh -c) with stdin connect to QEMU
via a Unix domain stream socket. QEMU then exchanges data via its own
end of the socket, just like it normally does.
"-chardev socket" supports some ways of connecting via protocols like
telnet, but that is only a subset of the functionality supported by
tools socat. To use socat instead, for example to connect via a socks
proxy, use:
-chardev 'socket,id=socat,cmd=exec socat FD:0 SOCKS4A:socks-proxy.localdomain:example.com:9999,,socksuser=nobody' \
-device usb-serial,chardev=socat
Beware that commas in the command must be escaped as double commas.
Or interactively in the console:
(qemu) chardev-add socket,id=cat,cmd=cat
(qemu) device_add usb-serial,chardev=cat
^ac
# cat >/dev/ttyUSB0
hello
hello
Another usage is starting swtpm from inside QEMU. swtpm will
automatically shut down once it looses the connection to the parent
QEMU, so there is no risk of lingering processes:
-chardev 'socket,id=chrtpm0,cmd=exec swtpm socket --terminate --ctrl type=unixio,,clientfd=0 --tpmstate dir=... --log file=swtpm.log' \
-tpmdev emulator,id=tpm0,chardev=chrtpm0 \
-device tpm-tis,tpmdev=tpm0
The patch was discussed upstream, but QEMU developers believe that the
code calling QEMU should be responsible for managing additional
processes. In OE-core, that would imply enhancing runqemu and
oeqa. This patch is a simpler solution.
Because it is not going upstream, the patch was written so that it is
as simple as possible.
Upstream-Status: Inappropriate [embedded specific]
Signed-off-by: Patrick Ohly <patrick.ohly@intel.com>
---
chardev/char-socket.c | 101 ++++++++++++++++++++++++++++++++++++++++++
chardev/char.c | 3 ++
qapi/char.json | 5 +++
3 files changed, 109 insertions(+)
diff --git a/chardev/char-socket.c b/chardev/char-socket.c
index 7ca5d97a..207fae4a 100644
--- a/chardev/char-socket.c
+++ b/chardev/char-socket.c
@@ -1278,6 +1278,67 @@ static bool qmp_chardev_validate_socket(ChardevSocket *sock,
return true;
}
+#ifndef _WIN32
+static void chardev_open_socket_cmd(Chardev *chr,
+ const char *cmd,
+ Error **errp)
+{
+ int fds[2] = { -1, -1 };
+ QIOChannelSocket *sioc = NULL;
+ pid_t pid = -1;
+ const char *argv[] = { "/bin/sh", "-c", cmd, NULL };
+
+ /*
+ * We need a Unix domain socket for commands like swtpm and a single
+ * connection, therefore we cannot use qio_channel_command_new_spawn()
+ * without patching it first. Duplicating the functionality is easier.
+ */
+ if (socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds)) {
+ error_setg_errno(errp, errno, "Error creating socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC)");
+ goto error;
+ }
+
+ pid = qemu_fork(errp);
+ if (pid < 0) {
+ goto error;
+ }
+
+ if (!pid) {
+ /* child */
+ dup2(fds[1], STDIN_FILENO);
+ execv(argv[0], (char * const *)argv);
+ _exit(1);
+ }
+
+ /*
+ * Hand over our end of the socket pair to the qio channel.
+ *
+ * We don't reap the child because it is expected to keep
+ * running. We also don't support the "reconnect" option for the
+ * same reason.
+ */
+ sioc = qio_channel_socket_new_fd(fds[0], errp);
+ if (!sioc) {
+ goto error;
+ }
+ fds[0] = -1;
+
+ g_free(chr->filename);
+ chr->filename = g_strdup_printf("cmd:%s", cmd);
+ tcp_chr_new_client(chr, sioc);
+
+ error:
+ if (fds[0] >= 0) {
+ close(fds[0]);
+ }
+ if (fds[1] >= 0) {
+ close(fds[1]);
+ }
+ if (sioc) {
+ object_unref(OBJECT(sioc));
+ }
+}
+#endif
static void qmp_chardev_open_socket(Chardev *chr,
ChardevBackend *backend,
@@ -1286,6 +1347,9 @@ static void qmp_chardev_open_socket(Chardev *chr,
{
SocketChardev *s = SOCKET_CHARDEV(chr);
ChardevSocket *sock = backend->u.socket.data;
+#ifndef _WIN32
+ const char *cmd = sock->cmd;
+#endif
bool do_nodelay = sock->has_nodelay ? sock->nodelay : false;
bool is_listen = sock->has_server ? sock->server : true;
bool is_telnet = sock->has_telnet ? sock->telnet : false;
@@ -1351,6 +1415,14 @@ static void qmp_chardev_open_socket(Chardev *chr,
update_disconnected_filename(s);
+#ifndef _WIN32
+ if (cmd) {
+ chardev_open_socket_cmd(chr, cmd, errp);
+
+ /* everything ready (or failed permanently) before we return */
+ *be_opened = true;
+ } else
+#endif
if (s->is_listen) {
if (qmp_chardev_open_socket_server(chr, is_telnet || is_tn3270,
is_waitconnect, errp) < 0) {
@@ -1370,9 +1442,26 @@ static void qemu_chr_parse_socket(QemuOpts *opts, ChardevBackend *backend,
const char *host = qemu_opt_get(opts, "host");
const char *port = qemu_opt_get(opts, "port");
const char *fd = qemu_opt_get(opts, "fd");
+#ifndef _WIN32
+ const char *cmd = qemu_opt_get(opts, "cmd");
+#endif
SocketAddressLegacy *addr;
ChardevSocket *sock;
+#ifndef _WIN32
+ if (cmd) {
+ /*
+ * Here we have to ensure that no options are set which are incompatible with
+ * spawning a command, otherwise unmodified code that doesn't know about
+ * command spawning (like socket_reconnect_timeout()) might get called.
+ */
+ if (path || sock->server || sock->has_telnet || sock->has_tn3270 || sock->reconnect || host || port || sock->tls_creds) {
+ error_setg(errp, "chardev: socket: cmd does not support any additional options");
+ return;
+ }
+ } else
+#endif
+
if ((!!path + !!fd + !!host) != 1) {
error_setg(errp,
"Exactly one of 'path', 'fd' or 'host' required");
@@ -1415,12 +1504,24 @@ static void qemu_chr_parse_socket(QemuOpts *opts, ChardevBackend *backend,
sock->has_tls_authz = qemu_opt_get(opts, "tls-authz");
sock->tls_authz = g_strdup(qemu_opt_get(opts, "tls-authz"));
+#ifndef _WIN32
+ sock->cmd = g_strdup(cmd);
+#endif
+
addr = g_new0(SocketAddressLegacy, 1);
+#ifndef _WIN32
+ if (path || cmd) {
+#else
if (path) {
+#endif
UnixSocketAddress *q_unix;
addr->type = SOCKET_ADDRESS_LEGACY_KIND_UNIX;
q_unix = addr->u.q_unix.data = g_new0(UnixSocketAddress, 1);
+#ifndef _WIN32
+ q_unix->path = cmd ? g_strdup_printf("cmd:%s", cmd) : g_strdup(path);
+#else
q_unix->path = g_strdup(path);
+#endif
} else if (host) {
addr->type = SOCKET_ADDRESS_LEGACY_KIND_INET;
addr->u.inet.data = g_new(InetSocketAddress, 1);
diff --git a/chardev/char.c b/chardev/char.c
index 7b6b2cb1..0c2ca64b 100644
--- a/chardev/char.c
+++ b/chardev/char.c
@@ -837,6 +837,9 @@ QemuOptsList qemu_chardev_opts = {
},{
.name = "path",
.type = QEMU_OPT_STRING,
+ },{
+ .name = "cmd",
+ .type = QEMU_OPT_STRING,
},{
.name = "host",
.type = QEMU_OPT_STRING,
diff --git a/qapi/char.json b/qapi/char.json
index a6e81ac7..517962c6 100644
--- a/qapi/char.json
+++ b/qapi/char.json
@@ -247,6 +247,10 @@
#
# @addr: socket address to listen on (server=true)
# or connect to (server=false)
+# @cmd: command to run via "sh -c" with stdin as one end of
+# a AF_UNIX SOCK_DSTREAM socket pair. The other end
+# is used by the chardev. Either an addr or a cmd can
+# be specified, but not both.
# @tls-creds: the ID of the TLS credentials object (since 2.6)
# @tls-authz: the ID of the QAuthZ authorization object against which
# the client's x509 distinguished name will be validated. This
@@ -272,6 +276,7 @@
##
{ 'struct': 'ChardevSocket',
'data': { 'addr': 'SocketAddressLegacy',
+ '*cmd': 'str',
'*tls-creds': 'str',
'*tls-authz' : 'str',
'*server': 'bool',
From f51e49e7d7d87b7254242b7360f99c2df94a5a2d Mon Sep 17 00:00:00 2001
From: Mark Asselstine <mark.asselstine@windriver.com>
Date: Tue, 26 Feb 2013 11:43:28 -0500
Subject: [PATCH] apic: fixup fallthrough to PIC
Commit 0e21e12bb311c4c1095d0269dc2ef81196ccb60a [Don't route PIC
interrupts through the local APIC if the local APIC config says so.]
missed a check to ensure the local APIC is enabled. Since if the local
APIC is disabled it doesn't matter what the local APIC config says.
If this check isn't done and the guest has disabled the local APIC the
guest will receive a general protection fault, similar to what is seen
here:
https://lists.gnu.org/archive/html/qemu-devel/2012-12/msg02304.html
The GPF is caused by an attempt to service interrupt 0xffffffff. This
comes about since cpu_get_pic_interrupt() calls apic_accept_pic_intr()
(with the local APIC disabled apic_get_interrupt() returns -1).
apic_accept_pic_intr() returns 0 and thus the interrupt number which
is returned from cpu_get_pic_interrupt(), and which is attempted to be
serviced, is -1.
Signed-off-by: Mark Asselstine <mark.asselstine@windriver.com>
Upstream-Status: Submitted [https://lists.gnu.org/archive/html/qemu-devel/2013-04/msg00878.html]
Signed-off-by: He Zhe <zhe.he@windriver.com>
---
hw/intc/apic.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/hw/intc/apic.c b/hw/intc/apic.c
index bce89911..df4b582e 100644
--- a/hw/intc/apic.c
+++ b/hw/intc/apic.c
@@ -603,7 +603,7 @@ int apic_accept_pic_intr(DeviceState *dev)
APICCommonState *s = APIC(dev);
uint32_t lvt0;
- if (!s)
+ if (!s || !(s->spurious_vec & APIC_SV_ENABLE))
return -1;
lvt0 = s->lvt[APIC_LVT_LINT0];
From 25a064f91f73630e5dff2a6aeb23d953c469cea6 Mon Sep 17 00:00:00 2001
From: Alistair Francis <alistair.francis@xilinx.com>
Date: Wed, 17 Jan 2018 10:51:49 -0800
Subject: [PATCH] linux-user: Fix webkitgtk hangs on 32-bit x86 target
Since commit "linux-user: Tidy and enforce reserved_va initialization"
(18e80c55bb6ec17c05ec0ba717ec83933c2bfc07) the Yocto webkitgtk build
hangs when cross compiling for 32-bit x86 on a 64-bit x86 machine using
musl.
To fix the issue reduce the MAX_RESERVED_VA macro to be a closer match
to what it was before the problematic commit.
Upstream-Status: Submitted http://lists.gnu.org/archive/html/qemu-devel/2018-01/msg04185.html
Signed-off-by: Alistair Francis <alistair.francis@xilinx.com>
---
linux-user/main.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/linux-user/main.c b/linux-user/main.c
index 8ffc5251..4067e739 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -77,7 +77,7 @@ int have_guest_base;
(TARGET_LONG_BITS == 32 || defined(TARGET_ABI32))
/* There are a number of places where we assign reserved_va to a variable
of type abi_ulong and expect it to fit. Avoid the last page. */
-# define MAX_RESERVED_VA (0xfffffffful & TARGET_PAGE_MASK)
+# define MAX_RESERVED_VA (0x7ffffffful & TARGET_PAGE_MASK)
# else
# define MAX_RESERVED_VA (1ul << TARGET_VIRT_ADDR_SPACE_BITS)
# endif
From b633b9a1813fcd715dce44659a89293f1c64ae8c Mon Sep 17 00:00:00 2001
From: Martin Jansa <martin.jansa@lge.com>
Date: Fri, 1 Jun 2018 08:41:07 +0000
Subject: [PATCH] Fix webkitgtk builds
This is a partial revert of "linux-user: fix mmap/munmap/mprotect/mremap/shmat".
This patch fixes qemu-i386 hangs during gobject-introspection in webkitgtk build
when musl is used on qemux86. This is the same issue that
0008-linux-user-Fix-webkitgtk-hangs-on-32-bit-x86-target.patch was
fixing in the 2.11 release.
This patch also fixes a build failure when building webkitgtk for
qemumips. A QEMU assert is seen while building webkitgtk:
page_check_range: Assertion `start < ((target_ulong)1 << L1_MAP_ADDR_SPACE_BITS)' failed.
This reverts commit ebf9a3630c911d0cfc9c20f7cafe9ba4f88cf583.
Upstream-Status: Pending
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
include/exec/cpu-all.h | 6 +-----
include/exec/cpu_ldst.h | 5 ++++-
linux-user/mmap.c | 17 ++++-------------
linux-user/syscall.c | 5 +----
4 files changed, 10 insertions(+), 23 deletions(-)
diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
index 536ea58f81..4c63a6a2e4 100644
--- a/include/exec/cpu-all.h
+++ b/include/exec/cpu-all.h
@@ -162,12 +162,8 @@ extern unsigned long guest_base;
extern int have_guest_base;
extern unsigned long reserved_va;
-#if HOST_LONG_BITS <= TARGET_VIRT_ADDR_SPACE_BITS
-#define GUEST_ADDR_MAX (~0ul)
-#else
-#define GUEST_ADDR_MAX (reserved_va ? reserved_va - 1 : \
+#define GUEST_ADDR_MAX (reserved_va ? reserved_va : \
(1ul << TARGET_VIRT_ADDR_SPACE_BITS) - 1)
-#endif
#else
#include "exec/hwaddr.h"
diff --git a/include/exec/cpu_ldst.h b/include/exec/cpu_ldst.h
index 9151fdb042..cb2b8f329f 100644
--- a/include/exec/cpu_ldst.h
+++ b/include/exec/cpu_ldst.h
@@ -65,7 +65,10 @@ typedef uint64_t abi_ptr;
#if HOST_LONG_BITS <= TARGET_VIRT_ADDR_SPACE_BITS
#define guest_addr_valid(x) (1)
#else
-#define guest_addr_valid(x) ((x) <= GUEST_ADDR_MAX)
+#define guest_addr_valid(x) ({ \
+ ((x) < (1ul << TARGET_VIRT_ADDR_SPACE_BITS)) && \
+ (!reserved_va || ((x) < reserved_va)); \
+})
#endif
#define h2g_valid(x) guest_addr_valid((unsigned long)(x) - guest_base)
diff --git a/linux-user/mmap.c b/linux-user/mmap.c
index 46a6e3a761..7735465462 100644
--- a/linux-user/mmap.c
+++ b/linux-user/mmap.c
@@ -78,7 +78,7 @@ int target_mprotect(abi_ulong start, abi_ulong len, int prot)
return -TARGET_EINVAL;
len = TARGET_PAGE_ALIGN(len);
end = start + len;
- if (!guest_range_valid(start, len)) {
+ if (end < start) {
return -TARGET_ENOMEM;
}
prot &= PROT_READ | PROT_WRITE | PROT_EXEC;
@@ -495,8 +495,8 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot,
* It can fail only on 64-bit host with 32-bit target.
* On any other target/host host mmap() handles this error correctly.
*/
- if (!guest_range_valid(start, len)) {
- errno = ENOMEM;
+ if ((unsigned long)start + len - 1 > (abi_ulong) -1) {
+ errno = EINVAL;
goto fail;
}
@@ -636,10 +636,8 @@ int target_munmap(abi_ulong start, abi_ulong len)
if (start & ~TARGET_PAGE_MASK)
return -TARGET_EINVAL;
len = TARGET_PAGE_ALIGN(len);
- if (len == 0 || !guest_range_valid(start, len)) {
+ if (len == 0)
return -TARGET_EINVAL;
- }
-
mmap_lock();
end = start + len;
real_start = start & qemu_host_page_mask;
@@ -694,13 +692,6 @@ abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size,
int prot;
void *host_addr;
- if (!guest_range_valid(old_addr, old_size) ||
- ((flags & MREMAP_FIXED) &&
- !guest_range_valid(new_addr, new_size))) {
- errno = ENOMEM;
- return -1;
- }
-
mmap_lock();
if (flags & MREMAP_FIXED) {
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 8b41a03901..bc5d85de02 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -4031,9 +4031,6 @@ static inline abi_ulong do_shmat(CPUArchState *cpu_env,
return -TARGET_EINVAL;
}
}
- if (!guest_range_valid(shmaddr, shm_info.shm_segsz)) {
- return -TARGET_EINVAL;
- }
mmap_lock();
@@ -6881,7 +6878,7 @@ static int open_self_maps(void *cpu_env, int fd)
}
if (h2g_valid(min)) {
int flags = page_get_flags(h2g(min));
- max = h2g_valid(max - 1) ? max : (uintptr_t)g2h(GUEST_ADDR_MAX) + 1;
+ max = h2g_valid(max - 1) ? max : (uintptr_t)g2h(GUEST_ADDR_MAX);
if (page_check_range(h2g(min), max - min, flags) == -1) {
continue;
}
--
2.22.0
From 5214dd4461f2090ef0965b4d2518f49927d61cbc Mon Sep 17 00:00:00 2001
From: He Zhe <zhe.he@windriver.com>
Date: Wed, 28 Aug 2019 19:56:28 +0800
Subject: [Qemu-devel] [PATCH] configure: Add pkg-config handling for libgcrypt
libgcrypt may also be controlled by pkg-config, this patch adds pkg-config
handling for libgcrypt.
Upstream-Status: Denied [https://lists.nongnu.org/archive/html/qemu-devel/2019-08/msg06333.html]
Signed-off-by: He Zhe <zhe.he@windriver.com>
---
configure | 48 ++++++++++++++++++++++++++++++++++++++++--------
1 file changed, 40 insertions(+), 8 deletions(-)
diff --git a/configure b/configure
index e44e454..0f362a7 100755
--- a/configure
+++ b/configure
@@ -2875,6 +2875,30 @@ has_libgcrypt() {
return 0
}
+has_libgcrypt_pkgconfig() {
+ if ! has $pkg_config ; then
+ return 1
+ fi
+
+ if ! $pkg_config --list-all | grep libgcrypt > /dev/null 2>&1 ; then
+ return 1
+ fi
+
+ if test -n "$cross_prefix" ; then
+ host=$($pkg_config --variable=host libgcrypt)
+ if test "${host%-gnu}-" != "${cross_prefix%-gnu}" ; then
+ print_error "host($host) does not match cross_prefix($cross_prefix)"
+ return 1
+ fi
+ fi
+
+ if ! $pkg_config --atleast-version=1.5.0 libgcrypt ; then
+ print_error "libgcrypt version is $($pkg_config --modversion libgcrypt)"
+ return 1
+ fi
+
+ return 0
+}
if test "$nettle" != "no"; then
pass="no"
@@ -2902,7 +2926,14 @@ fi
if test "$gcrypt" != "no"; then
pass="no"
- if has_libgcrypt; then
+ if has_libgcrypt_pkgconfig; then
+ gcrypt_cflags=$($pkg_config --cflags libgcrypt)
+ if test "$static" = "yes" ; then
+ gcrypt_libs=$($pkg_config --libs --static libgcrypt)
+ else
+ gcrypt_libs=$($pkg_config --libs libgcrypt)
+ fi
+ elif has_libgcrypt; then
gcrypt_cflags=$(libgcrypt-config --cflags)
gcrypt_libs=$(libgcrypt-config --libs)
# Debian has removed -lgpg-error from libgcrypt-config
@@ -2912,15 +2943,16 @@ if test "$gcrypt" != "no"; then
then
gcrypt_libs="$gcrypt_libs -lgpg-error"
fi
+ fi
- # Link test to make sure the given libraries work (e.g for static).
- write_c_skeleton
- if compile_prog "" "$gcrypt_libs" ; then
- LIBS="$gcrypt_libs $LIBS"
- QEMU_CFLAGS="$QEMU_CFLAGS $gcrypt_cflags"
- pass="yes"
- fi
+ # Link test to make sure the given libraries work (e.g for static).
+ write_c_skeleton
+ if compile_prog "" "$gcrypt_libs" ; then
+ LIBS="$gcrypt_libs $LIBS"
+ QEMU_CFLAGS="$QEMU_CFLAGS $gcrypt_cflags"
+ pass="yes"
fi
+
if test "$pass" = "yes"; then
gcrypt="yes"
cat > $TMPC << EOF
--
2.7.4
From 9125afb733d8c96416bb83c5adad39bb8d0803a1 Mon Sep 17 00:00:00 2001
From: Hongxu Jia <hongxu.jia@windriver.com>
Date: Tue, 12 Mar 2013 09:54:06 +0800
Subject: [PATCH] fix libcap header issue on some distro
1, When build qemu-native on SLED 11.2, there is an error:
...
| In file included from /usr/include/bits/sigcontext.h:28,
| from /usr/include/signal.h:339,
| from /buildarea2/tmp/work/i686-linux/qemu-native/1.4.0-r0/
qemu-1.4.0/include/qemu-common.h:42,
| from fsdev/virtfs-proxy-helper.c:23:
| /usr/include/asm/sigcontext.h:28: error: expected specifier-
qualifier-list before '__u64'
| /usr/include/asm/sigcontext.h:191: error: expected specifier-
qualifier-list before '__u64'
...
2, The virtfs-proxy-helper.c includes <sys/capability.h> and
qemu-common.h in sequence. The header include map is:
(`-->' presents `include')
...
"virtfs-proxy-helper.c" --> <sys/capability.h>
...
"virtfs-proxy-helper.c" --> "qemu-common.h" --> <signal.h> -->
<bits/sigcontext.h> --> <asm/sigcontext.h> --> <linux/types.h> -->
<asm/types.h> --> <asm-generic/types.h> --> <asm-generic/int-ll64.h>
...
3, The bug is found on SLED 11.2 x86. In libcap header file
/usr/include/sys/capability.h, it does evil stuff like this:
...
25 /*
26 * Make sure we can be included from userland by preventing
27 * capability.h from including other kernel headers
28 */
29 #define _LINUX_TYPES_H
30 #define _LINUX_FS_H
31 #define __LINUX_COMPILER_H
32 #define __user
33
34 typedef unsigned int __u32;
35 typedef __u32 __le32;
...
This completely prevents including /usr/include/linux/types.h.
The above `<asm/sigcontext.h> --> <linux/types.h>' is prevented,
and '__u64' is defined in <asm-generic/int-ll64.h>.
4, Modify virtfs-proxy-helper.c to include <sys/capability.h>
last to workaround the issue.
http://www.linuxtv.org/pipermail/vdr/2009-August/021194.html
http://patchwork.linuxtv.org/patch/12748/
Upstream-Status: Pending
Signed-off-by: Hongxu Jia <hongxu.jia@windriver.com>
---
fsdev/virtfs-proxy-helper.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/fsdev/virtfs-proxy-helper.c b/fsdev/virtfs-proxy-helper.c
index 6f132c5f..8329950c 100644
--- a/fsdev/virtfs-proxy-helper.c
+++ b/fsdev/virtfs-proxy-helper.c
@@ -13,7 +13,6 @@
#include <sys/resource.h>
#include <getopt.h>
#include <syslog.h>
-#include <sys/capability.h>
#include <sys/fsuid.h>
#include <sys/vfs.h>
#include <sys/ioctl.h>
@@ -27,7 +26,11 @@
#include "9p-iov-marshal.h"
#include "hw/9pfs/9p-proxy.h"
#include "fsdev/9p-iov-marshal.h"
-
+/*
+ * Include this one last due to some versions of it being buggy:
+ * http://www.linuxtv.org/pipermail/vdr/2009-August/021194.html
+ */
+#include <sys/capability.h>
#define PROGNAME "virtfs-proxy-helper"
#ifndef XFS_SUPER_MAGIC
From 0a53e906510cce1f32bc04a11e81ea40f834dac4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?An=C3=ADbal=20Lim=C3=B3n?= <anibal.limon@linux.intel.com>
Date: Wed, 12 Aug 2015 15:11:30 -0500
Subject: [PATCH] cpus.c: Add error messages when qemi_cpu_kick_thread fails.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Add custom_debug.h with function for print backtrace information.
When pthread_kill fails in qemu_cpu_kick_thread display backtrace and
current cpu information.
Upstream-Status: Inappropriate
Signed-off-by: Aníbal Limón <anibal.limon@linux.intel.com>
---
cpus.c | 5 +++++
custom_debug.h | 24 ++++++++++++++++++++++++
2 files changed, 29 insertions(+)
create mode 100644 custom_debug.h
diff --git a/cpus.c b/cpus.c
index e83f72b4..e6e2576e 100644
--- a/cpus.c
+++ b/cpus.c
@@ -1769,6 +1769,8 @@ static void *qemu_tcg_cpu_thread_fn(void *arg)
return NULL;
}
+#include "custom_debug.h"
+
static void qemu_cpu_kick_thread(CPUState *cpu)
{
#ifndef _WIN32
@@ -1781,6 +1783,9 @@ static void qemu_cpu_kick_thread(CPUState *cpu)
err = pthread_kill(cpu->thread->thread, SIG_IPI);
if (err && err != ESRCH) {
fprintf(stderr, "qemu:%s: %s", __func__, strerror(err));
+ fprintf(stderr, "CPU #%d:\n", cpu->cpu_index);
+ cpu_dump_state(cpu, stderr, 0);
+ backtrace_print();
exit(1);
}
#else /* _WIN32 */
diff --git a/custom_debug.h b/custom_debug.h
new file mode 100644
index 00000000..f029e455
--- /dev/null
+++ b/custom_debug.h
@@ -0,0 +1,24 @@
+#include <execinfo.h>
+#include <stdio.h>
+#define BACKTRACE_MAX 128
+static void backtrace_print(void)
+{
+ int nfuncs = 0;
+ void *buf[BACKTRACE_MAX];
+ char **symbols;
+ int i;
+
+ nfuncs = backtrace(buf, BACKTRACE_MAX);
+
+ symbols = backtrace_symbols(buf, nfuncs);
+ if (symbols == NULL) {
+ fprintf(stderr, "backtrace_print failed to get symbols");
+ return;
+ }
+
+ fprintf(stderr, "Backtrace ...\n");
+ for (i = 0; i < nfuncs; i++)
+ fprintf(stderr, "%s\n", symbols[i]);
+
+ free(symbols);
+}
From 0f1f2d4596aee037d3ccbcf10592466daa54107f Mon Sep 17 00:00:00 2001
From: Laurent Vivier <laurent@vivier.eu>
Date: Tue, 12 Nov 2019 15:25:56 +0100
Subject: [PATCH] linux-user: remove host stime() syscall
stime() has been withdrawn from glibc
(12cbde1dae6f "Use clock_settime to implement stime; withdraw stime.")
Implement the target stime() syscall using host
clock_settime(CLOCK_REALTIME, ...) as it is done internally in glibc.
Tested qemu-ppc/x86_64 with:
#include <time.h>
#include <stdio.h>
int main(void)
{
time_t t;
int ret;
/* date -u -d"2019-11-12T15:11:00" "+%s" */
t = 1573571460;
ret = stime(&t);
printf("ret %d\n", ret);
return 0;
}
# date; ./stime; date
Tue Nov 12 14:18:32 UTC 2019
ret 0
Tue Nov 12 15:11:00 UTC 2019
Upstream-Status: Backport [https://git.qemu.org/?p=qemu.git;a=commit;h=0f1f2d4596aee037d3ccbcf10592466daa54107f]
Buglink: https://bugs.launchpad.net/qemu/+bug/1852115
Reported-by: Cole Robinson <crobinso@redhat.com>
Signed-off-by: Laurent Vivier <laurent@vivier.eu>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Message-Id: <20191112142556.6335-1-laurent@vivier.eu>
---
linux-user/syscall.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -7651,10 +7651,12 @@ static abi_long do_syscall1(void *cpu_en
#ifdef TARGET_NR_stime /* not on alpha */
case TARGET_NR_stime:
{
- time_t host_time;
- if (get_user_sal(host_time, arg1))
+ struct timespec ts;
+ ts.tv_nsec = 0;
+ if (get_user_sal(ts.tv_sec, arg1)) {
return -TARGET_EFAULT;
- return get_errno(stime(&host_time));
+ }
+ return get_errno(clock_settime(CLOCK_REALTIME, &ts));
}
#endif
#ifdef TARGET_NR_alarm /* not on alpha */
From de594e47659029316bbf9391efb79da0a1a08e08 Mon Sep 17 00:00:00 2001
From: Paolo Bonzini <pbonzini@redhat.com>
Date: Wed, 14 Aug 2019 17:35:21 +0530
Subject: [PATCH] scsi: lsi: exit infinite loop while executing script
(CVE-2019-12068)
When executing script in lsi_execute_script(), the LSI scsi adapter
emulator advances 's->dsp' index to read next opcode. This can lead
to an infinite loop if the next opcode is empty. Move the existing
loop exit after 10k iterations so that it covers no-op opcodes as
well.
Upstream-Status: Backport [https://git.qemu.org/?p=qemu.git;a=commit;h=de594e47659029316bbf9391efb79da0a1a08e08]
CVE: CVE-2019-12068
Reported-by: Bugs SysSec <bugs-syssec@rub.de>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Changqing Li <changqing.li@windriver.com>
---
hw/scsi/lsi53c895a.c | 41 +++++++++++++++++++++++++++--------------
1 file changed, 27 insertions(+), 14 deletions(-)
diff --git a/hw/scsi/lsi53c895a.c b/hw/scsi/lsi53c895a.c
index 222a286..ec53b14 100644
--- a/hw/scsi/lsi53c895a.c
+++ b/hw/scsi/lsi53c895a.c
@@ -186,6 +186,9 @@ static const char *names[] = {
/* Flag set if this is a tagged command. */
#define LSI_TAG_VALID (1 << 16)
+/* Maximum instructions to process. */
+#define LSI_MAX_INSN 10000
+
typedef struct lsi_request {
SCSIRequest *req;
uint32_t tag;
@@ -1133,7 +1136,21 @@ static void lsi_execute_script(LSIState *s)
s->istat1 |= LSI_ISTAT1_SRUN;
again:
- insn_processed++;
+ if (++insn_processed > LSI_MAX_INSN) {
+ /* Some windows drivers make the device spin waiting for a memory
+ location to change. If we have been executed a lot of code then
+ assume this is the case and force an unexpected device disconnect.
+ This is apparently sufficient to beat the drivers into submission.
+ */
+ if (!(s->sien0 & LSI_SIST0_UDC)) {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "lsi_scsi: inf. loop with UDC masked");
+ }
+ lsi_script_scsi_interrupt(s, LSI_SIST0_UDC, 0);
+ lsi_disconnect(s);
+ trace_lsi_execute_script_stop();
+ return;
+ }
insn = read_dword(s, s->dsp);
if (!insn) {
/* If we receive an empty opcode increment the DSP by 4 bytes
@@ -1570,19 +1587,7 @@ again:
}
}
}
- if (insn_processed > 10000 && s->waiting == LSI_NOWAIT) {
- /* Some windows drivers make the device spin waiting for a memory
- location to change. If we have been executed a lot of code then
- assume this is the case and force an unexpected device disconnect.
- This is apparently sufficient to beat the drivers into submission.
- */
- if (!(s->sien0 & LSI_SIST0_UDC)) {
- qemu_log_mask(LOG_GUEST_ERROR,
- "lsi_scsi: inf. loop with UDC masked");
- }
- lsi_script_scsi_interrupt(s, LSI_SIST0_UDC, 0);
- lsi_disconnect(s);
- } else if (s->istat1 & LSI_ISTAT1_SRUN && s->waiting == LSI_NOWAIT) {
+ if (s->istat1 & LSI_ISTAT1_SRUN && s->waiting == LSI_NOWAIT) {
if (s->dcntl & LSI_DCNTL_SSM) {
lsi_script_dma_interrupt(s, LSI_DSTAT_SSI);
} else {
@@ -1970,6 +1975,10 @@ static void lsi_reg_writeb(LSIState *s, int offset, uint8_t val)
case 0x2f: /* DSP[24:31] */
s->dsp &= 0x00ffffff;
s->dsp |= val << 24;
+ /*
+ * FIXME: if s->waiting != LSI_NOWAIT, this will only execute one
+ * instruction. Is this correct?
+ */
if ((s->dmode & LSI_DMODE_MAN) == 0
&& (s->istat1 & LSI_ISTAT1_SRUN) == 0)
lsi_execute_script(s);
@@ -1988,6 +1997,10 @@ static void lsi_reg_writeb(LSIState *s, int offset, uint8_t val)
break;
case 0x3b: /* DCNTL */
s->dcntl = val & ~(LSI_DCNTL_PFF | LSI_DCNTL_STD);
+ /*
+ * FIXME: if s->waiting != LSI_NOWAIT, this will only execute one
+ * instruction. Is this correct?
+ */
if ((val & LSI_DCNTL_STD) && (s->istat1 & LSI_ISTAT1_SRUN) == 0)
lsi_execute_script(s);
break;
--
2.7.4
From 4fc0d23e8f6d795c679623d2ed2cbe6a7a17b9c7 Mon Sep 17 00:00:00 2001
From: Li Zhou <li.zhou@windriver.com>
Date: Tue, 10 Sep 2019 20:02:15 -0700
Subject: [PATCH] ip_reass: Fix use after free
Using ip_deq after m_free might read pointers from an allocation reuse.
This would be difficult to exploit, but that is still related with
CVE-2019-14378 which generates fragmented IP packets that would trigger this
issue and at least produce a DoS.
Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
Upstream-Status: Backport
CVE: CVE-2019-15890
Signed-off-by: Li Zhou <li.zhou@windriver.com>
---
slirp/src/ip_input.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/slirp/src/ip_input.c b/slirp/src/ip_input.c
index 8c75d914..c07d7d40 100644
--- a/slirp/src/ip_input.c
+++ b/slirp/src/ip_input.c
@@ -292,6 +292,7 @@ static struct ip *ip_reass(Slirp *slirp, struct ip *ip, struct ipq *fp)
*/
while (q != (struct ipasfrag *)&fp->frag_link &&
ip->ip_off + ip->ip_len > q->ipf_off) {
+ struct ipasfrag *prev;
i = (ip->ip_off + ip->ip_len) - q->ipf_off;
if (i < q->ipf_len) {
q->ipf_len -= i;
@@ -299,9 +300,10 @@ static struct ip *ip_reass(Slirp *slirp, struct ip *ip, struct ipq *fp)
m_adj(dtom(slirp, q), i);
break;
}
+ prev = q;
q = q->ipf_next;
- m_free(dtom(slirp, q->ipf_prev));
- ip_deq(q->ipf_prev);
+ ip_deq(prev);
+ m_free(dtom(slirp, prev));
}
insert:
--
2.23.0
This diff is collapsed.
From de0b1bae6461f67243282555475f88b2384a1eb9 Mon Sep 17 00:00:00 2001
From: Vincent Dehors <vincent.dehors@smile.fr>
Date: Thu, 23 Jan 2020 15:22:38 +0000
Subject: [PATCH] target/arm: Fix PAuth sbox functions
In the PAC computation, sbox was applied over wrong bits.
As this is a 4-bit sbox, bit index should be incremented by 4 instead of 16.
Test vector from QARMA paper (https://eprint.iacr.org/2016/444.pdf) was
used to verify one computation of the pauth_computepac() function which
uses sbox2.
Launchpad: https://bugs.launchpad.net/bugs/1859713
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Vincent DEHORS <vincent.dehors@smile.fr>
Signed-off-by: Adrien GRASSEIN <adrien.grassein@smile.fr>
Message-id: 20200116230809.19078-2-richard.henderson@linaro.org
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Upstream-Status: Backport [https://git.qemu.org/?p=qemu.git;a=patch;h=de0b1bae6461f67243282555475f88b2384a1eb9]
CVE: CVE-2020-10702
Signed-off-by: Lee Chee Yang <chee.yang.lee@intel.com>
---
target/arm/pauth_helper.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/target/arm/pauth_helper.c b/target/arm/pauth_helper.c
index d3194f2..0a5f41e 100644
--- a/target/arm/pauth_helper.c
+++ b/target/arm/pauth_helper.c
@@ -89,7 +89,7 @@ static uint64_t pac_sub(uint64_t i)
uint64_t o = 0;
int b;
- for (b = 0; b < 64; b += 16) {
+ for (b = 0; b < 64; b += 4) {
o |= (uint64_t)sub[(i >> b) & 0xf] << b;
}
return o;
@@ -104,7 +104,7 @@ static uint64_t pac_inv_sub(uint64_t i)
uint64_t o = 0;
int b;
- for (b = 0; b < 64; b += 16) {
+ for (b = 0; b < 64; b += 4) {
o |= (uint64_t)inv_sub[(i >> b) & 0xf] << b;
}
return o;
--
1.8.3.1
From c7ede54cbd2e2b25385325600958ba0124e31cc0 Mon Sep 17 00:00:00 2001
From: Ralf Haferkamp <rhafer@suse.com>
Date: Fri, 3 Jul 2020 14:51:16 +0200
Subject: [PATCH] Drop bogus IPv6 messages
Drop IPv6 message shorter than what's mentioned in the payload
length header (+ the size of the IPv6 header). They're invalid an could
lead to data leakage in icmp6_send_echoreply().
CVE: CVE-2020-10756
Upstream-Status: Backport
https://gitlab.freedesktop.org/slirp/libslirp/-/commit/c7ede54cbd2e2b25385325600958ba0124e31cc0
[SG: Based on libslirp commit c7ede54cbd2e2b25385325600958ba0124e31cc0 and adjusted context]
Signed-off-by: Stefan Ghinea <stefan.ghinea@windriver.com>
---
slirp/src/ip6_input.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/slirp/src/ip6_input.c b/slirp/src/ip6_input.c
index d9d2b7e9..0f2b1785 100644
--- a/slirp/src/ip6_input.c
+++ b/slirp/src/ip6_input.c
@@ -49,6 +49,13 @@ void ip6_input(struct mbuf *m)
goto bad;
}
+ // Check if the message size is big enough to hold what's
+ // set in the payload length header. If not this is an invalid
+ // packet
+ if (m->m_len < ntohs(ip6->ip_pl) + sizeof(struct ip6)) {
+ goto bad;
+ }
+
/* check ip_ttl for a correct ICMP reply */
if (ip6->ip_hl == 0) {
icmp6_send_error(m, ICMP6_TIMXCEED, ICMP6_TIMXCEED_INTRANS);
--
2.17.1
From ac2071c3791b67fc7af78b8ceb320c01ca1b5df7 Mon Sep 17 00:00:00 2001
From: BALATON Zoltan <balaton@eik.bme.hu>
Date: Mon, 6 Apr 2020 22:34:26 +0200
Subject: [PATCH] ati-vga: Fix checks in ati_2d_blt() to avoid crash
In some corner cases (that never happen during normal operation but a
malicious guest could program wrong values) pixman functions were
called with parameters that result in a crash. Fix this and add more
checks to disallow such cases.
Reported-by: Ziming Zhang <ezrakiez@gmail.com>
Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
Message-id: 20200406204029.19559747D5D@zero.eik.bme.hu
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Upstream-Status: Backport [https://git.qemu.org/?p=qemu.git;a=commit;h=ac2071c3791b67fc7af78b8ceb320c01ca1b5df7]
CVE: CVE-2020-11869
Signed-off-by: Lee Chee Yang <chee.yang.lee@intel.com>
---
hw/display/ati_2d.c | 37 ++++++++++++++++++++++++++-----------
1 file changed, 26 insertions(+), 11 deletions(-)
diff --git a/hw/display/ati_2d.c b/hw/display/ati_2d.c
index 42e8231..23a8ae0 100644
--- a/hw/display/ati_2d.c
+++ b/hw/display/ati_2d.c
@@ -53,12 +53,20 @@ void ati_2d_blt(ATIVGAState *s)
s->vga.vbe_start_addr, surface_data(ds), surface_stride(ds),
surface_bits_per_pixel(ds),
(s->regs.dp_mix & GMC_ROP3_MASK) >> 16);
- int dst_x = (s->regs.dp_cntl & DST_X_LEFT_TO_RIGHT ?
- s->regs.dst_x : s->regs.dst_x + 1 - s->regs.dst_width);
- int dst_y = (s->regs.dp_cntl & DST_Y_TOP_TO_BOTTOM ?
- s->regs.dst_y : s->regs.dst_y + 1 - s->regs.dst_height);
+ unsigned dst_x = (s->regs.dp_cntl & DST_X_LEFT_TO_RIGHT ?
+ s->regs.dst_x : s->regs.dst_x + 1 - s->regs.dst_width);
+ unsigned dst_y = (s->regs.dp_cntl & DST_Y_TOP_TO_BOTTOM ?
+ s->regs.dst_y : s->regs.dst_y + 1 - s->regs.dst_height);
int bpp = ati_bpp_from_datatype(s);
+ if (!bpp) {
+ qemu_log_mask(LOG_GUEST_ERROR, "Invalid bpp\n");
+ return;
+ }
int dst_stride = DEFAULT_CNTL ? s->regs.dst_pitch : s->regs.default_pitch;
+ if (!dst_stride) {
+ qemu_log_mask(LOG_GUEST_ERROR, "Zero dest pitch\n");
+ return;
+ }
uint8_t *dst_bits = s->vga.vram_ptr + (DEFAULT_CNTL ?
s->regs.dst_offset : s->regs.default_offset);
@@ -82,12 +90,16 @@ void ati_2d_blt(ATIVGAState *s)
switch (s->regs.dp_mix & GMC_ROP3_MASK) {
case ROP3_SRCCOPY:
{
- int src_x = (s->regs.dp_cntl & DST_X_LEFT_TO_RIGHT ?
- s->regs.src_x : s->regs.src_x + 1 - s->regs.dst_width);
- int src_y = (s->regs.dp_cntl & DST_Y_TOP_TO_BOTTOM ?
- s->regs.src_y : s->regs.src_y + 1 - s->regs.dst_height);
+ unsigned src_x = (s->regs.dp_cntl & DST_X_LEFT_TO_RIGHT ?
+ s->regs.src_x : s->regs.src_x + 1 - s->regs.dst_width);
+ unsigned src_y = (s->regs.dp_cntl & DST_Y_TOP_TO_BOTTOM ?
+ s->regs.src_y : s->regs.src_y + 1 - s->regs.dst_height);
int src_stride = DEFAULT_CNTL ?
s->regs.src_pitch : s->regs.default_pitch;
+ if (!src_stride) {
+ qemu_log_mask(LOG_GUEST_ERROR, "Zero source pitch\n");
+ return;
+ }
uint8_t *src_bits = s->vga.vram_ptr + (DEFAULT_CNTL ?
s->regs.src_offset : s->regs.default_offset);
@@ -137,8 +149,10 @@ void ati_2d_blt(ATIVGAState *s)
dst_y * surface_stride(ds),
s->regs.dst_height * surface_stride(ds));
}
- s->regs.dst_x += s->regs.dst_width;
- s->regs.dst_y += s->regs.dst_height;
+ s->regs.dst_x = (s->regs.dp_cntl & DST_X_LEFT_TO_RIGHT ?
+ dst_x + s->regs.dst_width : dst_x);
+ s->regs.dst_y = (s->regs.dp_cntl & DST_Y_TOP_TO_BOTTOM ?
+ dst_y + s->regs.dst_height : dst_y);
break;
}
case ROP3_PATCOPY:
@@ -179,7 +193,8 @@ void ati_2d_blt(ATIVGAState *s)
dst_y * surface_stride(ds),
s->regs.dst_height * surface_stride(ds));
}
- s->regs.dst_y += s->regs.dst_height;
+ s->regs.dst_y = (s->regs.dp_cntl & DST_Y_TOP_TO_BOTTOM ?
+ dst_y + s->regs.dst_height : dst_y);
break;
}
default:
--
1.8.3.1
From e423455c4f23a1a828901c78fe6d03b7dde79319 Mon Sep 17 00:00:00 2001
From: Thomas Huth <thuth@redhat.com>
Date: Wed, 25 Sep 2019 14:16:43 +0200
Subject: [PATCH] hw/core/loader: Fix possible crash in rom_copy()
Both, "rom->addr" and "addr" are derived from the binary image
that can be loaded with the "-kernel" paramer. The code in
rom_copy() then calculates:
d = dest + (rom->addr - addr);
and uses "d" as destination in a memcpy() some lines later. Now with
bad kernel images, it is possible that rom->addr is smaller than addr,
thus "rom->addr - addr" gets negative and the memcpy() then tries to
copy contents from the image to a bad memory location. This could
maybe be used to inject code from a kernel image into the QEMU binary,
so we better fix it with an additional sanity check here.
Cc: qemu-stable@nongnu.org
Reported-by: Guangming Liu
Buglink: https://bugs.launchpad.net/qemu/+bug/1844635
Message-Id: <20190925130331.27825-1-thuth@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
Upstream-Status: Backport [https://git.qemu.org/?p=qemu.git;a=patch;h=e423455c4f23a1a828901c78fe6d03b7dde79319]
CVE: CVE-2020-13765
Signed-off-by: Lee Chee Yang <chee.yang.lee@intel.com>
---
hw/core/loader.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/hw/core/loader.c b/hw/core/loader.c
index 0d60219..5099f27 100644
--- a/hw/core/loader.c
+++ b/hw/core/loader.c
@@ -1281,7 +1281,7 @@ int rom_copy(uint8_t *dest, hwaddr addr, size_t size)
if (rom->addr + rom->romsize < addr) {
continue;
}
- if (rom->addr > end) {
+ if (rom->addr > end || rom->addr < addr) {
break;
}
--
1.8.3.1
From b946434f2659a182afc17e155be6791ebfb302eb Mon Sep 17 00:00:00 2001
From: Gerd Hoffmann <kraxel@redhat.com>
Date: Tue, 25 Aug 2020 07:36:36 +0200
Subject: [PATCH] usb: fix setup_len init (CVE-2020-14364)
Store calculated setup_len in a local variable, verify it, and only
write it to the struct (USBDevice->setup_len) in case it passed the
sanity checks.
This prevents other code (do_token_{in,out} functions specifically)
from working with invalid USBDevice->setup_len values and overrunning
the USBDevice->setup_buf[] buffer.
Fixes: CVE-2020-14364
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Tested-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Li Qiang <liq3ea@gmail.com>
Message-id: 20200825053636.29648-1-kraxel@redhat.com
Upstream-Status: Backport
CVE: CVE-2020-14364
[https://git.qemu.org/?p=qemu.git;a=patch;h=b946434f2659a182afc17e155be6791ebfb302eb]
Signed-off-by: Li Wang <li.wang@windriver.com>
---
hw/usb/core.c | 16 ++++++++++------
1 file changed, 10 insertions(+), 6 deletions(-)
diff --git a/hw/usb/core.c b/hw/usb/core.c
index 5abd128..5234dcc 100644
--- a/hw/usb/core.c
+++ b/hw/usb/core.c
@@ -129,6 +129,7 @@ void usb_wakeup(USBEndpoint *ep, unsigned int stream)
static void do_token_setup(USBDevice *s, USBPacket *p)
{
int request, value, index;
+ unsigned int setup_len;
if (p->iov.size != 8) {
p->status = USB_RET_STALL;
@@ -138,14 +139,15 @@ static void do_token_setup(USBDevice *s, USBPacket *p)
usb_packet_copy(p, s->setup_buf, p->iov.size);
s->setup_index = 0;
p->actual_length = 0;
- s->setup_len = (s->setup_buf[7] << 8) | s->setup_buf[6];
- if (s->setup_len > sizeof(s->data_buf)) {
+ setup_len = (s->setup_buf[7] << 8) | s->setup_buf[6];
+ if (setup_len > sizeof(s->data_buf)) {
fprintf(stderr,
"usb_generic_handle_packet: ctrl buffer too small (%d > %zu)\n",
- s->setup_len, sizeof(s->data_buf));
+ setup_len, sizeof(s->data_buf));
p->status = USB_RET_STALL;
return;
}
+ s->setup_len = setup_len;
request = (s->setup_buf[0] << 8) | s->setup_buf[1];
value = (s->setup_buf[3] << 8) | s->setup_buf[2];
@@ -259,26 +261,28 @@ static void do_token_out(USBDevice *s, USBPacket *p)
static void do_parameter(USBDevice *s, USBPacket *p)
{
int i, request, value, index;
+ unsigned int setup_len;
for (i = 0; i < 8; i++) {
s->setup_buf[i] = p->parameter >> (i*8);
}
s->setup_state = SETUP_STATE_PARAM;
- s->setup_len = (s->setup_buf[7] << 8) | s->setup_buf[6];
s->setup_index = 0;
request = (s->setup_buf[0] << 8) | s->setup_buf[1];
value = (s->setup_buf[3] << 8) | s->setup_buf[2];
index = (s->setup_buf[5] << 8) | s->setup_buf[4];
- if (s->setup_len > sizeof(s->data_buf)) {
+ setup_len = (s->setup_buf[7] << 8) | s->setup_buf[6];
+ if (setup_len > sizeof(s->data_buf)) {
fprintf(stderr,
"usb_generic_handle_packet: ctrl buffer too small (%d > %zu)\n",
- s->setup_len, sizeof(s->data_buf));
+ setup_len, sizeof(s->data_buf));
p->status = USB_RET_STALL;
return;
}
+ s->setup_len = setup_len;
if (p->pid == USB_TOKEN_OUT) {
usb_packet_copy(p, s->data_buf, s->setup_len);
--
2.17.1
From 5519724a13664b43e225ca05351c60b4468e4555 Mon Sep 17 00:00:00 2001
From: Mauro Matteo Cascella <mcascell@redhat.com>
Date: Fri, 10 Jul 2020 11:19:41 +0200
Subject: [PATCH] hw/net/xgmac: Fix buffer overflow in xgmac_enet_send()
A buffer overflow issue was reported by Mr. Ziming Zhang, CC'd here. It
occurs while sending an Ethernet frame due to missing break statements
and improper checking of the buffer size.
Reported-by: Ziming Zhang <ezrakiez@gmail.com>
Signed-off-by: Mauro Matteo Cascella <mcascell@redhat.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Jason Wang <jasowang@redhat.com>
CVE: CVE-2020-15863
Upstream-Status: Backport
[https://git.qemu.org/?p=qemu.git;a=commit;h=5519724a13664b43e225ca05351c60b4468e4555]
Signed-off-by: Chee Yang Lee <chee.yang.lee@intel.com>
Signed-off-by: Li Wang <li.wang@windriver.com>
---
hw/net/xgmac.c | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/hw/net/xgmac.c b/hw/net/xgmac.c
index f49df95..f496f7e 100644
--- a/hw/net/xgmac.c
+++ b/hw/net/xgmac.c
@@ -217,21 +217,31 @@ static void xgmac_enet_send(XgmacState *s)
}
len = (bd.buffer1_size & 0xfff) + (bd.buffer2_size & 0xfff);
+ /*
+ * FIXME: these cases of malformed tx descriptors (bad sizes)
+ * should probably be reported back to the guest somehow
+ * rather than simply silently stopping processing, but we
+ * don't know what the hardware does in this situation.
+ * This will only happen for buggy guests anyway.
+ */
if ((bd.buffer1_size & 0xfff) > 2048) {
DEBUGF_BRK("qemu:%s:ERROR...ERROR...ERROR... -- "
"xgmac buffer 1 len on send > 2048 (0x%x)\n",
__func__, bd.buffer1_size & 0xfff);
+ break;
}
if ((bd.buffer2_size & 0xfff) != 0) {
DEBUGF_BRK("qemu:%s:ERROR...ERROR...ERROR... -- "
"xgmac buffer 2 len on send != 0 (0x%x)\n",
__func__, bd.buffer2_size & 0xfff);
+ break;
}
- if (len >= sizeof(frame)) {
+ if (frame_size + len >= sizeof(frame)) {
DEBUGF_BRK("qemu:%s: buffer overflow %d read into %zu "
- "buffer\n" , __func__, len, sizeof(frame));
+ "buffer\n" , __func__, frame_size + len, sizeof(frame));
DEBUGF_BRK("qemu:%s: buffer1.size=%d; buffer2.size=%d\n",
__func__, bd.buffer1_size, bd.buffer2_size);
+ break;
}
cpu_physical_memory_read(bd.buffer1_addr, ptr, len);
--
1.9.1
From 035e69b063835a5fd23cacabd63690a3d84532a8 Mon Sep 17 00:00:00 2001
From: Mauro Matteo Cascella <mcascell@redhat.com>
Date: Sat, 1 Aug 2020 18:42:38 +0200
Subject: [PATCH] hw/net/net_tx_pkt: fix assertion failure in
net_tx_pkt_add_raw_fragment()
An assertion failure issue was found in the code that processes network
packets
while adding data fragments into the packet context. It could be abused
by a
malicious guest to abort the QEMU process on the host. This patch
replaces the
affected assert() with a conditional statement, returning false if the
current
data fragment exceeds max_raw_frags.
Reported-by: Alexander Bulekov <alxndr@bu.edu>
Reported-by: Ziming Zhang <ezrakiez@gmail.com>
Reviewed-by: Dmitry Fleytman <dmitry.fleytman@gmail.com>
Signed-off-by: Mauro Matteo Cascella <mcascell@redhat.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
Upstream-Status: Backport
CVE: CVE-2020-16092
[https://git.qemu.org/?p=qemu.git;a=commit;h=035e69b063835a5fd23cacabd63690a3d84532a8]
Signed-off-by: Li Wang <li.wang@windriver.com>
---
hw/net/net_tx_pkt.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/hw/net/net_tx_pkt.c b/hw/net/net_tx_pkt.c
index 162f802..54d4c3b 100644
--- a/hw/net/net_tx_pkt.c
+++ b/hw/net/net_tx_pkt.c
@@ -379,7 +379,10 @@ bool net_tx_pkt_add_raw_fragment(struct NetTxPkt *pkt, hwaddr pa,
hwaddr mapped_len = 0;
struct iovec *ventry;
assert(pkt);
- assert(pkt->max_raw_frags > pkt->raw_frags);
+
+ if (pkt->raw_frags >= pkt->max_raw_frags) {
+ return false;
+ }
if (!len) {
return true;
--
2.17.1
From 693fd2acdf14dd86c0bf852610f1c2cca80a74dc Mon Sep 17 00:00:00 2001
From: Felipe Franciosi <felipe@nutanix.com>
Date: Thu, 23 Jan 2020 12:44:59 +0000
Subject: [PATCH] iscsi: Cap block count from GET LBA STATUS (CVE-2020-1711)
When querying an iSCSI server for the provisioning status of blocks (via
GET LBA STATUS), Qemu only validates that the response descriptor zero's
LBA matches the one requested. Given the SCSI spec allows servers to
respond with the status of blocks beyond the end of the LUN, Qemu may
have its heap corrupted by clearing/setting too many bits at the end of
its allocmap for the LUN.
A malicious guest in control of the iSCSI server could carefully program
Qemu's heap (by selectively setting the bitmap) and then smash it.
This limits the number of bits that iscsi_co_block_status() will try to
update in the allocmap so it can't overflow the bitmap.
Upstream-Status: Backport [https://git.qemu.org/?p=qemu.git;a=patch;h=693fd2acdf14dd86c0bf852610f1c2cca80a74dc]
CVE: CVE-2020-1711
Fixes: CVE-2020-1711
Cc: qemu-stable@nongnu.org
Signed-off-by: Felipe Franciosi <felipe@nutanix.com>
Signed-off-by: Peter Turschmid <peter.turschm@nutanix.com>
Signed-off-by: Raphael Norwitz <raphael.norwitz@nutanix.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Lee Chee Yang <chee.yang.lee@intel.com>
---
block/iscsi.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/block/iscsi.c b/block/iscsi.c
index 2aea7e3..cbd5729 100644
--- a/block/iscsi.c
+++ b/block/iscsi.c
@@ -701,7 +701,7 @@ static int coroutine_fn iscsi_co_block_status(BlockDriverState *bs,
struct scsi_get_lba_status *lbas = NULL;
struct scsi_lba_status_descriptor *lbasd = NULL;
struct IscsiTask iTask;
- uint64_t lba;
+ uint64_t lba, max_bytes;
int ret;
iscsi_co_init_iscsitask(iscsilun, &iTask);
@@ -721,6 +721,7 @@ static int coroutine_fn iscsi_co_block_status(BlockDriverState *bs,
}
lba = offset / iscsilun->block_size;
+ max_bytes = (iscsilun->num_blocks - lba) * iscsilun->block_size;
qemu_mutex_lock(&iscsilun->mutex);
retry:
@@ -764,7 +765,7 @@ retry:
goto out_unlock;
}
- *pnum = (int64_t) lbasd->num_blocks * iscsilun->block_size;
+ *pnum = MIN((int64_t) lbasd->num_blocks * iscsilun->block_size, max_bytes);
if (lbasd->provisioning == SCSI_PROVISIONING_TYPE_DEALLOCATED ||
lbasd->provisioning == SCSI_PROVISIONING_TYPE_ANCHORED) {
--
1.8.3.1
From b2663d527a1992ba98c0266458b21ada3b9d0d2e Mon Sep 17 00:00:00 2001
From: Changqing Li <changqing.li@windriver.com>
Date: Thu, 27 Feb 2020 12:07:35 +0800
Subject: [PATCH] tcp_emu: Fix oob access
The main loop only checks for one available byte, while we sometimes
need two bytes.
CVE: CVE-2020-7039
Upstream-Status: Backport
[https://gitlab.freedesktop.org/slirp/libslirp/commit/2655fffed7a9e765bcb4701dd876e9dab975f289]
Signed-off-by: Changqing Li <changqing.li@windriver.com>
---
slirp/src/tcp_subr.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/slirp/src/tcp_subr.c b/slirp/src/tcp_subr.c
index d6dd133..4bea2d4 100644
--- a/slirp/src/tcp_subr.c
+++ b/slirp/src/tcp_subr.c
@@ -886,6 +886,8 @@ int tcp_emu(struct socket *so, struct mbuf *m)
break;
case 5:
+ if (bptr == m->m_data + m->m_len - 1)
+ return 1; /* We need two bytes */
/*
* The difference between versions 1.0 and
* 2.0 is here. For future versions of
@@ -901,6 +903,10 @@ int tcp_emu(struct socket *so, struct mbuf *m)
/* This is the field containing the port
* number that RA-player is listening to.
*/
+
+ if (bptr == m->m_data + m->m_len - 1)
+ return 1; /* We need two bytes */
+
lport = (((uint8_t *)bptr)[0] << 8) + ((uint8_t *)bptr)[1];
if (lport < 6970)
lport += 256; /* don't know why */
--
2.7.4
From 8f67e76e4148e37f3d8d2bcbdee7417fdedb7669 Mon Sep 17 00:00:00 2001
From: Changqing Li <changqing.li@windriver.com>
Date: Thu, 27 Feb 2020 12:10:34 +0800
Subject: [PATCH] slirp: use correct size while emulating commands
While emulating services in tcp_emu(), it uses 'mbuf' size
'm->m_size' to write commands via snprintf(3). Use M_FREEROOM(m)
size to avoid possible OOB access.
Signed-off-by: default avatarPrasad J Pandit <pjp@fedoraproject.org>
Signed-off-by: Samuel Thibault's avatarSamuel Thibault
<samuel.thibault@ens-lyon.org>
Message-Id: <20200109094228.79764-3-ppandit@redhat.com>
CVE: CVE-2020-7039
Upstream-Status: Backport
[https://gitlab.freedesktop.org/slirp/libslirp/commit/82ebe9c370a0e2970fb5695aa19aa5214a6a1c80]
Signed-off-by: Changqing Li <changqing.li@windriver.com>
---
slirp/src/tcp_subr.c | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/slirp/src/tcp_subr.c b/slirp/src/tcp_subr.c
index 4bea2d4..e8ed4ef 100644
--- a/slirp/src/tcp_subr.c
+++ b/slirp/src/tcp_subr.c
@@ -696,7 +696,7 @@ int tcp_emu(struct socket *so, struct mbuf *m)
n4 = (laddr & 0xff);
m->m_len = bptr - m->m_data; /* Adjust length */
- m->m_len += snprintf(bptr, m->m_size - m->m_len,
+ m->m_len += snprintf(bptr, M_FREEROOM(m),
"ORT %d,%d,%d,%d,%d,%d\r\n%s", n1, n2, n3, n4,
n5, n6, x == 7 ? buff : "");
return 1;
@@ -731,8 +731,7 @@ int tcp_emu(struct socket *so, struct mbuf *m)
n4 = (laddr & 0xff);
m->m_len = bptr - m->m_data; /* Adjust length */
- m->m_len +=
- snprintf(bptr, m->m_size - m->m_len,
+ m->m_len += snprintf(bptr, M_FREEROOM(m),
"27 Entering Passive Mode (%d,%d,%d,%d,%d,%d)\r\n%s",
n1, n2, n3, n4, n5, n6, x == 7 ? buff : "");
@@ -758,8 +757,8 @@ int tcp_emu(struct socket *so, struct mbuf *m)
if (m->m_data[m->m_len - 1] == '\0' && lport != 0 &&
(so = tcp_listen(slirp, INADDR_ANY, 0, so->so_laddr.s_addr,
htons(lport), SS_FACCEPTONCE)) != NULL)
- m->m_len =
- snprintf(m->m_data, m->m_size, "%d", ntohs(so->so_fport)) + 1;
+ m->m_len = snprintf(m->m_data, M_ROOM(m),
+ "%d", ntohs(so->so_fport)) + 1;
return 1;
case EMU_IRC:
--
2.7.4
From 0b03959b72036afce151783720d9e54988cf76ef Mon Sep 17 00:00:00 2001
From: Changqing Li <changqing.li@windriver.com>
Date: Thu, 27 Feb 2020 12:15:04 +0800
Subject: [PATCH] slirp: use correct size while emulating IRC commands
While emulating IRC DCC commands, tcp_emu() uses 'mbuf' size
'm->m_size' to write DCC commands via snprintf(3). This may
lead to OOB write access, because 'bptr' points somewhere in
the middle of 'mbuf' buffer, not at the start. Use M_FREEROOM(m)
size to avoid OOB access.
Reported-by: default avatarVishnu Dev TJ <vishnudevtj@gmail.com>
Signed-off-by: default avatarPrasad J Pandit <pjp@fedoraproject.org>
Reviewed-by: Samuel Thibault's avatarSamuel Thibault
<samuel.thibault@ens-lyon.org>
Message-Id: <20200109094228.79764-2-ppandit@redhat.com>
CVE: CVE-2020-7039
Upstream-Status: Backport
[https://gitlab.freedesktop.org/slirp/libslirp/commit/ce131029d6d4a405cb7d3ac6716d03e58fb4a5d9]
Signed-off-by: Changqing Li <changqing.li@windriver.com>
---
slirp/src/tcp_subr.c | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/slirp/src/tcp_subr.c b/slirp/src/tcp_subr.c
index e8ed4ef..3a4a8ee 100644
--- a/slirp/src/tcp_subr.c
+++ b/slirp/src/tcp_subr.c
@@ -777,7 +777,8 @@ int tcp_emu(struct socket *so, struct mbuf *m)
return 1;
}
m->m_len = bptr - m->m_data; /* Adjust length */
- m->m_len += snprintf(bptr, m->m_size, "DCC CHAT chat %lu %u%c\n",
+ m->m_len += snprintf(bptr, M_FREEROOM(m),
+ "DCC CHAT chat %lu %u%c\n",
(unsigned long)ntohl(so->so_faddr.s_addr),
ntohs(so->so_fport), 1);
} else if (sscanf(bptr, "DCC SEND %256s %u %u %u", buff, &laddr, &lport,
@@ -787,8 +788,8 @@ int tcp_emu(struct socket *so, struct mbuf *m)
return 1;
}
m->m_len = bptr - m->m_data; /* Adjust length */
- m->m_len +=
- snprintf(bptr, m->m_size, "DCC SEND %s %lu %u %u%c\n", buff,
+ m->m_len += snprintf(bptr, M_FREEROOM(m),
+ "DCC SEND %s %lu %u %u%c\n", buff,
(unsigned long)ntohl(so->so_faddr.s_addr),
ntohs(so->so_fport), n1, 1);
} else if (sscanf(bptr, "DCC MOVE %256s %u %u %u", buff, &laddr, &lport,
@@ -798,8 +799,8 @@ int tcp_emu(struct socket *so, struct mbuf *m)
return 1;
}
m->m_len = bptr - m->m_data; /* Adjust length */
- m->m_len +=
- snprintf(bptr, m->m_size, "DCC MOVE %s %lu %u %u%c\n", buff,
+ m->m_len += snprintf(bptr, M_FREEROOM(m),
+ "DCC MOVE %s %lu %u %u%c\n", buff,
(unsigned long)ntohl(so->so_faddr.s_addr),
ntohs(so->so_fport), n1, 1);
}
--
2.7.4
From 14ec36e107a8c9af7d0a80c3571fe39b291ff1d4 Mon Sep 17 00:00:00 2001
From: Prasad J Pandit <pjp@fedoraproject.org>
Date: Mon, 13 Jan 2020 17:44:31 +0530
Subject: [PATCH] slirp: tftp: restrict relative path access
tftp restricts relative or directory path access on Linux systems.
Apply same restrictions on Windows systems too. It helps to avoid
directory traversal issue.
Fixes: https://bugs.launchpad.net/qemu/+bug/1812451
Reported-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
Reviewed-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
Message-Id: <20200113121431.156708-1-ppandit@redhat.com>
Upstream-Status: Backport [https://gitlab.freedesktop.org/slirp/libslirp/-/commit/14ec36e107a8c9af7d0a80c3571fe39b291ff1d4.patch]
CVE: CVE-2020-7211
Signed-off-by: Chee Yang Lee <chee.yang.lee@intel.com>
---
slirp/src/tftp.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/slirp/src/tftp.c b/slirp/src/tftp.c
index 093c2e0..e52e71b 100644
--- a/slirp/src/tftp.c
+++ b/slirp/src/tftp.c
@@ -344,8 +344,13 @@ static void tftp_handle_rrq(Slirp *slirp, struct sockaddr_storage *srcsas,
k += 6; /* skipping octet */
/* do sanity checks on the filename */
- if (!strncmp(req_fname, "../", 3) ||
- req_fname[strlen(req_fname) - 1] == '/' || strstr(req_fname, "/../")) {
+ if (
+#ifdef G_OS_WIN32
+ strstr(req_fname, "..\\") ||
+ req_fname[strlen(req_fname) - 1] == '\\' ||
+#endif
+ strstr(req_fname, "../") ||
+ req_fname[strlen(req_fname) - 1] == '/') {
tftp_send_error(spt, 2, "Access violation", tp);
return;
}
--
2.24.1
#!/bin/sh
#
#This script is used to run qemu test suites
#
ptestdir=$(dirname "$(readlink -f "$0")")
export SRC_PATH=$ptestdir
cd $ptestdir/tests
make -f Makefile.include -k runtest-TESTS | sed '/: OK/ s/^/PASS: /g'
BBCLASSEXTEND = "nativesdk"
require qemu.inc
# error: a parameter list without types is only allowed in a function definition
# void (*_function)(sigval_t);
COMPATIBLE_HOST_libc-musl = 'null'
DEPENDS = "glib-2.0 zlib pixman bison-native"
RDEPENDS_${PN}_class-target += "bash"
EXTRA_OECONF_append_class-target = " --target-list=${@get_qemu_target_list(d)}"
EXTRA_OECONF_append_class-target_mipsarcho32 = "${@bb.utils.contains('BBEXTENDCURR', 'multilib', ' --disable-capstone', '', d)}"
EXTRA_OECONF_append_class-nativesdk = " --target-list=${@get_qemu_target_list(d)}"
do_install_append_class-nativesdk() {
${@bb.utils.contains('PACKAGECONFIG', 'gtk+', 'make_qemu_wrapper', '', d)}
}
PACKAGECONFIG ??= " \
fdt sdl kvm \
${@bb.utils.filter('DISTRO_FEATURES', 'alsa xen', d)} \
"
PACKAGECONFIG_class-nativesdk ??= "fdt sdl kvm"
SUMMARY = "QEMU wrapper script"
HOMEPAGE = "http://qemu.org"
LICENSE = "MIT"
S = "${WORKDIR}"
DEPENDS += "qemu-native"
inherit qemu
do_populate_sysroot[depends] = ""
do_install () {
install -d ${D}${bindir_crossscripts}/
qemu_binary=${@qemu_target_binary(d)}
qemu_options='${QEMU_OPTIONS} -E LD_LIBRARY_PATH=$D${libdir}:$D${base_libdir}'
cat >> ${D}${bindir_crossscripts}/${MLPREFIX}qemuwrapper << EOF
#!/bin/sh
set -x
if [ ${@bb.utils.contains('MACHINE_FEATURES', 'qemu-usermode', 'True', 'False', d)} = False -a "${PN}" != "nativesdk-qemuwrapper-cross" ]; then
echo "qemuwrapper: qemu usermode is not supported"
exit 1
fi
$qemu_binary $qemu_options "\$@"
EOF
chmod +x ${D}${bindir_crossscripts}/${MLPREFIX}qemuwrapper
}
SYSROOT_DIRS += "${bindir_crossscripts}"
INHIBIT_DEFAULT_DEPS = "1"
BBCLASSEXTEND = "nativesdk"
Upstream-Status: Backport [https://dev.gnupg.org/T4459]
Signed-off-by: Khem Raj <raj.khem@gmail.com>
From 7865041c77f4f7005282f10f9b6666b19072fbdf Mon Sep 17 00:00:00 2001
From: NIIBE Yutaka <gniibe@fsij.org>
Date: Mon, 15 Apr 2019 15:10:44 +0900
Subject: [PATCH] awk: Prepare for Gawk 5.0.
* src/Makefile.am: Use pkg_namespace (instead of namespace).
* src/mkerrnos.awk: Likewise.
* lang/cl/mkerrcodes.awk: Don't escape # in regexp.
* src/mkerrcodes.awk, src/mkerrcodes1.awk, src/mkerrcodes2.awk: Ditto.
--
In Gawk 5.0, regexp routines are replaced by Gnulib implementation,
which only allows escaping specific characters.
GnuPG-bug-id: 4459
Reported-by: Marius Schamschula
Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
---
lang/cl/mkerrcodes.awk | 2 +-
src/Makefile.am | 2 +-
src/mkerrcodes.awk | 2 +-
src/mkerrcodes1.awk | 2 +-
src/mkerrcodes2.awk | 2 +-
src/mkerrnos.awk | 2 +-
src/mkstrtable.awk | 10 +++++-----
7 files changed, 11 insertions(+), 11 deletions(-)
--- a/lang/cl/mkerrcodes.awk
+++ b/lang/cl/mkerrcodes.awk
@@ -122,7 +122,7 @@ header {
}
!header {
- sub (/\#.+/, "");
+ sub (/#.+/, "");
sub (/[ ]+$/, ""); # Strip trailing space and tab characters.
if (/^$/)
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -293,7 +293,7 @@ code-from-errno.h: mkerrcodes$(EXEEXT_FO
errnos-sym.h: Makefile mkstrtable.awk errnos.in
$(AWK) -f $(srcdir)/mkstrtable.awk -v textidx=2 -v nogettext=1 \
- -v prefix=GPG_ERR_ -v namespace=errnos_ \
+ -v prefix=GPG_ERR_ -v pkg_namespace=errnos_ \
$(srcdir)/errnos.in >$@
--- a/src/mkerrcodes.awk
+++ b/src/mkerrcodes.awk
@@ -85,7 +85,7 @@ header {
}
!header {
- sub (/\#.+/, "");
+ sub (/#.+/, "");
sub (/[ ]+$/, ""); # Strip trailing space and tab characters.
if (/^$/)
--- a/src/mkerrcodes1.awk
+++ b/src/mkerrcodes1.awk
@@ -81,7 +81,7 @@ header {
}
!header {
- sub (/\#.+/, "");
+ sub (/#.+/, "");
sub (/[ ]+$/, ""); # Strip trailing space and tab characters.
if (/^$/)
--- a/src/mkerrcodes2.awk
+++ b/src/mkerrcodes2.awk
@@ -91,7 +91,7 @@ header {
}
!header {
- sub (/\#.+/, "");
+ sub (/#.+/, "");
sub (/[ ]+$/, ""); # Strip trailing space and tab characters.
if (/^$/)
--- a/src/mkerrnos.awk
+++ b/src/mkerrnos.awk
@@ -83,7 +83,7 @@ header {
}
!header {
- sub (/\#.+/, "");
+ sub (/#.+/, "");
sub (/[ ]+$/, ""); # Strip trailing space and tab characters.
if (/^$/)
--- a/src/mkstrtable.awk
+++ b/src/mkstrtable.awk
@@ -77,7 +77,7 @@
#
# The variable prefix can be used to prepend a string to each message.
#
-# The variable namespace can be used to prepend a string to each
+# The variable pkg_namespace can be used to prepend a string to each
# variable and macro name.
BEGIN {
@@ -102,7 +102,7 @@ header {
print "/* The purpose of this complex string table is to produce";
print " optimal code with a minimum of relocations. */";
print "";
- print "static const char " namespace "msgstr[] = ";
+ print "static const char " pkg_namespace "msgstr[] = ";
header = 0;
}
else
@@ -110,7 +110,7 @@ header {
}
!header {
- sub (/\#.+/, "");
+ sub (/#.+/, "");
sub (/[ ]+$/, ""); # Strip trailing space and tab characters.
if (/^$/)
@@ -150,7 +150,7 @@ END {
else
print " gettext_noop (\"" last_msgstr "\");";
print "";
- print "static const int " namespace "msgidx[] =";
+ print "static const int " pkg_namespace "msgidx[] =";
print " {";
for (i = 0; i < coded_msgs; i++)
print " " pos[i] ",";
@@ -158,7 +158,7 @@ END {
print " };";
print "";
print "static GPG_ERR_INLINE int";
- print namespace "msgidxof (int code)";
+ print pkg_namespace "msgidxof (int code)";
print "{";
print " return (0 ? 0";
From ec309e20b5a27d42a5fb915c328d61e924ab5f19 Mon Sep 17 00:00:00 2001
From: Hongxu Jia <hongxu.jia@windriver.com>
Date: Thu, 29 Mar 2018 15:12:17 +0800
Subject: [PATCH] support pkgconfig
Upstream-Status: Pending
Rebase to 1.28
Signed-off-by: Hongxu Jia <hongxu.jia@windriver.com>
Refactored for 1.33
Signed-off-by: Armin Kuster <akuster808@gmail.com>
---
configure.ac | 1 +
src/gpg-error.m4 | 71 +++--------------------------------------------------
4 files changed, 18 insertions(+), 69 deletions(-)
create mode 100644 src/gpg-error.pc.in
Index: libgpg-error-1.33/src/gpg-error.m4
===================================================================
--- libgpg-error-1.33.orig/src/gpg-error.m4
+++ libgpg-error-1.33/src/gpg-error.m4
@@ -26,139 +26,13 @@ dnl is added to the gpg_config_script_wa
dnl
AC_DEFUN([AM_PATH_GPG_ERROR],
[ AC_REQUIRE([AC_CANONICAL_HOST])
- gpg_error_config_prefix=""
- dnl --with-libgpg-error-prefix=PFX is the preferred name for this option,
- dnl since that is consistent with how our three siblings use the directory/
- dnl package name in --with-$dir_name-prefix=PFX.
- AC_ARG_WITH(libgpg-error-prefix,
- AC_HELP_STRING([--with-libgpg-error-prefix=PFX],
- [prefix where GPG Error is installed (optional)]),
- [gpg_error_config_prefix="$withval"])
+ min_gpg_error_version=ifelse([$1], ,0.0,$1)
+ PKG_CHECK_MODULES(GPG_ERROR, [gpg-error >= $min_gpg_error_version], [ok=yes], [ok=no])
- dnl Accept --with-gpg-error-prefix and make it work the same as
- dnl --with-libgpg-error-prefix above, for backwards compatibility,
- dnl but do not document this old, inconsistently-named option.
- AC_ARG_WITH(gpg-error-prefix,,
- [gpg_error_config_prefix="$withval"])
-
- if test x"${GPG_ERROR_CONFIG}" = x ; then
- if test x"${gpg_error_config_prefix}" != x ; then
- GPG_ERROR_CONFIG="${gpg_error_config_prefix}/bin/gpg-error-config"
- else
- case "${SYSROOT}" in
- /*)
- if test -x "${SYSROOT}/bin/gpg-error-config" ; then
- GPG_ERROR_CONFIG="${SYSROOT}/bin/gpg-error-config"
- fi
- ;;
- '')
- ;;
- *)
- AC_MSG_WARN([Ignoring \$SYSROOT as it is not an absolute path.])
- ;;
- esac
- fi
- fi
-
- AC_PATH_PROG(GPG_ERROR_CONFIG, gpg-error-config, no)
- min_gpg_error_version=ifelse([$1], ,1.33,$1)
- ok=no
-
- if test "$prefix" = NONE ; then
- prefix_option_expanded=/usr/local
- else
- prefix_option_expanded="$prefix"
- fi
- if test "$exec_prefix" = NONE ; then
- exec_prefix_option_expanded=$prefix_option_expanded
- else
- exec_prefix_option_expanded=$(prefix=$prefix_option_expanded eval echo $exec_prefix)
- fi
- libdir_option_expanded=$(prefix=$prefix_option_expanded exec_prefix=$exec_prefix_option_expanded eval echo $libdir)
-
- if test -f $libdir_option_expanded/pkgconfig/gpg-error.pc; then
- gpgrt_libdir=$libdir_option_expanded
- else
- if crt1_path=$(${CC:-cc} -print-file-name=crt1.o 2>/dev/null); then
- if possible_libdir=$(cd ${crt1_path%/*} && pwd 2>/dev/null); then
- if test -f $possible_libdir/pkgconfig/gpg-error.pc; then
- gpgrt_libdir=$possible_libdir
- fi
- fi
- fi
- fi
-
- if test "$GPG_ERROR_CONFIG" = "no" -a -n "$gpgrt_libdir"; then
- AC_PATH_PROG(GPGRT_CONFIG, gpgrt-config, no)
- if test "$GPGRT_CONFIG" = "no"; then
- unset GPGRT_CONFIG
- else
- GPGRT_CONFIG="$GPGRT_CONFIG --libdir=$gpgrt_libdir"
- if $GPGRT_CONFIG gpg-error >/dev/null 2>&1; then
- GPG_ERROR_CONFIG="$GPGRT_CONFIG gpg-error"
- AC_MSG_NOTICE([Use gpgrt-config with $gpgrt_libdir as gpg-error-config])
- gpg_error_config_version=`$GPG_ERROR_CONFIG --modversion`
- else
- unset GPGRT_CONFIG
- fi
- fi
- else
- gpg_error_config_version=`$GPG_ERROR_CONFIG --version`
- fi
- if test "$GPG_ERROR_CONFIG" != "no"; then
- req_major=`echo $min_gpg_error_version | \
- sed 's/\([[0-9]]*\)\.\([[0-9]]*\)/\1/'`
- req_minor=`echo $min_gpg_error_version | \
- sed 's/\([[0-9]]*\)\.\([[0-9]]*\)/\2/'`
- major=`echo $gpg_error_config_version | \
- sed 's/\([[0-9]]*\)\.\([[0-9]]*\).*/\1/'`
- minor=`echo $gpg_error_config_version | \
- sed 's/\([[0-9]]*\)\.\([[0-9]]*\).*/\2/'`
- if test "$major" -gt "$req_major"; then
- ok=yes
- else
- if test "$major" -eq "$req_major"; then
- if test "$minor" -ge "$req_minor"; then
- ok=yes
- fi
- fi
- fi
- if test -z "$GPGRT_CONFIG" -a -n "$gpgrt_libdir"; then
- if test "$major" -gt 1 -o "$major" -eq 1 -a "$minor" -ge 33; then
- AC_PATH_PROG(GPGRT_CONFIG, gpgrt-config, no)
- if test "$GPGRT_CONFIG" = "no"; then
- unset GPGRT_CONFIG
- else
- GPGRT_CONFIG="$GPGRT_CONFIG --libdir=$gpgrt_libdir"
- if $GPGRT_CONFIG gpg-error >/dev/null 2>&1; then
- GPG_ERROR_CONFIG="$GPGRT_CONFIG gpg-error"
- AC_MSG_NOTICE([Use gpgrt-config with $gpgrt_libdir as gpg-error-config])
- else
- unset GPGRT_CONFIG
- fi
- fi
- fi
- fi
- fi
- AC_MSG_CHECKING(for GPG Error - version >= $min_gpg_error_version)
if test $ok = yes; then
- GPG_ERROR_CFLAGS=`$GPG_ERROR_CONFIG --cflags`
- GPG_ERROR_LIBS=`$GPG_ERROR_CONFIG --libs`
- if test -z "$GPGRT_CONFIG"; then
- GPG_ERROR_MT_CFLAGS=`$GPG_ERROR_CONFIG --mt --cflags 2>/dev/null`
- GPG_ERROR_MT_LIBS=`$GPG_ERROR_CONFIG --mt --libs 2>/dev/null`
- else
- GPG_ERROR_MT_CFLAGS=`$GPG_ERROR_CONFIG --variable=mtcflags 2>/dev/null`
- GPG_ERROR_MT_CFLAGS="$GPG_ERROR_CFLAGS${GPG_ERROR_CFLAGS:+ }$GPG_ERROR_MT_CFLAGS"
- GPG_ERROR_MT_LIBS=`$GPG_ERROR_CONFIG --variable=mtlibs 2>/dev/null`
- GPG_ERROR_MT_LIBS="$GPG_ERROR_LIBS${GPG_ERROR_LIBS:+ }$GPG_ERROR_MT_LIBS"
- fi
- AC_MSG_RESULT([yes ($gpg_error_config_version)])
ifelse([$2], , :, [$2])
if test -z "$GPGRT_CONFIG"; then
- gpg_error_config_host=`$GPG_ERROR_CONFIG --host 2>/dev/null || echo none`
- else
- gpg_error_config_host=`$GPG_ERROR_CONFIG --variable=host 2>/dev/null || echo none`
+ gpg_error_config_host=`$PKG_CONFIG --variable=host gpg-error`
fi
if test x"$gpg_error_config_host" != xnone ; then
if test x"$gpg_error_config_host" != x"$host" ; then
@@ -174,15 +48,6 @@ AC_DEFUN([AM_PATH_GPG_ERROR],
fi
fi
else
- GPG_ERROR_CFLAGS=""
- GPG_ERROR_LIBS=""
- GPG_ERROR_MT_CFLAGS=""
- GPG_ERROR_MT_LIBS=""
- AC_MSG_RESULT(no)
ifelse([$3], , :, [$3])
fi
- AC_SUBST(GPG_ERROR_CFLAGS)
- AC_SUBST(GPG_ERROR_LIBS)
- AC_SUBST(GPG_ERROR_MT_CFLAGS)
- AC_SUBST(GPG_ERROR_MT_LIBS)
])
SUMMARY = "Small library that defines common error values for all GnuPG components"
HOMEPAGE = "http://www.gnupg.org/related_software/libgpg-error/"
BUGTRACKER = "https://bugs.g10code.com/gnupg/index"
LICENSE = "GPLv2+ & LGPLv2.1+"
LIC_FILES_CHKSUM = "file://COPYING;md5=59530bdf33659b29e73d4adb9f9f6552 \
file://COPYING.LIB;md5=2d5025d4aa3495befef8f17206a5b0a1 \
file://src/gpg-error.h.in;beginline=2;endline=18;md5=cd91e3ad1265a0c268efad541a39345e \
file://src/init.c;beginline=2;endline=17;md5=f01cdfcf747af5380590cfd9bbfeaaf7"
SECTION = "libs"
UPSTREAM_CHECK_URI = "https://gnupg.org/download/index.html"
SRC_URI = "${GNUPG_MIRROR}/libgpg-error/libgpg-error-${PV}.tar.bz2 \
file://pkgconfig.patch \
file://libgpg-error-1.36-gawk5-support.patch \
"
SRC_URI[md5sum] = "eff437f397e858a9127b76c0d87fa5ed"
SRC_URI[sha256sum] = "babd98437208c163175c29453f8681094bcaf92968a15cafb1a276076b33c97c"
BINCONFIG = "${bindir}/gpg-error-config"
inherit autotools binconfig-disabled pkgconfig gettext multilib_header multilib_script
MULTILIB_SCRIPTS = "${PN}-dev:${bindir}/gpgrt-config"
CPPFLAGS += "-P"
do_compile_prepend() {
TARGET_FILE=linux-gnu
if [ ${TARGET_OS} = "mingw32" ]; then
# There are no arch specific syscfg files for mingw32
TARGET_FILE=
elif [ ${TARGET_ARCH} = "arc" ]; then
# ARC syscfg file is automatically aliased to i686-pc-linux-gnu
TARGET_FILE=
elif [ ${TARGET_OS} != "linux" ]; then
TARGET_FILE=${TARGET_OS}
fi
case ${TARGET_ARCH} in
aarch64_be) TUPLE=aarch64-unknown-linux-gnu ;;
arm) TUPLE=arm-unknown-linux-gnueabi ;;
armeb) TUPLE=arm-unknown-linux-gnueabi ;;
i586|i686) TUPLE=i686-unknown-linux-gnu;;
mips64*) TUPLE=mips64el-unknown-linux-gnuabi64 ;;
mips*el) TUPLE=mipsel-unknown-linux-gnu ;;
mips*) TUPLE=mips-unknown-linux-gnu ;;
x86_64) TUPLE=x86_64-unknown-linux-gnu ;;
ppc) TUPLE=powerpc-unknown-linux-gnu ;;
ppc64) TUPLE=powerpc64-unknown-linux-gnu ;;
ppc64le) TUPLE=powerpc64le-unknown-linux-gnu ;;
*) TUPLE=${TARGET_ARCH}-unknown-linux-gnu ;;
esac
if [ -n "$TARGET_FILE" ]; then
cp ${S}/src/syscfg/lock-obj-pub.$TUPLE.h \
${S}/src/syscfg/lock-obj-pub.$TARGET_FILE.h
fi
}
do_install_append() {
# we don't have common lisp in OE
rm -rf "${D}${datadir}/common-lisp/"
oe_multilib_header gpg-error.h gpgrt.h
}
FILES_${PN}-dev += "${bindir}/gpg-error"
FILES_${PN}-doc += "${datadir}/libgpg-error/errorref.txt"
BBCLASSEXTEND = "native nativesdk"
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment