Livaの自己紹介ページ

  • (by Liva, 2013.06.20)

だぁれだ?

いろいろ

  • サイボウズ・ラボユース1期生サブメンバー
  • セキュリティ&プログラミングキャンプ2011 セキュアなOSを作ろうクラス
  • セキュリティキャンプ2013 セキュアなシステムを作ろうクラス セキュアなOSを作ろうゼミのチューター

Generic Container

osecpu072dをベースにして、汎用コンテナを作ってみました。 差分は以下のページから見れます。

https://github.com/liva/osecpu/commit/5248115243915b1ee981491d49e0ec334ea42c1a

osecpu.cがSJISなもんで、コメントが文字化けしてます。コメントはファイルをダウンロードして確認して下さい。

さて、汎用コンテナって何ぞや?という話と、使い方を解説していきます。 (ちなみに、以下で出てくる「整数データ」とは、ポインタと区別するための用語です。)

今現在、OSECPUのmallocで確保したメモリ領域(配列)には、確保時に指定した型のデータしか代入できません。T_SINT32の配列にT_UINT16の整数データを突っ込む事は可能ですが、T_VPTRを突っ込む事ができません。要するに、一つの配列内にポインタと整数データをごちゃ混ぜにして突っ込む事ができないわけです。

この仕様は、普通にASKAでOSECPU開発をしている人にとっては別に苦にならないでしょう。でも、僕みたいなちょっと変わった事をやろうとする人間にとっては少し都合が悪いのです。

というわけで、ポインタも整数データも突っ込める配列、名づけて汎用コンテナを作れるようにしました。ポインタと整数データの二種類が突っ込めるだけなのに「汎用」とはどういう事だ!と言う人がいるかもしれません。でも、この汎用コンテナに突っ込めないデータは無いんですよ?凄く汎用的じゃないですか!

さて、使い方をグダグダと喋ってもアレなので、以下のコードを見てください。

 

#include "osecpu_ask.h"

 

junkApi_malloc(P02, T_VOID, 18);

LIMM(R00,0x8);

LIMM(R01,0x1);

LIMM(R02,0x7);

SMEM0(R00,T_VOID,P02);

SMEM0(R00,T_VOID,P02); // 二重書き込みはOK

LMEM0(R00,T_VOID,P02); // 読み出しもOK

 

// PSMEM0(P03,T_VOID,P02); // 同じ所に別の型で書き込んではダメ

// PLMEM0(P03,T_VOID,P02); // 同じ所を別の型で読み出してはダメ

 

PADD(P03,T_VOID,P02,R01);

junkApi_malloc(P04, T_UINT32, 1024 * 1024);

PSMEM0(P04,T_VOID,P03); // まだ書き込みが無い所に別の型で書き込むのはOK

PLMEM0(P04,T_VOID,P03); // もちろん、読み出しもOK

 

// SMEM0(R01,T_VOID,P03);

// LMEM0(R02,T_VOID,P03);

 

PADD(P05,T_VOID,P03,R02);

// SMEM0(R01,T_VOID,P05); // ポインタを代入した場所から32バイトには整数データもポインタも代入できない

 

PADD(P05,T_VOID,P05,R01);

SMEM0(R02,T_VOID,P05); // 32バイトを超えれば書き込みOK

LMEM0(R02,T_VOID,P05);

 

PADD(P05,T_VOID,P05,R01);

PCP(P06,P05);

PCP(P07,P06);

 

PADD(P05,T_VOID,P05,R01);

// PSMEM0(P04,T_VOID,P05); // 最後尾から28バイト領域にはポインタを書き込む事はできない(はみ出しを禁止)

SMEM0(R02,T_VOID,P05); // 最後尾28バイト領域はmalloc時に整数データフラグが設定される

 

PADD(P06,T_VOID,P06,R02);

SMEM0(R02,T_VOID,P06); // 整数データはギリギリまで書ける

 

PSMEM0(P04,T_VOID,P07); // 最後尾から32バイトならポインタを書き込める

// SMEM0(R02,T_VOID,P06); // ただし、一度ポインタを書き込むとその後ろの領域には整数データを書き込めなくなる

 

32ビットのT_VOID型というのを新しく作りました。T_VOID型配列にはポインタも整数データも突っ込めちゃいます。だだし、この汎用コンテナはmallocでしか作れません。まあ、tallocにも容易に実装できるのですが、用途を考えると、あまりtallocでは使わないかなぁ、と。

さて、この汎用コンテナ、「何でも突っ込める=セキュリティが疎かになる」なんて事はありません。その代わり、一部制限があります。

  • 一度データを格納したら、そこに別の種類のデータを格納する事はできない。つまり、一度データを代入した時点で、その要素の大まかな型(ポインタか整数データか)が決まる。
  • ポインタは整数データの8倍の大きさがあり、このポインタが格納されている領域に整数データを書き込む事はもちろんできない。
  • 最後尾から28バイトにポインタを格納する事はできない。
  • 実装の都合上、PLMT0,PLMT1命令はこの汎用コンテナに対して使えない。

詳しい事は上のコードを読んで下さい。(ASKA書けないので、OSECPUのアセンブラで書きました。可読性低くてごめんなさい)上記のコードでコメントアウトされているのは、実行するとセキュリティエラーになるコードです。

ちなみに、汎用コンテナにポインタを書き込む時、型指定は(整数データを書き込む時も含め)T_VOIDですが、実際に書き込まれるのはT_VPTR(256ビット)です。ゆえに、ポインタを書き込んだ後ろにまた新しいデータを書き込みたいと思ったら、ポインタレジスタを8(<T_VPTR型のサイズ>/<T_VOID型のサイズ>=256/32=8)だけずらさなければいけません。

こめんと欄

  • 今まではちょっと別の所でOSECPUに関わってましたが、セキュキャンチューターになったのを切っ掛けに、こっちにも顔を出す事にしました。 -- Liva 2013-06-20 (木) 22:43:27

コメントお名前NameLink

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2013-09-24 (火) 19:19:42 (3241d)