1/ It's been very busy at MS ever since the new year started, and you've probably seen a bit of what we're working on with Visual Studio 2022 (devblogs.microsoft.com/visualstudio/v…).
2/ I'm going to go further back in history though, and talk about a defining moment for Visual Studio .NET (2002) and really all of Microsoft. In early 2002, Bill Gates sent a memo to the entire company that kicked off the Trustworthy Computing initiative.
3/ There had recently been a raft of serious computer viruses, coupled with the September 11th terrorist attacks; it was a turning point for the country, industry, and company.
4/ In DevDiv, that translated into a concentrated three month effort in which every single line of code was reviewed. Threat models were built, architecture inspected, trust boundaries defined, and fuzz testing performed.
5/ Visual Studio is unique – its primary purpose is to develop applications that, by definition, can and should be able to execute arbitrary actions in the security context of the logged-in user (and, indeed, in other contexts as dictated by the application being developed).
6/ There was, at the time, significant skepticism about whether there was any need to secure Visual Studio given its use cases. There was concern that no such protection could be given anyway.
7/ Finally, there was disagreement about whether developers needed such protection; surely developers were savvy enough to understand that VS would ultimately run code, and therefore the developer must always trust the code being run.
8/ This was institutionalized thinking at the time, and it took effort to reorient.
I will talk more about this in other posts, as well as where we are today. However, our focus on security revealed some surprises.
9/ The framework team spent a lot of time thinking through possible ways that a malicious user, extension, etc. may compromise an application. That led to an analysis of what was possible with IL that wasn't possible with C#.
10/ I honestly cannot remember exactly when this specific issue was discovered, but ultimately, the .NET team realized that they had assumed visibility and accessibility were the same, because that's largely how C# treated them. However, that's not true for the CLR.
11/ They are two distinct concepts. Visibility was a top-level concept that is basically split between exported and non-exported types. Accessibility is controlled by accessibility modifiers. The ability to call a method was controlled by accessibility.
12/ The ability to override a method was controlled by visibility. This meant that in the framework there were internal virtual methods within public types that could be overridden external to the assembly (even though they couldn't be called).
13/ This couldn't be done from C#, but could be done from IL. This was non-obvious, and there was a large amount of framework code that needed to be reviewed as a result.
14/ However, when we discussed this, we didn’t think this would be obvious to any user of C# and we ran the risk of other applications having security issues in their APIs if we shipped this way.
15/ There were several very heated discussions about it, because initially the C# team suggested changing the semantics of the runtime, and the CLR folks pointing out that C# wasn't the only language and there were cases where visibility and accessibility shouldn't be tied.
16/ I won't go into detail about meetings where there was literal yelling and table pounding, suffice it to say, people expressed their passion in ways that I'm happy to say are basically unheard of at Microsoft today.
17/ The resolution was to add a new strict flag MethodAttribute which the runtime enforces as a method may only be overridden if it's also accessible. The C# compiler was updated to emit this flag for any non-public virtual method.
18/ This was a great lesson for everyone about assumptions and the value of threat modeling as a way to locate potential security issues.
• • •
Missing some Tweet in this thread? You can try to
force a refresh
One of the stories that my first manager used to tell, that I always got a kick out of was the following. Context: Think Week was a week that Bill Gates used to take every year to learn about a huge variety of topics, and folks at MS would submit papers/bits. It was a big deal.
"I joined Microsoft on 3/19/99 and found out I was working on a new language. The first week was a blur just getting up to speed and I don't think I even installed the complier (not that it did much then - I think you could define an interface but not use it yet).
In my second week (3/27/99) I get an email from Drew saying that Bill [Gates] wants the C# Language spec and the latest build of the compiler by 4.30 (Note that it was 4.30 not 4/30). I'm still getting used to US dates so I see 4.30 and think it's 4:30pm that day.
Incremental rebuild was a feature of the C# compiler which was meant to increase the throughput after an initial build. It worked on the principle that changes in between builds are localized, and that the information gathered by the compiler from previous builds wouldn't be
entirely invalidated; specifically, some of the information and, indeed, the assembly itself could be updated in an incremental fashion resulting in faster builds.
Both the VS 2002 and VS 2003 compilers exposed this option through the /incr switch on the command line, and the ‘Incremental Rebuild’ option in the Advanced tab of Project Properties. In 2002 incremental rebuild was enabled by default for all project types.
In 2001 I had only recently joined Microsoft full time, so I was really just getting my feet underneath me in the org. There were many internal teams using C#, so one of the things I owned was an internal DL called CSharp User Community which had thousands of folks on it.
The point of the DL was for C# users to ask questions of each other to get help as they needed it, but I did participate a lot as often folks would ask for definitive answers. The downside to this is that I often received a large number of mails throughout the day directly.
If I'd had some more experience, I would have added the user community back to the threads much more often than I did. Regardless, this ownership led to some funny and uncomfortable situations.
I was trying to remember any interesting event associated with a new year and the best I could come up with this morning is many years after what I've been tweeting about, in 2010. In 2010 we were working on Dev11 (VS 2012) and iterating closely with Windows on Windows 8.
I was leading a team to create a tooling experience for JavaScript Windows Store apps. Windows 8 was the introduction of the Windows Store and the new WinRT APIs, ABI format, etc. that allowed languages like JS, C#, VB .NET, C++, etc. to directly call the Windows API.
It was still early in Dev11 development, and my team was writing a new JavaScript language service (as well as a new project system). There was already an existing JS language service.
1/ In early 2004 we were heads down executing on Edit and Continue across a large contingent of teams. There had been several iterations of scoping, redesigns, and customer feedback.
2/ We had a weekly meeting every Thursday morning when representatives from each of the teams would get together and review progress. It was fairly heavy weight, but there were so many teams involved that it was necessary to have a regular sync.
3/ Regardless, E&C was coalescing, but teams were stretched thin working diligently to enable scenarios, improve performance, fix bugs, etc. It had been a month or so since we decided to add support for C# to the matrix as well, so folks were a bit stressed.
1/ Edit and continue was a beloved feature of VB6 and was a priority for making migration onto .NET easy for RAD developers. EnC is magical when it works correctly. For web developers that are used to hot reloading, it enables that type of rapid development, but maintains state.
2/ Unfortunately, it is an extremely difficult feature to implement in a JIT'ed world as we discovered that with .NET 1.0. We actually had a version of EnC in the early releases of VS 2002.
3/ I'm fairly sure it persisted all the way up to Beta 1, though the history of when we removed it is a little hazy. The initial implementation wasn't coalescing. There were a huge number of bugs, it performed poorly, and it often corrupted the debuggee.