Skip to content

Commit

Permalink
Merge pull request #1425 from torben-hansen/upstream-merge-2024-01-29
Browse files Browse the repository at this point in the history
Upstream merge 2024 01 29
  • Loading branch information
torben-hansen authored Jan 31, 2024
2 parents b49958a + 1214025 commit 13708de
Show file tree
Hide file tree
Showing 9 changed files with 2,559 additions and 2,565 deletions.
86 changes: 45 additions & 41 deletions crypto/test/abi_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -88,43 +88,6 @@ static void ForEachMismatch(const CallerState &a, const CallerState &b,
LOOP_CALLER_STATE_REGISTERS()
#undef CALLER_STATE_REGISTER
}

// ReadUnwindResult adds the results of the most recent unwind test to |out|.
static void ReadUnwindResult(Result *out);

crypto_word_t RunTrampoline(Result *out, crypto_word_t func,
const crypto_word_t *argv, size_t argc,
bool unwind) {
CallerState state;
RAND_bytes(reinterpret_cast<uint8_t *>(&state), sizeof(state));

unwind &= g_unwind_tests_enabled;
CallerState state2 = state;
crypto_word_t ret = abi_test_trampoline(func, &state2, argv, argc, unwind);
#if defined(OPENSSL_X86_64) || defined(OPENSSL_X86)
// Query and clear the direction flag early, so negative tests do not
// interfere with |malloc|.
bool direction_flag = abi_test_get_and_clear_direction_flag();
#endif // OPENSSL_X86_64 || OPENSSL_X86

*out = Result();
ForEachMismatch(state, state2, [&](const char *reg) {
out->errors.push_back(std::string(reg) + " was not restored after return");
});
#if defined(OPENSSL_X86_64) || defined(OPENSSL_X86)
// Linux and Windows ABIs for x86 require the direction flag be cleared on
// return. (Some OpenSSL assembly preserves it, which is stronger, but we only
// require what is specified by the ABI so |CHECK_ABI| works with C compiler
// output.)
if (direction_flag) {
out->errors.emplace_back("Direction flag set after return");
}
#endif // OPENSSL_X86_64 || OPENSSL_X86
if (unwind) {
ReadUnwindResult(out);
}
return ret;
}
#endif // SUPPORTS_ABI_TEST

#if defined(SUPPORTS_UNWIND_TEST)
Expand Down Expand Up @@ -473,8 +436,8 @@ static bool g_in_trampoline = false;
// g_unwind_function_done, if |g_in_trampoline| is true, is whether the function
// under test has returned. It is undefined otherwise.
static bool g_unwind_function_done;
// g_trampoline_state, if |g_in_trampoline| is true, is the state the function
// under test must preserve. It is undefined otherwise.
// g_trampoline_state, during an unwind-enabled ABI test, is the state the
// function under test must preserve. It is undefined otherwise.
static CallerState g_trampoline_state;
// g_trampoline_sp, if |g_in_trampoline| is true, is the stack pointer of the
// trampoline frame. It is undefined otherwise.
Expand Down Expand Up @@ -535,8 +498,6 @@ static void CheckUnwind(UnwindCursor *cursor) {
g_in_trampoline = true;
g_unwind_function_done = false;
g_trampoline_sp = sp;
g_trampoline_state = cursor->GetCallerState().ValueOrDie(
"Error getting initial caller state");
} else {
if (sp == g_trampoline_sp || g_unwind_function_done) {
// |g_unwind_function_done| should imply |sp| is |g_trampoline_sp|, but
Expand Down Expand Up @@ -607,6 +568,7 @@ static void CheckUnwind(UnwindCursor *cursor) {
}
}

// ReadUnwindResult adds the results of the most recent unwind test to |out|.
static void ReadUnwindResult(Result *out) {
for (size_t i = 0; i < g_num_unwind_errors; i++) {
#if defined(OPENSSL_WINDOWS)
Expand Down Expand Up @@ -783,6 +745,48 @@ static void EnableUnwindTestsImpl() {}

#endif // SUPPORTS_UNWIND_TEST

#if defined(SUPPORTS_ABI_TEST)
crypto_word_t RunTrampoline(Result *out, crypto_word_t func,
const crypto_word_t *argv, size_t argc,
bool unwind) {
CallerState state;
RAND_bytes(reinterpret_cast<uint8_t *>(&state), sizeof(state));

unwind &= g_unwind_tests_enabled;
#if defined(SUPPORTS_UNWIND_TEST)
if (unwind) {
// Save the caller state for the unwind tester to check for.
g_trampoline_state = state;
}
#endif
CallerState state2 = state;
crypto_word_t ret = abi_test_trampoline(func, &state2, argv, argc, unwind);
#if defined(OPENSSL_X86_64) || defined(OPENSSL_X86)
// Query and clear the direction flag early, so negative tests do not
// interfere with |malloc|.
bool direction_flag = abi_test_get_and_clear_direction_flag();
#endif // OPENSSL_X86_64 || OPENSSL_X86

*out = Result();
ForEachMismatch(state, state2, [&](const char *reg) {
out->errors.push_back(std::string(reg) + " was not restored after return");
});
#if defined(OPENSSL_X86_64) || defined(OPENSSL_X86)
// Linux and Windows ABIs for x86 require the direction flag be cleared on
// return. (Some OpenSSL assembly preserves it, which is stronger, but we only
// require what is specified by the ABI so |CHECK_ABI| works with C compiler
// output.)
if (direction_flag) {
out->errors.emplace_back("Direction flag set after return");
}
#endif // OPENSSL_X86_64 || OPENSSL_X86
if (unwind) {
ReadUnwindResult(out);
}
return ret;
}
#endif // SUPPORTS_ABI_TEST

} // namespace internal

void EnableUnwindTests() { internal::EnableUnwindTestsImpl(); }
Expand Down
11 changes: 8 additions & 3 deletions include/openssl/target.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,13 +82,18 @@
#define OPENSSL_WINDOWS
#endif

// Trusty and Android baremetal aren't't Linux but currently define __linux__.
// As a workaround, we exclude them here.
// Trusty and Android baremetal aren't Linux but currently define __linux__.
// As a workaround, we exclude them here. We also exclude nanolibc. nanolibc
// sometimes build for a non-Linux target (which should not define __linux__),
// but also sometimes build for Linux. Although technically running in Linux
// userspace, this lacks all the libc APIs we'd normally expect on Linux, so we
// treat it as a non-Linux target.
//
// TODO(b/169780122): Remove this workaround once Trusty no longer defines it.
// TODO(b/291101350): Remove this workaround once Android baremetal no longer
// defines it.
#if defined(__linux__) && !defined(__TRUSTY__) && !defined(ANDROID_BAREMETAL)
#if defined(__linux__) && !defined(__TRUSTY__) && \
!defined(ANDROID_BAREMETAL) && !defined(OPENSSL_NANOLIBC)
#define OPENSSL_LINUX
#endif

Expand Down
71 changes: 55 additions & 16 deletions util/fipstools/delocate/delocate.go
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,47 @@ func (d *delocation) processDirective(statement, directive *node32) (*node32, er
return statement, nil
}

func (d *delocation) processSymbolExpr(expr *node32, b *strings.Builder) bool {
changed := false
assertNodeType(expr, ruleSymbolExpr)

for expr != nil {
atom := expr.up
assertNodeType(atom, ruleSymbolAtom)

for term := atom.up; term != nil; term = skipWS(term.next) {
if term.pegRule == ruleSymbolExpr {
changed = d.processSymbolExpr(term, b) || changed
continue
}

if term.pegRule != ruleLocalSymbol {
b.WriteString(d.contents(term))
continue
}

oldSymbol := d.contents(term)
newSymbol := d.mapLocalSymbol(oldSymbol)
if newSymbol != oldSymbol {
changed = true
}

b.WriteString(newSymbol)
}

next := skipWS(atom.next)
if next == nil {
break
}
assertNodeType(next, ruleSymbolOperator)
b.WriteString(d.contents(next))
next = skipWS(next.next)
assertNodeType(next, ruleSymbolExpr)
expr = next
}
return changed
}

func (d *delocation) processLabelContainingDirective(statement, directive *node32) (*node32, error) {
// The symbols within directives need to be mapped so that local
// symbols in two different .s inputs don't collide.
Expand All @@ -317,24 +358,12 @@ func (d *delocation) processLabelContainingDirective(statement, directive *node3
for node = skipWS(node.up); node != nil; node = skipWS(node.next) {
assertNodeType(node, ruleSymbolArg)
arg := node.up
var mapped string
assertNodeType(arg, ruleSymbolExpr)

for term := arg; term != nil; term = term.next {
if term.pegRule != ruleLocalSymbol {
mapped += d.contents(term)
continue
}

oldSymbol := d.contents(term)
newSymbol := d.mapLocalSymbol(oldSymbol)
if newSymbol != oldSymbol {
changed = true
}

mapped += newSymbol
}
var b strings.Builder
changed = d.processSymbolExpr(arg, &b) || changed

args = append(args, mapped)
args = append(args, b.String())
}

if !changed {
Expand Down Expand Up @@ -1722,6 +1751,16 @@ func writeAarch64Function(w stringWriter, funcName string, writeContents func(st
w.WriteString(".type " + funcName + ", @function\n")
w.WriteString(funcName + ":\n")
w.WriteString(".cfi_startproc\n")
// We insert a landing pad (`bti c` instruction) unconditionally at the beginning of
// every generated function so that they can be called indirectly (with `blr` or
// `br x16/x17`). The instruction is encoded in the HINT space as `hint #34` and is
// a no-op on machines or program states not supporting BTI (Branch Target Identification).
// None of the generated function bodies call other functions (with bl or blr), so we only
// insert a landing pad instead of signing and validating $lr with `paciasp` and `autiasp`.
// Normally we would also generate a .note.gnu.property section to annotate the assembly
// file as BTI-compatible, but if the input assembly files are BTI-compatible, they should
// already have those sections so there is no need to add an extra one ourselves.
w.WriteString("\thint #34 // bti c\n")
writeContents(w)
w.WriteString(".cfi_endproc\n")
w.WriteString(".size " + funcName + ", .-" + funcName + "\n")
Expand Down
16 changes: 6 additions & 10 deletions util/fipstools/delocate/delocate.peg
Original file line number Diff line number Diff line change
Expand Up @@ -47,18 +47,14 @@ QuotedText <- (EscapedChar / [^"])*
LabelContainingDirective <- LabelContainingDirectiveName WS SymbolArgs
LabelContainingDirectiveName <- ".xword" / ".word" / ".long" / ".set" / ".byte" / ".8byte" / ".4byte" / ".quad" / ".tc" / ".localentry" / ".size" / ".type" / ".uleb128" / ".sleb128"
SymbolArgs <- SymbolArg ((WS? ',' WS?) SymbolArg)*
SymbolShift <- ('<<' / '>>') WS? [0-9]+
SymbolArg <- (OpenParen WS?)? (
Offset /
SymbolType /
(Offset / LocalSymbol / SymbolName / Dot) (WS? Operator WS? (Offset / LocalSymbol / SymbolName))* /
LocalLabelRef WS? Operator WS? LocalLabelRef /
LocalSymbol TCMarker? /
SymbolName Offset /
SymbolName TCMarker?)
(WS? CloseParen)? (WS? SymbolShift)?
SymbolArg <- SymbolExpr
SymbolExpr <- SymbolAtom (WS? SymbolOperator WS? SymbolExpr)?
SymbolAtom <- Offset / SymbolType / LocalLabelRef / LocalSymbol TCMarker? / SymbolName Offset / SymbolName TCMarker? / Dot / OpenParen WS? SymbolExpr WS? CloseParen
SymbolOperator <- '+' / '-' / '|' / '<<' / '>>'

OpenParen <- '('
CloseParen <- ')'

SymbolType <- [@%] ('function' / 'object')
Dot <- '.'
TCMarker <- '[TC]'
Expand Down
Loading

0 comments on commit 13708de

Please sign in to comment.