Προσωπικά δεν μου αρέσουν οι διαφάνειες γι' αυτον ακριβώς τον λόγο -- εάν κάτι το βλέπεις για πρώτη φορά σου μένουν περισσότερες ερωτήσεις απ' ότι πριν

.
Master_ex έγραψε:Το overhead είναι 1.46x-10x το οποίο σε κάποιες περιπτώσεις είναι αμελητέο αλλά σε άλλες δεν είναι, ανάλογα πάντα για τι συστήματα μιλάμε.
Επίσης σύμφωνα με τις δοκιμές σου σε JS engines π.χ. το overhead είναι μεγαλύτερο.
Το overhead του libdft είναι συνάρτηση δυο παραγόντων:
- instrumentation overhead
- tracking overhead
To instrumentation overhead σχετίζεται με το να κάνεις inspect ένα instruction, να δεις τι operands έχει, τι sizes έχουν τα operands, κλπ, αλλά και με το recompilation που γίνεται at runtime. Φαντάσου το instruction
mov %eax, $0xbffff987. Ουσιαστικά λες ότι πρόκειται για ένα
transfer instruction (register to memory) και ότι τα sizes των operands είναι 1 word (32 bit). Όλο αυτό γίνεται dynamically, δηλαδή καθώς "τρέχει" ένα process. Αφού βρήκες ότι πρόκειται για ένα transfer, θέλεις να πας και να βάλεις λίγο extra code πίσω απο αυτό το instruction ώστε να κάνει propagate τα tags (meta-information) απο τον
shadow register στα 4 bytes της
shadow memory. Αυτός ό κώδικας που βάζεις σε κάθε περίπτωση πίσω απο κάθε instruction είναι αυτό που λέμε
DFT logic, και επειδή είναι κώδικας, τρώει cycles, που σημαίνει additional computation time. Αυτό είναι το tracking overhead. Το όλο θέμα, ερευνητικά, είναι πως μπορείς/πρέπει να είναι η δομή του DFT logic code ώστε να μπορέσεις να κάνεις minimize το slowdown. Επειδή ο κώδικας αυτός γίνεται dynamically recompiled με τον original code, υπάρχουν πράγματα που εάν τα κάνεις το slowdown ανεβαίνει πολυ. Για παράδειγμα, μιας και στο x86 έχεις μόνο 8 general purpose registers, εάν το DFT logic είναι αρκετά complex τότε δεν έχεις registers άλλους να χρησιμοποιήσεις και αντί να κάνεις inline τον additional code με τον original, κάνεις ένα function call -- φαντάσου τι γίνεται εάν πριν απο κάθε assembly instruction έχει ένα ολόκληρο function call (save registers, context switch, etc)! Ομοίως δεν είναι καλό να χρησιμοποιείς branches (if statements) γιατί αυτά πειράζουν τον EFLAGS, που πολύ απλά σημαίνει πάλι function call. Αν και είναι λίγο δύσκολο να περιγράψω research findings ενός χρόνου σε μια παράγραφο, το παραπάνω είναι representative πιστεύω του τι γίνεται under the hood.
Τώρα σχετικά με το measured overhead, η κατάσταση έχει ως εξής. Όσο περισσότερο I/O bound είναι ένα application, τόσο περισσότερο κρύβεται το
observed slowdown γιατί το application "περιμένει" το OS να εξυπηρετήσει τα requests του. Απο την άλλη, όσο περισσότερο CPU bound είναι ένα application, τόσο πιο εμφανές θα είναι το slowdown. Το ~50% (1.46x) overhead το πετυχαίνουμε σε applications σαν τον Apache που είναι για εμάς
best case scenarios. Απο την άλλη εάν πας στο bzip, το οποίο έχει CPU time 98% (κοινώς μόνο το 2% του χρόνου του έκανε I/O), τότε το observed slowdown είναι το
worst case και είναι ~7.5x. Τα μεγαλύτερα slodowns, πχ στο scp, είναι γιατί εκεί έχεις στρεσάρει και το I/O αλλά και το CPU at the same time -- λόγο DFT σε crypto operations και gigabit link. Τέλος το κομμάτι στο οποίο αναφέρεσαι είναι ένα ιδιαίτερο case:
runtime environments. Μόνο και μόνο το nullpin στην JS δίνει ~6x slowdown, συνεπώς τα cases αυτά θέλουν άλλο handling -- γι'αυτό το λέμε και research

.
Master_ex έγραψε:Αυτό λοιπόν που δεν έχω καταλάβει είναι πώς θα χρησιμοποιηθούν πρακτικά τα εργαλεία που έχουν βασιστεί στη libdft? Η ιδέα είναι να κάνουμε track τα δεδομένα μόνο σε servers ή άλλα "σημαντικά" μηχανήματα? Ή να υπάρχει κάτι σαν testing περίοδος των εφαρμογών που θέλουμε να τσεκάρουμε πριν το final release?
Το 2ο που λέω νομίζω ότι εξ'ορισμού είναι λάθος αφού αν ήταν έτσι δε θα πεδευόσουν να το φτιάξεις ώστε να λειτουργεί χωρίς αλλαγές στα binaries...
Το 1ο(+ το 2ο) πάλι αφήνει απέξω άλλες εφαρμογές όπως web browsers που θα μπορούσαν να εποφεληθούν από το data tracking.
Κοίτα το libdft είναι ένα library που σου δίνει την δυνατότητα να κάνεις αυτό που άλλοι λένε information flow tracking (αν και εγώ το λέω data flow tracking για τους δικούς μου λόγους -- μεγάλη κουβέντα αυτό αλλά εάν θες το συζητάμε, έχει να κάνει με το τι είναι data και τι information απο το perspective του framework). Εαν εσύ θέλεις να φτιάξεις ένα meta-tool που κάνει test εφαρμόγές για sensitive information leaks, τότε κανένα prob. Αυτό καλύπτει σενάρια που σχετίζονται με το ότι τρέχεις κάτι και θέλεις να δεις τι
βγάζει προς τα έξω unintentionally*. Απο την άλλη μπορείς να φτιάξεις μικρά meta-tools που τα βάζεις σε διάφορα apps και κάνεις track ακόμη και across processes (πχ Apache + MySQL + PHP) -- κοινώς περνάς τι είναι tagged απο το ένα process στο άλλο**. Σε κάθε περίπτωση το εκάστοτε meta-tool βασίζεται πάνω σε ένα συγκεκριμένο threat model:
τι προστατεύεις και
απο ποιόν.
*: (information leaks detection in Android):
http://appanalysis.org/tdroid10.pdf --
http://appanalysis.org/ -- OSDI 2010
**: (concatenated taint analysis):
http://www.cs.columbia.edu/~angelos/Pap ... ieeecs.pdf -- ARES 2009
Master_ex έγραψε:Οπότε θα έρθω στο δεύτερο ερώτημα που είναι αν γίνεται να μειώσεις κι άλλο αυτό το overhead και αν ναι πώς μπορεί να γίνει αυτό; (btw δεν έχω κοιτάξει καθόλου το κώδικά παρα μόνο τις διαφάνειες).
Για τα language runtime environments θέλεις άλλο design. Κάτι που έχω σκεφτεί είναι να κάνεις offload το tracking με augmented runtime environments που κάνουν αυτά track για εσένα. Πχ η Perl έχει την δυνατότητα να κάνει αυτό το πράγμα απο μόνη της (περίπου αυτό). Συνεπώς εκεί κάνεις το εξής, ξεκινάς track κανονικά και όταν καλείς ένα perl script, κάνεις switch σε native execution. Βέβαια θα χρειαστείς και κάποιο proxying facility για να περνάς στην Perl τι είναι tagged την στιγμή που ξεκινάει το execution, και να παίρνεις πίσω τι είναι tagged όταν τελειώσει το exec της Perl ώστε να συνεχίσεις. Απο την άλλη υπάρχουν και πολλά άλλα design choices που μπορούν να βοηθήσουν. Αυτό που θα προσπαθήσουμε να κάνουμε στο μέλλον είναι να κάνουμε parallelize. Μιας και τα περισσότερα cores κάθονται λόγο του ότι τα apps που τρέχουμε δεν είναι inherently parallel, αυτό που έχει νόημα να κάνεις είναι ίσως να προσπαθήσεις να βάλεις το DFT logic σε ένα 2o core -- αυτό θέλει synchronization και έχει πολλά system aspects, οπότε δεν είναι τόσο εύκολο όσο ακούγεται.
Master_ex έγραψε:Τέλος απ'ότι κατάλαβα το libdft-DTA είναι όλο το ζουμί καθώς αυτό εντοπίζει τα code injection attacks. Έχεις κάνει καθόλου δοκιμές με code injections? Αν ναι ποιά τα αποτελέσματα? (πέραν του extra overhead που αναφέρεις στις διαφάνειες)
Το libdft-DTA κάνει demonstrate το claim ότι μπορείς να κάνεις re-implement σε ~400 LOC κάτι που άλλοι χρειάστηκαν 5--10KLOC και πάλι δεν είναι reusable. Ναι έχω και results με stack smashing, format string, heap overflows, αλλά και με ret2libc και ROP όπου δεν γίνεται inject κάποιο shellcode.
Δυστιχώς δεν μπορώ να κάνω προς το παρόν release το paper του libdft γιατί είναι under review. Εκεί θα έβλεπες όλο το design, πως είναι δομημένο το instrumentation αλλά και τα routines που κάνουν implement το DFT logic, πως κάναμε τα measurements, κλπ. Εάν σε ενδιαφέρει πάντος μπορούμε να μιλήσουμε και offline γι' αυτό.