바이너리의 복수
썬 제품의 보안 파수꾼으로써 필자는 새롭게 발견된 버그 리포트를 계속해서 확인하고 썬 소프트웨어가 그것에 영향을 받는지 확인 합니다. 일반적으로 필자는 cscope 를 통해서 취약하다고 생각되는 코드의 부분을 찾습니다. 솔라리스에서는 대부분의 ON(OS/Net) 게이트가 cscope 인덱스화되어 있습니다. 솔라리스는 단순히 ON 이 아니고 WOS(Wad Of Stuff) 입니다; 코드와 바이너리는 여러개의 게이트를 통해서 흘러 들어 옵니다; 그리고 cscope 인덱스 혹은 소스에 접근 할 수 없는 수 많은 종류의 소프트웨어가 존재 합니다.

필자는 솔라리스 인스톨 이미지, JES 인스톨 이미지, 썬 클러스터 그리고 N1 소프트웨어와 수 많은 훌륭한 소프트웨어를 썬에서 얻었습니다. Perl 스크립트를 짜서 재귀적으로 파일과 디렉토리 컨텐츠를 검색할 수 있도록 했습니다. 할수 있는 한 최대로 텍스트 정보를 추출했습니다. 예를 들어 스트림 패키지를 디렉토리로 변환하거나, tar, zip, bzip 파일들를 압축해제 및 추출하거나, dis(1) 를 ELF (3) 파일에 대해 실행하고 바이너리 파일에 대해 strings(1) 을 실행했습니다. 모든 텍스트 정보들은 분리된 디렉토리에 저장되었습니다. 거의 수 기가바이트의 용량을 차지 했습니다. 초기 스크립트의 이름은 rob.pl (revenge of the binaries) 였습니다. 이것은 거의 하루가 걸리는 작업이었고; 어쨌든 성공했습니다.
그때 rob.pl 이 생성한 텍스트 파일들을 검색하기 위해, 필자는 정말로 좋은 텍스트 검색 엔진이 필요했습니다. 필자는 몇가지 범용 플레인 텍스트 혹은 html 문서 검색 엔진을 평가해 보았습니다. 그들은 매우 낮은 퍼포먼스를 보여주었거나 결과를 정확하게 찾아 오지 못했습니다. 결국 Lucene 이 최종적으로 선택 되었습니다. Lucene 은 다른 서치 엔진과는 다릅니다. 이것은 inverted index 를 생성하고 그것을 검색하는 라이브러리 입니다. 사용자는 사용자 고유의 파일들을 검색하기 위해 고유의 검색엔진을 만드는데 사용할 수 있습니다. 처음에 필자는 Lucene 에 같이 딸려 오는 예제 검색 엔진들을 사용해 보았고 그 스피드에 놀랐습니다. 그 다음 Lucene 웹사이트를 보고 Doug Cutting 가 Lucene 을 만들었다는 것을 알았습니다. 정보 검색을 공부하는 학생들에게는 아마 익숙한 이름일 것입니다.
검색 엔진
검색 엔진 기술은 로켓 기술과는 틀립니다. 이것은 현대 컴퓨터들이 나오기 전부터 있어 왔습니다. 책을 집어서 마지막 페이지를 보십시요. 대부분 "index" 섹션을 볼 수 있을 것입니다. 이것은 알파벳 순서로 특수한 단어들의 순서를 정렬한 목록으로 그에 대응하는 페이지 넘버가 같이 적혀 있습니다. 만약 전체 책에서 몇몇 단어를 찾는다면 (1) 인덱스에서 페이지 번호를 먼저 찾은 다음 (2) 페이지로 가서 (3) 페이지내에서 찾고자 하는 단어를 검색할 것입니다. 이것은 페이지마다 읽어 가면서 단어를 찾는거 보다 훨씬 빠릅니다.
현대의 모든 검색 엔진은 비슷한 일을 합니다. 구글이나 야후 같은 검색엔진에게 인터넷은 하나의 큰 책과 같고 웹페이지는 페이지와 같습니다. 그들은 인텍스를 생성하고 여러분이 주는 단어를 포함하고 있는 페이지들의 리스트를 돌려줍니다. 이것은 inverted index 라고 불리는데 문서를 단어들의 셋으로 보는 대신 문서의 셋을 주어진 단어로 보기 때문입니다.
프로그램
Lucene 의 좋은 점은 Lucene 은 문서의 내용을 이해하지 못한다는 것입니다. 여러분은 여러분 컨텐츠를 위한 고유의 분석기를 작성해야 할 것입니다. 그러므로 여러분에게는 다양항 종류의 파일들을 어떻게 해석할 것인지에 대한 권한과 자유가 있습니다. Lucene 은 여러분의 해석을 저장하고 검색하는데 매우 훌륭합니다. 다양한 언어를 공통 단어로 해석하기 위해 필자는 모든 프로그래밍 언어와 실행파일에 맞는 간단한 아이디어를 생각해 냈습니다. 프로그램은 "symbol definitions", "symbol references", "human readable text", "path" 와 "revision history" 를 가지고 있습니다.
OpenGrok 의 초기 버전은 rob.pl 로 명명된 펄 스크립트 였고 위의 5 가지 스트림을 추출해서 이것을 lucene 검색 엔진으로 파이프를 통해 연결 하였습니다. rob.pl 은 좀더 진화했습니다. 이제는 각 파일을 ctags 를 실행하고 정의를 추출합니다. 또한 프로그램 identifier 들을 파싱 하였습니다. ELF 파일들에 대해 dis(1) 를 실행하고 라벨과 호출 정의 심볼들을 추출해 냈습니다.
필자는 이것을 Universal Program Search Engine 이라고 부릅니다. 종종 이 프로그램을 필자의 머신에서 사용했었습니다. 이 시스템은 몇가지 보안 취약성들을 확정하거나 부정 판정을 하는데 사용 되었습니다. 예를 들어 솔라리스 7 이 gzprintf() 를 호출 하면 CVE-2003-0107 문제가 있었는데 이 프로그램을 통해서 솔라리스 내에서 영향을 받는 부분을 아주 정확하게 집어 낼 수 있었습니다.
Perl 을 Java 로
필자는 Perl 을 선택했습니다. 왜냐하면 매우 쉽고 코딩이 쉬웠기 때문입니다. 또한 적절한 자료 구조를 사용할수도 있었고 실제로 이 프로그램이 잘돌아 가는지 확인할 수 있는 가장 빠른 방법이였습니다. 그러나 필자는 perl 을 장기간의 솔루션으로 선택하는것이 잘못이었음을 깨달았습니다. perl 은 한번 쓰고 버리는 타입의 어플리케이션에 적당했습니다. 프로세스를 프로파일 해봤을떄 자바 프로세스는 대부분의 시간을 perl 이 텍스트를 파싱 하는것을 기다리는데 소비하고 있었습니다. 전체 프로그램 소스 트리 와 바이너리들을 처리하는 것은 거의 반나절이 걸리는 작업입니다. 결국 몇몇 perl 코드를 프로파일링하고 최적화 한 후에 시간을 8-9 시간으로 줄일 수 있었습니다. perl 은 소스 라인이 수백줄 밖에 안됨에도 불구하고 cpu 싸이클을 너무 많이 소비 했습니다.
그때 Lucene 에 즉 각 프로그램의 타입마다 토큰 스트림을 Lucene 인덱서에에 던져 주는 커스텀 분석기 를 직접 작성할 수 있음을 알았습니다. 이것은 아주 효율적이고 훨씬 빨랐습니다. 이제 ON 게이트 소스를 5개의 스트림으로 분해하고 인덱스 하는데 20분 밖에 걸리지 않습니다.
자바를 선택한 또 다른 이유는 1.5 버전 이후에 자료 구조가 Perl 과 매우 비슷해 졌고 (aka Collections) 프로그래밍 하기 쉬워졌기 때문입니다. 또한 더 효율적이고 빠릅니다.
오픈솔라리스
초기에는 LXR 기반 솔루션을 OpenSolaris 코드를 호스팅 하는데 사용하려고 했었습니다. LXR의 많은 이슈들 때문에 cscope 의 웹 전면을 프로토타입으로 만들었습니다. 내부적으로 우리는 cscope 를 광범위 하게 사용하고 있습니다. cscope 는 LXR 같은 다른 소스 코드 검색 툴이 가지지 못한 좋은 기능들을 가지고 있습니다. 검색 결과가 나오면 LXR 은 라인 번호를 없애 버리고 어디가 매치가 되는지 어떠한 실마리도 주지 않습니다. cscope 는 어디에 심볼이나 함수가 사용되었는지 라인 넘버를 보여 줍니다. Ctags 는 cscope 처럼 심볼 레퍼런스를 보여주지 않습니다. Cscope 는 작은 프로젝트에서는 완벽하게 동작하지만 OpenSolaris 같은 큰 프로젝트에는 잘 확장되지 않습니다.
Cscope 는 몇가지 마이너한 문제점을 가지고 있었습니다; 전문 검색이 너무 느렸습니다. 위의 책과의 비교를 다시 들어 보자면 cscope 는 여러분의 단어를 찾기위해 모든 페이지를 검색 했습니다. 또한 두가지 검색 조건의 AND 연산이 불가능해서 특정 소스트리내에서만 찾고자 할 경우 심각한 제한 사항이 되었습니다. 이러한 제한점을 회피하기 위해 우리는 미리 만들어진 cscope index 를 각 메이저 트리 가지들에 위치시켰습니다. (라이브러리 혹은 커널 코드) 또한 cscope 는 오직 C 혹은 C 같은 언어들만을 이해했기 때문에 makefile 들의 정의를 이해하지 못했습니다.
그때 대형 오픈 소스 프로젝트에 사용된 코드 검색 및 버전 컨트롤 웹 인터페이스를 서로 상호 비교해 보았습니다. ( http://lxr.mozilla.org/ 혹은 http://cvs.gnome.org/ 같은)
| Feature | --- LXR --- | --- ctags --- | --- cscope --- | --- CVSview/web --- |
|---|---|---|---|---|
| Full text Search | Y | # | ||
| Definition Search | # | Y | Y | |
| Identifier Search | Y | Y | ||
| Path search | Y | Y | ||
| History Search | ||||
| Shows matching lines | Y | Y | ||
| Hierarchical Search | ||||
| query syntax like AND, OR, field: | ||||
| Incremental update | ||||
| Syntax highlighting-Xref | Y | # | ||
| Interface for SCM | Y | |||
| open source | Y | Y | Y | |
| Usable URLs | Y | - | - | |
| Individual file download | - | - | Y | |
| Changes at directory level | - | - | # | |
| Multi language support | # | Y | # | - |
Y : 기능이 존재함
# : 기능이 부분적으로 존재함
- : 활용이 불가능함
참고: OpenGrok 은 위의 모든 기능을 제공함
Lucene 기반의 프로그램 검색 엔진은 위에서 지원하지 않는 모든 검색 기능들을 제공합니다. 이 프로그램은 전문 검색을 올바른 방법으로 수행하고 ctags 가 이해 하는 어떠한 언어의 정의라도 인식할 수 있습니다. 또한 소스 트리 (aka 계층 검색)의 가지를 몇단계 까지 검색할 지도 제한을 줄 수 있고 단순히 줄 번호 대신 매칭되는 줄을 보여 주고 인덱스를 증가분 업데이트로 수행합니다.
그당시에 OpenGrok 에 없는 단한가지 기능은 소스의 컬러-코딩 과 버전 컨트롤 정보 였고 이것은 구현하기 어렵지 않았습니다. 필자는 몇가지 Lex 같은 코드 생성기를 평가해 보았고 JFlex 가 제일 빨랐습니다. Jflex 는 이제 크로스 레퍼런스를 토큰화 하고 하이퍼-텍스팅 하는데 사용 됩니다.
이번년도 초에 OpenGrok 은 OpenSolaris 소스 코드를 호스트 하기위해 opensolaris.org 에 배치 되었고 오직 파일럿 커뮤니티 멤버들만이 접근할 수 있었습니다. 커뮤니티 멤버들의 많은 커멘트와 피드백에 의해서 계선되어 졌고 이번년도 6월 14일 에 모든 준비를 마쳤습니다. 이제 몇몇 사람들은 OpenGrok 을 OpenSolaris 의 10가지 매우 중요한 점 으로 여깁니다.
"가장 많이 쓰는 것을 빠르고 쉽게"
OpenSolarios 를 고려하기 전에 이것은 단순히 저를 위한 프로그램이였습니다. 만약 OpenSolaris 에 배치가 되고 공개적으로 알려지면 수백명의 사람들과 로봇이 계속해서 방문할 것입니다. 그것은 안전해야 했고 빠르고 효율적이여야 했으며 사용이 가능해야 했습니다.
OpenGrok 의 비밀은 "자주 쓰는 것들을 빠르고 쉡게" 라는 원칙입니다. 이것을 Chandan 법칙 (구글이 이 말을 처음 쓰는 사람이 필자라는 것을 알려 주었으므로!) 이라고 부릅시다. 이것은 컴퓨터 아키텍쳐의 가장 기본적인 원칙 "make the common case fast" ( Amdahl 의 법칙) 과 휴먼 컴퓨터 인터렉션 분야에서의 기본 원칙 "make the common case easier" 를 혼합한 것입니다. 여러분의 소프트웨어를 빌드하는데 Lucene 이나 자바 같은 최고의 툴들을 선택합니다. 결과는 여러분이 보시는대로 http://cvs.opensolaris.org 입니다. 저를 믿으십시오. 일을 복잡하게 만드는 것 보다 간단하게 만드는 것이 훨씬 더 노력을 많이 요구 합니다.
리팩토링
첫번째 워킹 프로토타입은 OpenSolaris 파일럿 커뮤니티 멤버들에게 공개 되었습니다. OpenGrok 은 오픈솔라리스가 공개되던날 slashdot 에 많은 주목을 받았습니다. 웹서버를 관리하고 있는 Allen 은 수십만명의 사용자가 방문했지만 CPU 사용율은 매우 낮았다고 합니다. 피랒는 안도할 수 있었고 그것을 빠르고 안전하고 확장성 있게 만드는 작업이 헛되지 않았음을 뜻했습니다.
그때 필자는 코드를 리팩토링 하기 시작해서 코드를 조직적으로 유지하고 기능을 확장하거나 좀더 많은 언어 타입을 지원하려는 사람들을 도와주었고 버전 컨트롤 시스템을 사용했습니다. 필자는 Netbeans 를 사용해서 리팩토링을 진행했습니다. Netbeans 는 필자가 처음 사용했을때 보다 아주 많이 바뀌어 있었습니다. Netbeans 는 자바 프로그래밍을 매우 즐거운 경험으로 만들어 줍니다. 코드를 자유자재로 이동할 수 있고; 사용되지 않는 메소드, 클래스를 안전하게 지워주고; 좀 더 논리적인 방법으로 재명명을 하는 등 이외에도 수 많은 일을 해 줍니다. 리팩토링은 시간이 걸리는 작업이고 코어 분석 엔진도 많이 바뀌었습니다. 이 작업을 마친 후에 이것을 OpenGrok 이라고 명명하고 오픈소스화 하였습니다.
다운로드 페이지를 통해 사용이 가능합니다. 로고는 괄호열기 기호를 가지고 있는데 이것은 C 혹은 자바의 시작 심볼을 뜻합니다. 닫기 기호가 없는 것이 오픈 소스를 의미 합니다.
OpenGrok Internals
OpenGrok 의 Internal은 OpenGrok Internals 에서 확인 가능합니다.
맺는 말
만약 소프트웨어 소스 코드가 어떤식으로 동작하는지 잘 이해하기 어렵거나 쉽고 올바르게 검색하기 힘들다면 반 대중이 이해하기 힘든 독점 소프트웨어 혹은 데이타 포맷과 다를바가 없습니다.
OpenGrok 은 그런면에서 오픈코드를 가능하게 하는 오픈 소스 입니다. 사람들이 소스 코드를 빠르게 찾을 수 있게 하고 그것을 보고 소스에 변화사항을 쉽게 찾을 수 있도록 도와 줍니다. 이것이 개발자의 작업을 아주 쉽게 만들어줄 것입니다.필자 역시도 소프트웨어의 보안 구멍을 찾을때 작업을 아주 쉽게 할 수 있습니다
"오픈솔라리스" 카테고리의 다른 글
- 오픈솔라리스의 빌드와 설치 (Part 2) (댓글 1개 / 트랙백 0개) 2006/03/23
- OpenSolaris 코드 브라우저를 이용하여 코드베이스 탐색하기 (댓글 1개 / 트랙백 1개) 2005/09/23
- 커널 프로그래머를 위한 에너지 스타 가이드라인 (댓글 1개 / 트랙백 0개) 2006/07/23
- 오픈솔라리스 domU 를 리눅스 dom0 에 설치하기 (댓글 0개 / 트랙백 0개) 2008/03/11
- Indiana 란 무엇이고 어떻게 참여할 수 있나요? (댓글 0개 / 트랙백 0개) 2008/04/17
- FAQ: 오픈솔라리스 ON(OS/Net) 번역 FAQ (댓글 0개 / 트랙백 0개) 2008/02/18
- 오픈 솔라리스를 위한 무선 네트워킹 (댓글 1개 / 트랙백 0개) 2006/01/23
- Xen: 다운로드, 설치 및 설정 정보 (댓글 0개 / 트랙백 0개) 2008/01/21
- FAQ: OpenSolaris.org (댓글 3개 / 트랙백 0개) 2006/09/23
- OpenSolaris 2008.05 발표 (댓글 0개 / 트랙백 0개) 2008/05/13
댓글을 달아 주세요
"가장 많이 쓰는 것을 빠르고 쉽게" 훌륭한 구호올습니다. 100번 공감합니다.
2007/09/18 22:13좋은 정보 감사해요~
2007/09/19 03:32좋은 정보 감사해요~
2007/09/19 23:10