1 00:00:00,000 --> 00:00:00,180 2 00:00:00,180 --> 00:00:02,920 >> SPEAKER 1: Let's write a program that gets a string from the user without 3 00:00:02,920 --> 00:00:05,700 using the CS50 Library's function GetString. 4 00:00:05,700 --> 00:00:08,720 To do this, we'll go ahead and use scanf, the function that the GetString 5 00:00:08,720 --> 00:00:10,950 function actually uses underneath the hood. 6 00:00:10,950 --> 00:00:13,780 But I'm going to do this deliberately in a buggy way. 7 00:00:13,780 --> 00:00:17,230 I'm going to do in a way that I think would be right, but it turns out that 8 00:00:17,230 --> 00:00:19,380 my assumption's going to be quite, quite flawed. 9 00:00:19,380 --> 00:00:20,800 And in fact, quite dangerous. 10 00:00:20,800 --> 00:00:24,750 Because bugs like the one I'm about to make can be exploited by adversaries 11 00:00:24,750 --> 00:00:28,870 such that your machine or your program can be taken over potentially. 12 00:00:28,870 --> 00:00:30,200 >> Let's begin as follows. 13 00:00:30,200 --> 00:00:33,540 First let's declare our string, otherwise known now as a char star, 14 00:00:33,540 --> 00:00:34,750 and call it s. 15 00:00:34,750 --> 00:00:39,400 Lets next prompt the user for a string, as with "string please." And 16 00:00:39,400 --> 00:00:44,250 let's now get the string from the user using scanf, quote unquote, "%s." In 17 00:00:44,250 --> 00:00:47,760 other words, let's inform scanf that we do in fact expect to get a string 18 00:00:47,760 --> 00:00:48,630 from the user. 19 00:00:48,630 --> 00:00:50,810 >> But now we need to tell scanf one other thing-- 20 00:00:50,810 --> 00:00:53,350 where to put the string that the user provides. 21 00:00:53,350 --> 00:00:57,840 Well, I'm going to quite simply start with comma s, specifying that I'd like 22 00:00:57,840 --> 00:00:59,320 scanf to put the string there. 23 00:00:59,320 --> 00:01:04,818 I'm next going to print out something like printf "thanks for the %s 24 00:01:04,818 --> 00:01:10,670 backslash n comma." And as always, I'm going to pass in the string, s. 25 00:01:10,670 --> 00:01:14,920 Now let's save, compile, and run this program, and see if we can't induce 26 00:01:14,920 --> 00:01:16,590 the problem I predicted. 27 00:01:16,590 --> 00:01:18,650 >> Make scanf-1. 28 00:01:18,650 --> 00:01:20,960 ./scanf-1. 29 00:01:20,960 --> 00:01:21,830 String please. 30 00:01:21,830 --> 00:01:25,540 Let's provide something like, "hello." "Thanks for the null." Hmm, that's not 31 00:01:25,540 --> 00:01:26,750 what I was expecting. 32 00:01:26,750 --> 00:01:28,240 So what's going on here? 33 00:01:28,240 --> 00:01:32,040 >> Well, it turns out because we declared s as a char star but we didn't 34 00:01:32,040 --> 00:01:36,120 actually stored in s the address of an actual chunk of memory, scanf didn't 35 00:01:36,120 --> 00:01:38,940 have anywhere to put the string that the user typed in. 36 00:01:38,940 --> 00:01:42,510 Indeed, if the user were to now type in a much longer string than "hello," 37 00:01:42,510 --> 00:01:46,780 for instance several lines of text or several paragraphs of text, it's quite 38 00:01:46,780 --> 00:01:50,280 possible that we might induce a so-called segmentation fault. 39 00:01:50,280 --> 00:01:53,570 >> Because scanf isn't going to know that I haven't actually put an address 40 00:01:53,570 --> 00:01:54,610 inside of s. 41 00:01:54,610 --> 00:01:58,000 Rather, it's going to see some value in s, some pattern of bits that may 42 00:01:58,000 --> 00:02:00,910 very well be a garbage value, there just by chance. 43 00:02:00,910 --> 00:02:04,600 And scanf is still going to try to write the user string to that address, 44 00:02:04,600 --> 00:02:08,789 even if it is a garbage value, which could indeed induce a crash. 45 00:02:08,789 --> 00:02:10,130 >> So how are we going to fix this? 46 00:02:10,130 --> 00:02:12,523