멜트다운(Meltdown)과 스펙터(Spectre)
지난 해 큰 이슈가 되었고,아직까지도 큰 영향을 미치고 있는 멜트다운과 스펙터 문제에 대해서 잘 설명된 글이 있어서 간략히 소개해 드립니다.
이 문제를 잘 이해하기 위해서는 컴퓨터의 기본적인 성격에 대해서는 이해해둘 필요가 있습니다. 첫 번째는 멍청하다는 점이고, 두 번째는 말도 안되게 빠르다는 점입니다.
효율
컴퓨터가 멍청하긴 하지만 엄청나게 빠르죠. 그렇기 때문에 혼자서 컴퓨터 한 대를 통째로 쓴다면, 한정된 자원을 비효율적으로 쓰게되는 문제점이 생깁니다. 내 문제에 대한 답을 엄청 빠르게 가져다 주니까, CPU는 거의 대부분의 시간동안 할일이 없는거죠.
저는 아이패드를 주로 쓰다보니까 사실 제 노트북도 한 달 중에 정작 쓰는 시간은 몇 시간 안됩니다. 대부분 그냥 잠들어 있어요. 그러니 저와 사용 패턴이 다른 몇 사람이 노트북을 공유한다고 하면, 서로서로 거의 불편할 일 없이 노트북을 더 효율적으로 쓸 수 있을 겁니다.
(출처: stratechery.com)
만약 아주 거대한 규모로 컴퓨터 자원을 마련해서 같이 쓰면 어떨까요? 수천명, 아니 수천만명이 거대한 컴퓨터를 공유해서 쓰는 겁니다. 이렇게 하면 컴퓨터를 여러 대 따로 돌리는 것에 비해서, 인프라를 더 효율적으로 배치할 수도 있고, 수많은 사람이 자원을 공유하는 것이니 만큼 그만큼 자원이 노는 틈도 더 없어질거라는 생각이 듭니다.
그런데 우리가 비용을 아낄 수 있을지 모르는데도, 내 컴퓨터를 잘 모르는 사람과 나눠쓰지 않으려는 뻔한 이유가 있죠. 내 개인적인 — 그리고 중요한 — 정보에 다른 사람이 접근하는 것이 걱정되기 때문입니다. 그래서 AWS같은 대형 클라우드 서비스는 가상 머신을 통해서 내가 공유된 컴퓨터를 마치 나만의 컴퓨터를 사용하는 것처럼 사용할 수 있게 해줍니다. 나는 내가 기록한 정보에만 접근하고, 다른 어떤 사람도 내 정보에 접근할 수 없도록 막아주는 것이죠.
만약, 이런 약속이 지켜질 수 없게된다면 그건 정말 큰 문제일 겁니다. 그리고 멜트다운과 스펙터로 발생하는 결과이자 두 취약점의 공통점이 바로 이것입니다. 권한이 없는 사용자가 다른 사람의 비밀 키나 비밀번호나 다른 사람이 보유하는 어떤 정보이든 접근할 수 없어야하는 정보에 접근 할 수 있다는 것입니다.
다중의 사용자가 가상머신을 통해 컴퓨팅 자원을 공유하는 구조는 아주 근본적인 가정에 바탕을 두고 있습니다. 어느 가상머신 이용자가 다른 사람의 데이터에 접근할 수 없다는 것이죠. 이 가정은 확장하면 가상머신 소프트웨어의 신뢰성에 바탕을 두고 있고, 가상머신 소프트웨어는 기반 운영체제에, 기반운용체제는 다시 서버를 돌리는 처리장치의 신뢰성에 기대고 있습니다.
잠시 커널에 대한 이야기를 하고 넘어가야 하겠는데요. 저도 전문가가 아니기에 커널에 대해서 잘 알고 있지는 않은데, 설명에 따르면 커널은 일반 이용자는 접근 할 수 없어야하는 운영체계의 핵심 부분 중 하나이고, 자체적으로 메모리를 가지고 있습니다. 이 메모리에는 코어 시스템의 데이터뿐 아니라 모든 사용자의 데이터가 다 저장될 수 있습니다.
심지어 이 커널에 대해서도 시스템은 가상화에 의존하고 있는데요. 커널 메모리도 기본적으로 실제의 저장장치로 되어 있어서 사용자가 자기네 프로그램을 위해서 활용할 수 있습니다. 커널 메모리의 어느 부분을 누가 사용하고 있는지, 추적하는 것이 CPU의 역할 중 하나이고, 두 개의 취약점은 바로 이 단계에서 발생하는 것입니다.
여기서 잠시 각각의 취약점을 좀더 수월하게 이해하기 위해서 각 메모리별 처리 속도에 대해서 잠시 이야기를 해보겠습니다.
계산의 속도
글쓴이는 컴퓨터를 크게 프로세서와 메모리, 저장장치(permanent storage)로 나누고 있습니다. 이와 다른 기준을 가지는 사람도 있겠지만, 이 기준이 틀렸다고 말할 사람은 없으리라 생각이 듭니다. 프로세서부터 저장장치까지를 조금 더 늘려 보면 아래와 같이 생각해 볼 수 있을 것 같습니다.
(출처: stratechery.com)
- CPU에 달린 register의 속도가 가장 빠르고 크기도 가장 작습니다. (예를 들어 2GHz 프로세서라고 한다면 초당 20억번 계산을 한다는 거죠.)
- 그 다음에 여러 종류의 캐시가 있습니다. 보통 L1, L2, L3 정도로 나뉘는데, 당연히 레지스터보다는 느리고 좀더 크죠. 숫자가 올라갈 수록 더 크고, 더 느려 집니다. 캐시는 보통 프로세서가 연산을 하기 위해서 즉각적으로 필요한 정보를 저장해 두고 있다가 레지스터에 넘겨주는 역할을 합니다.
- 그다음에는 보통 RAM이라고 말하는 메모리가 있죠. 이건 더 많은 자료를 가지고 있다가 캐시에게 전달해주는 역할을 합니다. 당연히 더 느리죠. 왜 필요한가하면 캐시에 비해서 용량이 훨씬 크고, 무척 저렴해 지거든요.
- 마지막으로 저장장치를 들 수 있습니다. 하드드라이브 같은 것 말이죠. SSD가 나오면서 많이 빨라지긴 했지만 그래봐야 위의 메모리에 비하면 느립니다.
- 네트워크 저장장치는 전통적인 영역으로 보긴 어렵지만 아무튼 비슷하게 설명할 수 있습니다. 접근하기 더 느리지만, 더 싸고, 용량이 크죠.
느리다는 것은 상대적인 개념입니다. CPU가 한 사이클 도는데 0.3나노초가 걸리는 반면에 메모리는 120나노초, SSD는 50에서 150마이크로 초가 걸리는데요. CPU 시간을 1초로 본다면 메모리가 6분이 걸리고 SSD는 이틀에서 엿새 정도 걸린다고 볼 수 있습니다. 엄청난 시간이죠.
계산은 찰나, 아는데는 반백년
글쓴이가 소개한 비유를 저도 그대로 가져와 보겠습니다.
여러분이 올림피아(미국 워싱턴 주의 도시)에서 사는데 마이크로소프트에서 여름인턴을 하게 되었다고 생각해 보세요. 짐을 싸서 가야하는데, 시애틀의 여름 날씨는 정말 얄궂어서 춥고 비가 쏟아질 때도 있고, 또 어떤 때는 아주 덥고 볕이 내리쬘 수도 있어요. 그날 날씨가 어떨지는 그날 아침이 되어봐야 알 수 있을 때가 대부분이죠. 그럼 어떻게 해야할까요. 굳이 똑똑할 필요도 없이 양쪽 날씨에 어울리는 옷을 모두 준비해서 가게 될 겁니다. 옷 가방에서 옷을 꺼내는 편이, 날씨 바뀔 때마다 집에 와서 옷을 바꿔가는 것보다 훨씬 쉽고 빠르니까요.
여기서부터 이러한 은유가 현실과 달라지게 됩니다. 실제로 현대의 프로세서는 단지 필요한 것보다 더 많은 데이터를 가져올뿐 아니라, 그 데이터를 기반으로 미리 계산을 해버립니다. 이것을 투기적 실행 (Speculative Execution)이라 부르고, 이 두 취약점의 핵심 사항이 됩니다.
이 은유를 알고리즘으로 표현하면 아래와 같습니다.
- 날씨를 확인한다(센서, 데이터 확인 등의 여러 하위 절차를 실행)
- 만약 맑으면, 반바지와 티셔츠를 입는다.
- 그렇지 않으면, 청바지와 스웨트티를 입는다.
다시 한 번 기억해 둘 사항은, 컴퓨터는 멍청하지만 말도 안되게 빠르다는 겁니다. “반바지와 티셔츠를 입는다” 또는 “청바지와 스웨트티를 입는다”를 실행하는 것은 실재로 몇 나노초 밖에 걸리지 않아요. 실제로 시간이 걸리는 것은 관찰하는 것이죠. 그렇기 때문에 프로세서는 시간을 아끼기 위해서 날씨를 알기도 전에 미리 당신에게 옷을 입혀 두는 것입니다. 이 때 대개는 과거 며칠간 날씨가 어땠는가 하는 과거 기록에 근거하겠죠. 그 말은 날씨 정보를 기다리는 동안 신발신고 악세서리도 챙겨둘 수 있다는 말이 됩니다. 동시에 여러가지 일을 할 수 있다는 것은 프로세서의 또 다른 측면 이지요.. 결론적으로 어떤 일을 하기 위한 가장 빠른 방법은 결과를 예측해서 시행하는 것이고, 만약 예측이 틀렸다면 그 에 맞춰서 새로 작업하는 것입니다.
멜트다운 Meltdown
이제 아래와 같이 바뀐 알고리즘을 생각해봅시다.
- 당신 상사의 달력을 체크해서 사무실에 있을 예정인지 확인
- 만약 사무실에 있으면, 슬랙과 와이셔츠를 입자
- 만약 사무실에 없으면, 반바지와 티셔츠를 입자
여긴 딱 하나 문제가 있는데, 당신은 상사의 달력에 접근해선 안된다는 것입니다. 컴퓨터는 멍청하다는 사실을 다시 한 번 명심합시다. 프로세서는 이 사실을 묵시적으로는 알 수 없고, 실제로 접근 가능한지 확인을 해봐야만 합니다. 그래서 실제로 위의 알고리즘 아래에 더 가까워집니다.
- 상사의 달력을 체크해서 사무실에 있을 예정인지 확인
- 이 인턴이 매니저 달력에접근 권한이 있는지 확인
- 접근 권한이 있다면, 달력에 접근
- 상사가 사무실에 있으면, 슬랙과 와이셔츠를 입자
- 상사가 사무실에 없으면, 반바지와 티셔츠를 입자
- 접근 권한이 없다면, 옷 입기를 멈출 것
여전히, 컴퓨터는 여러 일을 동시에 하는 것은 훌륭하지만, 데이터를 찾아보는 일을 서툴다는 것을 기억해 두세요. 이 케이스에서 프로세서는, 특정 조건 아래서, 그 달력을 봐도 되는지 알기도 전에 상사의 달력을 보고 무엇을 입을 지 결정하게 됩니다. 만약 나중에 달력에 접근할 수 없었다는 것을 깨닫게 되면, 프로세서는 모든 것을 되돌릴 것이지만 결국에는 아마 옷이 약간 어질러져 있을 지도 모릅니다. 이를 통해서 당신은 당신이 알아서는 안되었던 답을 추측해 볼 수 있을 것입니다.
이미 현실과 은유가 다르다고 말을 했고, 위 사례는 완전히 어거지이긴 하지만, 넓게 말해서 이것이 바로 멜트다운입니다. 프로세서는 그래도 되는지 안되는지 알기도 전에 선제적으로 타인의 데이터에 접근해서 불러오는데, 아닌 경우에도 캐시에 흔적을 남기게 됩니다. 그리고 이러한 흔적을 권한없는 사용자가 획득할 수 있게 되는 거에요.
스펙터 Spectre
스펙터는 훨씬 더 기교적이지만, 성공하기는 어려워요. 여러 사용자가 같은 프로세서를 쓴다는 사실을 기억하세요. 내가 여러분처럼 옷 가방을 싼다고 생각해봅시다. 이 때, 나는 그 다음에는 프로세서에게 언제나 날씨가 맑을 것으로 기대하도록 훈련 시킬 겁니다. 프로세서는 시간에 앞서 반바지와 티셔츠를 준비하겠죠. 그러면, 내가 아침에 일어났을 때, 프로세서는 반바지/티셔츠를 미리 골라뒀을 것이고, 만약 실제로 비가 오면, 옷을 다시 가방에 넣을 텐데, 항상 조금씩 어질러져 있을 겁니다.
이 비유는 사실 억지를 넘어서 말도 안되는 겁니다. 이런 식으로는 작동하지 않거든요. 정리하면 다음과 같습니다. 연산을 수행하면서 당신 데이터를 메인메모리에서 미리 불러오기만하고 끝나는 것이 아닙니다. 프로세서가 잘못된 분기를 따라가는 동안 일시적으로 캐시에 저장될 수 밖에 없습니다. 이렇게 저장된 데이터는 프로세서가 에러를 수정할 때, 재빠르게 삭제되겠지만, 나는 여전히 캐시에 어떤 데이터가 저장되었었는지 알아낼 수 있다는 겁니다. 바꿔 말하자면 방금 내가 당신의 데이터를 훔쳤다는 것입니다.
제가 이해한 바를 부연하자면, 일반적으로는 여러 분기와 계산이 오가니 캐시에 저장되었던 데이터를 누가 확인할 일이 잘 없습니다. 그런데, 누군가가 어떠한 분기를 반복하게 하는 프로그램을 만들어서 서버에서 실행시키면, 일반적으로는 별일이 없다가도 다른 사람의 접근권한이 없는 데이터에 액세스할 때, 투기적 실행 결과로 미리 데이터를 불러 냈다가 삭제하는 과정이 발생하게 될 것입니다. 메모리에서 데이터가 삭제되는 것은, 다른 데이터가 덮어 씌워지기 전까지는 이름표만 삭제된 것과 같으니까, 의도를 가진 누군가라면 짧은 순간 데이터를 추출해 낼 수 있을 것 같습니다.
설명하기에는 멜트다운이 더 쉽습니다. (애플의 프로세서도 똑같은 영향을 미친다고 인텔이 항의하고 있긴 하지만,) 이것은 기본적으로 설계상의 결함이기 때문이지요. 프로세서가 접근가능한 데이터인지를 확인하는 데 대한 책임이 있고, 그 확인이 너무 늦어서 데이터를 훔치게 되는 것은 버그일 수 밖에 업습니다. 또한, 그렇기 때문에 멜트다운은 소프트웨어적으로 수정될 수 있습니다.(기본적으로, 데이터를 사용하기 전에 접근 권한을 확인하는 절차를 하나 추가하면 됩니다. 동시에, 그렇기 때문에 이 패치로 성능 문제가 발생하게 되는 것이죠.)
스펙터는 이와 완전히 다른 문제입니다. 프로세서는 설계 목적에 맞게 작동하거든요. 앞서 몇 번 설명했듯이, 컴퓨터는 기본적인 계산은 어처구니없을만큼 빠르지만, 그 계산을 위해 데이터를 가져오는 데는 시간이 거의 영원토록 걸립니다. 그러니까, 병목에서 기다리지 않고, 최선의 추측에 근거해서 계산을 수행하는 것은 이 근원적인 불균형을 해결하기 위해 가능한 최선의 방법입니다. 대부분의 경우에 당신은 계산 결과를 엄청나게 빠르게 얻게 될 것이고, 만약 추측이 잘못되었다 해도, 모든 것을 순서대로 했을 때보다 더 느리지는 않으니까요.
이것은 또한,스펙터가 모든 프로세서에 영향을 미치는 이유이기도 합니다. 현대 프로세서의 평행성과 계산 속도를이용한 속도의 향상은 매우 커서 투기적 실행(Speculative Execution)은 피할 수 없는 선택지가 됩니다. 분기예측기가 다른 사용자에 의해 조작(훈련, train)되어서 캐시의 변화가 추적될 수 있다는 것은 작년이 되어서야 발생한 일입니다.
그리고, 이를 확장하면, 스펙터는 소프트웨어적으로 수정될 수 없다는 뜻입니다. 특정 명령(implementations)은 차단될 수 있지만, 취약성은 내재되어 있지요. 새로운 프로세서가 설계되어야겠지만, 이미 사용되고 있는 수십억개의 프로세서가 뿅하고 사라질 일은 없으니, 우리는 이 상황을 어떻게든 해쳐나가야 합니다.
마치며
기술이 발전함에 따라 이전에는 해결되지 않던 문제를 해결해 주기도 하지만, 기술 자체가 새로운 문제를 만들어 내기도 하고, 또 어떤 문제는 그 자체의 특성과 한계로 인해서 기술을 통해서는 좀처럼 해결할 수 없기도 합니다. 그리고 새롭게 생겨나는 문제들은 점점 더 복잡해져서 문외한으로서는 도무지 이해하기가 난감해져 가고 있습니다.
저도 IT 쪽으로는 아는게 없지만, 그래도 몇몇 중요한 문제에 대해서는 어느정도 이해가 필요하지 않나 하는 시점에 좋은 글을 봐서 소개해 보았습니다. 어찌되었든, 지금 우리는 컴퓨터에 둘러쌓인 채로 살고 있으니까요. 바로 그 기계에서 보안, 우리 개인정보와 관련되어 전지구적인 문제가 터졌다면 한 번 관심가져 볼 법하지 않을까요.
번역과정에서 제가 단어나 IT 개념을 잘못이해해서 오역이 있을지도 모르겠습니다. 지적해주시면 바로바로 수정하겠습니다.