RX631スタック領域等を保護するには?

IKUZOと申します、お伺いしたいのですが、
RX631でスタック領域を保護したいのですが、
MPUを使用するのでしょうか?
特権命令例外を使用するのでしょうか?
スタック領域というのは保護可能なんでしょうか?
スタック領域というのは簡単に壊すことができるので、
保護することができれば、安全ではないかと

Parents
  • IKUZOさん、こんにちは。NoMaYです。

    今回の「保護」は間口が広いのですね。まず、私の前の投稿に関しては、以下の通りに考えました。

    >特権命令例外とかは関係ないですよね?
    ハードウェアマニュアルを見たところ、以下の画面コピーの通り、例外事象の優先順位としては命令アクセス例外の方が特権命令例外や未定義命令例外より高くなっていましたので、実行禁止にすることで充分かと思います。

    14.7 例外事象の優先順位 (赤枠は私が書いたものです)
    resource.renesas.com/resource/lib/jpn/online_docs/um/RX/RX63N_RX631_ja/?Exceptions#TOC_14_7


    それで、以下に関しては、そもそもC言語ではスタック上に取った変数を扱うことが圧倒的に多いので、スタック領域は簡単に壊すことが出来る、というようなイメージが出来ているのではないでしょうか。また、スタック上にはリターンする時の「戻り番地」が格納されていますが、これが壊されてしまうとプログラムが暴走するので、そのイメージが更に強くなるのかも、と思います。あと、スタックオーバーフローが発生したりすることも、そのイメージが強くなる要因かも、と思います。(先程、別スレッド『RX610 1MからRX610 1.5Mへの置き替え』を読んでいて、そう思いました。)(そういえば、スタックオーバーフローでプログラムが暴走するのも、結局、戻り番地が壊されてしまうから(あるいはIRAMの下限を突き抜けてしまって戻り番地が滅茶苦茶になるから)、ということに帰着されるケースが多そうですね。)

    >これはC言語の場合ポインターが使用できたりしますので
    >うっかり他のアドレスを書き換えることはないのかということです、
    そういう間違ったプログラムで壊してしまう割合(というか危険性)は、スタックも他の領域も同程度ではないかと思うのです。

    そういえば、じまさんが紹介された機能ですが、CS+オンラインヘルプの文面からすると、スタックオーバーフローのチェックは行われないようですね。将来、そういうチェックをするオプションが追加されたりするかも知れないですね。

    ちょっと思ったのですが、この機能では、スタック上の「戻り番地」の直下(0x00000000方向)あたりに固定32ビット整数値を埋め込んでおいて、それが書き換わっているかどうかチェックしているのですが、固定値を埋め込むのではなくて「戻り番地のビット反転」を埋め込むようにする、というのもアリではないだろうか、と思いました。

    [追記]

    ああっ、でも、UスタックオーバーフローならMPUを使っても出来そうですね。例えば、以下のようにセクションをレイアウトしてMPUを適切に設定すれば良さそうな気がしてきました。

    0x00000000~0x0000000F  未使用                 リード/ライト/実行禁止 (つまり全禁止のBAC領域とする)
    0x00000010~0x0000LLLF  Uスタック              リード/ライト許可,実行禁止
    0x0000MMM0~0x000NNNNF  Iスタック,DATA,BSS,等  リード/ライト許可,実行禁止

    0xFFFPPPP0~0xFFFQQQQF  CONST,等               リード許可,ライト/実行禁止
    0xFFFRRRR0~0xFFFSSSSF  プログラム             実行許可,リード/ライト禁止
    0xFFFTTTT0~0xFFFFFFFF  未使用,固定ベクタ      リード/ライト/実行禁止 (つまり全禁止のBAC領域とする)

    注)
    ・0x0000MMM0 = (0x0000LLLF + 1) としています
    ・0xFFFRRRR0 = (0xFFFQQQQF + 1) としています
    ・0xFFFTTTT0 = (0xFFFSSSSF + 1) としています
    ・RX62N,RX621グループ用のアプリケーションノートを見た感じでは固定ベクタは全禁止のBAC領域で良さそうです

    [追記]

    他方、Iスタックオーバーフローは、少し手間を掛けられる且つオーバーフローしたタイミングから幾らか検出されるのが遅れることを大目にみられるなら、以下のような手もありそうです。

    (1) スタートアップルーチンかmain()の始め辺りでIスタックの底にシグネチャを書いておく
    (2) 例外ハンドラの入口ではISPの値がIスタックの底を突き抜けていないかチェックする
    (3) 例外ハンドラの出口ではIスタックの底に書いたシグネチャが書き換わっていないかチェックする

  • NoMaYさんいつもアドバイスありがとうございます、
    例外事象の優先順位をみると
    1 リセット
    2 ノンマスカブル割り込み
    3 割り込み
    4 命令アクセス例外
    5 未定義命令例外 特権命令例外
    6 無条件トラップ
    7 オペランドアクセス例外
    8 浮動小数点例外
    になっていますね「実行禁止にすることで充分」これでもかなり安全性が高くなると思います、
    「スタックオーバーフローでプログラムが暴走するのも、結局、戻り番地が壊されてしまうから」
    そうですよね、それで今回は128K Byte (64K 64K)をまるまるスタックに割り当てるようにはしたのですが、
    「UスタックオーバーフローならMPUを使っても出来そうですね。」そう言われればという気がします
    ただ小刻みに簡単にMPUに設定する方法というか、
Reply
  • NoMaYさんいつもアドバイスありがとうございます、
    例外事象の優先順位をみると
    1 リセット
    2 ノンマスカブル割り込み
    3 割り込み
    4 命令アクセス例外
    5 未定義命令例外 特権命令例外
    6 無条件トラップ
    7 オペランドアクセス例外
    8 浮動小数点例外
    になっていますね「実行禁止にすることで充分」これでもかなり安全性が高くなると思います、
    「スタックオーバーフローでプログラムが暴走するのも、結局、戻り番地が壊されてしまうから」
    そうですよね、それで今回は128K Byte (64K 64K)をまるまるスタックに割り当てるようにはしたのですが、
    「UスタックオーバーフローならMPUを使っても出来そうですね。」そう言われればという気がします
    ただ小刻みに簡単にMPUに設定する方法というか、
Children
No Data