Hallo,
Das regelmäßige Backup-Programm wird aber automatisch mit Root-Rechten gestartet (z.B. von "cron"), dazu muss trotzdem ein Daemon mit Root-Rechten ununterbrochen laufen.
Da hast Du recht. cron ist so ein Prozess der ständig läuft und root-Rechte hat aber cron ist klein genug das er einigermaßen fehlerfrei sein sollte und außerdem hat cron auch keine öffentlich erreichbaren Interfaces (wie TCP o.ä.).
Was ist mit inetd? Ich weiß, ein Ausgeburt der Hölle, aber mir gefällt es. Der muss Prozesse unter bestimmten Nutzernamen ausführen können, also muss er root sein. Und er ist definitiv per TCP (UDP?) von außen erreichbar.
Wie auch immer, gewisse Services müssen root-Rechte haben, solange du nicht für jede noch so kleine Aktion eine eigene Permission baust. Wenn der Kernel endlich hinreichend sicher ist, wird man sich an genau diesen Services versuchen.
Grafiktreiber sind enorm kurzlebig und zeitkritisch (jeder Hersteller will das neuste Feature seiner Chips auch bestmöglich anbieten) so das dort kaum auf Sicherheit u.ä. geachtet wird. Die besseren Treiber für die professionellen Workstations sind eben extra geprüft und zertifiziert und den normalen Treiber immer mindestens 6 Monate hinterher (aber das ist der typischen Klientel dieser Treiber egal).
Naja, ich denke, dass es dabei hauptsächlich um Funktionskorrektheit geht, weniger um Sicherheit. Professionelle Workstations sollten ohnehin weit weg vom öffentlichen Internet sein (mindestens NAT, besser Proxy).
Der Grund für die Implementation im Kernel (bei Monolithen) ist Performance (Windows) und eine gemeinsame API als Basis für mehrere Treiber (Linux). Gleicher Grund, wie die Implementation von WLAN im Kernel, damit nicht jeder Treiber seinen eigenen WLAN-Stack mitbringen muss (wie bei Windows XP) und damit jeder Treiber, egal von wem, die gleichen Dinge unterstützen kann (WPA, HostAP).
Möglichst diese Signatur noch an das TPM des Mainboards gebunden?
Nein, natürlich nicht! Schon allein der Gedanke ist völlig unpassend. Das sollte mit dem privaten Schlüssel von root erledigt werden und der ist nur über das Passwort (oder eine SmartCard oder ein US-Dongle oder ...) von root zugänglich.
Gut, dann bindest du eben den Schlüssel an das TPM. Dafür ist es schließlich da: Als Ersatz für SmartCard-Authentifizierung, wenn du dem System trauen kannst, es also nicht einfach wegtragen kannst.
zwischen RAM und den Busmastern (CPU, DMA, PCI/e).
Nein, im Chipsatz. Also in der Verbindung zwischen CPUs und RAM auf der einen Seite und der Peripherie auf der anderen Seite. Es geht nicht jeder RAM-Zugriff durch diesen Filter sondern nur das was von der Peripherie kommt. DMA hab ich auf meiner Plattform nicht, würde ich aber eventuell der CPU-Seite zurechnen wenn der Kernel aufpasst das da nichts unerlaubtes rein kommt, ansonsten doch lieber auf die Peripherie-Seite.
Das ist aber inkonsequent.
Im Chipsatz liegt die RAM-Steuerung, also kannst du die Liste auch direkt vor den RAM setzen und mit mehreren Eingängen (CPU, DMA, PCI-Bus, Firewire-Bus [extra], ...) versehen, die jeweils eigene Einträge haben. Der Unterschied ist dann gering und wenn du paranoid genug bist, könntest du eine Adressraumliste für jeden einzelnen Task im System haben.
Je nachdem, wie schnell ein Neuladen der Liste relativ zur Zeitscheibe von Tasks dauert, könnte das sogar erträglich sein. Allerdings bezweifle ich, dass sowas des Rätsels Lösung ist. Das Prinzip ist ja dasselbe wie ein Watchdog und der wurde ja auch schon hinreichend ausgenutzt. (Der DoS-Exploit muss den Watchdog nur selbst streicheln, schon legt man die Services trotzdem unbegrenzt lange lahm.)
Das wirst du aber gefühlt nicht unbedingt in die PC-Architektur eingebaut kriegen, es ist teure und eine Bremse.
Das sehe ich anders, auch bei der PC-Architektur gibt es eine zentrale Schnittstelle zwischen den CPUs mit ihrem RAM auf der einen Seite und der Peripherie auf der anderen Seite, eben der Chipsatz (dort wo der PCI(e)-Root-Complex sitzt).
Du vergisst die Kompatiblität mit der Urzeit. Halte dich von der PC-Architektur fern, die ist stabil seit 1981!
Prinzipiell möglich ist alles, aber umsetzbar ist es dann trotzdem nicht. Das können höchstens geschlossene Systeme a la Apple oder Spezialgeräte (embedded) machen, wo es angebracht ist.
IPC ist nicht der einzige Angriffspunkt, aber ein sehr zentral gelegener und daher gut geeigneter. Darum muss man dort besonders aufpassen.
Gut, IPC ist sehr wichtig und daher muss man dort besonders gut aufpassen, auch bzw. gerade bei der Konzeptentwicklung. Die anderen Syscalls sollte man aber auch nicht vernachlässigen. Es gab schon genug erfolgreiche Angriffe durch die (unbewachte) Hintertür.
Auf dem 27C3 (hoffentlich krieg ich noch ne Karte...) wird es einen Vortrag geben zu Angriffen durch Mischung von 32- und 64-Bit-Code in einer Anwendung und ungewöhnliches Verwenden von Syscalls in beiden Modi. Ähnlich kann man es ja auf ARM (mit ARM und Thumb-Code) oder MIPS (da gibt's jetzt auch einen kleineren Code) übertragen.
Nehmen wir an es würde einem Angreifer auf meiner Plattform gelingen sich zwischen einem Ethernet-Treiber und dem IP-Prozess zu drängeln (mal ganz egal wie das gehen soll), dann hat der Angreifer aber noch keinen wahlfreien Zugriff auf die Busmasterfunktionen des Ethernet-Controllers sondern kann sich nur Daten in seine eigenen Segmente schreiben lassen.
Richtig, weil du - und das meinte ich mit "komisches Zeug" - verschiedene Adressräume hast. Und zwar hardwareseitig, wenn du es wünschst. Bei Flatmem-Systemen gibt es ja nur einen und den kannst du aus Hardwaresicht nicht mit Paging erschlagen - eben weil DMA und so. Da braucht es dann die Fangschaltung von oben, die ist aber nicht in heutigen Systemen drin.
Was geht, sind Programmiersprachen, die inhärent sicher (bzw. korrekt) sind. Aber Ada will man nicht programmieren, von der Performance rede ich lieber nicht.
Soweit ich weiß ist der Performanceverlust bei Ada unterhalb der Messbarkeitsgrenze. Das einzigste was C/C++ wirklich fehlt sind die "run time array bound checks" und die muss der Programmierer dann von Hand erledigen (die Stellen wo er das effizienter erledigen kann als der Compiler dürften sehr rar sein), wenn der Programmierer das nicht tut gibt es die allseits beliebten Buffer-Overflows.
Njain. Bevor du in Ada anfangen kannst zu programmieren, bist du erstmal ziemlich lange damit beschäftigt, die Aufgabe und ihre Einzelteile und Abhängigkeiten zu beschreiben. Darum ist Ada ja auf Korrektheit prüfbar (im Gegensatz zu den meisten Programmiersprachen), aber der Programmierer muss dafür schon enormen Aufwand treiben
und er darf nicht mit unscharfen Aufgabenstellungen beworfen werden. Run-Time-Boundary-Checks will man ja mit so Dingen wie Java (virtuellen maschinen) oder .NET (managed code) erschlagen, im Endeffekt hab ich heute ne Statistik gefunden, wonach irgendwas um die Hälfte aller Sicherheitslücken auf Buffer Overflow-Angriffe zurückgeht.
Wusstest du übrigens, dass das Template-System von C++ turing-vollständig ist?
Bei meinem Konzept habe ich mich dazu entschieden das grundsätzlich immer jeder Prozess auf einen IPC-Service zugreifen darf (falls er denn die nötige ID kennt), der Kernel macht da nie irgendwelche Einschränkungen. Die Rechteverwaltung bleibt somit bei den Services hängen aber z.B. der VFS muss das eh erledigen (eine bereits geöffnete Datei kann nicht einfach so noch mal geöffnet werden) so das ich da keinen allzu großen Nachteil sehe. Seht ihr das anders?
Du trennst also nicht zwischen der Berechtigung des Zugriffs und der Berechtigung der Wunschaktion. Gibt es die Möglichkeit, die IPC-IDs zu bruteforcen?
Da wir das schonmal hatten, gibt es eigentlich eine Situation wo man über die gesamte Programmlaufzeit keinen Port zum lesen benötigt, aber eine Nachricht an einen Port schicken will/muss?
Ja, kann man durchaus konstruieren, z.B. wenn ich etwas in der Art eines Funkbroadcast verschicken möchte, wo es keine Bestätigung geben kann oder (aus Performancegründen) muss. Sowas wie "init", welches allen Prozessen mitteilt, dass das System jetzt herunterfährt/abschaltet oder meinetwegen auch UDP-Nachrichten.
Ich frage deshalb, weil man bei mir zwingend einen Port braucht um überhaupt eine Nachricht an einen anderen Port zu schreiben.
Damit sehe ich kein Problem. Für irgendwelche Aktionen brauchst du eigentlich immer ein Handle, das wäre bei dir der Port. Ist halt ne Designvorgabe, dass man keine "anonymen" IPC-Nachrichten schicken kann. Wenn du potentiell gefährlichen Prozessen verbietest, einen Port zu bekommen, dann verhinderst du effektiv die IPC-Kommunikation; für die Sicherheit ist das sicherlich förderlich.
Ich kann mir ehrlich gesagt auch nicht vorstellen wozu das gut sein soll das der Client selber quasi zum Service wird. Bei mir wird es sicher viele simple Programme (die trotzdem deutlich über Hello-World hinausgehen, ich denke da z.B. an Compiler o.ä.) geben die kein einziges eigenes Message-Target aufmachen.
Wenn du eine Syscall-API hast, die vollkommen asynchron und mit Callbacks arbeitet, wie z.B. das X11-Protokoll, dann ist jeder Client irgendwo ein Anbieter für so eine Callback-Struktur.
Gruß,
Svenska