aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xconfigure173
-rw-r--r--crypto/Makefile.objs8
-rw-r--r--crypto/init.c23
-rw-r--r--crypto/tlscredsx509.c21
-rw-r--r--crypto/tlssession.c8
-rw-r--r--include/qemu/osdep.h12
-rw-r--r--linux-user/ioctls.h46
-rw-r--r--linux-user/syscall.c180
-rw-r--r--linux-user/syscall_defs.h28
-rw-r--r--linux-user/syscall_types.h68
-rw-r--r--tests/Makefile.include2
-rw-r--r--tests/crypto-tls-x509-helpers.h3
-rw-r--r--tests/test-crypto-block.c2
-rw-r--r--tests/test-crypto-tlscredsx509.c8
14 files changed, 396 insertions, 186 deletions
diff --git a/configure b/configure
index 1d267b49cc..e39f63d01d 100755
--- a/configure
+++ b/configure
@@ -457,12 +457,9 @@ gtk=""
gtk_gl="no"
tls_priority="NORMAL"
gnutls=""
-gnutls_rnd=""
nettle=""
-nettle_kdf="no"
gcrypt=""
gcrypt_hmac="no"
-gcrypt_kdf="no"
vte=""
virglrenderer=""
tpm="yes"
@@ -2666,79 +2663,28 @@ fi
##########################################
# GNUTLS probe
-gnutls_works() {
- # Unfortunately some distros have bad pkg-config information for gnutls
- # such that it claims to exist but you get a compiler error if you try
- # to use the options returned by --libs. Specifically, Ubuntu for --static
- # builds doesn't work:
- # https://bugs.launchpad.net/ubuntu/+source/gnutls26/+bug/1478035
- #
- # So sanity check the cflags/libs before assuming gnutls can be used.
- if ! $pkg_config --exists "gnutls"; then
- return 1
- fi
-
- write_c_skeleton
- compile_prog "$($pkg_config --cflags gnutls)" "$($pkg_config --libs gnutls)"
-}
-
-gnutls_gcrypt=no
-gnutls_nettle=no
if test "$gnutls" != "no"; then
- if gnutls_works; then
+ if $pkg_config --exists "gnutls >= 3.1.18"; then
gnutls_cflags=$($pkg_config --cflags gnutls)
gnutls_libs=$($pkg_config --libs gnutls)
libs_softmmu="$gnutls_libs $libs_softmmu"
libs_tools="$gnutls_libs $libs_tools"
QEMU_CFLAGS="$QEMU_CFLAGS $gnutls_cflags"
gnutls="yes"
-
- # gnutls_rnd requires >= 2.11.0
- if $pkg_config --exists "gnutls >= 2.11.0"; then
- gnutls_rnd="yes"
- else
- gnutls_rnd="no"
- fi
-
- if $pkg_config --exists 'gnutls >= 3.0'; then
- gnutls_gcrypt=no
- gnutls_nettle=yes
- elif $pkg_config --exists 'gnutls >= 2.12'; then
- case $($pkg_config --libs --static gnutls) in
- *gcrypt*)
- gnutls_gcrypt=yes
- gnutls_nettle=no
- ;;
- *nettle*)
- gnutls_gcrypt=no
- gnutls_nettle=yes
- ;;
- *)
- gnutls_gcrypt=yes
- gnutls_nettle=no
- ;;
- esac
- else
- gnutls_gcrypt=yes
- gnutls_nettle=no
- fi
elif test "$gnutls" = "yes"; then
- feature_not_found "gnutls" "Install gnutls devel"
+ feature_not_found "gnutls" "Install gnutls devel >= 3.1.18"
else
gnutls="no"
- gnutls_rnd="no"
fi
-else
- gnutls_rnd="no"
fi
# If user didn't give a --disable/enable-gcrypt flag,
# then mark as disabled if user requested nettle
-# explicitly, or if gnutls links to nettle
+# explicitly
if test -z "$gcrypt"
then
- if test "$nettle" = "yes" || test "$gnutls_nettle" = "yes"
+ if test "$nettle" = "yes"
then
gcrypt="no"
fi
@@ -2746,16 +2692,16 @@ fi
# If user didn't give a --disable/enable-nettle flag,
# then mark as disabled if user requested gcrypt
-# explicitly, or if gnutls links to gcrypt
+# explicitly
if test -z "$nettle"
then
- if test "$gcrypt" = "yes" || test "$gnutls_gcrypt" = "yes"
+ if test "$gcrypt" = "yes"
then
nettle="no"
fi
fi
-has_libgcrypt_config() {
+has_libgcrypt() {
if ! has "libgcrypt-config"
then
return 1
@@ -2770,11 +2716,42 @@ has_libgcrypt_config() {
fi
fi
+ maj=`libgcrypt-config --version | awk -F . '{print $1}'`
+ min=`libgcrypt-config --version | awk -F . '{print $2}'`
+
+ if test $maj != 1 || test $min -lt 5
+ then
+ return 1
+ fi
+
return 0
}
+
+if test "$nettle" != "no"; then
+ if $pkg_config --exists "nettle >= 2.7.1"; then
+ nettle_cflags=$($pkg_config --cflags nettle)
+ nettle_libs=$($pkg_config --libs nettle)
+ nettle_version=$($pkg_config --modversion nettle)
+ libs_softmmu="$nettle_libs $libs_softmmu"
+ libs_tools="$nettle_libs $libs_tools"
+ QEMU_CFLAGS="$QEMU_CFLAGS $nettle_cflags"
+ nettle="yes"
+
+ if test -z "$gcrypt"; then
+ gcrypt="no"
+ fi
+ else
+ if test "$nettle" = "yes"; then
+ feature_not_found "nettle" "Install nettle devel >= 2.7.1"
+ else
+ nettle="no"
+ fi
+ fi
+fi
+
if test "$gcrypt" != "no"; then
- if has_libgcrypt_config; then
+ if has_libgcrypt; then
gcrypt_cflags=$(libgcrypt-config --cflags)
gcrypt_libs=$(libgcrypt-config --libs)
# Debian has remove -lgpg-error from libgcrypt-config
@@ -2788,22 +2765,6 @@ if test "$gcrypt" != "no"; then
libs_tools="$gcrypt_libs $libs_tools"
QEMU_CFLAGS="$QEMU_CFLAGS $gcrypt_cflags"
gcrypt="yes"
- if test -z "$nettle"; then
- nettle="no"
- fi
-
- cat > $TMPC << EOF
-#include <gcrypt.h>
-int main(void) {
- gcry_kdf_derive(NULL, 0, GCRY_KDF_PBKDF2,
- GCRY_MD_SHA256,
- NULL, 0, 0, 0, NULL);
- return 0;
-}
-EOF
- if compile_prog "$gcrypt_cflags" "$gcrypt_libs" ; then
- gcrypt_kdf=yes
- fi
cat > $TMPC << EOF
#include <gcrypt.h>
@@ -2819,7 +2780,7 @@ EOF
fi
else
if test "$gcrypt" = "yes"; then
- feature_not_found "gcrypt" "Install gcrypt devel"
+ feature_not_found "gcrypt" "Install gcrypt devel >= 1.5.0"
else
gcrypt="no"
fi
@@ -2827,36 +2788,6 @@ EOF
fi
-if test "$nettle" != "no"; then
- if $pkg_config --exists "nettle"; then
- nettle_cflags=$($pkg_config --cflags nettle)
- nettle_libs=$($pkg_config --libs nettle)
- nettle_version=$($pkg_config --modversion nettle)
- libs_softmmu="$nettle_libs $libs_softmmu"
- libs_tools="$nettle_libs $libs_tools"
- QEMU_CFLAGS="$QEMU_CFLAGS $nettle_cflags"
- nettle="yes"
-
- cat > $TMPC << EOF
-#include <stddef.h>
-#include <nettle/pbkdf2.h>
-int main(void) {
- pbkdf2_hmac_sha256(8, NULL, 1000, 8, NULL, 8, NULL);
- return 0;
-}
-EOF
- if compile_prog "$nettle_cflags" "$nettle_libs" ; then
- nettle_kdf=yes
- fi
- else
- if test "$nettle" = "yes"; then
- feature_not_found "nettle" "Install nettle devel"
- else
- nettle="no"
- fi
- fi
-fi
-
if test "$gcrypt" = "yes" && test "$nettle" = "yes"
then
error_exit "Only one of gcrypt & nettle can be enabled"
@@ -4202,7 +4133,14 @@ if compile_prog "" "" ; then
memfd=yes
fi
-
+# check for usbfs
+have_usbfs=no
+if test "$linux_user" = "yes"; then
+ if check_include linux/usbdevice_fs.h; then
+ have_usbfs=yes
+ fi
+ have_usbfs=yes
+fi
# check for fallocate
fallocate=no
@@ -5976,11 +5914,8 @@ echo "GTK GL support $gtk_gl"
echo "VTE support $vte $(echo_version $vte $vteversion)"
echo "TLS priority $tls_priority"
echo "GNUTLS support $gnutls"
-echo "GNUTLS rnd $gnutls_rnd"
echo "libgcrypt $gcrypt"
-echo "libgcrypt kdf $gcrypt_kdf"
echo "nettle $nettle $(echo_version $nettle $nettle_version)"
-echo "nettle kdf $nettle_kdf"
echo "libtasn1 $tasn1"
echo "curses support $curses"
echo "virgl support $virglrenderer $(echo_version $virglrenderer $virgl_version)"
@@ -6325,6 +6260,9 @@ fi
if test "$memfd" = "yes" ; then
echo "CONFIG_MEMFD=y" >> $config_host_mak
fi
+if test "$have_usbfs" = "yes" ; then
+ echo "CONFIG_USBFS=y" >> $config_host_mak
+fi
if test "$fallocate" = "yes" ; then
echo "CONFIG_FALLOCATE=y" >> $config_host_mak
fi
@@ -6416,24 +6354,15 @@ echo "CONFIG_TLS_PRIORITY=\"$tls_priority\"" >> $config_host_mak
if test "$gnutls" = "yes" ; then
echo "CONFIG_GNUTLS=y" >> $config_host_mak
fi
-if test "$gnutls_rnd" = "yes" ; then
- echo "CONFIG_GNUTLS_RND=y" >> $config_host_mak
-fi
if test "$gcrypt" = "yes" ; then
echo "CONFIG_GCRYPT=y" >> $config_host_mak
if test "$gcrypt_hmac" = "yes" ; then
echo "CONFIG_GCRYPT_HMAC=y" >> $config_host_mak
fi
- if test "$gcrypt_kdf" = "yes" ; then
- echo "CONFIG_GCRYPT_KDF=y" >> $config_host_mak
- fi
fi
if test "$nettle" = "yes" ; then
echo "CONFIG_NETTLE=y" >> $config_host_mak
echo "CONFIG_NETTLE_VERSION_MAJOR=${nettle_version%%.*}" >> $config_host_mak
- if test "$nettle_kdf" = "yes" ; then
- echo "CONFIG_NETTLE_KDF=y" >> $config_host_mak
- fi
fi
if test "$tasn1" = "yes" ; then
echo "CONFIG_TASN1=y" >> $config_host_mak
diff --git a/crypto/Makefile.objs b/crypto/Makefile.objs
index 756bab111b..256c9aca1f 100644
--- a/crypto/Makefile.objs
+++ b/crypto/Makefile.objs
@@ -20,11 +20,11 @@ crypto-obj-y += tlscredsx509.o
crypto-obj-y += tlssession.o
crypto-obj-y += secret.o
crypto-obj-$(CONFIG_GCRYPT) += random-gcrypt.o
-crypto-obj-$(if $(CONFIG_GCRYPT),n,$(CONFIG_GNUTLS_RND)) += random-gnutls.o
-crypto-obj-$(if $(CONFIG_GCRYPT),n,$(if $(CONFIG_GNUTLS_RND),n,y)) += random-platform.o
+crypto-obj-$(if $(CONFIG_GCRYPT),n,$(CONFIG_GNUTLS)) += random-gnutls.o
+crypto-obj-$(if $(CONFIG_GCRYPT),n,$(if $(CONFIG_GNUTLS),n,y)) += random-platform.o
crypto-obj-y += pbkdf.o
-crypto-obj-$(CONFIG_NETTLE_KDF) += pbkdf-nettle.o
-crypto-obj-$(if $(CONFIG_NETTLE_KDF),n,$(CONFIG_GCRYPT_KDF)) += pbkdf-gcrypt.o
+crypto-obj-$(CONFIG_NETTLE) += pbkdf-nettle.o
+crypto-obj-$(if $(CONFIG_NETTLE),n,$(CONFIG_GCRYPT)) += pbkdf-gcrypt.o
crypto-obj-y += ivgen.o
crypto-obj-y += ivgen-essiv.o
crypto-obj-y += ivgen-plain.o
diff --git a/crypto/init.c b/crypto/init.c
index f131c42306..c30156405a 100644
--- a/crypto/init.c
+++ b/crypto/init.c
@@ -37,33 +37,14 @@
/* #define DEBUG_GNUTLS */
/*
- * If GNUTLS is built against GCrypt then
- *
- * - When GNUTLS >= 2.12, we must not initialize gcrypt threading
- * because GNUTLS will do that itself
- * - When GNUTLS < 2.12 we must always initialize gcrypt threading
- * - When GNUTLS is disabled we must always initialize gcrypt threading
- *
- * But....
- *
- * When gcrypt >= 1.6.0 we must not initialize gcrypt threading
- * because gcrypt will do that itself.
- *
- * So we need to init gcrypt threading if
+ * We need to init gcrypt threading if
*
* - gcrypt < 1.6.0
- * AND
- * - gnutls < 2.12
- * OR
- * - gnutls is disabled
*
*/
#if (defined(CONFIG_GCRYPT) && \
- (!defined(CONFIG_GNUTLS) || \
- (LIBGNUTLS_VERSION_NUMBER < 0x020c00)) && \
- (!defined(GCRYPT_VERSION_NUMBER) || \
- (GCRYPT_VERSION_NUMBER < 0x010600)))
+ (GCRYPT_VERSION_NUMBER < 0x010600))
#define QCRYPTO_INIT_GCRYPT_THREADS
#else
#undef QCRYPTO_INIT_GCRYPT_THREADS
diff --git a/crypto/tlscredsx509.c b/crypto/tlscredsx509.c
index 98ee0424e5..d6ab4a9862 100644
--- a/crypto/tlscredsx509.c
+++ b/crypto/tlscredsx509.c
@@ -72,14 +72,6 @@ qcrypto_tls_creds_check_cert_times(gnutls_x509_crt_t cert,
}
-#if LIBGNUTLS_VERSION_NUMBER >= 2
-/*
- * The gnutls_x509_crt_get_basic_constraints function isn't
- * available in GNUTLS 1.0.x branches. This isn't critical
- * though, since gnutls_certificate_verify_peers2 will do
- * pretty much the same check at runtime, so we can just
- * disable this code
- */
static int
qcrypto_tls_creds_check_cert_basic_constraints(QCryptoTLSCredsX509 *creds,
gnutls_x509_crt_t cert,
@@ -130,7 +122,6 @@ qcrypto_tls_creds_check_cert_basic_constraints(QCryptoTLSCredsX509 *creds,
return 0;
}
-#endif
static int
@@ -299,14 +290,12 @@ qcrypto_tls_creds_check_cert(QCryptoTLSCredsX509 *creds,
return -1;
}
-#if LIBGNUTLS_VERSION_NUMBER >= 2
if (qcrypto_tls_creds_check_cert_basic_constraints(creds,
cert, certFile,
isServer, isCA,
errp) < 0) {
return -1;
}
-#endif
if (qcrypto_tls_creds_check_cert_key_usage(creds,
cert, certFile,
@@ -615,7 +604,6 @@ qcrypto_tls_creds_x509_load(QCryptoTLSCredsX509 *creds,
}
if (cert != NULL && key != NULL) {
-#if LIBGNUTLS_VERSION_NUMBER >= 0x030111
char *password = NULL;
if (creds->passwordid) {
password = qcrypto_secret_lookup_as_utf8(creds->passwordid,
@@ -630,15 +618,6 @@ qcrypto_tls_creds_x509_load(QCryptoTLSCredsX509 *creds,
password,
0);
g_free(password);
-#else /* LIBGNUTLS_VERSION_NUMBER < 0x030111 */
- if (creds->passwordid) {
- error_setg(errp, "PKCS8 decryption requires GNUTLS >= 3.1.11");
- goto cleanup;
- }
- ret = gnutls_certificate_set_x509_key_file(creds->data,
- cert, key,
- GNUTLS_X509_FMT_PEM);
-#endif
if (ret < 0) {
error_setg(errp, "Cannot load certificate '%s' & key '%s': %s",
cert, key, gnutls_strerror(ret));
diff --git a/crypto/tlssession.c b/crypto/tlssession.c
index 66a6fbe19c..2f28fa7f71 100644
--- a/crypto/tlssession.c
+++ b/crypto/tlssession.c
@@ -90,13 +90,7 @@ qcrypto_tls_session_pull(void *opaque, void *buf, size_t len)
}
#define TLS_PRIORITY_ADDITIONAL_ANON "+ANON-DH"
-
-#if GNUTLS_VERSION_MAJOR >= 3
-#define TLS_ECDHE_PSK "+ECDHE-PSK:"
-#else
-#define TLS_ECDHE_PSK ""
-#endif
-#define TLS_PRIORITY_ADDITIONAL_PSK TLS_ECDHE_PSK "+DHE-PSK:+PSK"
+#define TLS_PRIORITY_ADDITIONAL_PSK "+ECDHE-PSK:+DHE-PSK:+PSK"
QCryptoTLSSession *
qcrypto_tls_session_new(QCryptoTLSCreds *creds,
diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
index 4f8559e550..3bf48bcdec 100644
--- a/include/qemu/osdep.h
+++ b/include/qemu/osdep.h
@@ -123,6 +123,18 @@ extern int daemon(int, int);
#include "qemu/typedefs.h"
/*
+ * For mingw, as of v6.0.0, the function implementing the assert macro is
+ * not marked as noreturn, so the compiler cannot delete code following an
+ * assert(false) as unused. We rely on this within the code base to delete
+ * code that is unreachable when features are disabled.
+ * All supported versions of Glib's g_assert() satisfy this requirement.
+ */
+#ifdef __MINGW32__
+#undef assert
+#define assert(x) g_assert(x)
+#endif
+
+/*
* According to waitpid man page:
* WCOREDUMP
* This macro is not specified in POSIX.1-2001 and is not
diff --git a/linux-user/ioctls.h b/linux-user/ioctls.h
index 586c794639..ae8951625f 100644
--- a/linux-user/ioctls.h
+++ b/linux-user/ioctls.h
@@ -131,6 +131,52 @@
IOCTL(FS_IOC_GETFLAGS, IOC_R, MK_PTR(TYPE_INT))
IOCTL(FS_IOC_SETFLAGS, IOC_W, MK_PTR(TYPE_INT))
+#ifdef CONFIG_USBFS
+ /* USB ioctls */
+ IOCTL(USBDEVFS_CONTROL, IOC_RW,
+ MK_PTR(MK_STRUCT(STRUCT_usbdevfs_ctrltransfer)))
+ IOCTL(USBDEVFS_BULK, IOC_RW,
+ MK_PTR(MK_STRUCT(STRUCT_usbdevfs_bulktransfer)))
+ IOCTL(USBDEVFS_RESETEP, IOC_W, MK_PTR(TYPE_INT))
+ IOCTL(USBDEVFS_SETINTERFACE, IOC_W,
+ MK_PTR(MK_STRUCT(STRUCT_usbdevfs_setinterface)))
+ IOCTL(USBDEVFS_SETCONFIGURATION, IOC_W, MK_PTR(TYPE_INT))
+ IOCTL(USBDEVFS_GETDRIVER, IOC_R,
+ MK_PTR(MK_STRUCT(STRUCT_usbdevfs_getdriver)))
+ IOCTL_SPECIAL(USBDEVFS_SUBMITURB, IOC_W, do_ioctl_usbdevfs_submiturb,
+ MK_PTR(MK_STRUCT(STRUCT_usbdevfs_urb)))
+ IOCTL_SPECIAL(USBDEVFS_DISCARDURB, IOC_RW, do_ioctl_usbdevfs_discardurb,
+ MK_PTR(MK_STRUCT(STRUCT_usbdevfs_urb)))
+ IOCTL_SPECIAL(USBDEVFS_REAPURB, IOC_R, do_ioctl_usbdevfs_reapurb,
+ MK_PTR(TYPE_PTRVOID))
+ IOCTL_SPECIAL(USBDEVFS_REAPURBNDELAY, IOC_R, do_ioctl_usbdevfs_reapurb,
+ MK_PTR(TYPE_PTRVOID))
+ IOCTL(USBDEVFS_DISCSIGNAL, IOC_W,
+ MK_PTR(MK_STRUCT(STRUCT_usbdevfs_disconnectsignal)))
+ IOCTL(USBDEVFS_CLAIMINTERFACE, IOC_W, MK_PTR(TYPE_INT))
+ IOCTL(USBDEVFS_RELEASEINTERFACE, IOC_W, MK_PTR(TYPE_INT))
+ IOCTL(USBDEVFS_CONNECTINFO, IOC_R,
+ MK_PTR(MK_STRUCT(STRUCT_usbdevfs_connectinfo)))
+ IOCTL(USBDEVFS_IOCTL, IOC_RW, MK_PTR(MK_STRUCT(STRUCT_usbdevfs_ioctl)))
+ IOCTL(USBDEVFS_HUB_PORTINFO, IOC_R,
+ MK_PTR(MK_STRUCT(STRUCT_usbdevfs_hub_portinfo)))
+ IOCTL(USBDEVFS_RESET, 0, TYPE_NULL)
+ IOCTL(USBDEVFS_CLEAR_HALT, IOC_W, MK_PTR(TYPE_INT))
+ IOCTL(USBDEVFS_DISCONNECT, 0, TYPE_NULL)
+ IOCTL(USBDEVFS_CONNECT, 0, TYPE_NULL)
+ IOCTL(USBDEVFS_CLAIM_PORT, IOC_W, MK_PTR(TYPE_INT))
+ IOCTL(USBDEVFS_RELEASE_PORT, IOC_W, MK_PTR(TYPE_INT))
+ IOCTL(USBDEVFS_GET_CAPABILITIES, IOC_R, MK_PTR(TYPE_INT))
+ IOCTL(USBDEVFS_DISCONNECT_CLAIM, IOC_W,
+ MK_PTR(MK_STRUCT(STRUCT_usbdevfs_disconnect_claim)))
+#ifdef USBDEVFS_DROP_PRIVILEGES
+ IOCTL(USBDEVFS_DROP_PRIVILEGES, IOC_W, MK_PTR(TYPE_INT))
+#endif
+#ifdef USBDEVFS_GET_SPEED
+ IOCTL(USBDEVFS_GET_SPEED, 0, TYPE_NULL)
+#endif
+#endif /* CONFIG_USBFS */
+
IOCTL(SIOCATMARK, IOC_R, MK_PTR(TYPE_INT))
IOCTL(SIOCGIFNAME, IOC_RW, MK_PTR(TYPE_INT))
IOCTL(SIOCGIFFLAGS, IOC_W | IOC_R, MK_PTR(MK_STRUCT(STRUCT_short_ifreq)))
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index d2cc971143..cf4511b0e4 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -94,6 +94,10 @@
#include <linux/fiemap.h>
#endif
#include <linux/fb.h>
+#if defined(CONFIG_USBFS)
+#include <linux/usbdevice_fs.h>
+#include <linux/usb/ch9.h>
+#endif
#include <linux/vt.h>
#include <linux/dm-ioctl.h>
#include <linux/reboot.h>
@@ -4196,6 +4200,182 @@ static abi_long do_ioctl_ifconf(const IOCTLEntry *ie, uint8_t *buf_temp,
return ret;
}
+#if defined(CONFIG_USBFS)
+#if HOST_LONG_BITS > 64
+#error USBDEVFS thunks do not support >64 bit hosts yet.
+#endif
+struct live_urb {
+ uint64_t target_urb_adr;
+ uint64_t target_buf_adr;
+ char *target_buf_ptr;
+ struct usbdevfs_urb host_urb;
+};
+
+static GHashTable *usbdevfs_urb_hashtable(void)
+{
+ static GHashTable *urb_hashtable;
+
+ if (!urb_hashtable) {
+ urb_hashtable = g_hash_table_new(g_int64_hash, g_int64_equal);
+ }
+ return urb_hashtable;
+}
+
+static void urb_hashtable_insert(struct live_urb *urb)
+{
+ GHashTable *urb_hashtable = usbdevfs_urb_hashtable();
+ g_hash_table_insert(urb_hashtable, urb, urb);
+}
+
+static struct live_urb *urb_hashtable_lookup(uint64_t target_urb_adr)
+{
+ GHashTable *urb_hashtable = usbdevfs_urb_hashtable();
+ return g_hash_table_lookup(urb_hashtable, &target_urb_adr);
+}
+
+static void urb_hashtable_remove(struct live_urb *urb)
+{
+ GHashTable *urb_hashtable = usbdevfs_urb_hashtable();
+ g_hash_table_remove(urb_hashtable, urb);
+}
+
+static abi_long
+do_ioctl_usbdevfs_reapurb(const IOCTLEntry *ie, uint8_t *buf_temp,
+ int fd, int cmd, abi_long arg)
+{
+ const argtype usbfsurb_arg_type[] = { MK_STRUCT(STRUCT_usbdevfs_urb) };
+ const argtype ptrvoid_arg_type[] = { TYPE_PTRVOID, 0, 0 };
+ struct live_urb *lurb;
+ void *argptr;
+ uint64_t hurb;
+ int target_size;
+ uintptr_t target_urb_adr;
+ abi_long ret;
+
+ target_size = thunk_type_size(usbfsurb_arg_type, THUNK_TARGET);
+
+ memset(buf_temp, 0, sizeof(uint64_t));
+ ret = get_errno(safe_ioctl(fd, ie->host_cmd, buf_temp));
+ if (is_error(ret)) {
+ return ret;
+ }
+
+ memcpy(&hurb, buf_temp, sizeof(uint64_t));
+ lurb = (void *)((uintptr_t)hurb - offsetof(struct live_urb, host_urb));
+ if (!lurb->target_urb_adr) {
+ return -TARGET_EFAULT;
+ }
+ urb_hashtable_remove(lurb);
+ unlock_user(lurb->target_buf_ptr, lurb->target_buf_adr,
+ lurb->host_urb.buffer_length);
+ lurb->target_buf_ptr = NULL;
+
+ /* restore the guest buffer pointer */
+ lurb->host_urb.buffer = (void *)(uintptr_t)lurb->target_buf_adr;
+
+ /* update the guest urb struct */
+ argptr = lock_user(VERIFY_WRITE, lurb->target_urb_adr, target_size, 0);
+ if (!argptr) {
+ g_free(lurb);
+ return -TARGET_EFAULT;
+ }
+ thunk_convert(argptr, &lurb->host_urb, usbfsurb_arg_type, THUNK_TARGET);
+ unlock_user(argptr, lurb->target_urb_adr, target_size);
+
+ target_size = thunk_type_size(ptrvoid_arg_type, THUNK_TARGET);
+ /* write back the urb handle */
+ argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
+ if (!argptr) {
+ g_free(lurb);
+ return -TARGET_EFAULT;
+ }
+
+ /* GHashTable uses 64-bit keys but thunk_convert expects uintptr_t */
+ target_urb_adr = lurb->target_urb_adr;
+ thunk_convert(argptr, &target_urb_adr, ptrvoid_arg_type, THUNK_TARGET);
+ unlock_user(argptr, arg, target_size);
+
+ g_free(lurb);
+ return ret;
+}
+
+static abi_long
+do_ioctl_usbdevfs_discardurb(const IOCTLEntry *ie,
+ uint8_t *buf_temp __attribute__((unused)),
+ int fd, int cmd, abi_long arg)
+{
+ struct live_urb *lurb;
+
+ /* map target address back to host URB with metadata. */
+ lurb = urb_hashtable_lookup(arg);
+ if (!lurb) {
+ return -TARGET_EFAULT;
+ }
+ return get_errno(safe_ioctl(fd, ie->host_cmd, &lurb->host_urb));
+}
+
+static abi_long
+do_ioctl_usbdevfs_submiturb(const IOCTLEntry *ie, uint8_t *buf_temp,
+ int fd, int cmd, abi_long arg)
+{
+ const argtype *arg_type = ie->arg_type;
+ int target_size;
+ abi_long ret;
+ void *argptr;
+ int rw_dir;
+ struct live_urb *lurb;
+
+ /*
+ * each submitted URB needs to map to a unique ID for the
+ * kernel, and that unique ID needs to be a pointer to
+ * host memory. hence, we need to malloc for each URB.
+ * isochronous transfers have a variable length struct.
+ */
+ arg_type++;
+ target_size = thunk_type_size(arg_type, THUNK_TARGET);
+
+ /* construct host copy of urb and metadata */
+ lurb = g_try_malloc0(sizeof(struct live_urb));
+ if (!lurb) {
+ return -TARGET_ENOMEM;
+ }
+
+ argptr = lock_user(VERIFY_READ, arg, target_size, 1);
+ if (!argptr) {
+ g_free(lurb);
+ return -TARGET_EFAULT;
+ }
+ thunk_convert(&lurb->host_urb, argptr, arg_type, THUNK_HOST);
+ unlock_user(argptr, arg, 0);
+
+ lurb->target_urb_adr = arg;
+ lurb->target_buf_adr = (uintptr_t)lurb->host_urb.buffer;
+
+ /* buffer space used depends on endpoint type so lock the entire buffer */
+ /* control type urbs should check the buffer contents for true direction */
+ rw_dir = lurb->host_urb.endpoint & USB_DIR_IN ? VERIFY_WRITE : VERIFY_READ;
+ lurb->target_buf_ptr = lock_user(rw_dir, lurb->target_buf_adr,
+ lurb->host_urb.buffer_length, 1);
+ if (lurb->target_buf_ptr == NULL) {
+ g_free(lurb);
+ return -TARGET_EFAULT;
+ }
+
+ /* update buffer pointer in host copy */
+ lurb->host_urb.buffer = lurb->target_buf_ptr;
+
+ ret = get_errno(safe_ioctl(fd, ie->host_cmd, &lurb->host_urb));
+ if (is_error(ret)) {
+ unlock_user(lurb->target_buf_ptr, lurb->target_buf_adr, 0);
+ g_free(lurb);
+ } else {
+ urb_hashtable_insert(lurb);
+ }
+
+ return ret;
+}
+#endif /* CONFIG_USBFS */
+
static abi_long do_ioctl_dm(const IOCTLEntry *ie, uint8_t *buf_temp, int fd,
int cmd, abi_long arg)
{
diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
index 18d434d6dc..99bbce083c 100644
--- a/linux-user/syscall_defs.h
+++ b/linux-user/syscall_defs.h
@@ -863,6 +863,34 @@ struct target_pollfd {
#define TARGET_FS_IOC_FIEMAP TARGET_IOWR('f',11,struct fiemap)
+/* usb ioctls */
+#define TARGET_USBDEVFS_CONTROL TARGET_IOWRU('U', 0)
+#define TARGET_USBDEVFS_BULK TARGET_IOWRU('U', 2)
+#define TARGET_USBDEVFS_RESETEP TARGET_IORU('U', 3)
+#define TARGET_USBDEVFS_SETINTERFACE TARGET_IORU('U', 4)
+#define TARGET_USBDEVFS_SETCONFIGURATION TARGET_IORU('U', 5)
+#define TARGET_USBDEVFS_GETDRIVER TARGET_IOWU('U', 8)
+#define TARGET_USBDEVFS_SUBMITURB TARGET_IORU('U', 10)
+#define TARGET_USBDEVFS_DISCARDURB TARGET_IO('U', 11)
+#define TARGET_USBDEVFS_REAPURB TARGET_IOWU('U', 12)
+#define TARGET_USBDEVFS_REAPURBNDELAY TARGET_IOWU('U', 13)
+#define TARGET_USBDEVFS_DISCSIGNAL TARGET_IORU('U', 14)
+#define TARGET_USBDEVFS_CLAIMINTERFACE TARGET_IORU('U', 15)
+#define TARGET_USBDEVFS_RELEASEINTERFACE TARGET_IORU('U', 16)
+#define TARGET_USBDEVFS_CONNECTINFO TARGET_IOWU('U', 17)
+#define TARGET_USBDEVFS_IOCTL TARGET_IOWRU('U', 18)
+#define TARGET_USBDEVFS_HUB_PORTINFO TARGET_IORU('U', 19)
+#define TARGET_USBDEVFS_RESET TARGET_IO('U', 20)
+#define TARGET_USBDEVFS_CLEAR_HALT TARGET_IORU('U', 21)
+#define TARGET_USBDEVFS_DISCONNECT TARGET_IO('U', 22)
+#define TARGET_USBDEVFS_CONNECT TARGET_IO('U', 23)
+#define TARGET_USBDEVFS_CLAIM_PORT TARGET_IORU('U', 24)
+#define TARGET_USBDEVFS_RELEASE_PORT TARGET_IORU('U', 25)
+#define TARGET_USBDEVFS_GET_CAPABILITIES TARGET_IORU('U', 26)
+#define TARGET_USBDEVFS_DISCONNECT_CLAIM TARGET_IORU('U', 27)
+#define TARGET_USBDEVFS_DROP_PRIVILEGES TARGET_IOWU('U', 30)
+#define TARGET_USBDEVFS_GET_SPEED TARGET_IO('U', 31)
+
/* cdrom commands */
#define TARGET_CDROMPAUSE 0x5301 /* Pause Audio Operation */
#define TARGET_CDROMRESUME 0x5302 /* Resume paused Audio Operation */
diff --git a/linux-user/syscall_types.h b/linux-user/syscall_types.h
index 24631b09be..b98a23b0f1 100644
--- a/linux-user/syscall_types.h
+++ b/linux-user/syscall_types.h
@@ -266,3 +266,71 @@ STRUCT(blkpg_ioctl_arg,
TYPE_INT, /* flags */
TYPE_INT, /* datalen */
TYPE_PTRVOID) /* data */
+
+#if defined(CONFIG_USBFS)
+/* usb device ioctls */
+STRUCT(usbdevfs_ctrltransfer,
+ TYPE_CHAR, /* bRequestType */
+ TYPE_CHAR, /* bRequest */
+ TYPE_SHORT, /* wValue */
+ TYPE_SHORT, /* wIndex */
+ TYPE_SHORT, /* wLength */
+ TYPE_INT, /* timeout */
+ TYPE_PTRVOID) /* data */
+
+STRUCT(usbdevfs_bulktransfer,
+ TYPE_INT, /* ep */
+ TYPE_INT, /* len */
+ TYPE_INT, /* timeout */
+ TYPE_PTRVOID) /* data */
+
+STRUCT(usbdevfs_setinterface,
+ TYPE_INT, /* interface */
+ TYPE_INT) /* altsetting */
+
+STRUCT(usbdevfs_disconnectsignal,
+ TYPE_INT, /* signr */
+ TYPE_PTRVOID) /* context */
+
+STRUCT(usbdevfs_getdriver,
+ TYPE_INT, /* interface */
+ MK_ARRAY(TYPE_CHAR, USBDEVFS_MAXDRIVERNAME + 1)) /* driver */
+
+STRUCT(usbdevfs_connectinfo,
+ TYPE_INT, /* devnum */
+ TYPE_CHAR) /* slow */
+
+STRUCT(usbdevfs_iso_packet_desc,
+ TYPE_INT, /* length */
+ TYPE_INT, /* actual_length */
+ TYPE_INT) /* status */
+
+STRUCT(usbdevfs_urb,
+ TYPE_CHAR, /* type */
+ TYPE_CHAR, /* endpoint */
+ TYPE_INT, /* status */
+ TYPE_INT, /* flags */
+ TYPE_PTRVOID, /* buffer */
+ TYPE_INT, /* buffer_length */
+ TYPE_INT, /* actual_length */
+ TYPE_INT, /* start_frame */
+ TYPE_INT, /* union number_of_packets stream_id */
+ TYPE_INT, /* error_count */
+ TYPE_INT, /* signr */
+ TYPE_PTRVOID, /* usercontext */
+ MK_ARRAY(MK_STRUCT(STRUCT_usbdevfs_iso_packet_desc), 0)) /* desc */
+
+STRUCT(usbdevfs_ioctl,
+ TYPE_INT, /* ifno */
+ TYPE_INT, /* ioctl_code */
+ TYPE_PTRVOID) /* data */
+
+STRUCT(usbdevfs_hub_portinfo,
+ TYPE_CHAR, /* nports */
+ MK_ARRAY(TYPE_CHAR, 127)) /* port */
+
+STRUCT(usbdevfs_disconnect_claim,
+ TYPE_INT, /* interface */
+ TYPE_INT, /* flags */
+ MK_ARRAY(TYPE_CHAR, USBDEVFS_MAXDRIVERNAME + 1)) /* driver */
+#endif /* CONFIG_USBFS */
diff --git a/tests/Makefile.include b/tests/Makefile.include
index 7fe8578972..f77a495109 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -115,7 +115,7 @@ check-unit-$(CONFIG_GNUTLS) += tests/test-io-channel-tls$(EXESUF)
check-unit-y += tests/test-io-channel-command$(EXESUF)
check-unit-y += tests/test-io-channel-buffer$(EXESUF)
check-unit-y += tests/test-base64$(EXESUF)
-check-unit-$(if $(CONFIG_NETTLE_KDF),y,$(CONFIG_GCRYPT_KDF)) += tests/test-crypto-pbkdf$(EXESUF)
+check-unit-$(if $(CONFIG_NETTLE),y,$(CONFIG_GCRYPT)) += tests/test-crypto-pbkdf$(EXESUF)
check-unit-y += tests/test-crypto-ivgen$(EXESUF)
check-unit-y += tests/test-crypto-afsplit$(EXESUF)
check-unit-y += tests/test-crypto-xts$(EXESUF)
diff --git a/tests/crypto-tls-x509-helpers.h b/tests/crypto-tls-x509-helpers.h
index 921341c649..88c30d7c94 100644
--- a/tests/crypto-tls-x509-helpers.h
+++ b/tests/crypto-tls-x509-helpers.h
@@ -22,8 +22,7 @@
#include <gnutls/x509.h>
#if !(defined WIN32) && \
- defined(CONFIG_TASN1) && \
- (LIBGNUTLS_VERSION_NUMBER >= 0x020600)
+ defined(CONFIG_TASN1)
# define QCRYPTO_HAVE_TLS_TEST_SUPPORT
#endif
diff --git a/tests/test-crypto-block.c b/tests/test-crypto-block.c
index fd29a045d2..fae4ffc453 100644
--- a/tests/test-crypto-block.c
+++ b/tests/test-crypto-block.c
@@ -29,7 +29,7 @@
#endif
#if (defined(_WIN32) || defined RUSAGE_THREAD) && \
- (defined(CONFIG_NETTLE_KDF) || defined(CONFIG_GCRYPT_KDF))
+ (defined(CONFIG_NETTLE) || defined(CONFIG_GCRYPT))
#define TEST_LUKS
#else
#undef TEST_LUKS
diff --git a/tests/test-crypto-tlscredsx509.c b/tests/test-crypto-tlscredsx509.c
index 30f9ac4bbf..940a026c6e 100644
--- a/tests/test-crypto-tlscredsx509.c
+++ b/tests/test-crypto-tlscredsx509.c
@@ -283,14 +283,8 @@ int main(int argc, char **argv)
true, true, GNUTLS_KP_TLS_WWW_SERVER, NULL,
0, 0);
- /* Technically a CA cert with basic constraints
- * key purpose == key signing + non-critical should
- * be rejected. GNUTLS < 3.1 does not reject it and
- * we don't anticipate them changing this behaviour
- */
TLS_TEST_REG(badca1, true, cacert4req.filename, servercert4req.filename,
- (GNUTLS_VERSION_MAJOR == 3 && GNUTLS_VERSION_MINOR >= 1) ||
- GNUTLS_VERSION_MAJOR > 3);
+ true);
TLS_TEST_REG(badca2, true,
cacert5req.filename, servercert5req.filename, true);
TLS_TEST_REG(badca3, true,