From nobody Sat Sep 23 18:22:35 2023 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4RtHYR3cqsz4v3LJ; Sat, 23 Sep 2023 18:22:35 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4RtHYR2nHNz4l2p; Sat, 23 Sep 2023 18:22:35 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1695493355; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=+bssu/+ds5vU/Ee3/WYrc8sNYgsBZinLKMaglI/4Es4=; b=gXOxgS+mIIxMA5vKai/ZKaoZhEYlIjDBHH13xlofsVFJl/el27yu58MlmLmtNPdMDYd+dN vxe1rY9D0aJ+tEG1CfWx2Mc+gJfjNNJ56dBC3OOBzMAfPHXDUhxfKiqYMaPlfgKxJDL7dG g66JBPvI72wG+tBk6jkTtjkANYlXG78iE40LUx04bIf14M4EmQ+oogQ67yUtCwSq7fbaw2 DhqpdxXlrcL69dNcckQLndN6Q3t41EcYrCoIE6jxXmM+DIu6PWrIC5PnBq696Ci26fz/NQ aHuXdgTHNXR/U0/dWpsyBwYI4sYRkQ4MQso/FLWz3J9QT5xzPmYQTD65ZxqGOQ== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1695493355; a=rsa-sha256; cv=none; b=WZY20xoslteotviXa4K8mRGRQGUmVaXujODIPg+8rABwC/HoY0BljY8by/iDI+E1SRZ3up vjDH3RImnWbqKesUQB3mQViVVBfsAMS8LdlZgUZ3k8aQ42qnuU5BCAvS0Ht7uX+AfrRocn 53IsvKn167oQUkForWZ61ZRdK2xSjA78ixiDybjlZ1iTUqSJmuHVzFzY9sezTS+PdsbIEb Y6SHvlur32HqL/poF55I11PrPGyoT9N/UfIHFG8h0OKN/+QG6db1XmIU8WzYa1svTVymZa ajLqTVsbziwimGkEmpOOM5xR8HQPhfkur5XIRKKzisvr6rZ0HH8GR8AxlOOwLA== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1695493355; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=+bssu/+ds5vU/Ee3/WYrc8sNYgsBZinLKMaglI/4Es4=; b=ixy9s3ssbegqMWAzd6c72KjAi+yIZq5q5WEzHAELmSX9ePhqsfkM/PPDKQI2PTKAFGokTE pq1xAsk27B8pkXH0JbSByw5Boi5nxpA8tfmA4PORAH0PCZEfOHbUnUyS4BGkQ06YKIgu0g mFF9SHeUh+7+jwMfK8wGet1+AUaGxb3eK1xyawz2k0iOeBedzN5xd0xnLRrnUidSZA76ZV bq5SoMT8z04ev6Lxc7AwyeybcDgX6haP7FzYe0PG7XIG0N5Z3XjMsasQNpE9oyEAQbWQ+Z zswP9SZrvm49FSaNAc03noi+SuQuY9R69Ce82vruhoKDxzdFhBZvCMPj8RZQmQ== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4RtHYR1Ynfzw9; Sat, 23 Sep 2023 18:22:35 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.17.1/8.17.1) with ESMTP id 38NIMZrs004235; Sat, 23 Sep 2023 18:22:35 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.17.1/8.17.1/Submit) id 38NIMZlO004232; Sat, 23 Sep 2023 18:22:35 GMT (envelope-from git) Date: Sat, 23 Sep 2023 18:22:35 GMT Message-Id: <202309231822.38NIMZlO004232@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Robert Clausecker Subject: git: 0666c6fc0322 - stable/14 - lib/libc/amd64/string/memcmp.S: harden against phony buffer lengths List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-all@freebsd.org X-BeenThere: dev-commits-src-all@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: fuz X-Git-Repository: src X-Git-Refname: refs/heads/stable/14 X-Git-Reftype: branch X-Git-Commit: 0666c6fc0322e0a4912288cd8b02213d52b2a9ce Auto-Submitted: auto-generated The branch stable/14 has been updated by fuz: URL: https://cgit.FreeBSD.org/src/commit/?id=0666c6fc0322e0a4912288cd8b02213d52b2a9ce commit 0666c6fc0322e0a4912288cd8b02213d52b2a9ce Author: Robert Clausecker AuthorDate: 2023-09-14 05:19:01 +0000 Commit: Robert Clausecker CommitDate: 2023-09-23 18:21:42 +0000 lib/libc/amd64/string/memcmp.S: harden against phony buffer lengths When memcmp(a, b, len) (or equally, bcmp) is called with a phony length such that a + len < a, the code would malfunction and not compare the two buffers correctly. While such arguments are illegal (buffers do not wrap around the end of the address space), it is neverthless conceivable that people try things like memcmp(a, b, SIZE_MAX) to compare a and b until the first mismatch, in the knowledge that such a mismatch exists, expecting memcmp() to stop comparing somewhere around the mismatch. While memcmp() is usually written to confirm to this assumption, no version of ISO/IEC 9899 guarantees this behaviour (in contrast to memchr() for which it is). Neverthless it appears sensible to at least not grossly misbehave on phony lengths. This change hardens memcmp() against this case by comparing at least until the end of the address space if a + len overflows a 64 bit integer. Sponsored by: The FreeBSD Foundation Approved by: mjg (blanket, via IRC) See also: b2618b651b28fd29e62a4e285f5be09ea30a85d4 MFC after: 1 week (cherry picked from commit 953b93cf24d8871c62416c9bcfca935f1f1853b6) --- lib/libc/amd64/string/memcmp.S | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/lib/libc/amd64/string/memcmp.S b/lib/libc/amd64/string/memcmp.S index d192229677b3..dc8bcff73cb9 100644 --- a/lib/libc/amd64/string/memcmp.S +++ b/lib/libc/amd64/string/memcmp.S @@ -328,13 +328,28 @@ ARCHENTRY(memcmp, baseline) movdqu 16(%rsi, %rdi, 1), %xmm1 pcmpeqb 16(%rdi), %xmm1 # compare second half of this iteration add %rcx, %rdx # pointer to last byte in buffer - pcmpeqb %xmm2, %xmm0 + jc .Loverflow # did this overflow? +0: pcmpeqb %xmm2, %xmm0 pmovmskb %xmm0, %eax xor $0xffff, %eax # any mismatch? jne .Lmismatch_head add $64, %rdi # advance to next iteration jmp 1f # and get going with the loop + /* + * If we got here, a buffer length was passed to memcmp(a, b, len) + * such that a + len < a. While this sort of usage is illegal, + * it is plausible that a caller tries to do something like + * memcmp(a, b, SIZE_MAX) if a and b are known to differ, intending + * for memcmp() to stop comparing at the first mismatch. This + * behaviour is not guaranteed by any version of ISO/IEC 9899, + * but usually works out in practice. Let's try to make this + * case work by comparing until the end of the address space. + */ +.Loverflow: + mov $-1, %rdx # compare until the end of memory + jmp 0b + /* process buffer 32 bytes at a time */ ALIGN_TEXT 0: movdqu -32(%rsi, %rdi, 1), %xmm0