• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
No Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

Bintuils with patches for Dreamcast


Commit MetaInfo

Revision25162c795b1a2becf936bb3581d86a307ea491eb (tree)
Time2021-07-16 00:51:56
AuthorNick Clifton <nickc@redh...>
CommiterNick Clifton

Log Message

Fix a stack exhaustion problem in the Rust demangling code in the libiberty library.

PR 99935
* rust-demangle.c: Add recursion limit.

Change Summary

Incremental Difference

--- a/libiberty/ChangeLog
+++ b/libiberty/ChangeLog
@@ -1,3 +1,8 @@
1+2021-07-15 Nick Clifton <nickc@redhat.com>
2+
3+ PR 99935
4+ * rust-demangle.c: Add recursion limit.
5+
16 2021-07-05 Nick Clifton <nickc@redhat.com>
27
38 Reapply this change from commit:
--- a/libiberty/rust-demangle.c
+++ b/libiberty/rust-demangle.c
@@ -74,6 +74,12 @@ struct rust_demangler
7474 /* Rust mangling version, with legacy mangling being -1. */
7575 int version;
7676
77+ /* Recursion depth. */
78+ uint recursion;
79+ /* Maximum number of times demangle_path may be called recursively. */
80+#define RUST_MAX_RECURSION_COUNT 1024
81+#define RUST_NO_RECURSION_LIMIT ((uint) -1)
82+
7783 uint64_t bound_lifetime_depth;
7884 };
7985
@@ -671,6 +677,15 @@ demangle_path (struct rust_demangler *rdm, int in_value)
671677 if (rdm->errored)
672678 return;
673679
680+ if (rdm->recursion != RUST_NO_RECURSION_LIMIT)
681+ {
682+ ++ rdm->recursion;
683+ if (rdm->recursion > RUST_MAX_RECURSION_COUNT)
684+ /* FIXME: There ought to be a way to report
685+ that the recursion limit has been reached. */
686+ goto fail_return;
687+ }
688+
674689 switch (tag = next (rdm))
675690 {
676691 case 'C':
@@ -688,10 +703,7 @@ demangle_path (struct rust_demangler *rdm, int in_value)
688703 case 'N':
689704 ns = next (rdm);
690705 if (!ISLOWER (ns) && !ISUPPER (ns))
691- {
692- rdm->errored = 1;
693- return;
694- }
706+ goto fail_return;
695707
696708 demangle_path (rdm, in_value);
697709
@@ -776,9 +788,15 @@ demangle_path (struct rust_demangler *rdm, int in_value)
776788 }
777789 break;
778790 default:
779- rdm->errored = 1;
780- return;
791+ goto fail_return;
781792 }
793+ goto pass_return;
794+
795+ fail_return:
796+ rdm->errored = 1;
797+ pass_return:
798+ if (rdm->recursion != RUST_NO_RECURSION_LIMIT)
799+ -- rdm->recursion;
782800 }
783801
784802 static void
@@ -1320,6 +1338,7 @@ rust_demangle_callback (const char *mangled, int options,
13201338 rdm.skipping_printing = 0;
13211339 rdm.verbose = (options & DMGL_VERBOSE) != 0;
13221340 rdm.version = 0;
1341+ rdm.recursion = (options & DMGL_NO_RECURSE_LIMIT) ? RUST_NO_RECURSION_LIMIT : 0;
13231342 rdm.bound_lifetime_depth = 0;
13241343
13251344 /* Rust symbols always start with _R (v0) or _ZN (legacy). */