Bounds checking
In der Programmierung ist Grenzüberprüfung oder bounds checking jede Methode, bei der überprüft wird, ob der Wert einer Variablen innerhalb bestimmter Grenzen ist, bevor sie verwendet wird. Diese Methoden werden normalerweise angewendet, um entweder zu überprüfen, dass eine Zahl den Wertebereich eines bestimmten Datentyps nicht überschreitet (Wertebereichsüberprüfung), oder dass eine Variable, die zum Indizieren eines Arrays verwendet wird, nicht außerhalb des Arrays zeigt (Indexüberprüfung). Ist die Variable nicht innerhalb der Grenzen, wird normalerweise eine Ausnahmebehandlung gestartet.
Da das Überprüfen der Grenzen oft zeitaufwendig ist, wird zum Beispiel bei der Optimierung von Compilern auf das Vermeiden von Grenzüberprüfung geachtet.
Wertebereichsüberprüfung
BearbeitenBei der Wertebereichsüberprüfung wird darauf geachtet, dass eine Zahl innerhalb eines bestimmten Wertebereiches ist, zum Beispiel, dass eine Ganzzahl von einem 16-Bit-Ganzzahltypen aufgenommen werden kann. (z. B. Arithmetischer Überlauf). Dies ist nicht das gleiche wie Typenüberprüfung. Andere Wertebereiche sind in anderer Weise restriktiv. Wenn zum Beispiel eine Variable die Nummer eines Monats im Jahr speichern soll, dann darf sie nur die Zahlen von 1 bis 12 aufnehmen.
Indexüberprüfung
BearbeitenBei der Indexüberprüfung werden bei allen Ausdrücken, bei denen in einem Array indiziert wird, der Index gegen die Grenzen des Arrays (die bei der Deklaration des Arrays festgelegt wurden) getestet. Wenn der Index nicht innerhalb der Grenzen ist, wird ein „Out-of-bounds“-Fehler ausgelöst. Das Lesen oder Schreiben außerhalb der Grenzen eines Arrays kann zu Fehlfunktionen und Abstürzen des Programms führen. Es kann auch zu einer Vielzahl von Sicherheitsrisiken (siehe auch Pufferüberlauf) führen, daher ist dynamische Indexüberprüfung eine gängige Praxis in vielen höheren Programmiersprachen.
Frühe Programmiersprachen mit Indexüberprüfung sind Algol 60, Algol 68 und Pascal (kompiliert), so wie auch die Skriptsprache BASIC.
Viele Programmiersprachen wie zum Beispiel C verwenden nie automatische Indexüberprüfungen, um die Laufzeit zu verringern. Dadurch bleiben viele Off-by-One-Fehler oder Pufferüberläufe unbemerkt. Es stellt sich die Frage, ob dies ein zu großes Opfer für die Beschleunigung der Programme ist.[1] Etablierte Programmiersprachen, die Laufzeitüberprüfung unterstützen, sind Ada, C#, Haskell, Java, JavaScript, Lisp, PHP, Python, Ruby, Rust, und Visual Basic. C++, D und OCaml haben Compiler switches, um Grenzüberprüfungen während der Laufzeit zu aktivieren. C# hat außerdem sogenannte „unsafe regions“. Das sind Sektionen des Codes, in dem für eine höhere Effizienz unter anderem keine Grenzüberprüfungen durchgeführt werden. Dadurch kann an besonders kritischen Stellen Zeit gewonnen werden, ohne das gesamte Programm zu gefährden.
Die JS++ Programmiersprache ist in der Lage mithilfe von „existent types“, einem nominellen Typ, der beschreibt, ob der Index innerhalb der Grenzen ist oder nicht, während der Kompilierung zu überprüfen, ob ein Index in den erlaubten Grenzen ist. Es hat sich gezeigt, dass „existent types“ die Kompilierzeit nur um 1 ms verlängern.[2]
Hardware bounds checking
BearbeitenDie Sicherheit, die durch Grenzüberprüfung hinzukommt, kostet CPU-Zeit, die allerdings wegfällt, wenn die Überprüfung nicht durch die Software, sondern durch Hardware durchgeführt wird. Eins der ersten Systeme mit Hardware bounds checking war das ICL 2900 Series Mainframe (angekündigt in 1974).[3]
Der VAX Computer hat einen INDEX
Assembly-Befehl für Array-Indexüberprüfung der sechs Operanden akzeptiert, von denen alle jeden beliebigen VAX-Adressierungsmodus verwenden können. Der B6500 und auch Burroughs-Computer führten Grenzüberprüfungen durch, wenn eine Sprache verwendet wurde, die Assembly-Code erzeugte. Eine begrenzte Anzahl von CPUs haben später spezielle Befehle für Grenzüberprüfungen, z. B. der CHK2-Befehl für die Motorola 68000-Serie.
Seit 2005 gibt es Forschungen zu Methoden, um die integrierte virtuellen Speicherverwaltungseinheit von x86 für die Sicherheit von Array-Indizierung und Pufferzugriff zu erhöhen.[4] In 2015 brachte Intel die Erweiterung Intel MPX für ihre Skylake-Architektur auf den Markt, die die Grenzen in einem CPU-Register und einer Tabelle im Speicher nutzt. Seit 2017 werden MPX-Erweiterungen von GCC unterstützt.
Weblinks
Bearbeiten- “On The Advantages Of Tagged Architecture”, IEEE Transactions On Computers, Volume C-22, Number 7, July, 1973.
- “The Emperor’s Old Clothes ( vom 2. Oktober 2017 im Internet Archive)”, The 1980 ACM Turing Award Lecture, CACM volume 24 number 2, February 1981, pp 75–83.
- “Bcc: Runtime checking for C programs”, Samuel C. Kendall, Proceedings of the USENIX Summer 1983 Conference.
- “Bounds Checking for C”, Richard Jones and Paul Kelly, Imperial College, July 1995.
- “ClearPath Enterprise Servers MCP Security Overview”, Unisys, April 2006.
- “Secure Virtual Architecture: A Safe Execution Environment for Commodity Operating Systems”, John Criswell, Andrew Lenharth, Dinakar Dhurjati, Vikram Adve, SOSP'07 21st ACM Symposium on Operating Systems Principles, 2007.
- “Fail-Safe C”, Yutaka Oiwa. Implementation of the Memory-safe Full ANSI-C Compiler. ACM SIGPLAN Conference on Programming Language Design and Implementations (PLDI2009), June 2009.
- “address-sanitizer”, Timur Iskhodzhanov, Alexander Potapenko, Alexey Samsonov, Kostya Serebryany, Evgeniy Stepanov, Dmitriy Vyukov, LLVM Dev Meeting, November 18, 2011.
- Safe C Library of Bounded APIs
- The Safe C Library. In: Dr. Dobb’s Journal. 20. Februar 2009 (englisch, drdobbs.com ( des vom 2. Dezember 2013 im Internet Archive) [abgerufen am 13. November 2012]).
- Safe C API—Concise solution of buffer overflow, The OWASP Foundation, OWASP AppSec, Beijing 2011
- The GNU C++ Library Manual Macros
- libc++ 11.0 documentation Debug Mode
Einzelnachweise
Bearbeiten- ↑ C. Cowan, F. Wagle, F. Calton Pu, S. Beattie, J. Walpole: Proceedings DARPA Information Survivability Conference and Exposition. DISCEX'00. Band 2. IEEE, 1999, ISBN 978-0-7695-0490-2, Buffer overflows: Attacks and defenses for the vulnerability of the decade, S. 119–129, doi:10.1109/DISCEX.2000.821514 (englisch).
- ↑ JS++ 0.9.0: Efficient Compile Time Analysis of Out-of-Bounds Errors – JS++ Blog. Abgerufen am 7. November 2023 (englisch).
- ↑ J. K. Buckle: The ICL 2900 Series. Macmillan Computer Science Series, 1978, ISBN 978-0-333-21917-1, S. 17, 77 (englisch, fujitsu.com ( des vom 20. April 2018 im Internet Archive) [abgerufen am 20. April 2018]).
- ↑ Lap-Chung Lam, Tzi-Cker Chiueh: 2005 International Conference on Dependable Systems and Networks (DSN'05). 2005, ISBN 0-7695-2282-3, Checking Array Bound Violation Using Segmentation Hardware, S. 388–397, doi:10.1109/DSN.2005.25 (englisch).