1 # Address Space Layout Randomisation 2 3 Briefly, see: `psecflags(1)`, `security-flags(5)` 4 5 ## Administration 6 7 ASLR is implemented via process security-flags (which we introduce), there are 8 two sets of flags per-process: The effective set and the inheritable set (see 9 `security-flags(5)`). The effective set is immutable, it can only change when 10 the process calls `exec(2)`, at which point the effective set is replaced by 11 the inheritable set (with one exception). Security flags are inherited upon 12 `fork(2)` (but the inheritable set is not promoted until `exec(2)`, as 13 mentioned). 14 15 This is such that a given execution of an executable has a constant set of 16 security-flags, which simplifies things for everyone. 17 18 This unfortunately means that to enable ASLR fully system-wide, requires a 19 reboot or at least restart of a majority of services. 20 21 The system-wide ASLR flag is an SMF property on the new service 22 `svc:/system/process-security`, which contains a `secflags` property group, 23 with one boolean property per implemented flag (see, again, 24 `security-flags(5)`). At present, this will not take effect (at all) until a 25 reboot. 26 27 Per-process setting (and inspecting) of security-flags is done via 28 `psecflags(1)`. 29 30 ## Privilege 31 32 A process may change the security-flags of any process to which it could send 33 a signal with `kill(2)`, as long as the process also has the 34 `PRIV_PROC_SECFLAGS` privilege. This privilege is granted by default, but is 35 not a `basic` privilege. If you have configured custom privileges for certain 36 users or services, they will not automatically gain the new 37 `PRIV_PROC_SECFLAGS` (unfortunately). 38 39 ## Executable tagging 40 41 There is a somewhat compatible property of dynamic executables, `DT_SUNW_ASLR` 42 which controls the ASLR behaviour of a given executable. If this dynamic tag 43 has a value of 1, ASLR is always enabled for an execution of this process. If 44 the tag has a value of 0, ASLR is never enabled for an execution of this 45 process. The default is to inherit the ASLR flag as normal. 46 47 This allows a process for which ASLR is known to be problematic to explicitly 48 forbid it, and for processes of special sensitivity to mandate it. 49 50 This is controlled via the `-z aslr` flag to `ld(1)`. 51 52 ## Missing bits/Problems/Worries 53 54 ### The stack skewing may skew too much of the stack 55 56 At present, we skew the absolute base of the stack, which means the gap 57 between a user stack frame and the process environment is constant. I have 58 this vague memory that that's sub-par, and that we want to skew the stack 59 _after_ the environment, etc. I could be entirely wrong about that though. 60 61 ### We skew each mapping separately 62 63 Some systems calculate a random skew for the various parts of a process at 64 execution time, and apply that same skew to each mapping. That obviously 65 minimises the performance impact of this significantly for processes that 66 perform many mappings. 67 68 Due to some unfortunate aspects of how we manage the user address space and 69 mappings, we don't do that right now. We calculate a separate random skew for 70 each mapping we attempt. 71 72 ### The way we skew mappings is problematic 73 74 The user address space is currently managed somewhat unfortunately (from our 75 point of view, at least). When attempting a mapping we first determine the 76 highest gap into which the requested mapping can fit, and then we place the 77 mapping at the highest address in that gap. This is how we manage user 78 fragmentation. 79 80 The current ASLR implementation works in basically the same way. We still 81 find the highest gap into which the given mapping may fit, and choose the 82 highest address at which it may fit. The only difference is that we then slew 83 it backward by a random (but co-aligned), amount. 84 85 This is obviously not as random as it could be, but is the easiest way I've 86 found in the current code base for introducing uncertainty while also 87 preserving any attempt at preventing unbounded user fragmentation. 88 89 It is not impossible to imagine a long-lived process that makes many mappings 90 being in a position where mappings later in its life are 100% predictable 91 given this implementation, however. In fact, I think it is fairly likely. 92 93 I think the most at risk would be a process which makes many mappings, and 94 uses `dlopen(3c)` at unpredictable times (rather than, as is most common, during 95 setup). Dynamic objects tend to have strict (and high) alignment requirements 96 which in such a process are likely to only be fulfillable at a single location 97 in the address space gap we choose, and thus be entirely predictable. 98 99 ### We want a per-zone configuration item, but it's not implemented yet 100 101 I plan to implement a per-zone configuration item similar to `limitpriv` which 102 describes a zones default security-flags. This will be set during 103 `zone_create` and apply to _every_ process in a zone (rather than the GZ 104 implementation, from which `svc.startd(1M)`, `svc.configd(1M)`, and `init(1M)` 105 are immune unless tagged). 106 107 This will also allow a global zone administrator to configure the 108 security-flags of a zone, and then take `PRIV_PROC_SECFLAGS` away from that 109 zone, such that the security-flag configuration of the zone is forced upon it. 110 111 This is somewhat ugly though, since `svc:/system/process-security` and its 112 settings in the zone will thus be inoperative. 113 114 ### Randomisation of executable base addresses requires PIE 115 116 To randomise the executable base address, we need position independent 117 executables, which appears like it would turn into a whole separate project 118 (though perhaps not too large a project). That code isn't here, so the 119 executable base is fixed. 120 121 This means that rather than return-to-libc one could return-to-executable 122 trivially and successfully, I think. (That would include using the 123 executable's PLT to vector yourself to libc. Should the executable have a PLT 124 entry for something useful to you).