320 likes | 426 Views
ソースコード流用の コードクローンメトリクスに基づく検出手法. † 奈良先端科学技術大学院大学 情報科学研究科 ‡ 大阪大学 大学院情報科学研究科 ○岡原聖 † 真鍋雄貴 ‡ 山内寛己 † 門田暁人 † 松本健一 †. 背景. 出荷前にソースコード流用の有無を 検出する技術が必要とされている. [ 1 ] : “ 「 USB 版 Windows 7 」作成ツールに GPL コード Microsoft が謝罪 ”, http://www.itmedia.co.jp/news/articles/0911/16/news026.html
E N D
ソースコード流用のコードクローンメトリクスに基づく検出手法ソースコード流用のコードクローンメトリクスに基づく検出手法 †奈良先端科学技術大学院大学 情報科学研究科 ‡大阪大学 大学院情報科学研究科 ○岡原聖† 真鍋雄貴‡ 山内寛己† 門田暁人† 松本健一† 知能ソフトウェア工学研究会
背景 出荷前にソースコード流用の有無を検出する技術が必要とされている [1]:“「USB版Windows 7」作成ツールにGPLコード Microsoftが謝罪”, http://www.itmedia.co.jp/news/articles/0911/16/news026.html [2]: “PlayStation 2 Game ICO Violates the GPL”, http://news.slashdot.org/article.pl?sid=07/11/28/0328215 • 近年,オープンソースソフトウェア(OSS)を流用したソフトウェア開発が増えている • 開発コストの低減,高信頼性の確保 • 開発の外注等によりOSSのソースコードが意図せず混入し,ライセンス違反を犯してしまうケースがある • Microsoftが外注したWindows7へのUpgrade支援ツール[1] • SCEIが開発したPS2ゲーム「ICO」のライブラリ[2] 知能ソフトウェア工学研究会
ソースコード流用とコードクローン コードの流用 流用先のソフトウェア 流用元のOSS コードクローン(重複するコード列) 流用したコードはコードクローン(以下クローン)として表れる 知能ソフトウェア工学研究会
ソースコード流用検出の難しさ 流用の事実はない GUI生成の定型処理 どの程度の量のクローンが検出されたならば流用とみなせるかを明らかにする必要がある 1.クローンの量を測るメトリクスが必要 2.メトリクス値について流用とみなす基準値が必要 GUI生成の定型処理 出荷するソフトウェア OSS コードクローン(重複するコード列) • クローンは独立に開発されたソフトウェア間でも存在する • 定型処理,偶然の一致など 知能ソフトウェア工学研究会
研究目的,アプローチ • 研究目的 • クローンの量によりソースコード流用の有無を判断する方法を確立する • 任意の2つのソフトウェア間で,一方が他方のソースコードを流用しているか否かを定量的に判断する • アプローチ • 2つのクローンメトリクスを提案する • 最大クローン長 • 部分類似度 • 各メトリクスの流用と見なす基準値(閾値)を求める • 多数のOSSを用いて実験的に求める 知能ソフトウェア工学研究会
本研究で用いるクローン 流用後に変数名や定数名などを 変更することがありえるため • クローンの種類 • Exact Clone 完全一致のクローン • Renamed Clone変数名や空行の不一致を許容するクローン • Gapped Cloneコードの削除,追加を許容するクローン 知能ソフトウェア工学研究会
} x = b - c ; if ( x > 0 ) n = 0 ; while ( b > 0 ) { Renamed Cloneの検出方法 • トークン解析プログラム言語の字句規則に従いトークンに分割する • トークン変換変数(p),定数(i),型(t)種類毎にトークンを置換する • マッチング一致する部分列をクローンとする ...... ...... ------------ ------------ ------------ ------------ ------------ ------------ ------------ ----------- ----------- ----------- ----------- ----------- ----------- ----------- y = 0 ; x = y - z ; if ( x > 0 ) n = 1 ; z = 0 ; 知能ソフトウェア工学研究会
y = 0 ; x = y - z ; } } if ( x > 0 ) n = 1 ; x x = = b b - - c c ; ; z = 0 ; if if ( ( x x > > 0 0 ) ) n n = = 0 0 ; ; while while ( ( b b > > 0 0 ) ) { { Renamed Cloneの検出方法 • トークン解析プログラム言語の字句規則に従いトークンに分割する • トークン変換変数(p),定数(i),型(t)種類毎にトークンを置換する • マッチング一致する部分列をクローンとする ...... ...... ------------ ------------ ------------ ------------ ------------ ------------ ------------ ----------- ----------- ----------- ----------- ----------- ----------- ----------- y = 0 ; x = y - z ; if ( x > 0 ) n = 1 ; z = 0 ; 知能ソフトウェア工学研究会
p = i ; p = p - p ; y = 0 ; if ( p > i ) p = i ; x = y - z ; p = i ; } } } if ( x > 0 ) n = 1 ; x p x = = = p b b - - - c c p ; ; ; z = 0 ; if if if ( ( ( p x x > > > i 0 0 ) ) ) n p n = = = i 0 0 ; ; ; while while while ( ( ( b p b > > > 0 0 i ) ) ) { { { Renamed Cloneの検出方法 • トークン解析プログラム言語の字句規則に従いトークンに分割する • トークン変換変数(p),定数(i),型(t)種類毎にトークンを置換する • マッチング一致する部分列をクローンとする ...... ...... ------------ ------------ ------------ ------------ ------------ ------------ ------------ ----------- ----------- ----------- ----------- ----------- ----------- ----------- y = 0 ; x = y - z ; if ( x > 0 ) n = 1 ; z = 0 ; 知能ソフトウェア工学研究会
p = i ; p = p - p ; } if ( p > i ) p = i ; p = p - p ; p = i ; if ( p > i ) p = i ; while ( p > i ) { p = i ; p = p - p ; y = 0 ; if ( p > i ) p = i ; x = y - z ; p = i ; } } } if ( x > 0 ) n = 1 ; x x p = = = b p b - - - c c i ; ; ; z = 0 ; if if if ( ( ( x p x > > > 0 i 0 ) ) ) n n p = = = 0 0 i ; ; ; while while while ( ( ( b b p > > > 0 i 0 ) ) ) { { { Renamed Cloneの検出方法 • トークン解析プログラム言語の字句規則に従いトークンに分割する • トークン変換変数(p),定数(i),型(t)種類毎にトークンを置換する • マッチング一致する部分列をクローンとする ...... ...... ------------ ------------ ------------ ------------ ------------ ------------ ------------ ----------- ----------- ----------- ----------- ----------- ----------- ----------- y = 0 ; x = y - z ; if ( x > 0 ) n = 1 ; z = 0 ; 知能ソフトウェア工学研究会
流用検出のためのクローンメトリクス(1)最大クローン長[3]流用検出のためのクローンメトリクス(1)最大クローン長[3] 最大クローン 最大クローン長 ファイル群 A ファイル群 B • 最大クローン長と流用の関係 • 最大クローン長が大きい:流用の可能性は高い • 最大クローン長が小さい:流用の可能性は低い [3]:岡原 聖, 真鍋 雄貴, 山内 寛己, 門田 暁人, 松本 健一, 井上 克郎, “コードクローンの長さに基づくプログラム盗用確率の実験的算出,” 信学技報, No.SS2008-40, pp.7-11, Oct. 2008. • 定義 • 検出されたクローンで最大のトークン数 知能ソフトウェア工学研究会
流用検出のためのクローンメトリクス(2)部分類似度流用検出のためのクローンメトリクス(2)部分類似度 算出式 ファイルの長さ |a| ファイルの長さ |b| 最大クローン長 MLCC ファイル全体を流用していなくとも, 部分的な流用が存在すると部分類似度は大きくなる ファイル群A ファイル群B • 定義 • 最大クローンを含むファイルにのみ着目した類似度 知能ソフトウェア工学研究会
流用の判断方法 検出されるクローンは流用ではない 検出されるクローンは流用である これらの閾値は理論的に求めることは不可能 1.多数のソフトウェアを集めて正解集合を作成する 2.正解集合を用いて実験的に閾値を求める 流用なし閾値 流用あり閾値 (例:最大クローン長) 閾値を超えるクローンを流用あり(流用なし)と判断する 知能ソフトウェア工学研究会
閾値の決定方法 適合率が 1 かつ 再現率が最大値となる 各メトリクスの値を閾値とする • 閾値は必ず流用あり(流用なし)と判断できるもの:false-positiveなし • 適合率,再現率を用いて閾値を導出 • 適合率 • 検出結果中に含まれる正検出の割合を示す指標 • 再現率 • 正解集合のうち,どの程度正検出できたかを示す指標 知能ソフトウェア工学研究会
閾値の導出実験 [4]:“CCFinderホームページ”, http://www.ccfinder.net/ccfinderx-j.html • 実験目的 • 流用の判断基準となる閾値を,多数のOSSを用いて実験的に導出する • 実験環境 • クローン検出ツール • CCFinderX[4] • 実験対象のソフトウェア • 50件のOSS • ドメイン:Security, Audio, Game など • 開発言語:C言語,C++ 知能ソフトウェア工学研究会
閾値の導出における実験手順 • 50件のOSSを用いて,正解集合を作成する • プログラムの構造,コメント文,クローンの内容などから判断した • OSSの全ての組合せにおいてクローンを検出する • 最大クローン長,部分類似度を算出する • 流用あり(流用なし)の適合率,再現率をそれぞれ算出する 知能ソフトウェア工学研究会
閾値の導出結果 流用あり閾値 流用あり(最大クローン長) 知能ソフトウェア工学研究会
閾値の導出結果 流用なし閾値 流用なし(最大クローン長) 知能ソフトウェア工学研究会
閾値の導出結果 流用あり閾値 流用あり(部分類似度) 知能ソフトウェア工学研究会
閾値の導出結果 流用なし閾値 流用なし(部分類似度) 知能ソフトウェア工学研究会
閾値の導出結果 • 流用あり閾値 • 両メトリクスとも半数以上の流用を検出できている • 流用なし閾値 • 部分類似度の流用なし閾値を導出できなかった 2つのメトリクスを併用して流用を検出することで 検出割合が向上するかを確認する 知能ソフトウェア工学研究会
追実験の結果 作成した流用あり正解集合121件のうち, 102件(約84%)をfalse-positiveなしで検出できた • 結果 • 最大クローン長で検出できなかった30件の流用のうち,11件を流用として検出できた 知能ソフトウェア工学研究会
メトリクスを併用して検出できた流用 /* Splice in "list" into "head" */ static inline void glame_list_splice(structglame_list_head *list, structglame_list_head *head) { structglame_list_head *first = list->next; if (first != list) { structglame_list_head *last = list->prev; structglame_list_head *at = head->next; first->prev = head; head->next = first; last->next = at; at->prev = last; } } /* * Splice in "list" into "head" */ static INLINE void list_splice(structlist_head *list, structlist_head *head) { structlist_head *first = list->next; if (first != list) { structlist_head *last = list->prev; structlist_head *at = head->next; first->prev = head; head->next = first; last->next = at; at->prev = last; } } ファイル長さ:141 ファイル長さ:223 最大クローン長 59,部分類似度 0.32 知能ソフトウェア工学研究会
まとめ,今後の課題 • まとめ ソースコード流用のクローンメトリクスを用いた検出手法を提案した • 最大クローン長と部分類似度の流用あり閾値,流用なし閾値を導出した • 流用あり閾値を用いて約84%の流用をfalse-positiveなしで検出できた • 今後の課題流用あり(流用なし)検出の精度向上を目指す • 他のクローンメトリクスを調査する 知能ソフトウェア工学研究会
関連研究 クローン ファイル群 A ファイル群 B [4]:L. Prechelt, G. Malpohl, and M.Philippsen, “Finding Plagiarisms among a Set of Programs with JPlag,” J.Universal Computer Science, vol.8, no.11, pp.1016-1038, Nov. 2002. • コードクローンを用いた手法:JPlag[4] • クローンに基づいた「ソースコード間の類似度」を用いる • Jplagの問題点 • ソースコードの一部分だけを利用する流用を,流用ありと判断することが難しい 知能ソフトウェア工学研究会
関連研究 [5]:玉田 春昭, 神崎 雄一郎, 中村 匡秀, 門田 暁人, 松本 健一, ``Java クラスファイルからプログラム指紋を抽出する方法の提案'', 信学技報 情報セキュリティ研究会, Vol. ISEC2003-29, pp.127--133, July 2003. • バースマークを用いた手法 • バースマークとはクラスの継承関係,クラスの出現回数,クラスの実行順序などのプログラムの特徴量 • バースマークを併用して流用(盗用)の検出を行う • バースマークの問題点 • 流用の検出を行う者(PM,品質管理実施者など)が定性的に判断する必要がある • 一意に決定することが困難である • ソフトウェア全体での判断になる 知能ソフトウェア工学研究会
本研究の使用用途 • ソフトウェアの開発委託元が,開発委託先で流用を行っていないかの確認 • 学生の演習課題でコピーアンドペーストを行っていないかの確認 • 民事裁判での証拠 • 裁判では互いの資料提出があるため,コードクローンを利用することは可能 知能ソフトウェア工学研究会
人手によるコスト 目安となる閾値が存在することで,人手による判断を行うクローンを減少出来る • ソフトウェア間でクローン検出を行うと,多数のクローンが検出される • コストが非常に高いことが予想される 知能ソフトウェア工学研究会
ソースコード流用による損害賠償 • CAおよび1999年にCAが買収した米PLATINUM technology Internationalで勤務経験のあるプログラマやソフトウエア開発者を雇用して盗用を行う • 賠償内容)約2億ドルの損害賠償および恒久的差し止めを求める(継続中) • Mark ZuckerbergがConnectUの知的財産権およびコードを盗んでこの巨大人気ソーシャルネットワークを構築 • 賠償内容)約6500万ドルの損害賠償を受け取る 知能ソフトウェア工学研究会
検出できなかった流用 if (size == 0) return NULL;/* no allocation required */ /* Allocate combined header + user data storage. */ { register pointer new = malloc (sizeof (header) + size); /* address of header */ ((header *)new)->h.next = last_alloca_header; ((header *)new)->h.deep = depth; last_alloca_header = (header *)new; /* User storage begins just after header. */ return (pointer)((char *)new + sizeof(header)); } if (size == 0) return NULL;/* No allocation required. */ /* Allocate combined header + user data storage. */ { register pointer new = malloc (sizeof (header) + size); /* Address of header. */ ((header *) new)->h.next = last_alloca_header; ((header *) new)->h.deep = depth; last_alloca_header = (header *) new; /* User storage begins just after header. */ return (pointer) ((char *) new + sizeof (header)); } ファイル長さ:636 ファイル長さ:1191 最大クローン長 78,部分類似度 0.085 知能ソフトウェア工学研究会