On 6/29/2022 11:51 PM, Stephen Fuld wrote:
> On 6/29/2022 12:18 PM, MitchAlsup wrote:
>> This thread addresses how architectures can make themselves more
>> secure from various attack strategies.
>> <
>> Everyone should chime in with their favorite methods and aparatuses
>
> A couple of points.
>
> 1.   You have mentioned before the steps you take to prevent side
> channel attacks such as Spectre, etc. No need to repeat them here, just
> to mention that this is another set of attack strategies. And that
> there may be other such strategies in the future.
>
IOW: Security is hard...
A few options (anti-injection protections):
1A, ASLR:
Some protection via the power of random numbers;
Very weak if attacker can guess or brute force the randomization;
Generally cheap.
1B, Security Tokens:
Fairly effective against stack-based buffer overflows;
Limited in scope;
Non-zero performance cost.
1C, Non-Executable Stack/Heap:
Can prevent many types of hostile code injections;
Cheap if supported by hardware;
Requires special "RWX memory" for JIT or Lambdas;
1D, Bounds-Checked Pointers
Can prevent out-of-bounds access as it happens.
Basically, "Capabilities without the memory tagging".
Weaker due to no way to prevent forging.
BJX2 does A/B/C here in the 64-bit ABI, D would require the 128-bit ABI.
Protection against non-trusted code:
2A, User/Supervisor Split
Pretty much every OS for the past 25+ years does this;
Depends on the OS enforcing the HAL/Syscalls and other things;
Should not be possible to sidestep the kernel or drivers.
2B, Hypervisor:
Slightly stronger, mostly by adding additional layers.
Can be broken if the code knows how to break the multiple layers.
2C, My VUGID system was originally intended partly for this scenario:
Enforce UID/GID + ACL checking on threads and memory objects;
Drawbacks: Relatively complicated to put into use effectively;
Can offers protection even with known memory addresses;
Similar properties to traditional page-based memory protection.
"Getting ROOT" breaks VUGID though.
2D, Capabilities:
Could offer fairly strong protection, if used correctly;
Relatively expensive to support in hardware and in software;
Tagged memory, 128-bit pointers, ...
If a way exists to steal or forge capabilities:
... the whole system is broken ...
2E, Type-Safety based Security
Similar properties to capabilities
Just with type-safety instead.
Typically requires a language design like Java or C#.
Typically also a GC because manual MM can break it.
...
Doesn't play well with writing code in C or C++.
2F, Very Big ASLR
Make address space very big and addresses hard to guess.
BJX2 (on paper) does A, C, and F.
Potentially, 1D + 2F could do a "poor mans imitation" of 2D.
Still kinda moot as TestKern still has roughly about as much memory
protection going on as MS-DOS...
Issues like Spectre or similar are an entirely different class of issue.
I suspect for a lot of these, a very dumb in-order CPU could be an
advantage (can't as easily "steal" information that isn't present in the
first place).
> 2.   As Ivan has pointed out, there is no architectural prevention
> against bags of cash or pretty women (or men, if the subject prefers).
Well, assuming the person experiences a sense of attraction in some form
other than as an abstracted set of social behaviors; and/or some level
of generalized anxiety about still being alone and similar... (but no
real interest in anything "casual" as this seems like it would be pretty
much pointless in terms of moving towards ones' end goals).
They could lure someone with claims like "Hey, want to live rent-free, I
can provide a couch to crash on. There will also be a fridge perpetually
stocked with food and beer.", "Hey man, that is a tempting offer, but
what is the catch?...", but there is always a catch, "aint no free
couch", ...
> And no prevention against the latest breach -
>
>
https://www.avclub.com/drunk-usb-drive-amagasaki-japan-data-leak-1849117533
>
> Though these don't relieve the designer of working hard to prevent other
> types of attacks.
>
>
>> <
>> My 66000 has a Safe Stack mode (which I am contemplating making
>> the only execution mode).
>
> This is generally a good idea, but you have to provide a mechanism for
> some programs, e.g. debuggers, to read the stack, and then, of course,
> some mechanism to prevent unauthorized use of the first mechanism. :-)
>
>
Yep.
Not really an obvious "good" solution within the traditional space.
One possible alternate approach would be a sort of "continuation passing
style" where the "continuation" (control-float graph) and "lexical
binding frame" (local variables and similar) are two
partially-independent constructs. Both would be present as dynamically
allocated structures which, while partially tied together, would be
structurally independent, and would take over the combined role
traditionally assigned to a call-stack. They would be created and
destroyed dynamically under normal control frame, but may be "captured"
into a more persistent form (likely via a linked-list walk, and setting
a "do not destroy when control-flow leaves this frame" flag for
everything along the path).
Some languages are built around such an execution model, but the obvious
drawback is that doing stuff this way is likely to have a "fairly steep"
impact on performance compared with a more traditional "C-like"
execution model.
But, it is possible it could be helped some if the ISA and low-level ABI
were adapted to help with using this model in place of the more
traditional linear stack approach.
There are a few languages around which traditional assume an execution
model like this though.