9
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

[実験] WebAssembly で脆弱な C 言語アプリケーションはセキュアになるか?

Last updated at Posted at 2025-12-01

この記事は NTTドコモソリューションズ AdventCalendar 2025 の 2 日目の記事です。

普段は RHEL の問合せサポートやカーネル関連の技術調査をしています。OS 担当といえば、OS 上で動作するという理由だけで様々なこぼれ球を拾う担当としてもおなじみのため、幅広い知識が求められます(持論)。今回は WebAssembly のセキュリティ機能について検証してみました。


はじめに

WebAssembly(以降 Wasm) は、W3C によって標準化が進められている仮想命令セットおよびバイナリフォーマットです。

いろいろな言語のコンパイルターゲットとして利用されていて、たとえば Rust や C 言語からも Wasm バイナリを生成できます。一般的には Rust や C 言語でコンパイルしたら ELF バイナリを生成しますが、Wasm もそのような汎用的なバイナリフォーマットです。

ただし ELF バイナリは、次のように CPU が直接実行できる一方で、

$ file /usr/bin/date
/usr/bin/date: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=40b5cff5fd5f36660b638da8ffcfce3831e8265d, for GNU/Linux 3.2.0, stripped

$ /usr/bin/date
2025年 11月 26日 水曜日 13:50:47 JST

Wasm は仮想の命令セットのため、直接は実行できません。

$ file main.wasm
main.wasm: WebAssembly (wasm) binary module version 0x1 (MVP)

$ ./main.wasm
-bash: ./main.wasm: バイナリファイルを実行できません: 実行形式エラー

これを実行するのが Wasm ランタイムです。Wasm はかつては WEB ブラウザで主に実行されていましたが、最近は WASI という規格の制定が進んだおかげで、サーバサイドでコンテナのように使えるようになってきました。今回は主にサーバサイド用途で検証します。

調査すること

https://webassembly.org/ によると、Wasm の特徴は次の通りです。

  • Efficient and fast
    • 効率的なバイナリフォーマット
    • 幅広いプラットフォームで利用可能な一般的なハードウェア機能を利用しネイティブ速度に近い速度を目指す
  • Safe
    • メモリセーフ
    • (上記 URL には書いてませんが) 関数呼び出しの書き換えなどによる意図しない制御フローの乗っ取りが起きづらい 参考 webassembly.org > Security
  • Open and debuggable
  • Part of the open web platform
    • バージョンレス、機能テスト済み、後方互換性を維持するよう設計されている

利用者目線では、この中でも Safe の部分(セキュリティ関連)が気になるところです。Wasm を活用すれば、既存の脆弱なアプリケーションもコストをかけずに、セキュアになるかもしれません!ということで、今回は C 言語で書いた脆弱なアプリケーションが、Wasm に載せるだけでセキュアになるかを調べてみました。

検証条件

  • C 言語で書かれた脆弱なアプリケーションを用意します
  • gcc でコンパイルして、脆弱性があることを確認します
  • wasi-sdk 27.0 を利用して Wasm バイナリを生成します1
  • Wasm ランタイムで実行して脆弱性の有無を確認します
    • Wasm ランタイムには wasmer 6.1.0 を利用します

リターンアドレスの書き換え

次のアプリケーションは、fgets の引数が誤っており、バッファオーバフローが発生します。これにより、リターンアドレスの書き換えが可能です(関数 A から 関数 B を呼び出した。関数 B の処理が終わったので関数 A に戻ろうとしたけど、なぜか関数 C に戻ってしまった)。

buffer_overflow.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void private_function(){
    printf("SECRET\n");
}

void vuln() {
    char buf[64];
    fgets(buf, 1000, stdin);
    printf("%s\n", buf);
}

int main(int argc, char **argv){

    printf("type: ");
    vuln();
    printf("Done\n");

    return 0;
}

コンパイルすると警告をだしてくれますが、いったん無視します。

$ gcc -g3 -o buffer_overflow buffer_overflow.c
buffer_overflow.c: 関数 ‘vuln’ 内:
buffer_overflow.c:11:5: 警告: ‘fgets’ writing 1000 bytes into a region of size 64 overflows the destination [-Wstringop-overflow=]
   11 |     fgets(buf, 1000, stdin);
      |     ^~~~~~~~~~~~~~~~~~~~~~~
buffer_overflow.c:10:10: 備考: destination object ‘buf’ of size 64
   10 |     char buf[64];
      |          ^~~
次のファイルから読み込み:  buffer_overflow.c:1:
/usr/include/stdio.h:586:14: 備考: in a call to function ‘fgets’ declared with attribute ‘access (write_only, 1, 2)’
  586 | extern char *fgets (char *__restrict __s, int __n, FILE *__restrict __stream)
      |              ^~~~~

詳細は省略しますが、ユーザが入力を工夫すれば、本来は実行できない private_function が実行できます。

$ (python -c "print('a' * 0x48 + '\x46\x11\x40\x00\x00\x00\x00\x00');") | ./buffer_overflow
type: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaF@
SECRET
Segmentation fault (コアダンプ)

これを Wasm ランタイムで実行してみます。

$ ./wasi-sdk-27.0-x86_64-linux/bin/clang --sysroot ./wasi-sdk-27.0-x86_64-linux/share/wasi-sysroot -o buffer_overflow.wasm buffer_overflow.c

$ (python -c "print('a' * 0x48 + '\x46\x11\x40\x00\x00\x00\x00\x00');") | wasmer ./buffer_overflow.wasm
⠁ Compiling to WebAssembly
type: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaF@
Done

攻撃を防げたようです。

なぜ gcc でコンパイルしたものがリターンアドレスを書き換えられたのかを振り返って考えると、関数を呼び出したときに(callq 命令実行時に)、呼び出し元の次のアドレスがスタックに積まれ、vuln() 関数はそのスタックの延長でメモリを操作しているからです。つまり、次の図のようになります。

image.png

ここで、Wasm は呼び出しスタックがヒープスタックとは別領域にあるようです。

A protected call stack that is invulnerable to buffer overflows in the module heap ensures safe function returns.
出典: "WebAssembly.org > Security" https://webassembly.org/docs/security/ (参照日:2025.11.27)

つまり、リターンアドレスはスタックの連続した領域にありません。

image.png

そのため、リターンアドレスは書き換えられないようです。

呼び出し関数の書き換え

次のアプリケーションは、fgets の引数が誤っており、バッファオーバフローが発生します。今回は関数ポインタを書き換えてみます。

function_call.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void private_function(){
    printf("SECRET\n");
}

void public_function() {
   printf("HELLO\n");
}

void vuln() {
    void (*p)(void);
    p = &public_function;

    char buf[64];
    fgets(buf, 1000, stdin);
    printf("%s\n", buf);

    p();
}

int main(int argc, char **argv){

    printf("type: ");
    vuln();
    printf("Done\n");

    return 0;
}

コンパイルすると警告をだしてくれますが、いったん無視します。

$ gcc -g3 -o function_call function_call.c
function_call.c: 関数 ‘vuln’ 内:
function_call.c:18:5: 警告: ‘fgets’ writing 1000 bytes into a region of size 64 overflows the destination [-Wstringop-overflow=]
   18 |     fgets(buf, 1000, stdin);
      |     ^~~~~~~~~~~~~~~~~~~~~~~
function_call.c:17:10: 備考: destination object ‘buf’ of size 64
   17 |     char buf[64];
      |          ^~~
次のファイルから読み込み:  function_call.c:1:
/usr/include/stdio.h:586:14: 備考: in a call to function ‘fgets’ declared with attribute ‘access (write_only, 1, 2)’
  586 | extern char *fgets (char *__restrict __s, int __n, FILE *__restrict __stream)
      |              ^~~~~

詳細は省略しますが、ユーザが入力を工夫すれば、本来は実行されるはずのない private_function が実行できます。ひとつ前の例と同じじゃないの?という感じもしますが、前回はリターンアドレスの書き換えで、今回はジャンプする関数の書き換えという点が違いです。

$ (python -c "print('a' * 0x48 + '\x46\x11\x40\x00\x00\x00\x00\x00');") | ./function_call
type: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaF@
SECRET
Done
Segmentation fault (コアダンプ)

これを Wasm ランタイムで実行してみます。clang のデフォルトでは、利用しない関数はコンパイル時に消されてしまうので、残すオプション(--no-gc-sections)でコンパイルしています。

$ ./wasi-sdk-27.0-x86_64-linux/bin/clang --sysroot ./wasi-sdk-27.0-x86_64-linux/share/wasi-sysroot  -Wl,--no-gc-sections -o ./function_call.wasm ./function_call.c

$ (python -c "print('a' * 0x48 + '\x46\x11\x40\x00\x00\x00\x00\x00');") | wasmer ./function_call.wasm
⠁ Compiling to WebAssembly
type: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaF@
RuntimeError: uninitialized element
RuntimeError: uninitialized element
    at vuln (function_call.wasm[49]:0x976)
    at main (function_call.wasm[50]:0x9e7)
    at __main_void (function_call.wasm[64]:0x37e0)
    at _start (function_call.wasm[46]:0x88a)

おや RuntimeError: uninitialized element が発生しました。

Wasm バイナリの WAT 表現(objdump -D 的なやつ)を見てみると、メモリの使い方が gcc でコンパイルしたものとは違うようです。WAT 表現を見ても一般人には意味がわからないので、LLM を活用しつつ、fputs で操作する変数から 76 バイト離れたところに関数ポインタのアドレスがあるとアタリをつけます。

$ wasm-tools print function_call.wasm
...
  (func $vuln (;49;) (type 0)
    (local i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32)
    global.get $__stack_pointer
    local.set 0
    i32.const 96
    local.set 1
    local.get 0
    local.get 1
    i32.sub
    local.set 2
    local.get 2
    global.set $__stack_pointer
    i32.const 1
    local.set 3
    local.get 2
    local.get 3
    i32.store offset=92
    i32.const 16
    local.set 4
    local.get 2
    local.get 4
    i32.add
    local.set 5
    local.get 5
    local.set 6
    i32.const 0
    local.set 7
    local.get 7
    i32.load offset=1244
    local.set 8
    i32.const 1000
    local.set 9
    local.get 6
    local.get 9
    local.get 8
    call $fgets
    drop
    i32.const 16
    local.set 10
    local.get 2
    local.get 10
    i32.add
    local.set 11
    local.get 11
    local.set 12
    local.get 2
    local.get 12
    i32.store
    i32.const 1085
    local.set 13
    local.get 13
    local.get 2
    call $printf
    drop
    local.get 2
    i32.load offset=92
    local.set 14
    local.get 14
    call_indirect (type 0)
    i32.const 96
    local.set 15
    local.get 2
    local.get 15
    i32.add
    local.set 16
    local.get 16
    global.set $__stack_pointer
    return
  )
...

また関数呼び出しには call_indirect という命令を利用していました。これは引数に関数テーブルのインデックスを取るようです。関数テーブルは、次のようになっていました。

$ wasm-tools print function_call.wasm
(module $function_call.wasm
...
  (table (;0;) 7 7 funcref)
...
  (elem (;0;) (i32.const 1) func $public_function $__stdio_close $__stdio_read $__stdio_seek $__stdio_write $__stdout_write)

たとえば関数テーブルのインデックス 2 を実行したければ、次のようにすれば良さそうです。

$ python -c "import sys; sys.stdout.buffer.write(b'A'*76 + b'\x02\x00\x00\x00' + b'\n')" | wasmer ./function_call.wasm
⠁ Compiling to WebAssembly
type: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
RuntimeError: indirect call type mismatch
    at vuln (function_call.wasm[49]:0x976)
    at main (function_call.wasm[50]:0x9e7)
    at __main_void (function_call.wasm[64]:0x37e0)
    at _start (function_call.wasm[46]:0x88a)    

実行してみると RuntimeError: indirect call type mismatch が発生しました。実行する関数は差し替えられたようですが、どうやら関数シグネチャが異なる呼び出しはできないようです。これは Wasm の次の特徴に該当しています。

Indirect function calls are subject to a type signature check at runtime; the type signature of the selected indirect function must match the type signature specified at the call site.
出典: "WebAssembly.org > Security" https://webassembly.org/docs/security/ (参照日:2025.11.27)

private_function を実行してみようと思いましたが、関数テーブルに載らない関数はそもそもジャンプも指定できないため、どうやっても実行できませんでした。ということでセキュアになったようです。

補足検証

関数テーブルに載っていて、差し替え前の関数とシグネチャが合えば実行できます。ということは、例えば次のようなケースでは脆弱性が残りそうです。

function_call.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void private_function(){
    printf("SECRET\n");
}

void public_function() {
   printf("HELLO\n");
}

void vuln() {
    void (*p)(void);
    p = &private_function;
    p = &public_function;

    char buf[64];
    fgets(buf, 1000, stdin);
    printf("%s\n", buf);

    p();
}

int main(int argc, char **argv){
    printf("type: ");
    vuln();
    printf("Done\n");

    return 0;
}

Wasm ランタイムで実行すると、脆弱性が残っていることが分かります。

$ ./wasi-sdk-27.0-x86_64-linux/bin/clang --sysroot ./wasi-sdk-27.0-x86_64-linux/share/wasi-sysroot  -Wl,--no-gc-sections -o ./function_call.wasm ./function_call.c

$ wasm-tools print function_call.wasm
(module $function_call.wasm
...
  (table (;0;) 8 8 funcref)
...
  (elem (;0;) (i32.const 1) func $private_function $public_function $__stdio_close $__stdio_read $__stdio_seek $__stdio_write $__stdout_write)

# index 1 番目が private_function
$ python -c "import sys; sys.stdout.buffer.write(b'A'*76 + b'\x01\x00\x00\x00' + b'\n')" | wasmer ./function_call.wasm
⠁ Compiling to WebAssembly
type: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
SECRET
Done

変数の上書き

次のアプリケーションは、バッファオーバフローにより、変数が上書きされます。

buffer_overflow_variables.c
#include <stdio.h>
#include <string.h>

int main() {
    int flag = 99;
    char buffer[10];
    char *buflong = "this is too long text here";

    printf("Before buffer overflow: %d\n", flag);

    strcpy(buffer, buflong);

    printf("After buffer overflow: %d\n", flag);

    return 0;
}

実行すると flag 変数が書き換えられました。

$ gcc -o buffer_overflow_variables buffer_overflow_variables.c

$ ./buffer_overflow_variables
Before buffer overflow: 99
After buffer overflow: 1701995880

これを Wasm ランタイムで実行してみます。

$ ./wasi-sdk-27.0-x86_64-linux/bin/clang --sysroot ./wasi-sdk-27.0-x86_64-linux/share/wasi-sysroot -o buffer_overflow_variables.wasm buffer_overflow_variables.c

$ wasmer buffer_overflow_variables.wasm
⠁ Compiling to WebAssembly                                                                                                                                                  Before buffer overflow: 99
After buffer overflow: 1869357167

flag 変数が書き換えられました。脆弱性が残っています。

WAT 表現をみてみると、main 関数はここらへんのようです。

$ wasm-tools print buffer_overflow_variables.wasm
...
  (func $__original_main (;7;) (type 8) (result i32)
    (local i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32)
    global.get $__stack_pointer
    local.set 0
    i32.const 48
    local.set 1
    local.get 0
    local.get 1
    i32.sub
    local.set 2
    local.get 2
    global.set $__stack_pointer
    i32.const 0
    local.set 3
    local.get 2
    local.get 3
    i32.store offset=44
    i32.const 99
    local.set 4
    local.get 2
    local.get 4

どうやら int flag = 99;i32.const 99local.set 4 あたりのようです。https://developer.mozilla.org/en-US/docs/WebAssembly/Reference/Variables/local.set によると、local.set はスタックに積まれた値(今回は99)を変数領域(今回は$4)に確認する命令のようです。

LLM を活用しつつ続きを読んでいくと、結局 strcpy を実行する際は、local.set を用いて変数をリニアメモリ上に配置しているようです。

$ wasm-tools print buffer_overflow_variables.wasm
...
    i32.const 99
    local.set 4
    local.get 2
    local.get 4
    i32.store offset=40
    i32.const 1061
    local.set 5
    local.get 2
    local.get 5
    i32.store offset=24
    local.get 2
    i32.load offset=40
    local.set 6
    local.get 2
    local.get 6
    i32.store
    i32.const 1132
    local.set 7
    local.get 7
    local.get 2
    call $printf
    drop
    i32.const 30
    local.set 8
    local.get 2
    local.get 8
    i32.add
    local.set 9
    local.get 9
    local.set 10
    local.get 2
    i32.load offset=24
    local.set 11
    local.get 10
    local.get 11
    call $strcpy

次のドキュメントによると、Wasm はローカル変数(今回でいえば $4)を独自の領域に確保しており、この領域に対してはバッファオーバフローの影響はありません。しかし、リニアメモリはバッファオーバフローが影響します。

Compared to traditional C/C++ programs, these semantics obviate certain classes of memory safety bugs in WebAssembly. Buffer overflows, which occur when data exceeds the boundaries of an object and accesses adjacent memory regions, cannot affect local or global variables stored in index space, they are fixed-size and addressed by index. Data stored in linear memory can overwrite adjacent objects, since bounds checking is performed at linear memory region granularity and is not context-sensitive. However, the presence of control-flow integrity and protected call stacks prevents direct code injection attacks. Thus, common mitigations such as data execution prevention (DEP) and stack smashing protection (SSP) are not needed by WebAssembly programs.
出典: "WebAssembly > Security" https://webassembly.org/docs/security/ (参照日:2025.11.27)

C 言語上はローカル変数なのでバッファオーバフロー耐性があるのかと思いましたが、C 言語でローカル変数使っていようが、Wasm ではリニアメモリ上で操作してるので意味ありませんでした。ということになりそうです。

ゼロ除算エラー

次のアプリケーションは、ゼロ除算エラーが発生してプロセスが停止します。ゼロ除算エラー自体が脆弱性といえるかは微妙ですが、意図しないプロセス停止は DoS 攻撃(Denial of Service attack)につながります。

zero_div.c
#include <stdio.h>

int main(int argc, char **argv){
    printf("%d\n", 100/0);
    printf("Done\n");
    return 0;
}

コンパイルすると警告をだしてくれますが、いったん無視します。

$ gcc -g3 -o zero_div zero_div.c
zero_div.c: 関数 ‘main’ 内:
zero_div.c:4:23: 警告: ゼロ除算が発生しました [-Wdiv-by-zero]
    4 |     printf("%d\n", 100/0);
      |                       ^

実行すると、プロセスが途中でダウンしました。

$ ./zero_div
浮動小数点例外 (コアダンプ)

これを Wasm ランタイムで実行してみます。

$ ./wasi-sdk-27.0-x86_64-linux/bin/clang --sysroot ./wasi-sdk-27.0-x86_64-linux/share/wasi-sysroot -o zero_div.wasm ./zero_div.c
./zero_div.c:4:23: warning: division by zero is undefined [-Wdivision-by-zero]
    4 |     printf("%d\n", 100/0);
      |                       ^~
1 warning generated.

$ wasmer zero_div.wasm
⠁ Compiling to WebAssembly
0
Done

プロセスは途中で終了せず、正常に終了しました。セキュアになりました。

(本当はドキュメントに書いてるとおりに Trap されると思ってたのですが、なぜかそのまま成功しました。…なぜ? 他の Wasm ランタイム(wasmtime)でも動作確認しましたが、正常に終了しました。Trap をランタイムがどう扱うか次第なんだと思うんですが、ここでは、起きた事実だけを記載しておきます。)

. Operations that can trap include:

specifying an invalid index in any index space,
performing an indirect function call with a mismatched signature,
exceeding the maximum size of the protected call stack,
accessing out-of-bounds addresses in linear memory,
executing an illegal arithmetic operations (e.g. division or remainder by zero, signed division overflow, etc).
出典 "WebAssembly.org > Security" https://webassembly.org/docs/security/ (参照日:2025.11.27)

ランタイムによるアクセス制御

次のアプリケーションは /tmp/passwd ファイルを読み取ります。

read_passwd.c
#include <stdio.h>
#include <stdlib.h>

int main(void) {
    const char *path = "/tmp/password.txt";
    FILE *fp = fopen(path, "r");
    if (!fp) {
        perror("fopen");
        fprintf(stderr, "Failed to open: %s\n", path);
        return EXIT_FAILURE;
    }

    char buf[4096];
    while (fgets(buf, sizeof(buf), fp)) {
        fputs(buf, stdout);
    }

    if (ferror(fp)) {
        perror("read error");
        fclose(fp);
        return EXIT_FAILURE;
    }

    fclose(fp);
    return EXIT_SUCCESS;
}

実行すると、/tmp/password.txt が読み取れます。

$ gcc -o read_passwd read_passwd.c
$ echo "SECRET" > /tmp/password.txt
$ ./read_passwd
SECRET

これを Wasm ランタイムで実行します。

$ ./wasi-sdk-27.0-x86_64-linux/bin/clang --sysroot ./wasi-sdk-27.0-x86_64-linux/share/wasi-sysroot -o read_passwd.wasm read_passwd.c
$  wasmer read_passwd.wasm
⠁ Compiling to WebAssembly
fopen: No such file or directory
Failed to open: /tmp/password.txt

fopen: No such file or directory になりました。これは Wasm ランタイムがアプリケーションからアクセスできるディレクトリを制限しているためです。

--dir でアクセス範囲を指定するとアクセスできます。ファイルのほかにも、環境変数なども隔離されており、Docker コンテナの隔離とそっくりです。

$  wasmer run --dir /tmp read_passwd.wasm
⠁ Compiling to WebAssembly
SECRET

Wasm は下回りの操作(ファイルアクセスやネットワーク通信など)を直接実行できません。そのような下回りの操作は WASI API を通して Wasm ランタイムに委譲する形で、これらの隔離を実現しています。そのため、適切にアクセス範囲を制限しておけば、何かしらの脆弱性があった場合の影響範囲を局所化できそうです。

もちろんコンテナ技術と組み合わせて namespaces の隔離も併用すれば、多層でのセキュリティも実現できます。

まとめ

今回の検証結果をまとめます。

検証パターン GCC バイナリ Wasm
リターンアドレス書き換えによる制御乗っ取り 脆弱 セキュア
関数ポインタ書き換えによる制御乗っ取り 脆弱 条件付きでセキュア
変数上書き 脆弱 脆弱(な場合がある)
ゼロ除算エラーによるクラッシュ クラッシュ セキュア
ファイルアクセス 脆弱 セキュア(適切にアクセス範囲を制御していれば)

Wasm は、仕様レベルで既存のバイナリよりもセキュアな仕組みになっており、これまで問題になっていた脆弱性の一部は防げそうです。とくに CFI(control-flow integrity) 対策などが強力そうです。今回触れてない範囲でもいろいろな対策が組まれていますので、詳細は https://webassembly.org/docs/security/ を参照してください。

しかし、いくつかのパターン(リニアメモリ上での操作や、call_indirect で関数差し替え前後のシグネチャが一致するパターンなど)では脆弱性が残ることもわかりました。万能ではないので、仕組みを理解して、どこまでセキュリティを担保できるかを検討しながら使う必要がありそうです。

また今回は高級アセンブラで有名な C 言語から Wasm に変換しましたが、言語によっては言語仕様やランタイムでいろいろ追加のセキュリティ機能があるはずです。特定言語と組み合わせれば、より強力なセキュリティが実現できると思います。

参考


記載されている会社名、製品名、サービス名は、各社の商標または登録商標です。

  1. wasi-sdk は clang ベースなので、元のアプリケーションとは微妙に条件が違う点に注意してください。たとえばメモリ配置などが異なる場合があります。ただし、今回の検証範囲では、clang でも gcc でも同じ脆弱性があります。

9
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?