Fix stdio regression

This change fixes a nasty regression caused by
80b211e314 which deadlocked.

This change also causes MbedTLS to prefer the ChaCha ciphersuite on
older CPUs that don't have AES hardware instructions.
This commit is contained in:
Justine Tunney 2022-05-19 00:34:15 -07:00
parent 9208c83f7a
commit 6e52cba37a
14 changed files with 232 additions and 51 deletions

View file

@ -23,7 +23,7 @@
// @return byte in range 0..255, or -1 w/ errno
// @see fgetc_unlocked()
getchar:
lea stdin(%rip),%rdi
mov stdin(%rip),%rdi
mov %rdi,%r11
ezlea fgetc_unlocked,ax
jmp stdio_unlock

View file

@ -23,7 +23,7 @@
// @return wide character or -1 on EOF or error
// @see fgetwc_unlocked()
getwchar:
lea stdin(%rip),%rdi
mov stdin(%rip),%rdi
mov %rdi,%r11
ezlea fgetwc_unlocked,ax
jmp stdio_unlock

View file

@ -24,7 +24,7 @@
// @return c (as unsigned char) if written or -1 w/ errno
// @see fputc_unlocked()
putchar:
lea stdout(%rip),%rsi
mov stdout(%rip),%rsi
mov %rsi,%r11
ezlea fputc_unlocked,ax
jmp stdio_unlock

View file

@ -24,7 +24,7 @@
// @return wc if written or -1 w/ errno
// @see fputwc_unlocked()
putwchar:
lea stdout(%rip),%rsi
mov stdout(%rip),%rsi
mov %rsi,%r11
ezlea fputwc_unlocked,ax
jmp stdio_unlock

View file

@ -17,7 +17,11 @@
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/errno.h"
#include "libc/nexgen32e/threaded.h"
asm(".weak\t__asan_init");
asm(".weak\t__asan_register_globals");
asm(".weak\t__asan_unregister_globals");
asm(".weak\t__asan_version_mismatch_check_v8");
/**
* Global variable for last error.
@ -32,14 +36,3 @@
* @see __errno_location() stable abi
*/
errno_t __errno;
/**
* Returns address of errno variable.
*
* @see __initialize_tls()
* @see __install_tls()
*/
privileged nocallersavedregisters errno_t *(__errno_location)(void) {
if (!__tls_enabled) return &__errno;
return (errno_t *)(__get_tls() + 0x3c);
}

View file

@ -0,0 +1,31 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2022 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/errno.h"
#include "libc/nexgen32e/threaded.h"
/**
* Returns address of errno variable.
*
* @see __initialize_tls()
* @see __install_tls()
*/
privileged nocallersavedregisters errno_t *(__errno_location)(void) {
if (!__tls_enabled) return &__errno;
return (errno_t *)(__get_tls() + 0x3c);
}

View file

@ -37,7 +37,8 @@ LIBC_SYSV_A_FILES := \
libc/sysv/restorert.S \
libc/sysv/syscall.S \
libc/sysv/systemfive.S \
libc/sysv/errno.greg.c \
libc/sysv/errno_location.greg.c \
libc/sysv/errno.c \
libc/sysv/strace.greg.c \
libc/sysv/describeos.greg.c \
$(wildcard libc/sysv/consts/*) \
@ -75,12 +76,6 @@ o/libc/sysv/consts/syscon.internal.inc: \
libc/macros-cpp.internal.inc \
libc/macros.internal.inc
# we can't use asan and ubsan because:
# we're higher in the topological order of things
o/$(MODE)/libc/sysv/errno.greg.o: \
OVERRIDE_CFLAGS += \
-fno-sanitize=all
#───────────────────────────────────────────────────────────────────────────────
LIBC_SYSV_CALLS = \

View file

@ -31,7 +31,7 @@
#include "libc/testlib/testlib.h"
#include "third_party/xed/x86.h"
int gotsignal;
volatile int gotsignal;
char testlib_enable_tmp_setup_teardown;
void ContinueOnError(int sig, siginfo_t *si, ucontext_t *ctx) {
@ -207,7 +207,7 @@ TEST(munmap, tinyFile_roundupUnmapSize) {
ASSERT_SYS(0, 0, close(3));
EXPECT_TRUE(MemoryExists(p));
// some kernels/versions support this, some don't
// EXPECT_FALSE(MemoryExists(p + 5));
EXPECT_FALSE(MemoryExists(p + PAGESIZE));
EXPECT_SYS(0, 0, munmap(p, FRAMESIZE));
EXPECT_FALSE(MemoryExists(p));
EXPECT_FALSE(MemoryExists(p + 5));
@ -230,3 +230,24 @@ TEST(munmap, tinyFile_preciseUnmapSize) {
EXPECT_SYS(0, 0, munmap(q, 5));
EXPECT_FALSE(MemoryExists(q));
}
// clang-format off
TEST(munmap, tinyFile_mapThriceUnmapOnce) {
char *p;
ASSERT_SYS(0, 3, open("doge", O_RDWR | O_CREAT | O_TRUNC, 0644));
ASSERT_SYS (0, 5, write(3, "hello", 5));
ASSERT_NE(MAP_FAILED, (p=mmap(0, FRAMESIZE, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0)));
ASSERT_NE(MAP_FAILED, mmap(p+FRAMESIZE*1, 5, PROT_READ, MAP_PRIVATE, 3, 0));
ASSERT_NE(MAP_FAILED, mmap(p+FRAMESIZE*3, 5, PROT_READ, MAP_PRIVATE, 3, 0));
ASSERT_SYS(0, 0, close(3));
EXPECT_TRUE(MemoryExists(p+FRAMESIZE*0));
EXPECT_TRUE(MemoryExists(p+FRAMESIZE*1));
EXPECT_FALSE(MemoryExists(p+FRAMESIZE*2));
EXPECT_TRUE(MemoryExists(p+FRAMESIZE*3));
EXPECT_SYS(0, 0, munmap(p, FRAMESIZE*5));
EXPECT_FALSE(MemoryExists(p+FRAMESIZE*0));
EXPECT_FALSE(MemoryExists(p+FRAMESIZE*1));
EXPECT_FALSE(MemoryExists(p+FRAMESIZE*2));
EXPECT_FALSE(MemoryExists(p+FRAMESIZE*3));
}
// clang-format on

View file

@ -15,6 +15,7 @@
See the License for the specific language governing permissions and
limitations under the License.
*/
#include "libc/nexgen32e/x86feature.h"
#include "third_party/mbedtls/cipher.h"
#include "third_party/mbedtls/common.h"
#include "third_party/mbedtls/platform.h"
@ -44,10 +45,6 @@ asm(".include \"libc/disclaimer.inc\"");
#if defined(MBEDTLS_SSL_TLS_C)
const uint16_t ciphersuite_preference[] =
{
#if defined(MBEDTLS_SSL_CIPHERSUITES)
MBEDTLS_SSL_CIPHERSUITES,
#else
#ifdef MBEDTLS_KEY_EXCHANGE_SOME_PFS_ENABLED
MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
@ -175,7 +172,141 @@ const uint16_t ciphersuite_preference[] =
MBEDTLS_TLS_PSK_WITH_NULL_SHA,
#endif
#endif /* MBEDTLS_SSL_CIPHERSUITES */
0
};
// if we don't have aes-ni then chacha will do a
// better job guarding against timing attacks
const uint16_t ciphersuite_preference_nehalem[] =
{
#ifdef MBEDTLS_KEY_EXCHANGE_SOME_PFS_ENABLED
MBEDTLS_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
#endif
#ifdef MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED
MBEDTLS_TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256,
MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_GCM_SHA384,
MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_GCM_SHA256,
MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CCM_SHA256,
#endif
#ifdef MBEDTLS_KEY_EXCHANGE_SOME_PFS_ENABLED
MBEDTLS_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
MBEDTLS_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384,
MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM,
MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM,
MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,
MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,
MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,
#endif
#ifdef MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED
MBEDTLS_TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256,
MBEDTLS_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384,
MBEDTLS_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256,
MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384,
MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256,
MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384,
MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256,
#endif
#ifdef MBEDTLS_KEY_EXCHANGE_SOME_PFS_ENABLED
MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
#endif
#ifdef MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED
MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA,
MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA,
MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA,
MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA,
#endif
#ifdef MBEDTLS_KEY_EXCHANGE_SOME_NON_PFS_ENABLED
MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384,
MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256,
MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384,
MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256,
MBEDTLS_TLS_RSA_WITH_AES_256_GCM_SHA384,
MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256,
MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384,
MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256,
MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256,
MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA256,
MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,
MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,
MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA,
MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA,
#endif
#ifdef MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED
MBEDTLS_TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256,
MBEDTLS_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384,
MBEDTLS_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256,
MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384,
MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256,
MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA,
MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA,
MBEDTLS_TLS_PSK_WITH_CHACHA20_POLY1305_SHA256,
MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384,
MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256,
MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA384,
MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA,
MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA256,
MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA,
#endif
#ifdef MBEDTLS_DES_C
MBEDTLS_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
MBEDTLS_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA,
MBEDTLS_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA,
MBEDTLS_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA,
MBEDTLS_TLS_RSA_WITH_3DES_EDE_CBC_SHA, // e.g. IE 8 XP
MBEDTLS_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,
MBEDTLS_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA,
MBEDTLS_TLS_PSK_WITH_3DES_EDE_CBC_SHA,
#endif
#ifdef MBEDTLS_ENABLE_WEAK_CIPHERSUITES
MBEDTLS_TLS_DHE_RSA_WITH_DES_CBC_SHA,
MBEDTLS_TLS_RSA_WITH_DES_CBC_SHA,
#endif
#ifdef MBEDTLS_CIPHER_NULL_CIPHER
MBEDTLS_TLS_ECDHE_ECDSA_WITH_NULL_SHA,
MBEDTLS_TLS_ECDHE_RSA_WITH_NULL_SHA,
MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA384,
MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA256,
MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA,
MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA384,
MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA256,
MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA,
MBEDTLS_TLS_RSA_WITH_NULL_SHA256,
MBEDTLS_TLS_RSA_WITH_NULL_SHA,
MBEDTLS_TLS_RSA_WITH_NULL_MD5,
MBEDTLS_TLS_ECDH_RSA_WITH_NULL_SHA,
MBEDTLS_TLS_ECDH_ECDSA_WITH_NULL_SHA,
MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA384,
MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA256,
MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA,
MBEDTLS_TLS_PSK_WITH_NULL_SHA384,
MBEDTLS_TLS_PSK_WITH_NULL_SHA256,
MBEDTLS_TLS_PSK_WITH_NULL_SHA,
#endif
0
};
@ -1338,12 +1469,6 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
0, 0, 0, 0, 0 }
};
#if defined(MBEDTLS_SSL_CIPHERSUITES)
const uint16_t *mbedtls_ssl_list_ciphersuites( void )
{
return( ciphersuite_preference );
}
#else
#define MAX_CIPHERSUITES sizeof( ciphersuite_definitions ) / \
sizeof( ciphersuite_definitions[0] )
static uint16_t supported_ciphersuites[MAX_CIPHERSUITES];
@ -1375,7 +1500,12 @@ const uint16_t *mbedtls_ssl_list_ciphersuites( void )
const uint16_t *p;
uint16_t *q;
for( p = ciphersuite_preference, q = supported_ciphersuites;
if( X86_HAVE( AES ) )
p = ciphersuite_preference;
else
p = ciphersuite_preference_nehalem;
for( q = supported_ciphersuites;
*p != 0 && q < supported_ciphersuites + MAX_CIPHERSUITES - 1;
p++ )
{
@ -1393,7 +1523,6 @@ const uint16_t *mbedtls_ssl_list_ciphersuites( void )
return( supported_ciphersuites );
}
#endif /* MBEDTLS_SSL_CIPHERSUITES */
const mbedtls_ssl_ciphersuite_t *mbedtls_ssl_ciphersuite_from_string(
const char *ciphersuite_name )

View file

@ -7605,6 +7605,7 @@ static uint16_t ssl_preset_suiteb_ciphersuites[] = {
MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,
MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_GCM_SHA384,
0
};

View file

@ -1984,8 +1984,8 @@ _PyMem_DebugRawAlloc(int use_calloc, void *ctx, size_t nbytes)
_PyMem_DebugCheckAddress(api->api_id, p+2*SST);
if (IsAsan()) {
__asan_poison((uintptr_t)(p + SST + 1), SST-1, kAsanHeapUnderrun);
__asan_poison((uintptr_t)tail, SST, kAsanHeapOverrun);
__asan_poison((p + SST + 1), SST-1, kAsanHeapUnderrun);
__asan_poison(tail, SST, kAsanHeapOverrun);
}
return p + 2*SST;
@ -2041,7 +2041,7 @@ _PyMem_DebugRawFree(void *ctx, void *p)
nbytes += 4*SST;
if (nbytes > 0) {
if (IsAsan()) {
__asan_unpoison((uintptr_t)q, nbytes);
__asan_unpoison(q, nbytes);
}
memset(q, DEADBYTE, nbytes);
}
@ -2080,12 +2080,12 @@ _PyMem_DebugRawRealloc(void *ctx, void *p, size_t nbytes)
tail = q + nbytes;
w = 0x0101010101010101ull * FORBIDDENBYTE;
WRITE64LE(tail, w);
if (IsAsan()) __asan_poison((uintptr_t)tail, SST, kAsanHeapOverrun);
if (IsAsan()) __asan_poison(tail, SST, kAsanHeapOverrun);
write_size_t(tail + SST, serialno);
if (nbytes > original_nbytes) {
/* growing: mark new extra memory clean */
if (IsAsan()) {
__asan_unpoison((uintptr_t)(q + original_nbytes),
__asan_unpoison((q + original_nbytes),
nbytes - original_nbytes);
}
memset(q + original_nbytes, CLEANBYTE,

View file

@ -432,7 +432,7 @@ void HandleClient(void) {
WARNF("%s got unexpected input event from client %#x", exename,
fds[0].revents);
}
WARNF("%s client disconnected so killing worker", exename);
WARNF("%s client disconnected so killing worker %d", exename, child);
LOGIFNEG1(kill(child, 9));
LOGIFNEG1(waitpid(child, 0, 0));
LOGIFNEG1(close(g_clifd));

View file

@ -7064,6 +7064,10 @@ static void TlsInit(void) {
int suite;
if (unsecure) return;
if (suiteb && !X86_HAVE(AES)) {
WARNF("you're using suite b crypto but don't have aes-ni");
}
if (!sslinitialized) {
InitializeRng(&rng);
InitializeRng(&rngcli);

View file

@ -17,6 +17,7 @@
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/bits/bits.h"
#include "libc/intrin/kprintf.h"
#include "libc/log/color.internal.h"
#include "libc/log/log.h"
#include "libc/nexgen32e/cpuid4.internal.h"
@ -92,6 +93,7 @@ void showcachesizes(void) {
int main(int argc, char *argv[]) {
int x;
long tsc_aux;
ShowCrashReports();
showvendor();
showmodel();
@ -106,14 +108,19 @@ int main(int argc, char *argv[]) {
}
if (X86_HAVE(HYPERVISOR)) {
unsigned eax, ebx, ecx, edx;
asm("push\t%%rbx\n\t"
"cpuid\n\t"
"mov\t%%ebx,%1\n\t"
int ax, cx;
char s[4 * 3 + 1];
asm("push\t%%rbx\r\n"
"cpuid\r\n"
"mov\t%%ebx,0+%2\r\n"
"mov\t%%ecx,4+%2\r\n"
"mov\t%%edx,8+%2\r\n"
"movb\t$0,12+%2\r\n"
"pop\t%%rbx"
: "=a"(eax), "=rm"(ebx), "=c"(ecx), "=d"(edx)
: "0"(0x40000000), "2"(0));
printf("Running inside %.4s%.4s%.4s (eax=%#x)\n", &ebx, &ecx, &edx, eax);
: "=a"(ax), "=c"(cx), "=o"(s)
: "0"(0x40000000), "1"(0)
: "rdx");
kprintf("Running inside %s (eax=%#x)\n", s, ax);
}
printf("\n");