1 00:00:06,320 --> 00:00:11,499 [Music] 2 00:00:15,440 --> 00:00:21,119 good morning everyone um hi i'm betsy 3 00:00:18,560 --> 00:00:24,480 and i'm going to be your mc today in 4 00:00:21,119 --> 00:00:27,199 kaya theater um and tomorrow as well so 5 00:00:24,480 --> 00:00:29,279 um wasn't that an amazing keynote i've 6 00:00:27,199 --> 00:00:31,359 like noted down a lot of things to look 7 00:00:29,279 --> 00:00:33,360 up and read and so on 8 00:00:31,359 --> 00:00:34,880 but we have so many more exciting talks 9 00:00:33,360 --> 00:00:37,040 today 10 00:00:34,880 --> 00:00:40,719 and i should um also 11 00:00:37,040 --> 00:00:42,399 uh in introducing myself mention that i 12 00:00:40,719 --> 00:00:44,399 am 13 00:00:42,399 --> 00:00:46,879 working on this conference 14 00:00:44,399 --> 00:00:49,440 for you today i'm from the lands of the 15 00:00:46,879 --> 00:00:51,120 yagara people in brisbane um and i 16 00:00:49,440 --> 00:00:52,160 acknowledge their elders past and 17 00:00:51,120 --> 00:00:54,000 present 18 00:00:52,160 --> 00:00:54,879 um 19 00:00:54,000 --> 00:00:57,199 and 20 00:00:54,879 --> 00:00:59,760 yeah it's a beautiful day outside here i 21 00:00:57,199 --> 00:01:01,920 hope it's lovely conference day where 22 00:00:59,760 --> 00:01:03,680 you all are as well 23 00:01:01,920 --> 00:01:06,640 so first up today 24 00:01:03,680 --> 00:01:08,799 um we have case cook 25 00:01:06,640 --> 00:01:11,840 so case has been working with free 26 00:01:08,799 --> 00:01:14,560 software since 1994 has been a debian 27 00:01:11,840 --> 00:01:16,479 developer since 2007 and has been a 28 00:01:14,560 --> 00:01:19,119 member of the linux kernel technical 29 00:01:16,479 --> 00:01:21,119 advisory board since 2019 he is 30 00:01:19,119 --> 00:01:23,520 currently employed as a linux kernel 31 00:01:21,119 --> 00:01:26,400 security engineer by google focusing on 32 00:01:23,520 --> 00:01:28,960 upstream kernel security defenses 33 00:01:26,400 --> 00:01:31,360 so case will be taking questions today 34 00:01:28,960 --> 00:01:33,520 so if you'd like to put your questions 35 00:01:31,360 --> 00:01:35,439 during the talk in the little questions 36 00:01:33,520 --> 00:01:38,240 tab at the top of the chat in venulis 37 00:01:35,439 --> 00:01:39,840 there um the questions are moderated so 38 00:01:38,240 --> 00:01:41,040 your question will appear right away 39 00:01:39,840 --> 00:01:43,920 you've got to wait for one of us 40 00:01:41,040 --> 00:01:45,840 volunteers to manage to approve it 41 00:01:43,920 --> 00:01:47,680 and also check in with that questions 42 00:01:45,840 --> 00:01:49,439 tab regularly during the talk because 43 00:01:47,680 --> 00:01:50,399 you can upload questions that you want 44 00:01:49,439 --> 00:01:52,320 answered 45 00:01:50,399 --> 00:01:55,119 um so i'll see you back at the end of 46 00:01:52,320 --> 00:01:56,880 the talk to pass on your questions um 47 00:01:55,119 --> 00:01:58,000 case we're looking forward to hearing 48 00:01:56,880 --> 00:02:00,320 from you 49 00:01:58,000 --> 00:02:01,200 awesome thanks for having me 50 00:02:00,320 --> 00:02:06,399 um 51 00:02:01,200 --> 00:02:08,000 hi uh as i said i'm case cook uh here to 52 00:02:06,399 --> 00:02:10,239 talk to you about uh some of the work 53 00:02:08,000 --> 00:02:12,000 we're doing in linux kernel uh for 54 00:02:10,239 --> 00:02:13,360 actually doing some meaningful bounce 55 00:02:12,000 --> 00:02:14,800 checking 56 00:02:13,360 --> 00:02:16,480 um 57 00:02:14,800 --> 00:02:18,000 i'll just dive in 58 00:02:16,480 --> 00:02:19,120 so i 59 00:02:18,000 --> 00:02:21,599 got 60 00:02:19,120 --> 00:02:23,760 more and more irritated by some of the 61 00:02:21,599 --> 00:02:26,879 flaws that were cropping up 62 00:02:23,760 --> 00:02:28,879 in the kernel around buffer overflows 63 00:02:26,879 --> 00:02:30,160 and i wanted to 64 00:02:28,879 --> 00:02:32,000 see if there was a way we could actually 65 00:02:30,160 --> 00:02:33,040 put a stop to this 66 00:02:32,000 --> 00:02:35,360 so i 67 00:02:33,040 --> 00:02:37,840 as a sort of data analysis step i looked 68 00:02:35,360 --> 00:02:40,160 at the last you know three years or so 69 00:02:37,840 --> 00:02:42,640 of any of this kernel cvs that mentioned 70 00:02:40,160 --> 00:02:44,480 buffer overflow and tried to root cause 71 00:02:42,640 --> 00:02:45,760 them and figure that out 72 00:02:44,480 --> 00:02:47,200 so the 73 00:02:45,760 --> 00:02:48,640 you know one of the largest not the 74 00:02:47,200 --> 00:02:52,160 largest but i'll get through it first is 75 00:02:48,640 --> 00:02:54,080 the array index overflows 76 00:02:52,160 --> 00:02:56,560 and looking at that there were seven out 77 00:02:54,080 --> 00:02:58,879 of those 25 78 00:02:56,560 --> 00:03:02,319 that we looked at and the the good news 79 00:02:58,879 --> 00:03:06,000 is like using example here 80 00:03:02,319 --> 00:03:09,280 that these are pretty well solvable 81 00:03:06,000 --> 00:03:10,400 so if you look at this example oops 82 00:03:09,280 --> 00:03:12,640 you've got 83 00:03:10,400 --> 00:03:15,680 you've got this algorithm name that was 84 00:03:12,640 --> 00:03:18,560 64 bytes long and 85 00:03:15,680 --> 00:03:20,560 if you were to access it 86 00:03:18,560 --> 00:03:22,400 beyond the 64-bit if there's no 87 00:03:20,560 --> 00:03:24,959 instrumentation it would just happily 88 00:03:22,400 --> 00:03:26,400 access memory beyond the end of of that 89 00:03:24,959 --> 00:03:29,760 buffer and 90 00:03:26,400 --> 00:03:31,120 you know badness would ensue 91 00:03:29,760 --> 00:03:32,480 but 92 00:03:31,120 --> 00:03:35,280 if you actually 93 00:03:32,480 --> 00:03:37,920 build the kernel with ubison bounds um 94 00:03:35,280 --> 00:03:39,920 and either trap or the panic on warrants 95 00:03:37,920 --> 00:03:42,640 this control set 96 00:03:39,920 --> 00:03:43,920 this doesn't happen anymore all these 97 00:03:42,640 --> 00:03:44,720 kinds of things 98 00:03:43,920 --> 00:03:47,200 on 99 00:03:44,720 --> 00:03:48,799 unknown sized array 100 00:03:47,200 --> 00:03:51,360 indexing 101 00:03:48,799 --> 00:03:53,439 get caught um for example you can see a 102 00:03:51,360 --> 00:03:55,680 little summary of what would happen here 103 00:03:53,439 --> 00:03:57,920 if you get you actually get an array 104 00:03:55,680 --> 00:04:01,439 index out of bounds at runtime 105 00:03:57,920 --> 00:04:04,159 and it would either 106 00:04:01,439 --> 00:04:05,920 trap that process or trap that threat of 107 00:04:04,159 --> 00:04:08,159 execution with ubisone trap or would 108 00:04:05,920 --> 00:04:10,560 panic the whole system if you set panic 109 00:04:08,159 --> 00:04:11,599 on warren 110 00:04:10,560 --> 00:04:15,040 though 111 00:04:11,599 --> 00:04:17,440 in the in this particular example 112 00:04:15,040 --> 00:04:19,199 that got changed from a fixed size array 113 00:04:17,440 --> 00:04:21,120 to a flexible array 114 00:04:19,199 --> 00:04:22,479 uh which means you actually lose any 115 00:04:21,120 --> 00:04:24,080 kind of bounce checking that the 116 00:04:22,479 --> 00:04:26,000 compiler can do 117 00:04:24,080 --> 00:04:28,639 so that's not the best 118 00:04:26,000 --> 00:04:30,720 fix for it but uh it's it's it's a 119 00:04:28,639 --> 00:04:32,880 reasonable example for showing what that 120 00:04:30,720 --> 00:04:34,880 would have looked like um so all these 121 00:04:32,880 --> 00:04:37,600 just go away if if the kernel is 122 00:04:34,880 --> 00:04:39,680 compiled ub sandbounds so 123 00:04:37,600 --> 00:04:41,520 that array index overflow section sort 124 00:04:39,680 --> 00:04:44,639 of goes away you don't have buffer 125 00:04:41,520 --> 00:04:46,960 overflows like that anymore 126 00:04:44,639 --> 00:04:50,240 and so what's left is 127 00:04:46,960 --> 00:04:53,600 this the huge section where mem copy is 128 00:04:50,240 --> 00:04:55,040 used against a buffer 129 00:04:53,600 --> 00:04:58,240 and looking through 130 00:04:55,040 --> 00:05:00,800 those 11 the one that set me off 131 00:04:58,240 --> 00:05:03,600 really was this one which was called 132 00:05:00,800 --> 00:05:06,160 bleeding tooth which 133 00:05:03,600 --> 00:05:07,120 was a bluetooth vulnerability 134 00:05:06,160 --> 00:05:09,280 and 135 00:05:07,120 --> 00:05:11,039 it just annoyed me to no end because 136 00:05:09,280 --> 00:05:13,840 again the compiler knows how big this 137 00:05:11,039 --> 00:05:16,160 buffer is and yet it does no bounce 138 00:05:13,840 --> 00:05:17,759 checking whatsoever 139 00:05:16,160 --> 00:05:20,240 and if we look through the others you 140 00:05:17,759 --> 00:05:22,240 sort of see this same pattern over and 141 00:05:20,240 --> 00:05:24,160 over here's an entire structure we know 142 00:05:22,240 --> 00:05:25,520 how big it is and we're going to copy 143 00:05:24,160 --> 00:05:27,680 into it 144 00:05:25,520 --> 00:05:29,280 but it's unchecked at run time 145 00:05:27,680 --> 00:05:31,759 here's another one where we know the 146 00:05:29,280 --> 00:05:33,440 size of that buffer and there's no 147 00:05:31,759 --> 00:05:35,199 runtime checking 148 00:05:33,440 --> 00:05:37,280 and again 149 00:05:35,199 --> 00:05:38,960 these just sort of continue 150 00:05:37,280 --> 00:05:39,919 and you you see the pattern over and 151 00:05:38,960 --> 00:05:42,240 over 152 00:05:39,919 --> 00:05:44,800 um in fact this became 153 00:05:42,240 --> 00:05:46,080 so common in the last couple of years 154 00:05:44,800 --> 00:05:47,840 that uh 155 00:05:46,080 --> 00:05:49,759 there's a couple 156 00:05:47,840 --> 00:05:50,800 at the end 157 00:05:49,759 --> 00:05:53,600 where 158 00:05:50,800 --> 00:05:56,160 you see we've got ssids people started 159 00:05:53,600 --> 00:05:57,120 looking at this as a common overflow 160 00:05:56,160 --> 00:05:59,680 place 161 00:05:57,120 --> 00:06:01,280 and now we've got ssid overflow and 162 00:05:59,680 --> 00:06:03,520 another one this one doesn't even have a 163 00:06:01,280 --> 00:06:05,759 cve assigned but it's fixed 164 00:06:03,520 --> 00:06:08,080 and another one so that's three in a row 165 00:06:05,759 --> 00:06:10,639 of exactly the same flaw 166 00:06:08,080 --> 00:06:12,880 all of which the compiler knows how big 167 00:06:10,639 --> 00:06:16,479 this buffer is and yet it happily just 168 00:06:12,880 --> 00:06:17,360 clobbers past the end of it 169 00:06:16,479 --> 00:06:18,080 um 170 00:06:17,360 --> 00:06:19,440 so 171 00:06:18,080 --> 00:06:21,360 some of you may be thinking well wait a 172 00:06:19,440 --> 00:06:22,960 second i thought config fortify source 173 00:06:21,360 --> 00:06:24,319 solved this 174 00:06:22,960 --> 00:06:25,280 um 175 00:06:24,319 --> 00:06:28,639 and 176 00:06:25,280 --> 00:06:28,639 well let's answer that question 177 00:06:29,280 --> 00:06:32,960 if you take a look at what the fortified 178 00:06:31,600 --> 00:06:34,400 mem copy 179 00:06:32,960 --> 00:06:36,240 looks like 180 00:06:34,400 --> 00:06:38,080 this top part is 181 00:06:36,240 --> 00:06:39,759 where we 182 00:06:38,080 --> 00:06:41,039 basically get the size of the object 183 00:06:39,759 --> 00:06:42,720 what's the destination size what's the 184 00:06:41,039 --> 00:06:44,800 source size 185 00:06:42,720 --> 00:06:48,160 this next chunk is the compile time 186 00:06:44,800 --> 00:06:50,080 portion that says hey if we know the 187 00:06:48,160 --> 00:06:52,240 size that we're going to be copying at 188 00:06:50,080 --> 00:06:54,240 compile time then it's a fixed size we 189 00:06:52,240 --> 00:06:56,000 can actually do the checking immediately 190 00:06:54,240 --> 00:06:58,479 and throw a compile time warning rather 191 00:06:56,000 --> 00:07:01,039 than doing a runtime warning 192 00:06:58,479 --> 00:07:02,960 and then finally if those weren't if it 193 00:07:01,039 --> 00:07:05,199 wasn't a built-in constant then we can 194 00:07:02,960 --> 00:07:06,160 do the runtime checking 195 00:07:05,199 --> 00:07:08,160 and 196 00:07:06,160 --> 00:07:10,240 if everything is fine we go on and 197 00:07:08,160 --> 00:07:11,199 actually do the mem copy 198 00:07:10,240 --> 00:07:13,360 so the 199 00:07:11,199 --> 00:07:15,599 problem actually lies in this which is 200 00:07:13,360 --> 00:07:17,360 the built-in object size call which 201 00:07:15,599 --> 00:07:19,360 we're where we say how big is our 202 00:07:17,360 --> 00:07:21,599 destination 203 00:07:19,360 --> 00:07:23,280 um and so we dive into built in object 204 00:07:21,599 --> 00:07:26,080 size a little bit more that last 205 00:07:23,280 --> 00:07:27,520 parameter is what mode to be using 206 00:07:26,080 --> 00:07:30,560 in mode 0 207 00:07:27,520 --> 00:07:32,960 we're actually measuring the outer 208 00:07:30,560 --> 00:07:35,440 structure not what's being referenced 209 00:07:32,960 --> 00:07:37,120 directly not the member itself 210 00:07:35,440 --> 00:07:39,680 as an example 211 00:07:37,120 --> 00:07:40,880 we can see here in this structure 212 00:07:39,680 --> 00:07:43,360 if we ask for 213 00:07:40,880 --> 00:07:44,639 a built-in object size of count 214 00:07:43,360 --> 00:07:46,720 in mode 0 215 00:07:44,639 --> 00:07:48,800 we actually get the answer of 16 because 216 00:07:46,720 --> 00:07:51,280 that's the full size of the remaining 217 00:07:48,800 --> 00:07:54,160 everything after from count on 218 00:07:51,280 --> 00:07:56,319 is how much is left and this is to block 219 00:07:54,160 --> 00:07:57,360 having a mem copy go beyond the end of a 220 00:07:56,319 --> 00:08:00,240 structure 221 00:07:57,360 --> 00:08:01,520 but it doesn't help a mem copy block 222 00:08:00,240 --> 00:08:02,720 going beyond the end of a structure 223 00:08:01,520 --> 00:08:05,039 member 224 00:08:02,720 --> 00:08:07,440 but you see in mode one we actually get 225 00:08:05,039 --> 00:08:09,840 the true size of count as four and we 226 00:08:07,440 --> 00:08:11,440 can see all our you know each of these 227 00:08:09,840 --> 00:08:13,520 as an example here you know i say well 228 00:08:11,440 --> 00:08:15,840 how big is name well it's not eight as 229 00:08:13,520 --> 00:08:18,639 far as in mode 0 it's 12 which means 230 00:08:15,840 --> 00:08:20,639 well we could clobber or read the secret 231 00:08:18,639 --> 00:08:23,440 value that follows it 232 00:08:20,639 --> 00:08:26,639 whereas in mode 1 we'd actually limit it 233 00:08:23,440 --> 00:08:28,240 and if we have a dynamically sized array 234 00:08:26,639 --> 00:08:29,520 at the end or what's called a flexible 235 00:08:28,240 --> 00:08:31,680 array 236 00:08:29,520 --> 00:08:33,039 a built-in object size refuses to know 237 00:08:31,680 --> 00:08:34,719 anything about it it says i don't know 238 00:08:33,039 --> 00:08:37,039 minus one i don't know how big this is 239 00:08:34,719 --> 00:08:37,039 at all 240 00:08:37,760 --> 00:08:41,519 and what actually happened with the 241 00:08:38,959 --> 00:08:44,399 bleeding tooth attack is uh it was 242 00:08:41,519 --> 00:08:46,880 attacking stuff within the same 243 00:08:44,399 --> 00:08:49,440 composite structure just past the end of 244 00:08:46,880 --> 00:08:52,240 the the buffer that was uh being used by 245 00:08:49,440 --> 00:08:56,880 the mem copy so specifically this last 246 00:08:52,240 --> 00:08:56,880 uh advertised uh advertised data 247 00:08:57,040 --> 00:09:02,640 it wrote past it and clobbered the 248 00:08:59,839 --> 00:09:03,680 the list head for next and continued its 249 00:09:02,640 --> 00:09:05,680 attack 250 00:09:03,680 --> 00:09:08,399 so that's an example of you know going 251 00:09:05,680 --> 00:09:09,760 past one and hitting some secret thing 252 00:09:08,399 --> 00:09:11,120 that you didn't want to expose but the 253 00:09:09,760 --> 00:09:12,720 memcap was perfectly happy to do it 254 00:09:11,120 --> 00:09:16,399 because it wasn't past the end of the 255 00:09:12,720 --> 00:09:16,399 hci dev structure itself 256 00:09:16,959 --> 00:09:21,040 so back to fortified mem copy obviously 257 00:09:19,279 --> 00:09:22,720 the solution here is we need to fix the 258 00:09:21,040 --> 00:09:23,920 built-in object size and switch the 259 00:09:22,720 --> 00:09:26,880 modes 260 00:09:23,920 --> 00:09:29,519 and actually have it say mode one 261 00:09:26,880 --> 00:09:32,080 that's obviously what we need to do so i 262 00:09:29,519 --> 00:09:32,080 guess we're done 263 00:09:32,480 --> 00:09:36,240 so here's my wall of text 264 00:09:34,640 --> 00:09:40,160 if we look at the mem copy calls on a 265 00:09:36,240 --> 00:09:42,640 recent x86 64 all mod config build 266 00:09:40,160 --> 00:09:43,600 which doesn't really represent 267 00:09:42,640 --> 00:09:45,519 uh 268 00:09:43,600 --> 00:09:47,839 i don't know a real world case it mostly 269 00:09:45,519 --> 00:09:50,720 represents worst case this is all the 270 00:09:47,839 --> 00:09:53,519 code that could be built there's about 271 00:09:50,720 --> 00:09:55,519 35 000 m copy calls in total 272 00:09:53,519 --> 00:09:57,519 22 000 where we don't know the buffer 273 00:09:55,519 --> 00:10:00,720 destination buffer size at all 274 00:09:57,519 --> 00:10:02,800 uh 12 000 where we know both so we can 275 00:10:00,720 --> 00:10:04,800 actually validate them at compile time 276 00:10:02,800 --> 00:10:06,720 so we know that those 33 percent are 277 00:10:04,800 --> 00:10:09,120 always going to be correct 278 00:10:06,720 --> 00:10:11,279 and then about you know 1200 279 00:10:09,120 --> 00:10:13,519 only 3 percent where the destination 280 00:10:11,279 --> 00:10:15,360 buffer size is known but the copy size 281 00:10:13,519 --> 00:10:16,480 is dynamic and you know evaluated 282 00:10:15,360 --> 00:10:19,120 runtime 283 00:10:16,480 --> 00:10:22,240 and going through that list of cves 284 00:10:19,120 --> 00:10:25,200 all 11 of them were in this 285 00:10:22,240 --> 00:10:27,680 three percent so if we actually can fix 286 00:10:25,200 --> 00:10:30,079 this we would have solved all of those 287 00:10:27,680 --> 00:10:31,200 buffer overflows 288 00:10:30,079 --> 00:10:33,040 which 289 00:10:31,200 --> 00:10:35,680 was very exciting because when i first 290 00:10:33,040 --> 00:10:36,959 ran these numbers it was it seemed like 291 00:10:35,680 --> 00:10:38,959 we were going to run into trouble and 292 00:10:36,959 --> 00:10:41,200 that we wouldn't actually fix the big 293 00:10:38,959 --> 00:10:45,120 the big problem but uh it turns out the 294 00:10:41,200 --> 00:10:45,120 bulk of it comes from this case 295 00:10:45,519 --> 00:10:50,160 uh but of course that would be too easy 296 00:10:48,240 --> 00:10:53,600 to switch to mode one 297 00:10:50,160 --> 00:10:57,680 um of those twelve thousands or so uh 298 00:10:53,600 --> 00:10:59,040 known buffer size and known copy size um 299 00:10:57,680 --> 00:11:01,839 some of those actually need to be fixed 300 00:10:59,040 --> 00:11:04,720 because the kernel would intentionally 301 00:11:01,839 --> 00:11:07,200 overflow member targets 302 00:11:04,720 --> 00:11:08,720 the good news if there is some in that 303 00:11:07,200 --> 00:11:11,360 was that they would appear at compile 304 00:11:08,720 --> 00:11:12,480 time so it was easy to sort of catch 305 00:11:11,360 --> 00:11:14,959 them all 306 00:11:12,480 --> 00:11:18,000 and so what do i mean by intentional 307 00:11:14,959 --> 00:11:20,320 cross member overflows 308 00:11:18,000 --> 00:11:22,880 uh what we'd have is 309 00:11:20,320 --> 00:11:24,800 uh this kind of example where 310 00:11:22,880 --> 00:11:28,480 we've we've got a mem copy that's 311 00:11:24,800 --> 00:11:30,160 targeting um this key material member so 312 00:11:28,480 --> 00:11:32,079 that's what the compiler sees that's 313 00:11:30,160 --> 00:11:34,560 what it looks at and when the 314 00:11:32,079 --> 00:11:38,079 built-in object size runs with mode 1 it 315 00:11:34,560 --> 00:11:39,600 says ok key material is max anchor key 316 00:11:38,079 --> 00:11:42,480 length long 317 00:11:39,600 --> 00:11:45,519 and then it looks at key m len and it 318 00:11:42,480 --> 00:11:46,640 sees you know oh we've actually asked 319 00:11:45,519 --> 00:11:48,720 for 320 00:11:46,640 --> 00:11:51,040 all three of these fields because we're 321 00:11:48,720 --> 00:11:51,920 going to copy out of some source 322 00:11:51,040 --> 00:11:54,000 and 323 00:11:51,920 --> 00:11:55,760 intentionally overwrite you know do 324 00:11:54,000 --> 00:11:57,680 three writes at once is basically what's 325 00:11:55,760 --> 00:12:00,000 going on here 326 00:11:57,680 --> 00:12:02,160 and the kernel had kind of a lot of 327 00:12:00,000 --> 00:12:03,839 these and we can't move on to doing 328 00:12:02,160 --> 00:12:05,440 runtime checking if we can't even build 329 00:12:03,839 --> 00:12:09,279 the kernel in the first place to deal 330 00:12:05,440 --> 00:12:09,279 with these cases either 331 00:12:09,680 --> 00:12:13,600 so 332 00:12:10,880 --> 00:12:16,399 sort of the traditional solution is you 333 00:12:13,600 --> 00:12:17,600 let the compiler have some new way to 334 00:12:16,399 --> 00:12:19,760 refer to 335 00:12:17,600 --> 00:12:21,279 all three of these members under one 336 00:12:19,760 --> 00:12:23,200 name 337 00:12:21,279 --> 00:12:25,519 this is an example of adding a name 338 00:12:23,200 --> 00:12:27,680 structure around these three and then 339 00:12:25,519 --> 00:12:31,200 suddenly you can say okay 340 00:12:27,680 --> 00:12:33,680 we're going to target the tkip 341 00:12:31,200 --> 00:12:36,000 and you know the length we're copying in 342 00:12:33,680 --> 00:12:38,480 is correct everything's everything's 343 00:12:36,000 --> 00:12:41,120 fine we're good 344 00:12:38,480 --> 00:12:43,040 but when we add a named structure like 345 00:12:41,120 --> 00:12:45,120 this because we again we need to be able 346 00:12:43,040 --> 00:12:48,079 to name it so that the mem copy has a 347 00:12:45,120 --> 00:12:50,560 target in mind for its destination 348 00:12:48,079 --> 00:12:53,279 suddenly we have to remove all the 349 00:12:50,560 --> 00:12:55,519 references to the key material member 350 00:12:53,279 --> 00:12:57,680 and replace it with its now full name 351 00:12:55,519 --> 00:13:00,160 which is the you know the the added 352 00:12:57,680 --> 00:13:02,800 structure name dot key material 353 00:13:00,160 --> 00:13:04,560 and doing that for every instance 354 00:13:02,800 --> 00:13:07,279 of each of those members for every 355 00:13:04,560 --> 00:13:09,680 member that gets wrapped in a structure 356 00:13:07,279 --> 00:13:12,959 was going to be 357 00:13:09,680 --> 00:13:16,720 unpalatable shall we say to to upstream 358 00:13:12,959 --> 00:13:16,720 it would be an enormous amount of churn 359 00:13:17,920 --> 00:13:22,240 so 360 00:13:19,839 --> 00:13:24,639 with uh with keith pather keith 361 00:13:22,240 --> 00:13:27,440 packard's help uh i 362 00:13:24,639 --> 00:13:29,760 added struct group as a macro that would 363 00:13:27,440 --> 00:13:31,120 actually give us both you could refer to 364 00:13:29,760 --> 00:13:32,639 things either 365 00:13:31,120 --> 00:13:35,120 by its original name 366 00:13:32,639 --> 00:13:36,639 or by its wrapped name so you'd have 367 00:13:35,120 --> 00:13:38,000 both 368 00:13:36,639 --> 00:13:40,399 both ways of referring to things you 369 00:13:38,000 --> 00:13:42,399 could change you could add your mem copy 370 00:13:40,399 --> 00:13:46,480 but you wouldn't have to rewrite the 371 00:13:42,399 --> 00:13:46,480 rest of all the references to it 372 00:13:46,959 --> 00:13:50,240 uh this works through an interesting uh 373 00:13:49,199 --> 00:13:51,760 trick 374 00:13:50,240 --> 00:13:53,360 uh which is 375 00:13:51,760 --> 00:13:56,480 it's the struct group is actually a 376 00:13:53,360 --> 00:13:58,720 macro that creates a union 377 00:13:56,480 --> 00:14:00,399 of both an anonymous struct and a named 378 00:13:58,720 --> 00:14:02,000 structure but they have identical 379 00:14:00,399 --> 00:14:04,240 members so they'd have the same 380 00:14:02,000 --> 00:14:07,600 locations so each of them the they're 381 00:14:04,240 --> 00:14:07,600 basically alias to each other 382 00:14:09,760 --> 00:14:14,000 and this this works really well 383 00:14:12,160 --> 00:14:14,880 there are some additional helpers for 384 00:14:14,000 --> 00:14:18,000 adding 385 00:14:14,880 --> 00:14:19,360 attributes and tags to to the created 386 00:14:18,000 --> 00:14:20,880 union 387 00:14:19,360 --> 00:14:21,839 and the structures within them stuff 388 00:14:20,880 --> 00:14:24,399 like that 389 00:14:21,839 --> 00:14:26,880 but this solves a problem of getting us 390 00:14:24,399 --> 00:14:29,120 a name a single name that we can use to 391 00:14:26,880 --> 00:14:32,240 refer to a group of sub-members within a 392 00:14:29,120 --> 00:14:34,639 structure without disrupting the rest of 393 00:14:32,240 --> 00:14:34,639 the kernel 394 00:14:36,399 --> 00:14:40,160 so 395 00:14:37,199 --> 00:14:41,040 now we can say all right we've got 396 00:14:40,160 --> 00:14:43,760 you know 397 00:14:41,040 --> 00:14:45,279 m-copy runtime checking is now possible 398 00:14:43,760 --> 00:14:47,199 we can just do this we can do the 399 00:14:45,279 --> 00:14:49,199 built-in object size 400 00:14:47,199 --> 00:14:53,440 with mode 1 401 00:14:49,199 --> 00:14:53,440 just like we thought we could do 402 00:14:53,600 --> 00:14:57,199 and 403 00:14:54,399 --> 00:14:59,600 what happens here then is again at 404 00:14:57,199 --> 00:15:02,000 compile time we're looking at the size 405 00:14:59,600 --> 00:15:05,120 uh and for the for those cases they're 406 00:15:02,000 --> 00:15:06,560 the size is known at compile time 407 00:15:05,120 --> 00:15:08,560 and we get the correct 408 00:15:06,560 --> 00:15:12,320 uh we you know pass the read and write 409 00:15:08,560 --> 00:15:13,920 overflows uh chat tests here and we can 410 00:15:12,320 --> 00:15:16,480 move on to actually 411 00:15:13,920 --> 00:15:19,120 triggering stuff at runtime 412 00:15:16,480 --> 00:15:19,960 the problem of course here is that 413 00:15:19,120 --> 00:15:21,199 we need to 414 00:15:19,960 --> 00:15:24,240 [Music] 415 00:15:21,199 --> 00:15:26,959 deal with similar multi-member 416 00:15:24,240 --> 00:15:28,959 overwrites at runtime there are those in 417 00:15:26,959 --> 00:15:30,959 the kernel as well that aren't visible 418 00:15:28,959 --> 00:15:32,880 at compile time 419 00:15:30,959 --> 00:15:34,000 and that means that instead of just 420 00:15:32,880 --> 00:15:37,360 panicking 421 00:15:34,000 --> 00:15:39,199 we actually have to compare 422 00:15:37,360 --> 00:15:41,920 the mode 0 423 00:15:39,199 --> 00:15:44,959 object size and the mode 1 object size 424 00:15:41,920 --> 00:15:48,079 and if we have encountered a you know a 425 00:15:44,959 --> 00:15:50,240 new version of this with mode 1 426 00:15:48,079 --> 00:15:51,199 uh you know the the more constrained 427 00:15:50,240 --> 00:15:53,360 version 428 00:15:51,199 --> 00:15:55,680 we can't panic the system anymore 429 00:15:53,360 --> 00:15:57,600 because it used to work and now if we 430 00:15:55,680 --> 00:15:59,040 just suddenly say never mind we'll panic 431 00:15:57,600 --> 00:16:01,040 the system every time you're doing the 432 00:15:59,040 --> 00:16:03,600 thing that you've been doing for forever 433 00:16:01,040 --> 00:16:06,000 since memcop used to allow it 434 00:16:03,600 --> 00:16:06,959 that's not going to fly either 435 00:16:06,000 --> 00:16:10,000 so 436 00:16:06,959 --> 00:16:12,720 the now we've had to split these tests 437 00:16:10,000 --> 00:16:13,680 and say if it's a mode 0 failure go 438 00:16:12,720 --> 00:16:15,680 ahead and panic because that's what 439 00:16:13,680 --> 00:16:18,560 we've been doing forever 440 00:16:15,680 --> 00:16:20,480 and on mode 1 we can issue a warning 441 00:16:18,560 --> 00:16:22,560 and the idea is 442 00:16:20,480 --> 00:16:25,279 as we make our way through 443 00:16:22,560 --> 00:16:28,800 a development process and running these 444 00:16:25,279 --> 00:16:30,399 kernels and under real world workloads 445 00:16:28,800 --> 00:16:32,000 we can collect those warnings find the 446 00:16:30,399 --> 00:16:33,920 places where that's happening 447 00:16:32,000 --> 00:16:35,600 and fix them up 448 00:16:33,920 --> 00:16:38,639 the other thing is we can instrument 449 00:16:35,600 --> 00:16:40,880 these and find them in advance 450 00:16:38,639 --> 00:16:42,800 so that's some of the work that i've 451 00:16:40,880 --> 00:16:45,120 been doing is trying to go through and 452 00:16:42,800 --> 00:16:47,920 find these cases where it's happening at 453 00:16:45,120 --> 00:16:50,079 run time and differentiate them from the 454 00:16:47,920 --> 00:16:52,480 places that are where we don't know the 455 00:16:50,079 --> 00:16:54,560 size of the buffer at all 456 00:16:52,480 --> 00:16:55,920 and getting people to find these on 457 00:16:54,560 --> 00:16:57,440 their own rather than just being 458 00:16:55,920 --> 00:16:59,120 surprised by a warning that suddenly 459 00:16:57,440 --> 00:17:00,720 appears 460 00:16:59,120 --> 00:17:02,000 another approach to this has been 461 00:17:00,720 --> 00:17:04,240 running these kinds of instrumented 462 00:17:02,000 --> 00:17:05,679 kernels under sis collar under fuzzing 463 00:17:04,240 --> 00:17:07,919 things like that 464 00:17:05,679 --> 00:17:09,919 so we have a 465 00:17:07,919 --> 00:17:12,880 an advanced warning about getting 466 00:17:09,919 --> 00:17:16,720 getting and fixing these cases 467 00:17:12,880 --> 00:17:18,720 so we don't end up with the surprises 468 00:17:16,720 --> 00:17:20,160 so now we're done oh but no wait a 469 00:17:18,720 --> 00:17:22,079 second let's go back and look at that 470 00:17:20,160 --> 00:17:22,880 list again 471 00:17:22,079 --> 00:17:25,120 so 472 00:17:22,880 --> 00:17:27,280 while we've handled this you know the 473 00:17:25,120 --> 00:17:29,840 what looked like this tiny case of you 474 00:17:27,280 --> 00:17:32,400 know three percent or so 475 00:17:29,840 --> 00:17:33,840 um but that did cover all the cvs in the 476 00:17:32,400 --> 00:17:36,720 past three years 477 00:17:33,840 --> 00:17:39,440 we realistically can't ignore the fact 478 00:17:36,720 --> 00:17:41,919 that more than half of these memcapa 479 00:17:39,440 --> 00:17:43,840 uses are against 480 00:17:41,919 --> 00:17:45,600 destinations sizes 481 00:17:43,840 --> 00:17:49,120 buffer sizes that aren't known to the 482 00:17:45,600 --> 00:17:50,480 compiler they're entirely dynamic 483 00:17:49,120 --> 00:17:52,400 and we 484 00:17:50,480 --> 00:17:54,480 really to you know 485 00:17:52,400 --> 00:17:57,679 to seriously deal with buffer overflows 486 00:17:54,480 --> 00:17:59,120 we need to address this as well 487 00:17:57,679 --> 00:18:01,440 so that's 488 00:17:59,120 --> 00:18:03,440 a big part of that are the the flexible 489 00:18:01,440 --> 00:18:05,200 array case that i talked about a little 490 00:18:03,440 --> 00:18:07,760 bit earlier 491 00:18:05,200 --> 00:18:10,160 and in those cases if you remember built 492 00:18:07,760 --> 00:18:12,559 an object size returns minus one it says 493 00:18:10,160 --> 00:18:15,280 i don't know how big this is 494 00:18:12,559 --> 00:18:16,559 um so these cases 495 00:18:15,280 --> 00:18:17,679 where i'm showing that i've got 496 00:18:16,559 --> 00:18:20,720 highlighted with this with the 497 00:18:17,679 --> 00:18:22,559 destination and source sizes are are are 498 00:18:20,720 --> 00:18:24,160 never true because 499 00:18:22,559 --> 00:18:26,000 we can't know the size for the 500 00:18:24,160 --> 00:18:29,840 destination and it'll just fall straight 501 00:18:26,000 --> 00:18:29,840 through to the underlying mem copy 502 00:18:30,080 --> 00:18:33,520 um 503 00:18:31,120 --> 00:18:36,160 to give you sort of an example of this 504 00:18:33,520 --> 00:18:37,840 and talk a little bit about the flexible 505 00:18:36,160 --> 00:18:40,240 flexible arrays you know here's an 506 00:18:37,840 --> 00:18:42,720 example of some bitmap image and we've 507 00:18:40,240 --> 00:18:44,960 got a count of pixels and then we've got 508 00:18:42,720 --> 00:18:47,039 our pixel data which is not byte size 509 00:18:44,960 --> 00:18:49,360 it's u32 510 00:18:47,039 --> 00:18:52,400 and if we ask built an object size how 511 00:18:49,360 --> 00:18:54,480 big is pixel data it says i don't know 512 00:18:52,400 --> 00:18:56,400 and you can't even you can't even use 513 00:18:54,480 --> 00:18:57,760 sizeof on it this is actually considered 514 00:18:56,400 --> 00:18:59,280 an invalid expression because it's a 515 00:18:57,760 --> 00:19:01,360 flexible array and can't be noted 516 00:18:59,280 --> 00:19:04,400 compile time and sizeof needs to be 517 00:19:01,360 --> 00:19:06,640 evaluatable at compile time 518 00:19:04,400 --> 00:19:08,960 our flexible arrays are a relatively 519 00:19:06,640 --> 00:19:10,880 recent addition to the c 520 00:19:08,960 --> 00:19:12,799 language standard 521 00:19:10,880 --> 00:19:14,880 and before that there were fake flexible 522 00:19:12,799 --> 00:19:16,880 arrays and the kernel of course is 523 00:19:14,880 --> 00:19:18,240 filled to that because it has an old 524 00:19:16,880 --> 00:19:21,360 code base 525 00:19:18,240 --> 00:19:23,760 and the one of them the most the more 526 00:19:21,360 --> 00:19:26,400 recent fake flexible arrays is the zero 527 00:19:23,760 --> 00:19:29,039 element array so this is a new 528 00:19:26,400 --> 00:19:30,880 c extension 529 00:19:29,039 --> 00:19:33,280 but built in object size also considers 530 00:19:30,880 --> 00:19:35,200 this to be a flexible array so we can't 531 00:19:33,280 --> 00:19:38,400 even detect these very easily however 532 00:19:35,200 --> 00:19:41,679 sizeof happily considers this to be zero 533 00:19:38,400 --> 00:19:45,360 bytes long so even if we could somehow 534 00:19:41,679 --> 00:19:46,640 manage use sizeof it would freak out 535 00:19:45,360 --> 00:19:49,760 before that 536 00:19:46,640 --> 00:19:51,200 was the really old style which was a one 537 00:19:49,760 --> 00:19:54,240 element array 538 00:19:51,200 --> 00:19:56,640 and this was what you know what c did 539 00:19:54,240 --> 00:19:58,080 before that and just totally stepped on 540 00:19:56,640 --> 00:20:00,000 itself and 541 00:19:58,080 --> 00:20:01,840 but built an object size again says i 542 00:20:00,000 --> 00:20:04,080 don't know this looks like it's probably 543 00:20:01,840 --> 00:20:06,320 a flexible array so i refuse to believe 544 00:20:04,080 --> 00:20:09,679 how big it is even though size of again 545 00:20:06,320 --> 00:20:12,559 is happily says oh yeah it's uh u32 cool 546 00:20:09,679 --> 00:20:14,159 cool that's that's four bytes 547 00:20:12,559 --> 00:20:16,880 but of course 548 00:20:14,159 --> 00:20:19,520 if i change this to some large value 549 00:20:16,880 --> 00:20:21,919 it is also treated as a flexible array 550 00:20:19,520 --> 00:20:24,080 so any array at the end of a structure 551 00:20:21,919 --> 00:20:26,559 is treated as a flexible array which is 552 00:20:24,080 --> 00:20:29,039 really frustrating because it limits the 553 00:20:26,559 --> 00:20:31,039 ability of 554 00:20:29,039 --> 00:20:32,720 our kernel to be able to do any kind of 555 00:20:31,039 --> 00:20:35,840 bounce checking on something that isn't 556 00:20:32,720 --> 00:20:37,840 a flexible array so the goal here is as 557 00:20:35,840 --> 00:20:39,520 this corner case exists is to fix this 558 00:20:37,840 --> 00:20:41,520 by basically 559 00:20:39,520 --> 00:20:43,520 switching built-in object size around to 560 00:20:41,520 --> 00:20:45,679 refuse to 561 00:20:43,520 --> 00:20:47,760 believe that trailing arrays are 562 00:20:45,679 --> 00:20:49,919 flexible arrays only true flexible 563 00:20:47,760 --> 00:20:51,840 arrays are flexible arrays this doesn't 564 00:20:49,919 --> 00:20:54,240 exist yet for the compiler 565 00:20:51,840 --> 00:20:55,679 the expectation is we're we can add this 566 00:20:54,240 --> 00:20:56,480 option 567 00:20:55,679 --> 00:20:59,200 and 568 00:20:56,480 --> 00:21:00,720 gain back some coverage for things so in 569 00:20:59,200 --> 00:21:02,480 the meantime 570 00:21:00,720 --> 00:21:04,080 if you have an array that you want 571 00:21:02,480 --> 00:21:05,200 protected in your data structure please 572 00:21:04,080 --> 00:21:06,799 don't put it at the end of your 573 00:21:05,200 --> 00:21:09,039 structure 574 00:21:06,799 --> 00:21:09,039 um 575 00:21:09,440 --> 00:21:14,799 right so continuing to use that um 576 00:21:12,159 --> 00:21:17,120 we need to be able to solve dynamically 577 00:21:14,799 --> 00:21:19,919 sized destination overflows 578 00:21:17,120 --> 00:21:22,960 the good news is that the bounds of 579 00:21:19,919 --> 00:21:25,760 these things are stored somewhere 580 00:21:22,960 --> 00:21:27,600 it just takes checking it 581 00:21:25,760 --> 00:21:29,760 and the better news with flexible arrays 582 00:21:27,600 --> 00:21:33,520 is that that is usually stored somewhere 583 00:21:29,760 --> 00:21:36,000 nearby usually in the same structure as 584 00:21:33,520 --> 00:21:38,240 as the flexible array itself 585 00:21:36,000 --> 00:21:40,000 and certainly many call sites already 586 00:21:38,240 --> 00:21:42,240 try to check the bounds but there's 587 00:21:40,000 --> 00:21:43,280 always going to be bugs in open coded 588 00:21:42,240 --> 00:21:44,880 checks 589 00:21:43,280 --> 00:21:46,159 and even within that how many of these 590 00:21:44,880 --> 00:21:48,080 places are remembering to check the 591 00:21:46,159 --> 00:21:50,880 storage size of the variable that 592 00:21:48,080 --> 00:21:53,520 contains the bounds like in this example 593 00:21:50,880 --> 00:21:56,000 the pixels count is a u16 that's not a 594 00:21:53,520 --> 00:21:57,600 size t it's not a 64-bit value it's 595 00:21:56,000 --> 00:22:01,360 small so what happens if you try to 596 00:21:57,600 --> 00:22:01,360 store something that's too big in it 597 00:22:01,520 --> 00:22:06,960 what i'd really like to see in the 598 00:22:03,440 --> 00:22:09,600 future for the c standard is to actually 599 00:22:06,960 --> 00:22:11,520 provide the compiler with a way to 600 00:22:09,600 --> 00:22:13,360 reason about the bounds 601 00:22:11,520 --> 00:22:15,200 so they can do things in a dynamic 602 00:22:13,360 --> 00:22:16,400 fashion this exists in some other 603 00:22:15,200 --> 00:22:18,000 languages 604 00:22:16,400 --> 00:22:21,360 where you can actually hint to the 605 00:22:18,000 --> 00:22:24,159 compiler what is being used to track to 606 00:22:21,360 --> 00:22:26,799 track the size of flexible array 607 00:22:24,159 --> 00:22:28,320 for example this style of syntax 608 00:22:26,799 --> 00:22:31,280 has been proposed 609 00:22:28,320 --> 00:22:33,360 you say pixel data but it's controlled 610 00:22:31,280 --> 00:22:35,280 you know its size is going to be found 611 00:22:33,360 --> 00:22:36,400 in the pixels 612 00:22:35,280 --> 00:22:37,520 member 613 00:22:36,400 --> 00:22:38,880 and then the compiler can actually 614 00:22:37,520 --> 00:22:40,559 reason about the bounds and do sanity 615 00:22:38,880 --> 00:22:42,480 checking and other things 616 00:22:40,559 --> 00:22:44,559 where the other options already exist to 617 00:22:42,480 --> 00:22:45,520 do sanity checking it can extend it and 618 00:22:44,559 --> 00:22:48,880 cover 619 00:22:45,520 --> 00:22:48,880 the flexible array cases too 620 00:22:49,760 --> 00:22:52,159 so 621 00:22:50,799 --> 00:22:55,440 instead of 622 00:22:52,159 --> 00:22:58,080 relying on the compiler and um and these 623 00:22:55,440 --> 00:23:00,400 other missing c features uh we're 624 00:22:58,080 --> 00:23:02,320 basically forced to create a new api 625 00:23:00,400 --> 00:23:05,280 and then disallow 626 00:23:02,320 --> 00:23:08,080 mem copy for destinations that aren't a 627 00:23:05,280 --> 00:23:09,919 constant size there aren't a size known 628 00:23:08,080 --> 00:23:12,880 at compile time 629 00:23:09,919 --> 00:23:15,760 to really cut that sixty percent down uh 630 00:23:12,880 --> 00:23:18,480 dramatically by by replacing the api and 631 00:23:15,760 --> 00:23:20,559 not use mem copy and 632 00:23:18,480 --> 00:23:23,200 move on to new things 633 00:23:20,559 --> 00:23:24,559 so continuing to use this bitmap um 634 00:23:23,200 --> 00:23:26,240 image example 635 00:23:24,559 --> 00:23:28,559 you know here's sort of 636 00:23:26,240 --> 00:23:30,159 what things look like if it's open coded 637 00:23:28,559 --> 00:23:32,559 we've got some 638 00:23:30,159 --> 00:23:34,799 some counts uh we're going to allocate 639 00:23:32,559 --> 00:23:36,320 storage for it we're going to assign 640 00:23:34,799 --> 00:23:37,679 how you know how many pixels there are 641 00:23:36,320 --> 00:23:39,840 and we're going to copy 642 00:23:37,679 --> 00:23:41,279 the screen data off into this 643 00:23:39,840 --> 00:23:42,400 but of course every single one of these 644 00:23:41,279 --> 00:23:44,400 steps 645 00:23:42,400 --> 00:23:47,679 this count that could overflow what are 646 00:23:44,400 --> 00:23:49,520 those types who knows 647 00:23:47,679 --> 00:23:51,279 at least for this example is using 648 00:23:49,520 --> 00:23:53,760 struct size which should do the right 649 00:23:51,279 --> 00:23:56,799 thing as far as calculating a correct 650 00:23:53,760 --> 00:23:59,360 size but if count has already overflowed 651 00:23:56,799 --> 00:24:01,279 that's not going to do the right thing 652 00:23:59,360 --> 00:24:04,480 here we've got a size t count being 653 00:24:01,279 --> 00:24:06,000 assigned to a u16 pixels so that could 654 00:24:04,480 --> 00:24:08,559 go wrong 655 00:24:06,000 --> 00:24:10,640 and then our mem copy is going to do 656 00:24:08,559 --> 00:24:12,720 another open coded 657 00:24:10,640 --> 00:24:16,080 multiplication of 658 00:24:12,720 --> 00:24:17,760 the data size of that of that member 659 00:24:16,080 --> 00:24:20,240 times a count 660 00:24:17,760 --> 00:24:22,640 so each one of these pieces can go wrong 661 00:24:20,240 --> 00:24:24,799 and there's you know in this example no 662 00:24:22,640 --> 00:24:27,279 checking of any of those cases 663 00:24:24,799 --> 00:24:29,360 so if we can replace all of this with a 664 00:24:27,279 --> 00:24:30,320 standard api that actually does all of 665 00:24:29,360 --> 00:24:33,600 that 666 00:24:30,320 --> 00:24:35,840 all of those checks we can actually um 667 00:24:33,600 --> 00:24:38,320 just get rid of a whole bunch of this 668 00:24:35,840 --> 00:24:40,960 and just collapse it into what is 669 00:24:38,320 --> 00:24:44,400 effectively deserialization we're taking 670 00:24:40,960 --> 00:24:45,679 some string of bits 671 00:24:44,400 --> 00:24:47,919 out of memory 672 00:24:45,679 --> 00:24:51,039 and stuffing it into 673 00:24:47,919 --> 00:24:53,919 this you know array of some data type so 674 00:24:51,039 --> 00:24:56,320 it's it's a form of deserialization 675 00:24:53,919 --> 00:24:58,640 and then we can throw out this all the 676 00:24:56,320 --> 00:24:59,520 open coded stuff and um and get it of 677 00:24:58,640 --> 00:25:01,279 course 678 00:24:59,520 --> 00:25:03,600 i've left the 679 00:25:01,279 --> 00:25:05,360 width times height overflow for the 680 00:25:03,600 --> 00:25:07,279 future 681 00:25:05,360 --> 00:25:08,559 since we want to be able to 682 00:25:07,279 --> 00:25:09,840 we need to be able to catch integer 683 00:25:08,559 --> 00:25:11,760 overflows too but that's a whole 684 00:25:09,840 --> 00:25:14,159 separate talk 685 00:25:11,760 --> 00:25:16,080 so there's other helpers that we can add 686 00:25:14,159 --> 00:25:17,840 as well for cases where the allocation 687 00:25:16,080 --> 00:25:20,000 has already occurred so here's an 688 00:25:17,840 --> 00:25:23,200 allocation that has occurred and we've 689 00:25:20,000 --> 00:25:25,279 got the size you know how many 690 00:25:23,200 --> 00:25:27,039 of those members exist is already part 691 00:25:25,279 --> 00:25:29,200 of the structure and we can just do the 692 00:25:27,039 --> 00:25:31,440 deserialization again 693 00:25:29,200 --> 00:25:34,240 but instead of doing the allocation we 694 00:25:31,440 --> 00:25:36,159 can actually check the size and do other 695 00:25:34,240 --> 00:25:38,480 things it's actually more work to do 696 00:25:36,159 --> 00:25:40,480 this uh than than to do the allocation 697 00:25:38,480 --> 00:25:43,440 because we already did the checks on the 698 00:25:40,480 --> 00:25:44,559 allocation size 699 00:25:43,440 --> 00:25:46,720 so 700 00:25:44,559 --> 00:25:48,080 what does that look like 701 00:25:46,720 --> 00:25:50,000 so 702 00:25:48,080 --> 00:25:54,080 the first part is 703 00:25:50,000 --> 00:25:56,159 creating a helper to actually deal with 704 00:25:54,080 --> 00:25:59,360 clamping the size of the data type to 705 00:25:56,159 --> 00:26:01,039 the data type storage for a given member 706 00:25:59,360 --> 00:26:02,960 and just walking through here really 707 00:26:01,039 --> 00:26:06,240 quickly we we 708 00:26:02,960 --> 00:26:08,880 extract uh or rather get a 64-bit 709 00:26:06,240 --> 00:26:10,559 representation of the counts that we've 710 00:26:08,880 --> 00:26:13,200 got 711 00:26:10,559 --> 00:26:16,320 we use another existing macro 712 00:26:13,200 --> 00:26:20,000 to actually find out how large 713 00:26:16,320 --> 00:26:21,919 a value the given member can can store 714 00:26:20,000 --> 00:26:24,640 so it you know it actually goes through 715 00:26:21,919 --> 00:26:27,520 and says oh is this a signed 16 716 00:26:24,640 --> 00:26:29,039 bit value well it can't store 717 00:26:27,520 --> 00:26:30,880 the the full 718 00:26:29,039 --> 00:26:32,320 two bytes it's one bit short of that 719 00:26:30,880 --> 00:26:35,039 because it's signed and basically it 720 00:26:32,320 --> 00:26:37,520 does it has all that logic involved 721 00:26:35,039 --> 00:26:39,600 so we can actually extract that and says 722 00:26:37,520 --> 00:26:41,360 hey if you're trying to store a count 723 00:26:39,600 --> 00:26:42,960 that exceeds the storage 724 00:26:41,360 --> 00:26:45,840 of this member 725 00:26:42,960 --> 00:26:48,159 we're going to freak out and truncate it 726 00:26:45,840 --> 00:26:49,360 and you know warn about it and return a 727 00:26:48,159 --> 00:26:50,880 safe value that can actually be 728 00:26:49,360 --> 00:26:54,400 represented 729 00:26:50,880 --> 00:26:56,320 by that by that one 730 00:26:54,400 --> 00:26:58,240 and i showed that first because it's 731 00:26:56,320 --> 00:27:01,520 basically the first thing that the mem 732 00:26:58,240 --> 00:27:02,720 deflects dupe would do is we've got this 733 00:27:01,520 --> 00:27:04,640 pointer 734 00:27:02,720 --> 00:27:06,480 we're gonna make sure we have a safe 735 00:27:04,640 --> 00:27:09,279 value that we can store we're going to 736 00:27:06,480 --> 00:27:11,760 calculate using struct size helper again 737 00:27:09,279 --> 00:27:12,640 how many bytes it will take to 738 00:27:11,760 --> 00:27:15,279 store 739 00:27:12,640 --> 00:27:17,520 the beginning of the structure plus 740 00:27:15,279 --> 00:27:19,039 you know source count many members 741 00:27:17,520 --> 00:27:20,799 following it 742 00:27:19,039 --> 00:27:22,960 and then we're going to try to allocate 743 00:27:20,799 --> 00:27:25,440 that size if an overflow in in this 744 00:27:22,960 --> 00:27:28,480 occurs uh struct size uh 745 00:27:25,440 --> 00:27:29,760 becomes a size t max and k malek will 746 00:27:28,480 --> 00:27:31,840 refuse to 747 00:27:29,760 --> 00:27:34,559 excuse me we'll refuse to allocate that 748 00:27:31,840 --> 00:27:36,240 so we will not get the allocation 749 00:27:34,559 --> 00:27:36,960 in the next in the test which is why 750 00:27:36,240 --> 00:27:38,960 we're 751 00:27:36,960 --> 00:27:40,159 checking for that 752 00:27:38,960 --> 00:27:42,320 and then we can figure out how many 753 00:27:40,159 --> 00:27:44,320 bytes you want to copy 754 00:27:42,320 --> 00:27:47,279 and we wipe the beginning 755 00:27:44,320 --> 00:27:48,480 of the structure and then copy over uh 756 00:27:47,279 --> 00:27:50,640 what we want 757 00:27:48,480 --> 00:27:53,520 that we're deserializing and then set 758 00:27:50,640 --> 00:27:56,320 the member count 759 00:27:53,520 --> 00:27:58,880 if you're very astute you may notice 760 00:27:56,320 --> 00:28:00,960 in the setting of the member count we're 761 00:27:58,880 --> 00:28:03,200 using this from cpu function that got 762 00:28:00,960 --> 00:28:05,760 passed into the macro 763 00:28:03,200 --> 00:28:07,840 sometimes these 764 00:28:05,760 --> 00:28:10,480 flexible arrays are stored 765 00:28:07,840 --> 00:28:11,380 their their bounds are stored not in 766 00:28:10,480 --> 00:28:13,200 native cpu 767 00:28:11,380 --> 00:28:14,399 [Music] 768 00:28:13,200 --> 00:28:16,320 storage 769 00:28:14,399 --> 00:28:18,480 because they're being used they're being 770 00:28:16,320 --> 00:28:20,640 passed to you know 771 00:28:18,480 --> 00:28:22,799 devices or being passed over the network 772 00:28:20,640 --> 00:28:25,360 or doing other things so the bounds are 773 00:28:22,799 --> 00:28:27,279 tend to be stored not necessarily in cpu 774 00:28:25,360 --> 00:28:29,520 native formats so we actually have to 775 00:28:27,279 --> 00:28:31,679 pass in a conversion 776 00:28:29,520 --> 00:28:33,360 function here that's not the general 777 00:28:31,679 --> 00:28:35,840 case but that 778 00:28:33,360 --> 00:28:39,760 is needed for enough of them that it's 779 00:28:35,840 --> 00:28:39,760 it's a it's now an option for this 780 00:28:40,000 --> 00:28:43,840 and then the big one which doesn't do 781 00:28:42,000 --> 00:28:45,120 the allocation but it has to actually 782 00:28:43,840 --> 00:28:47,200 verify 783 00:28:45,120 --> 00:28:49,440 the sizes of things 784 00:28:47,200 --> 00:28:51,919 it's going to copy 785 00:28:49,440 --> 00:28:53,440 so this does the same clamping at the 786 00:28:51,919 --> 00:28:55,840 beginning 787 00:28:53,440 --> 00:28:57,919 figures out destination 788 00:28:55,840 --> 00:29:00,240 you know how many can we actually store 789 00:28:57,919 --> 00:29:03,840 and this one does a 2 cpu because it may 790 00:29:00,240 --> 00:29:06,559 not be stored in in cpu native form 791 00:29:03,840 --> 00:29:08,480 so we know how many count 792 00:29:06,559 --> 00:29:10,799 we can store to the destination we 793 00:29:08,480 --> 00:29:13,440 calculate the full size of the structure 794 00:29:10,799 --> 00:29:14,880 plus its trailing members 795 00:29:13,440 --> 00:29:17,039 and then we do the same again for the 796 00:29:14,880 --> 00:29:19,120 source and compare the destination and 797 00:29:17,039 --> 00:29:21,679 source and yell very loudly if it's 798 00:29:19,120 --> 00:29:23,440 overflowed and and truncate it if it 799 00:29:21,679 --> 00:29:25,919 were going to overflow 800 00:29:23,440 --> 00:29:27,360 then we can do the mem copy which you 801 00:29:25,919 --> 00:29:30,000 know we've safely we've actually 802 00:29:27,360 --> 00:29:32,640 verified now 803 00:29:30,000 --> 00:29:34,159 and then set the the new member 804 00:29:32,640 --> 00:29:36,320 to the current size 805 00:29:34,159 --> 00:29:39,360 and then return that pointer again 806 00:29:36,320 --> 00:29:41,279 so that does the bulk of that work 807 00:29:39,360 --> 00:29:44,240 and that should get us through 808 00:29:41,279 --> 00:29:46,559 that other 66 percent uh pretty pretty 809 00:29:44,240 --> 00:29:48,720 well it won't cover everything in there 810 00:29:46,559 --> 00:29:50,559 because we'll still have open strings 811 00:29:48,720 --> 00:29:52,640 and other stuff but the 812 00:29:50,559 --> 00:29:55,120 vast majority of the problem is is the 813 00:29:52,640 --> 00:29:56,480 flexible array members um 814 00:29:55,120 --> 00:29:58,240 there's other cases where there are 815 00:29:56,480 --> 00:30:00,960 other bounds you know a single string 816 00:29:58,240 --> 00:30:01,760 allocation has a bounds somewhere so 817 00:30:00,960 --> 00:30:03,679 we'll 818 00:30:01,760 --> 00:30:05,440 as we make our way through the remaining 819 00:30:03,679 --> 00:30:06,399 remainder of that 66 percent we'll 820 00:30:05,440 --> 00:30:08,640 probably 821 00:30:06,399 --> 00:30:11,600 add more apis as we go 822 00:30:08,640 --> 00:30:12,720 but this is what's on the schedule uh as 823 00:30:11,600 --> 00:30:14,559 far as 824 00:30:12,720 --> 00:30:16,799 protecting the kernel 825 00:30:14,559 --> 00:30:18,880 um and i say schedule because 826 00:30:16,799 --> 00:30:20,240 here we are sort of looking at where 827 00:30:18,880 --> 00:30:20,960 things are and 828 00:30:20,240 --> 00:30:23,520 and 829 00:30:20,960 --> 00:30:27,120 what it takes to get things converted 830 00:30:23,520 --> 00:30:29,279 so 5.16 was released uh january 9th and 831 00:30:27,120 --> 00:30:32,559 that has the strut group macro and its 832 00:30:29,279 --> 00:30:34,799 related helpers are in it 833 00:30:32,559 --> 00:30:36,480 and almost all of the flexible array 834 00:30:34,799 --> 00:30:38,799 conversions where we converted from the 835 00:30:36,480 --> 00:30:41,679 ancient style you know 836 00:30:38,799 --> 00:30:43,600 one element array being used you know 837 00:30:41,679 --> 00:30:45,840 being lied to 838 00:30:43,600 --> 00:30:47,679 and zero element arrays uh being 839 00:30:45,840 --> 00:30:49,679 converted to a proper flexible array so 840 00:30:47,679 --> 00:30:51,360 we can actually the compiler can start 841 00:30:49,679 --> 00:30:52,960 to reason about it 842 00:30:51,360 --> 00:30:54,799 better 843 00:30:52,960 --> 00:30:56,159 those are almost almost completely 844 00:30:54,799 --> 00:30:58,080 landed there 845 00:30:56,159 --> 00:31:00,960 for 5.17 846 00:30:58,080 --> 00:31:03,519 which the merge window is open right now 847 00:31:00,960 --> 00:31:05,120 all the struct group conversions using 848 00:31:03,519 --> 00:31:09,120 that new macro 849 00:31:05,120 --> 00:31:10,640 i have landed so we can start adding 850 00:31:09,120 --> 00:31:13,039 the next step would of course be 851 00:31:10,640 --> 00:31:14,880 enforcement but um 852 00:31:13,039 --> 00:31:16,880 and then there's array bounds which i 853 00:31:14,880 --> 00:31:19,200 haven't mentioned until now 854 00:31:16,880 --> 00:31:22,080 this is another case of compiler being 855 00:31:19,200 --> 00:31:25,120 able to check the size of objects for 856 00:31:22,080 --> 00:31:27,360 things beyond just mem copy 857 00:31:25,120 --> 00:31:29,279 it'll actually do 858 00:31:27,360 --> 00:31:31,600 direct 859 00:31:29,279 --> 00:31:34,080 direct accesses on structures it'll 860 00:31:31,600 --> 00:31:35,760 check to see where how large the 861 00:31:34,080 --> 00:31:36,960 allocation or how large it thinks the 862 00:31:35,760 --> 00:31:38,559 object is 863 00:31:36,960 --> 00:31:40,559 so it's related to the built-in object 864 00:31:38,559 --> 00:31:43,840 size almost all those are finally fixed 865 00:31:40,559 --> 00:31:46,640 so we can turn that back on 866 00:31:43,840 --> 00:31:48,320 so hopefully by 5.8 867 00:31:46,640 --> 00:31:50,320 in may 868 00:31:48,320 --> 00:31:51,840 we can enable the compile-time m-copy 869 00:31:50,320 --> 00:31:53,840 enforcement 870 00:31:51,840 --> 00:31:56,559 so we don't have any more of those 871 00:31:53,840 --> 00:31:58,399 cross-member or beyond member 872 00:31:56,559 --> 00:32:00,159 overflows sneaking their way into the 873 00:31:58,399 --> 00:32:03,679 kernel 874 00:32:00,159 --> 00:32:05,440 and hopefully the flexible array 875 00:32:03,679 --> 00:32:07,360 helpers that i talked about in the 876 00:32:05,440 --> 00:32:09,760 previous three slides 877 00:32:07,360 --> 00:32:12,399 will start landing there 878 00:32:09,760 --> 00:32:16,399 and those conversions can begin 879 00:32:12,399 --> 00:32:19,360 and then hopefully on in july for 5.19 880 00:32:16,399 --> 00:32:22,799 uh we can enable the runtime m-copy 881 00:32:19,360 --> 00:32:24,159 enforcement uh so we would have had a 882 00:32:22,799 --> 00:32:26,399 release where 883 00:32:24,159 --> 00:32:28,399 we can get through finding a bunch of 884 00:32:26,399 --> 00:32:30,080 those and fixing them so we can turn 885 00:32:28,399 --> 00:32:31,760 them on 886 00:32:30,080 --> 00:32:35,360 and hopefully then we will come out of 887 00:32:31,760 --> 00:32:39,120 this year with a vastly improved 888 00:32:35,360 --> 00:32:41,919 buffer overflow defense in the kernel 889 00:32:39,120 --> 00:32:44,240 that everyone can actually use when they 890 00:32:41,919 --> 00:32:46,399 turn on fortify source my goal would 891 00:32:44,240 --> 00:32:49,440 actually be make fortify souls fortify 892 00:32:46,399 --> 00:32:50,799 source a default there's no good reason 893 00:32:49,440 --> 00:32:52,799 not to have it on 894 00:32:50,799 --> 00:32:54,840 it's like if you don't have it on you 895 00:32:52,799 --> 00:32:57,360 just want to get owned for some 896 00:32:54,840 --> 00:33:00,000 reason um 897 00:32:57,360 --> 00:33:02,799 so i've got a little bit of time left 898 00:33:00,000 --> 00:33:05,360 over um i've got any questions or 899 00:33:02,799 --> 00:33:06,720 feedback uh now's a good time i think 900 00:33:05,360 --> 00:33:09,519 we're gonna go through any questions 901 00:33:06,720 --> 00:33:11,279 that came up or answer anything 902 00:33:09,519 --> 00:33:13,039 that's there so thank you for your 903 00:33:11,279 --> 00:33:14,080 attention um 904 00:33:13,039 --> 00:33:17,519 you can 905 00:33:14,080 --> 00:33:21,120 get the slides here and email me or see 906 00:33:17,519 --> 00:33:21,120 me on twitter so thank you 907 00:33:21,600 --> 00:33:27,600 hi thank you kate um i tried my best to 908 00:33:25,679 --> 00:33:29,679 to follow that i haven't even looked at 909 00:33:27,600 --> 00:33:32,720 c in years so it was a challenge but it 910 00:33:29,679 --> 00:33:34,480 was eye-opening so thank you so much and 911 00:33:32,720 --> 00:33:36,240 judging from the chat there were quite a 912 00:33:34,480 --> 00:33:40,399 lot of people who were able to follow it 913 00:33:36,240 --> 00:33:43,120 much better than i was um so there are 914 00:33:40,399 --> 00:33:45,519 quite a few questions here so everyone 915 00:33:43,120 --> 00:33:48,080 please go um upload the questions you 916 00:33:45,519 --> 00:33:50,960 want to make sure we get time for 917 00:33:48,080 --> 00:33:54,000 and i'll start in on them 918 00:33:50,960 --> 00:33:56,960 so the top question right now is what is 919 00:33:54,000 --> 00:34:00,080 the actual use case for built-in object 920 00:33:56,960 --> 00:34:04,000 size foo zero i'm struggling to imagine 921 00:34:00,080 --> 00:34:05,679 what the use case for mode zero is um so 922 00:34:04,000 --> 00:34:08,240 mode zero 923 00:34:05,679 --> 00:34:10,480 difference was inter object and intra 924 00:34:08,240 --> 00:34:13,040 object so being able to block 925 00:34:10,480 --> 00:34:14,480 a mem copy beyond the edge of a 926 00:34:13,040 --> 00:34:16,960 structure so you wouldn't have an 927 00:34:14,480 --> 00:34:20,639 overflow from an m copy from one 928 00:34:16,960 --> 00:34:24,320 structure into the next structure 929 00:34:20,639 --> 00:34:26,000 mostly it's there for the reasons i 930 00:34:24,320 --> 00:34:28,560 outlined and all the gotchas we had 931 00:34:26,000 --> 00:34:30,560 within the kernel is that the c source 932 00:34:28,560 --> 00:34:32,240 like c sources have been abusing them 933 00:34:30,560 --> 00:34:34,879 copy for so long 934 00:34:32,240 --> 00:34:37,839 by doing this intentional overflow um 935 00:34:34,879 --> 00:34:39,760 but overflow didn't tend to go beyond 936 00:34:37,839 --> 00:34:40,879 the end of a structure 937 00:34:39,760 --> 00:34:43,200 um so 938 00:34:40,879 --> 00:34:45,200 you'd had you know this you know inexact 939 00:34:43,200 --> 00:34:47,040 form where you'd say sure sure we can 940 00:34:45,200 --> 00:34:48,720 know the size of it for this but we 941 00:34:47,040 --> 00:34:50,320 can't go beyond it 942 00:34:48,720 --> 00:34:52,879 and then we can tighten it and once 943 00:34:50,320 --> 00:34:55,919 we've you know eliminated 944 00:34:52,879 --> 00:34:56,800 all of the cases in a in a given 945 00:34:55,919 --> 00:35:00,079 tree 946 00:34:56,800 --> 00:35:01,680 uh of of that kind of thing and that was 947 00:35:00,079 --> 00:35:03,440 if i'm remembering correctly i think 948 00:35:01,680 --> 00:35:07,440 that for 949 00:35:03,440 --> 00:35:09,520 user space builds um like glib c 950 00:35:07,440 --> 00:35:11,760 stuff like that where fortify source had 951 00:35:09,520 --> 00:35:13,680 two modes which was uh fortify source 952 00:35:11,760 --> 00:35:16,480 equals one which would actually be mode 953 00:35:13,680 --> 00:35:18,000 zero for uh the bos 954 00:35:16,480 --> 00:35:20,240 and fortify starts equals two would 955 00:35:18,000 --> 00:35:22,560 actually be mode one for bos so it was 956 00:35:20,240 --> 00:35:25,440 mostly about 957 00:35:22,560 --> 00:35:28,400 having a migration path towards a 958 00:35:25,440 --> 00:35:30,560 stricter code base 959 00:35:28,400 --> 00:35:32,960 it's amazing how um 960 00:35:30,560 --> 00:35:36,320 hearing about i guess historical 961 00:35:32,960 --> 00:35:37,599 patterns of use and misuse kind of 962 00:35:36,320 --> 00:35:39,680 influence 963 00:35:37,599 --> 00:35:42,560 all of the the really 964 00:35:39,680 --> 00:35:44,400 technical details of things and how 965 00:35:42,560 --> 00:35:46,560 changes are made painful it's 966 00:35:44,400 --> 00:35:48,079 fascinating 967 00:35:46,560 --> 00:35:50,160 um 968 00:35:48,079 --> 00:35:52,640 all right next question 969 00:35:50,160 --> 00:35:55,839 how did you find and categorize these 30 970 00:35:52,640 --> 00:35:57,440 000 or so uses of mem copy 971 00:35:55,839 --> 00:35:58,960 yeah that's a good question 972 00:35:57,440 --> 00:36:00,960 that's probably probably the easiest 973 00:35:58,960 --> 00:36:02,880 part of it um 974 00:36:00,960 --> 00:36:05,359 but let's see if i can go up through 975 00:36:02,880 --> 00:36:08,079 slides and show 976 00:36:05,359 --> 00:36:11,280 if we look at the here we go 977 00:36:08,079 --> 00:36:13,680 uh in in the in the mem copy 978 00:36:11,280 --> 00:36:16,640 fortified mem copy we can actually see 979 00:36:13,680 --> 00:36:18,480 the the different states we can see when 980 00:36:16,640 --> 00:36:21,359 we have a dynamic size versus a constant 981 00:36:18,480 --> 00:36:22,240 size when we know the size or not 982 00:36:21,359 --> 00:36:24,400 so 983 00:36:22,240 --> 00:36:25,760 we can emit warnings 984 00:36:24,400 --> 00:36:29,040 in each of these cases because this is 985 00:36:25,760 --> 00:36:31,760 an inline function so for e if we if we 986 00:36:29,040 --> 00:36:33,760 add a warning like we do for the 987 00:36:31,760 --> 00:36:36,560 the write overflow and read overflow 988 00:36:33,760 --> 00:36:39,200 functions here um we'll actually 989 00:36:36,560 --> 00:36:40,720 throw a compile time 990 00:36:39,200 --> 00:36:42,640 well that those will throw compile time 991 00:36:40,720 --> 00:36:44,160 error but if you do a compile time 992 00:36:42,640 --> 00:36:46,079 warning 993 00:36:44,160 --> 00:36:47,839 you can actually build build the entire 994 00:36:46,079 --> 00:36:49,760 tree and then you just catch all the 995 00:36:47,839 --> 00:36:51,599 warnings and collate them at the end and 996 00:36:49,760 --> 00:36:54,000 just look at them because you'll have 997 00:36:51,599 --> 00:36:55,760 one warning for each use of memcapi in 998 00:36:54,000 --> 00:36:56,880 each of the different states 999 00:36:55,760 --> 00:37:00,000 so that that's actually pretty 1000 00:36:56,880 --> 00:37:03,440 straightforward but it's also i said for 1001 00:37:00,000 --> 00:37:05,599 the all mod config build isn't strictly 1002 00:37:03,440 --> 00:37:09,800 a representation of the real world but 1003 00:37:05,599 --> 00:37:09,800 it is the worst case scenario 1004 00:37:11,680 --> 00:37:15,599 great it's yeah 1005 00:37:13,839 --> 00:37:18,160 that does sound easier than i was 1006 00:37:15,599 --> 00:37:20,000 expecting it to be 1007 00:37:18,160 --> 00:37:22,160 um okay 1008 00:37:20,000 --> 00:37:25,200 how do you enforce the usage of the new 1009 00:37:22,160 --> 00:37:26,320 macros like struct group and new code 1010 00:37:25,200 --> 00:37:27,280 um 1011 00:37:26,320 --> 00:37:30,160 so 1012 00:37:27,280 --> 00:37:32,800 this is one of the painful parts of of 1013 00:37:30,160 --> 00:37:34,160 making these migrations in the kernel 1014 00:37:32,800 --> 00:37:36,320 uh is 1015 00:37:34,160 --> 00:37:39,280 there isn't really a good way to enforce 1016 00:37:36,320 --> 00:37:41,920 it until everything's done um 1017 00:37:39,280 --> 00:37:43,599 so really it's mostly a matter of uh 1018 00:37:41,920 --> 00:37:45,280 educating people 1019 00:37:43,599 --> 00:37:47,920 adding checks where 1020 00:37:45,280 --> 00:37:49,680 where it's possible in in the compiler 1021 00:37:47,920 --> 00:37:51,440 as we slowly make our way through 1022 00:37:49,680 --> 00:37:52,640 various subsystems 1023 00:37:51,440 --> 00:37:55,520 um 1024 00:37:52,640 --> 00:37:57,520 adding because there's a check patch 1025 00:37:55,520 --> 00:37:59,440 perl script that tries to do some sanity 1026 00:37:57,520 --> 00:38:01,440 checks on patches that are being uh 1027 00:37:59,440 --> 00:38:02,320 proposed for the kernel so that could 1028 00:38:01,440 --> 00:38:04,560 you know 1029 00:38:02,320 --> 00:38:06,000 warn about hey it looks like this isn't 1030 00:38:04,560 --> 00:38:08,160 known or something 1031 00:38:06,000 --> 00:38:10,160 um you should try using the new api so 1032 00:38:08,160 --> 00:38:12,800 it's mostly about education and other 1033 00:38:10,160 --> 00:38:14,800 things but once you get to a 1034 00:38:12,800 --> 00:38:17,200 tipping point really you can we can 1035 00:38:14,800 --> 00:38:19,040 actually modify this mem copy again to 1036 00:38:17,200 --> 00:38:20,640 say oh hey 1037 00:38:19,040 --> 00:38:23,520 i have a destination size out of 1038 00:38:20,640 --> 00:38:25,760 built-in object size that says -1 1039 00:38:23,520 --> 00:38:28,400 we don't even allow that to build 1040 00:38:25,760 --> 00:38:31,520 anymore and then suddenly you the only 1041 00:38:28,400 --> 00:38:33,359 thing you can do is use that api 1042 00:38:31,520 --> 00:38:35,359 i don't expect that to happen 1043 00:38:33,359 --> 00:38:37,920 anytime soon 1044 00:38:35,359 --> 00:38:40,720 but we can use similar instrumentation 1045 00:38:37,920 --> 00:38:43,839 to how i pulled the numbers on on uses 1046 00:38:40,720 --> 00:38:45,920 and see like how much you know how how 1047 00:38:43,839 --> 00:38:48,960 much further do we have what's missing 1048 00:38:45,920 --> 00:38:48,960 what else can we fill in 1049 00:38:50,560 --> 00:38:55,359 okay our next question 1050 00:38:53,119 --> 00:38:58,640 is are distribution kernels usually 1051 00:38:55,359 --> 00:39:01,200 compiled with fortify source currently 1052 00:38:58,640 --> 00:39:03,359 yes um as far as i know every 1053 00:39:01,200 --> 00:39:05,200 distribution i've seen has fortify 1054 00:39:03,359 --> 00:39:07,119 source enabled for their uh for their 1055 00:39:05,200 --> 00:39:10,320 kernels um 1056 00:39:07,119 --> 00:39:12,480 almost no one is using um config ubison 1057 00:39:10,320 --> 00:39:16,240 bounds right now the only one i know of 1058 00:39:12,480 --> 00:39:18,240 is android so the kernel on android is 1059 00:39:16,240 --> 00:39:20,720 is you know blocking 1060 00:39:18,240 --> 00:39:23,680 array index overflows but no one else is 1061 00:39:20,720 --> 00:39:26,079 yet um i've been kind of uh 1062 00:39:23,680 --> 00:39:27,040 harassing the the ubuntu kernel team 1063 00:39:26,079 --> 00:39:29,440 nicely 1064 00:39:27,040 --> 00:39:32,400 to turn that on um they ran into 1065 00:39:29,440 --> 00:39:34,240 problems with uh out of tree modules 1066 00:39:32,400 --> 00:39:36,640 actually doing the wrong thing like they 1067 00:39:34,240 --> 00:39:38,880 were they had bugs in them so they had 1068 00:39:36,640 --> 00:39:40,560 to turn it off you know that some some 1069 00:39:38,880 --> 00:39:42,880 driver that people would load would 1070 00:39:40,560 --> 00:39:43,920 instantly crash a system because 1071 00:39:42,880 --> 00:39:46,480 they were 1072 00:39:43,920 --> 00:39:48,480 actually accessing their own stuff 1073 00:39:46,480 --> 00:39:50,640 with the wrong indexes 1074 00:39:48,480 --> 00:39:53,839 but as those get fixed we can hopefully 1075 00:39:50,640 --> 00:39:53,839 more distros will turn that on 1076 00:39:54,800 --> 00:39:59,839 somewhat related is there any particular 1077 00:39:57,520 --> 00:40:01,920 list news site etc to follow for new 1078 00:39:59,839 --> 00:40:03,359 safer copy semantics as they land in the 1079 00:40:01,920 --> 00:40:04,720 kernel 1080 00:40:03,359 --> 00:40:06,800 um 1081 00:40:04,720 --> 00:40:08,079 i would say 1082 00:40:06,800 --> 00:40:10,960 lwn 1083 00:40:08,079 --> 00:40:12,800 usually has a lot of write-ups on on new 1084 00:40:10,960 --> 00:40:15,200 developments as they're coming um 1085 00:40:12,800 --> 00:40:16,960 there's also uh 1086 00:40:15,200 --> 00:40:19,920 some kernel documentation 1087 00:40:16,960 --> 00:40:23,119 in the process docs on on deprecated 1088 00:40:19,920 --> 00:40:24,480 um interfaces and apis and language 1089 00:40:23,119 --> 00:40:26,560 forms 1090 00:40:24,480 --> 00:40:27,280 and that's probably a good place to look 1091 00:40:26,560 --> 00:40:29,520 as 1092 00:40:27,280 --> 00:40:31,040 as we remove stuff 1093 00:40:29,520 --> 00:40:33,680 from the kernel 1094 00:40:31,040 --> 00:40:36,160 like disallowing variable length arrays 1095 00:40:33,680 --> 00:40:37,839 and doing other stuff that ends up going 1096 00:40:36,160 --> 00:40:39,920 into the deprecated 1097 00:40:37,839 --> 00:40:41,760 documentations it says you know you 1098 00:40:39,920 --> 00:40:43,839 can't can't do these things anymore and 1099 00:40:41,760 --> 00:40:47,040 most them get enforced 1100 00:40:43,839 --> 00:40:47,040 by compiler options 1101 00:40:48,800 --> 00:40:52,400 we've still got a few more questions and 1102 00:40:50,800 --> 00:40:54,560 we've got i think just under five 1103 00:40:52,400 --> 00:40:56,240 minutes to go so we'll just keep going 1104 00:40:54,560 --> 00:40:58,640 with your questions thanks everyone for 1105 00:40:56,240 --> 00:41:00,079 posting so many questions you've got a 1106 00:40:58,640 --> 00:41:03,599 really really 1107 00:41:00,079 --> 00:41:06,760 interested audience there case okay um 1108 00:41:03,599 --> 00:41:06,760 all right 1109 00:41:07,280 --> 00:41:12,560 i'll be in the other the post talk chat 1110 00:41:09,920 --> 00:41:14,000 room as well um since i couldn't watch 1111 00:41:12,560 --> 00:41:16,400 chat while doing this but i'll be in 1112 00:41:14,000 --> 00:41:18,640 that that one uh so if there's if we run 1113 00:41:16,400 --> 00:41:19,680 out of time i'm happy to keep talking 1114 00:41:18,640 --> 00:41:21,920 there 1115 00:41:19,680 --> 00:41:24,160 yeah we've still got time for uh 1116 00:41:21,920 --> 00:41:25,280 a couple more questions live 1117 00:41:24,160 --> 00:41:27,920 um 1118 00:41:25,280 --> 00:41:30,160 rapidly being uploaded right now 1119 00:41:27,920 --> 00:41:33,119 is what is the overall performance 1120 00:41:30,160 --> 00:41:35,760 impact of turning all the safeties on 1121 00:41:33,119 --> 00:41:36,720 um almost nothing 1122 00:41:35,760 --> 00:41:38,960 the 1123 00:41:36,720 --> 00:41:40,800 the sizes are 1124 00:41:38,960 --> 00:41:42,480 i mean most of the stuff is compile time 1125 00:41:40,800 --> 00:41:44,560 and then adding a check 1126 00:41:42,480 --> 00:41:48,079 like this tends to 1127 00:41:44,560 --> 00:41:49,040 end up with one one compare added which 1128 00:41:48,079 --> 00:41:52,720 gets 1129 00:41:49,040 --> 00:41:54,160 totally lost um in in the overall 1130 00:41:52,720 --> 00:41:56,079 the work because you're about to do a 1131 00:41:54,160 --> 00:41:57,359 mem copy usually 1132 00:41:56,079 --> 00:41:59,599 in into 1133 00:41:57,359 --> 00:42:01,119 you know an area you've you know the 1134 00:41:59,599 --> 00:42:03,599 memory is already hot there's all these 1135 00:42:01,119 --> 00:42:05,359 other things and even the branches 1136 00:42:03,599 --> 00:42:06,560 don't don't appear to be measurably 1137 00:42:05,359 --> 00:42:08,400 different 1138 00:42:06,560 --> 00:42:10,400 it adds a tiny 1139 00:42:08,400 --> 00:42:11,839 amount of image size because you're 1140 00:42:10,400 --> 00:42:13,680 adding a couple bytes for the 1141 00:42:11,839 --> 00:42:16,160 instructions to do the checks but it's 1142 00:42:13,680 --> 00:42:18,480 it's almost nothing which is kind of 1143 00:42:16,160 --> 00:42:20,160 nice because it's a it's a very very low 1144 00:42:18,480 --> 00:42:22,560 cost 1145 00:42:20,160 --> 00:42:25,440 and it's deterministic 1146 00:42:22,560 --> 00:42:27,760 that that's great when um 1147 00:42:25,440 --> 00:42:30,480 such significant improvements like that 1148 00:42:27,760 --> 00:42:32,400 don't come at too much of a cost yeah 1149 00:42:30,480 --> 00:42:34,000 it's so good 1150 00:42:32,400 --> 00:42:36,560 um okay 1151 00:42:34,000 --> 00:42:39,280 what's next i noticed one of the copy 1152 00:42:36,560 --> 00:42:42,240 macros included a memset call zeroing 1153 00:42:39,280 --> 00:42:43,599 the dust is this a behavior change 1154 00:42:42,240 --> 00:42:46,800 um 1155 00:42:43,599 --> 00:42:48,480 it might be it depends on 1156 00:42:46,800 --> 00:42:52,319 on what the uh 1157 00:42:48,480 --> 00:42:53,280 what the prior code was doing um 1158 00:42:52,319 --> 00:42:55,440 the 1159 00:42:53,280 --> 00:42:58,400 i would argue that it's a correct it's a 1160 00:42:55,440 --> 00:43:01,280 it's a correctness change and that if it 1161 00:42:58,400 --> 00:43:02,880 is if it is a behavior change that's a 1162 00:43:01,280 --> 00:43:05,280 problem because that means something was 1163 00:43:02,880 --> 00:43:08,240 depending on an old value that wasn't 1164 00:43:05,280 --> 00:43:09,760 being cleared uh since we're uh 1165 00:43:08,240 --> 00:43:13,119 since what's being allocated is the 1166 00:43:09,760 --> 00:43:15,520 entire structure plus the trailing 1167 00:43:13,119 --> 00:43:18,160 arrays 1168 00:43:15,520 --> 00:43:20,160 you want to have initialized 1169 00:43:18,160 --> 00:43:23,119 the rest of the structure 1170 00:43:20,160 --> 00:43:25,520 and if you haven't that's a problem 1171 00:43:23,119 --> 00:43:27,680 and a flaw in itself normally when you 1172 00:43:25,520 --> 00:43:30,319 look at 1173 00:43:27,680 --> 00:43:32,800 the code for these things you'll have an 1174 00:43:30,319 --> 00:43:34,640 allocation and then it'll set a whole 1175 00:43:32,800 --> 00:43:36,800 bunch of members within the structure 1176 00:43:34,640 --> 00:43:39,440 and then i'll do the copy et cetera 1177 00:43:36,800 --> 00:43:42,079 so adding the memset 1178 00:43:39,440 --> 00:43:44,480 would seem like it might be redundant in 1179 00:43:42,079 --> 00:43:46,640 these cases but luckily that stuff will 1180 00:43:44,480 --> 00:43:49,119 get elided by the compiler when the 1181 00:43:46,640 --> 00:43:51,280 compiler tries to do the compile because 1182 00:43:49,119 --> 00:43:54,480 it sees a mem set but then it sees later 1183 00:43:51,280 --> 00:43:55,839 rights uh that are that are being put 1184 00:43:54,480 --> 00:43:57,760 into the same place 1185 00:43:55,839 --> 00:43:59,119 and i'll just get rid of the zeroing 1186 00:43:57,760 --> 00:44:00,000 that happens in all the places that it 1187 00:43:59,119 --> 00:44:01,839 can 1188 00:44:00,000 --> 00:44:06,160 so you usually end up with absolutely no 1189 00:44:01,839 --> 00:44:06,160 difference in the final binary output 1190 00:44:06,319 --> 00:44:12,880 so i'm just grinning wildly because i 1191 00:44:09,359 --> 00:44:15,520 have definitely myself both written and 1192 00:44:12,880 --> 00:44:18,400 fixed code that has been unknowingly 1193 00:44:15,520 --> 00:44:20,240 dependent on on bugs or gaps in the in 1194 00:44:18,400 --> 00:44:22,640 the language itself 1195 00:44:20,240 --> 00:44:24,640 very familiar with that 1196 00:44:22,640 --> 00:44:25,920 um okay we've got time for one more 1197 00:44:24,640 --> 00:44:28,160 question live 1198 00:44:25,920 --> 00:44:30,160 what is the second most common cause of 1199 00:44:28,160 --> 00:44:32,400 cds 1200 00:44:30,160 --> 00:44:36,520 second most common i'm not sure this is 1201 00:44:32,400 --> 00:44:36,520 even the most common but um 1202 00:44:38,000 --> 00:44:43,040 i haven't gone through to to analyze 1203 00:44:40,160 --> 00:44:44,560 them lately um i'd say 1204 00:44:43,040 --> 00:44:46,720 i'd say probably 1205 00:44:44,560 --> 00:44:50,240 this may be the second most common uh 1206 00:44:46,720 --> 00:44:52,400 i'd say probably one of the largest 1207 00:44:50,240 --> 00:44:54,640 issues that the colonel is still dealing 1208 00:44:52,400 --> 00:44:57,040 with is use after free 1209 00:44:54,640 --> 00:44:58,319 so just dealing with temporal problems 1210 00:44:57,040 --> 00:45:01,839 with 1211 00:44:58,319 --> 00:45:04,640 bad code freeing a portion of memory 1212 00:45:01,839 --> 00:45:06,800 that it thinks uh is no longer being 1213 00:45:04,640 --> 00:45:07,920 used but something else is using it 1214 00:45:06,800 --> 00:45:10,240 um 1215 00:45:07,920 --> 00:45:12,319 there's a lot of causes for that some of 1216 00:45:10,240 --> 00:45:13,920 that is arithmetic overflow which is 1217 00:45:12,319 --> 00:45:16,079 gonna be another piece that we're gonna 1218 00:45:13,920 --> 00:45:17,520 take a look at once once this is nailed 1219 00:45:16,079 --> 00:45:19,200 down 1220 00:45:17,520 --> 00:45:21,200 but yeah i would say use after free 1221 00:45:19,200 --> 00:45:22,480 arithmetic overflow and buffer overflows 1222 00:45:21,200 --> 00:45:25,280 are 1223 00:45:22,480 --> 00:45:28,240 related they're interrelated and 1224 00:45:25,280 --> 00:45:31,280 the some of the major problems 1225 00:45:28,240 --> 00:45:31,280 with c generally 1226 00:45:31,599 --> 00:45:36,160 hit the tricky ones from my limited 1227 00:45:34,160 --> 00:45:38,400 memory of c 1228 00:45:36,160 --> 00:45:40,079 all right okay we are out of time 1229 00:45:38,400 --> 00:45:42,560 so there are still a couple more 1230 00:45:40,079 --> 00:45:45,680 questions in the questions tab uh 1231 00:45:42,560 --> 00:45:47,119 we will copy them over to the 1232 00:45:45,680 --> 00:45:50,240 the 1233 00:45:47,119 --> 00:45:53,200 post talk chat kaya theater text channel 1234 00:45:50,240 --> 00:45:54,880 which is over in the in venulis in the 1235 00:45:53,200 --> 00:45:57,040 in the tab if it's not appearing for you 1236 00:45:54,880 --> 00:45:59,200 in the channel list um click the browse 1237 00:45:57,040 --> 00:46:01,680 all channels and find post talk chat 1238 00:45:59,200 --> 00:46:03,680 kaya theater and join that um case we'll 1239 00:46:01,680 --> 00:46:04,880 head over to there for a bit of a chat 1240 00:46:03,680 --> 00:46:05,839 during the break 1241 00:46:04,880 --> 00:46:08,000 um 1242 00:46:05,839 --> 00:46:09,680 so thank you very much for your talk 1243 00:46:08,000 --> 00:46:12,319 case i'm pretty sure you're gonna get a 1244 00:46:09,680 --> 00:46:14,880 lot of questions in the chat um 1245 00:46:12,319 --> 00:46:17,280 and have have a have a good quick break 1246 00:46:14,880 --> 00:46:21,319 everyone and we will be back shortly 1247 00:46:17,280 --> 00:46:21,319 awesome thank you bye