x86でもプロセッサによるバッファオーバーフロー対策 64
ストーリー by Oliver
他のarchの良い所を真似る 部門より
他のarchの良い所を真似る 部門より
marusa 曰く、 "ITmediaの記事から。(米ZDNetの原文) 近い内に、AMDやIntelのプロセッサにバッファオーバーフローを防止するための機能が組み込まれるようだ。AMDのAthlon64は、"Execution Protection"によってバッファオーバーフローを防止する。現在出荷されているAthlon64には既にこのための回路が存在しているが、無効化されている。この機能を利用できるようになるのは、マイクロソフトがWindows XP ServicePack2をリリースしてからになるという。Intelも次期Pentium4 (Prescott)に同様の機能を実装するようだ。"
セキュリティホール警告の例 (スコア:4, おもしろおかしい)
AMDやIntelのプロセッサに組み込まれている
バッファオーバーフローを防止するための機能に、
バッファオーバーフローのセキュリティホール
AMDやIntelのプロセッサに組み込まれている、
バッファオーバーフローを防止するための機能「safecpu」に、
バッファオーバーフローの問題があることが明らかにされた。
AMDやIntelはWebサイトの警告で,
それらのcpuをアップグレードしていないユーザーに対し,
すぐに最寄りのPC販売店にて、59800円の最新版にアップグレードするよう呼びかけている。
Re:セキュリティホール警告の例 (スコア:2, おもしろおかしい)
Re:セキュリティホール警告の例 (スコア:5, 参考になる)
Intelの開発者向けサポート [intel.co.jp]
ASCII24の記事 [ascii24.com]
Re:セキュリティホール警告の例 (スコア:0)
Transmetaならできそうですな。
Re:セキュリティホール警告の例 (スコア:0)
そろそろ新しいPC買いませんか。新機種が出てますよ、と言われ
差額で新機種購入してしまうキャンペーンになる。
#32bitマシーンにはバグがあり64bitにすると改善される噂まで
新たなワームにウハウハ (スコア:2, 興味深い)
アクセスしようとするとデタラメな結果を出すのか?
例外条件として処理するのか?
もしフリーズするとかだったらそれを目的とするワームが作られのではないかと
#パケット一発WinNuke再び
Re:新たなワームにウハウハ (スコア:1, 参考になる)
その割り込みをどう処理するかはモニタ(OS)の役割。
Re:新たなワームにウハウハ (スコア:0)
バッファオーバーフローで作成されたコードをそのまま実行
バッファオーバーフローで作成されたコードを実行しようとするとアクセス違反でプログラム終了
Re:新たなワームにウハウハ (スコア:2, 参考になる)
>プログラムBの一部として実行された時に初めて被害が出る。
プログラムAがデータを読み込み、プログラムAの一部を、読み込んだデータのアドレス(マシンコード)へ飛ばすように書き換え、実際にその領域に飛んでしまったときに被害が出るのでは?
他のプロセス空間を書き換えるバッファオーバフローがあるとは寡聞にして知りませんでした。
Re:新たなワームにウハウハ (スコア:1, 参考になる)
なんでバッファオーバフローの話でプロセス間のメモリ保護の話が出てくるんだか。
"Execution Protection"てのはpage translation tableのNX(実行不可)ビットのこと。
トラップがかかるのは書き込み時じゃなくて、実行が許可されてないページを実行しようとした時だよ。
ガード領域 (スコア:2, 参考になる)
小粋なことをしてなかったな~と改めて認識しますね。コード領域とデータ領域の
分離とかやった時代からだいぶ経つのに結局はスピード最優先の開発が仇になっていると
いうことかな? まあ、開発の方向のバランスの取り方は難しいと言えば難しいんですけどね。
ここ数年だからなぁ、CPUが暇持て余している時間が多くなったのは。
Re:ガード領域 (スコア:1, 参考になる)
ここが意味不明ですね。
以前x86互換CPUを作っていた技術者から聞いた話ですが、IntelのCPUが命令キャッシュとデータキャッシュを独立して持つようになったときに、自己書き換え型のプログラムの実行も保証するように設計したらしいですね。
これは回路的にも動作的にも結構なオーバーヘッドになります。なぜなら、データキャッシュと命令キャッシュでコヒーレンシを保たないといけないからです。せっかく命令とデータに分かれているものをいちいち関連付けているわけですね。
コメント中の「スピード最優先」が何のスピードを指しているのかy読み取りずらいのですが、CPU開発スピード、もしくはCPU動作スピードをさしているとしたら、それは的外れなコメントです。
intelが優先したものは、CPU動作の互換性です。実装のきれいさとか、プログラミングのフィロソフィーは二の次だったのです。
Re:ガード領域 (スコア:1, 参考になる)
指したのはCPUの動作スピードです。なぜそれかというと、
> intelが優先したものは、CPU動作の互換性です。実装のきれいさとか、プログラミングのフィロソフィーは二の次だったのです。
互換CPU作っている以上、それはデフォルトですから議論以前の問題です。(互換性は有ってあたりまえ)
その互換を保った上で、如何に開発のスタンスをどちらの方向に持っていくかは
開発方針次第になります。もしくはWindowsの様に互換性を徐々に外していく方向性とか。
それはIntelの政治手腕も入ってくるので技術的な面だけ語っても意味は無いのですが、
互換性と一言で言っても、その上でできることは色々あります。
Re:ガード領域 (スコア:0)
やっぱわけわかんないですね。
自己書き換えプログラムが相当多いならば、ハードウェアで対処するというのは全体的な処理スピードを稼ぐことができます。ただし、CPUのクロック周波数を稼ぐことができないのは前に書いたとおりです。
しかし、自己書き換えはとイレギュラーなプログラミングです。意図的に書かないと作れないものです。これは自己書き換えプログラムが少数であることを示唆していると考えられます。
そうした場合、少数のプログラムでしかもイレギュラーなものの互換性を保つためにCPUのクロック
互換性の重要性が認識される例 (スコア:0)
技術者2: そんなんたいしたことないじゃん。誰かが問題なし!といえばOKだよ。
…沈黙…
上司: じゃあ従来通り保証するということで。
Re:ガード領域 (スコア:0)
当時のプロテクトルーチンやブート時のROMから
RAMへ転送してから実行とか出来るようにするためでしょうか?
Re:ガード領域 (スコア:1, 参考になる)
WindowsのDOS窓でもいいけど、とにかく自己書き換えを
行うDOSアプリが残っていたということ。
# 現在でもまだ残っていると思う。
Re:ガード領域 (スコア:0)
Re:ガード領域 (スコア:1)
自己書き換えってのが何処までを指すのかについては俺は疎いんですが、
気になるのが、わが愛しの(笑)Delphiは、
こんな風に「Object Instance」なるものを実行時に生成してる(ってことですよね?) [asahi-net.or.jp]って点です。
もしかして書き換えが禁止されたら、こういう高速化も駄目になるっすか?
それとも書き換えじゃなくて書き足しだと問題無いんでしょうか?
余談ですが、GUIライブラリを作るかたがたは、是非とも(?)、
他の言語やライブラリからバインドされる時のことを出来るだけ想定して、
言語側が任意(?)の「印」を個々のGUI部品に持たせられるようなデータ領域
(しかも高速にアクセス可能な)を用意しておいて頂けると、幸いです。
そうすりゃこんな難しい仕組み(実行時にコード生成なんて)は要らなくなるはず。
#…という意味(技術的に)だと理解しているんですが、間違いだったら突っ込んでください(^^;
GUI部品と言語のバインディング(に限らず、双方どちらもが主体者に成り得る状況)では、
双方が双方の「自分の相方」を低コストで区別できる仕組みがないと
辛そうですね。
平たい一例で言えば相互参照なポインタっていうか。
Re:ガード領域 (スコア:1)
実行時とはどこにも書かれてないようですが。
実行時に生成してるんじゃなくて、コンパイル時に処理してると思いますよ。
ウィンドウプロシージャの設定はコードの書きかえなどしなくても、実行時に普通にできますから問題ありません。
Re:ガード領域 (スコア:1)
あれ?そうですか?
「MakeObjectInstance にメソッドポインタを渡すと Object Instance を作成してくれます。
また FreeObjectInstance は Object Instance を削除してくれます。」
と書かれているのを、俺は「実行時にやるんだな」と解釈しました。
それにMakeだけならともかく
(実行時じゃなくコンパイル時に走らせるって手もあるかとも考えられそうなんで)、
Freeまで用意されてるってことは
(普通は「コードを」削除する必要なんて無いはずですよね。それもコンパイル時になんて。)、
これってやっぱり実行時なんじゃないでしょうか?
で、その生成/削除されるっていうObject Instanceなるものが何か?の説明のほうを見ると、
「Windows はメッセージ処理ハンドラが普通のプロシージャであると思っていますが、
我々(VCL)が欲しいのは、オブジェクトのメソッドの呼び出しです。
これを実現するには、いったんウィンドウからのメッセージを単純なプロシージャで受け、
そこからオブジェクトのメソッドを呼び出す仕掛けが必要です。
VCL では小さなコード片を使ってこれを実現しています。」
とのことです。
メソッドポインタ(Delphi用語に限らず一般論として)に必要なのは、
メソッドのコード自体へのポインタだけじゃなく、
selfつーかthisつまり対象オブジェクトへのポインタとか
(あるいはこの場合だとOS提供のWidgetのほうかな?どっちにせよ同じことですが)
のように、「実行時に」生成/削除されるモノへのポインタも含みます。
#Delphiも実行時のコードで自在にWidgetを生成/削除できます。当然ですが。
ってことは、ObjectInstanceは、
オブジェクトへのポインタを内在する「小さなコード片」でないとならない。
一言で言えば、Widget1つあたり、このコード片も1つづつ
存在してないとならない(そしてWidget消えたらコード片も捨てる)
っていう性質のもの、なのだと俺は理解しています。
で、そんなものは、実行時にでないと作れない、と。
間違ってるでしょうか?
----
ええと。他の環境で、Widgetの言語ラッパーを作ってみたときも、
この「相互」参照の問題に悩まされた記憶が少し有ります。
Widgetが「1つの」Cポインタを(プロシジャの関数ポインタのために)覚える余地は
用意してくれてるんですが、「2つ目の」Cポインタ(this)を覚えさせたくても
もう場所(構造体のメンバ変数だの、API関数の引数だの)に用意されてない、
ってなことがあったような。
#Winの場合は、あの頁によれば、用意はされてるものの遅い、ということのようですね。
#VBじゃ許せてもDelphiじゃ許せない、ってことでしょうか(^^;
で、仕方ないから、コールされる関数自体にthisを埋め込んじゃう、ということなのでしょうね。
C(Delphiも同じことです:てーかアセンブラつーかネイティブ)の「関数」のモデルだと
こういうクロージャみたいな情報(^^;を埋め込むには、結局泥臭いことをやらないとならんわけですよね。
それがObjectInstanceなるものなのだと理解しました。
----
>ウィンドウプロシージャの設定はコードの書きかえなどしなくても
あの文は、そういう問題ではない、という主旨なんだと理解しました。
その「設定」ってのは単に既に有るプロシジャのポインタを何処か(Widgetの中身)に代入する、
という意味だと思いますが、それだけだとWidgetがインスタンスを区別できないんで。
「区別」については、間接参照で間に合わす手は幾らでも有りますが、
たぶんそれらでは遅いってことなんでしょうね。
switch文みたいなものも要らない(前述のようにWidgetとラッパObjectの数自体が
実行するまで予測不能なので、switch的なことをしようとすれば結局
Hashtableみたいなもので動的にやる羽目になります。そりゃ遅いでしょうね。
GUIイベントが来るたびにそれをやっていたのでは、ちょっとねえ…)
ようにするには、Widget自体がthisを知っているか、それが駄目なら或いは
Widgetから直接呼ばれるコード「が」直接thisを知っているか、ってことなんでしょうね。
普通ならコードに引数を渡せば済むんですが、それを(素早く)渡す事が出来るモノが存在しないそうなので、
泥臭く埋め込まざるを得ない、と。
Delphiは実に欲張りです。
動的言語みたいなこともしたいくせに、
コンパイル静的言語のメリットも出来るだけ残したがってる。
そういう節が端々に感じられます。興味深い。
Re:ガード領域 (スコア:1)
Windowのプロパティを使うと遅いっていうのは、Windows3.1時代の名残りでなく今でも重要なんでしょうか。
まあBorlandはライブラリの実行速度に気をつかっているようですから、今から実装し直しても同じようなことになりそうですけどね。
#VCLのソースを読んで結構ショックを受けたり。
Re:ガード領域 (スコア:1)
生成したコードをファイルに吐き出してダイナミックリンクすればOKです。:-)
なんていう冗談はさておき、安全のためにはコード領域(とその中のコード)の
生成を全てOSに任せるべきなんでしょうね。
そうした場合、オンメモリでのコード生成を許可するべきかどうかは
微妙なところだと思います。
(出来なきゃ不便、出来ると危険)
Re:ガード領域 (スコア:1)
Widgetを動的に生成するたびにDLLも1つづつ動的に生成しろ、と?(^^;;;
(上に書いた俺理解が間違ってなければの話ですが)
>生成を全てOSに任せるべきなんでしょうね
まあ、「関数」と「コード領域」がイコールな言語を前提としてるってのが
そもそもの痛さの始まりなんですけどね。
これがLispみたいに状態(クロージャ?)をも関数が持てて
関数の複製(や、そのついでに状態を付加する)が出来るっていうなら
悩みは無かったのですが。
Widgetとかは、C言語の意味での関数のポインタが渡されることしか
想定していない(つまり「直接」Callされる)ので、
勝手にLisp風関数のポインタを渡すわけにもいかず。
Widgetについてはですが(どれだけ一般化できる話なのかは俺には判りませんが)、
「人を呪わば穴二つ」と思っています。つまり、
(C的な)関数と、データと、の2つのポインタが、結局最低限必要なんですよね。
言語側が用意してる任意のデータ構造(Objectとか)を解釈するためには、
それを解釈できる(最低でもCの)関数も与える必要があるわけで。
-----
CodeのVerifierが作れるならばイイんですけどね。
つまり、生成(やロード)したコードをVerifyする義務が有れば
動的生成だからってビビる必要が無くなるはずで。
#ん。これってJavaか?
要するに (スコア:1)
欠陥アーキテクチャのCPUを使ったシステム(Windowsに限らず)に
依存しているこの世の中って????
スタックオーバーフローなんて、OS/コンパイラー以前に
システム設計時につぶせるものだと思うのですが...。
^-_^-_-~
救世主はきっといる。
Re:要するに (スコア:5, 興味深い)
>システム設計時につぶせるものだと思うのですが...。
歴史的に言えば、サブルーチンは、かつて、自己書換プログラムとして実装されていた。(JMP命令しかなかった)
ノイマン型コンピュータの基本構造は、その頃の発想から、実質まるで変わっていないし、変えたくても、互換性維持のためには変えられなかったのが、おそらく実情。
実際、互換性を維持したまま高速化するの為のアーキテクチャ変更は、高度に進歩している。
OSでは、Multicsで、ハードレベルで複雑かつ高度な保護が考えられていた。が、それは滅びて、代わりに、簡単で保護の無いUnix(この命名自体、元々パロディ)が普及してしまい、現在に至る。
高級言語での保護も、言語レベルでの保護を捨てたCが普及してしまい、オブジェクト指向が提唱されても、保護の無い点でも互換性のあるC++が主流になった。
プログラミングの発想を根本から変える可能性のあったPrologや、第五世代も滅んだ。
>救世主はきっといる。
商業的の神は、既に「互換性の維持」をメシアに選んでいる模様...
//神を捨てる?
-- Buy It When You Found It --
Re:要するに (スコア:0)
あー、それでわかりました。どうしてうちの親
Re:要するに (スコア:1)
ノイマン型でもハーバードアーキテクチャならバッファオーバーフローによる不正な命令コードの実行なんて事態は絶対に発生しえない。
この問題はノイマン型であることに由来するものではない。
ということでしょ。
個人的には、引数だとかローカル変数というデータ情報とリターンアドレスというコード情報を同じスタックに積むというやり方が最大の問題でしょう。
ハーバードアーキテクチャなんて使いにくいものにしなくても
スタックを2本持ち、
コールスタックの方にはそれ以外の情報は持てないように
すれば簡単に解決しますね。
もっとも、コンパイラの処理内容と呼び出し規約の問題なので、
既存のプログラムとの互換性がまったく持てないのが難点でしょうか?
Re:要するに (スコア:1)
「今日では」って所が重要なのですが、
元々、「ハーバードアーキテクチャ」とは、命令用メモリとデータ用メモリが分離しているもの [google.co.jp]を指す言葉です。
今でもDSPとかに見られます。
それを、キャッシュメモリを命令用とデータ用に分離していることを指す言葉にも流用してるだけです。
Re:要するに (スコア:1, 参考になる)
まぁ、セグメント単位での実行権限制御はあるのに、なぜページ単位では無かったのかとか疑問はありますが。
あと、スタックあふれじゃなくてバッファあふれだと思う。
Re:要するに (スコア:0)
重なりがあるように設定するWindowsがタコなだけではないだろうか?
おまけに、x86はセグメントのベースアドレスだけではなく、
セグメントサイズも設定でき
Re:要するに (スコア:1)
なんですが、 「セグメント管理なんて煩雑なことは嫌」といって その工夫をあえてしないフラットメモリモデルを 採用することにしたのが 今の世の中というかUNIXとWindowsの隆盛なわけです。
Re:要するに (スコア:1)
「セグメント管理なんて煩雑なことは嫌」っていうのは, おそらく8086がまき散らした害毒でしょうね. 本来はセグメント機能によって主記憶の用途管理がちゃんとできるはずだったのですが, 8086上のDOS環境では単純に足りないアドレスをゴマかすための機構に成り下がっちゃいましたからね. 8086の設計ってConcurrent-CP/Mみたいに数10kB単位のプログラムをセグメント管理で複数動かすというものだったんじゃないですかね? そんな時代じゃ, たかだか数MB程度フラットに使わせろってのも切実な願いだったわけで.
時は過ぎて32bitアーキテクチャが標準になったら, 今度はプログラム側が要求するアドレス空間が32bitぎりぎりになっちゃって, やはりセグメントを使う余裕が無くなったというのが現状だと思います.
そう考えると, 今IA64やamd64によって過去の頸木から(完全ではないとはいえ)抜け出せそうな状況というのは, セグメント管理が見直される絶好のタイミングになるのではないでしょうか.
Re:要するに (スコア:1)
あながち8086ばかりでもなくて、上から降りてくる方の動きとしてMulticsの失敗も強烈なトラウマになってるんじゃないかと思うんですよ。いやむしろそっちじゃないかと。
ほら、プログラマにモデルを受け入れさせるとともにOSを供給しなきゃいけないじゃないですか。
ややこしいものを作りたくない背景のもとでUNIXは流行ったし、UNIXが動けばいいやでRISCのアーキテクチャも殆どフラット一色。VAX/VMS辺りは知りませんが、RISCの流れがそうなったってことはミニコンも末期頃にはセグメントが廃れてたんじゃないかと想像したり。 それを見て、何だフラットでいいのか、でWindowsもバージョンが3になったらセグメントを捨てた。 POWER/PowerPCだけはメインフレーム由来のOSとソフトウエアを載せるためにセグメントを盛り込み続けてるみたいですね。
セグメントを使う余裕、に関しては、x86ではセグメントをめいっぱい使えば論理アドレス空間は64TBあるし、PentiumPro以降のPAEを使えば物理アドレス空間は64GBまで伸びた。ま、どうせ仮想記憶をかぶせて使うので、物理アドレスが少なければディスクへ出ていくだけのこと。 つまり、プログラムの要求するアドレス空間が大きくなったことは セグメントに関する態度への影響としてはむしろ、 セグメントを求める方向への圧力になりますよね。
そんな中、セグメントという道具があっても使わなかったのに、 IA64やAMD64でフラットモデルの広い空間を手にしてしまったら、 やっぱりセグメントには戻りたくない人が大勢を占めるんじゃないでしょうか。
再びセグメントを使うか、 えいやっと倍にして64bitフラットで行くか、に関しては、 随分昔にMIPS R4000やUltraSPARCやAlphaが出る頃に検討され、 64bitフラットが採用されたわけですよね。 やっぱりセグメントは求められてなかったって ことじゃないかしら。
そういう選択を見ていると、 アーキテクチャレベルの二次元アドレス的なセグメントが 大々的に復活してくることはもはやないんじゃないかしら。 IA64のリージョンや64bitなPOWERのセグメントは 64bitアドレスの上位ビットがセレクタになるので、 結局プログラムから見えるイメージは64bitフラットですよね。 一方で、フラットなメモリ空間上に配置された 論理的なセグメント(TEXTとかBSSとか)を ページテーブル上で適当に権限設定して 使い分ける枠組みでなら、UNIXとの親和性も悪くなさそうで、 結局そっちへ行くんじゃないかしら。
Re:要するに (スコア:0)
プロテクトモードで割り込みが受取れるくらいまでのブートアップコードを書いてみれば386セグメントのめんどくささが分かるでしょう。
Re:要するに (スコア:1)
8bit、16bit CPU では特権モードやらプロテクションの機能が備わっているものは少ないでしょう。(私は知りません)
そのノリを未だに引きずっているのだと思います。
Re:要するに (スコア:0)
(プロテクトモードは激しく無用だったが)
今後の主流 (スコア:1)
ワームなのかウィルスなのか分かりませんが, 攻撃ツールの基本としてスクリプト言語が使われるようになるんですかね. perl/Ruby/Python/VBなど十分に強力ですし, プログラムは全てデータですから自己改変だろうがなんだろうが自由度は格段に大きいですし. 唯一の救いは人が目で見て中身を判断できることですけど, 引っかかるような人は最初から中身なんて見ないでしょうし.
Re:今後の主流 (スコア:1)
Re:今後の主流 (スコア:0)
Re:今後の主流 (スコア:1)
つまり (スコア:0)
データシート (スコア:0)
データシートとかマニュアルとか適切な資料に
既に載ってるんでしょうか?。
いや、XPだけじゃなくて*BSD/Linuxでもと思ったので。
OpenBSDは既にW^Xでそれを実現してますが。
Re:データシート (スコア:2, 参考になる)
AMDのWWWサイトにマニュアルがありました。 多分これのことだと思います。
PAEを有効にするとページディレクトリとページテーブルの 各エントリの上位に未使用ビットがたっぷりあるので、 そのうち1ビットを実行禁止フラグに割り当てるようです。
カーネルのVMがPAEに対応してさえいれば、 NetBSDの他のアーキテクチャ用の実行禁止ビットを使った実装を 移植するのにそう大きな困難はないんじゃないかと、 x86用の*BSD/Linuxのカーネルの中身をよく知らないままに のんきに推測しています。
Re:データシート (スコア:2, 参考になる)
あー、ごめんなさい。
プラスモデレートしていただいて悪いんですが (っていうか投稿してからモデレートされるまで早っ) ページの実行禁止(というか実行許可が普通かな)フラグを 使ったバッファオーバフロー対策が NetBSDに盛り込まれているかどうかは、 実は知りません。
ただ、NetBSDだったかどうかがあやふやなだけで、 x86以外のアーキテクチャ向けのUNIX類似のシステムで ページの実行許可フラグを 使った実装が現れたという声を 近辺で聞いた覚えがあったので、 あるのならそれを移植するのは難しくないだろうという点は 動きません。
*BSD界隈でご存じの方突っ込んでください。
_|\○_ 平身低頭
Re:データシート (スコア:1, 参考になる)
私も BSD 方面に詳しい訳じゃありませんが、この辺の話じゃありませんか?
Re:データシート (スコア:0)
W^X at OpenBSD(Re:データシート) (スコア:0)
Re:データシート (スコア:2, 興味深い)
-----
[AMD64 アーキテクチャ技術資料]
http://www.amd.com/jp-ja/Processors/DevelopWithAMD/0,,30_2252_739_7044,00.html
-----
PAE 自体、OS のデフォルト設定では使用していないはずです (boot.ini に /PAE を付属すると使えるみたい)。PAE 自体、システムのパフォーマンスを落としてしまうからです。以下の記事で AMD は「PAEでは特別なコーディングが必要で、オーバーヘッドも大きいので誰も使わない」とまで言っています。なので XP SP2 で機能が有効になったとしてもデフォルトでは使用されない可能性が高いです。
-----
[Prescottは64bitアドレッシングを実装?]
http://pc.watch.impress.co.jp/docs/2003/0506/kaigai01.htm
-----
最後にPDC2003 で公開された XP SP2 に組み込まれる機能情報を紹介しておきます。興味深い所では JIT の互換性についての注意点がある所でしょうか。もちろん CLR は問題無いことも説明にあります。
-----
[Windows XP Service Pack 2: 開発者向け情報]
http://www.microsoft.com/japan/msdn/windows/windowsxp/securityinxpsp2.asp
-----
Mc.N
ま、まさか (スコア:0)