Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incorrect Validation for Element Segment Initialization #4013

Open
Q1IQ opened this issue Jan 9, 2025 · 5 comments
Open

Incorrect Validation for Element Segment Initialization #4013

Q1IQ opened this issue Jan 9, 2025 · 5 comments

Comments

@Q1IQ
Copy link

Q1IQ commented Jan 9, 2025

Subject of the issue

iwasm does not correctly handle element segment initialization using global.get for non-imported globals.

Test case

Uploading program.wasm.txt…

Your environment

  • OS: Ubuntu 20.04
  • CPU: amd64
  • WAMR version: iwasm 2.2.0
  • Commands:
iwasm --interp -f main ./program.wasm
iwasm --fast-jit -f main ./program.wasm
iwasm --llvm-jit -f main ./program.wasm
iwasm --multi-tier-jit -f main./program.wasm

Actual behavior

WASM module load failed: unknown global 0

Expected State

Element segment offset expressions should be able to reference both imported and non-imported globals. The module should pass validation without errors.

@TianlongLiang
Copy link
Collaborator

Hi, it seems that the file wasn't uploaded successfully, could you try to upload it again?

@Asuk4
Copy link

Asuk4 commented Jan 10, 2025

program.wasm.txt

Hi, it seems that the file wasn't uploaded successfully, could you try to upload it again?

@TianlongLiang
Copy link
Collaborator

I think the actual behavior is as expected, because in wasm spec states:

Globals, however, are not recursive and not accessible within constant expressions when they are defined locally. The effect of defining the limited context
C' for validating certain definitions is that they can only access functions and imported globals and nothing else.

Also, from the wasm-validator result of your example:

/opt/wabt/bin/wasm-validate --verbose global.wasm                                                     
BeginModule(version: 1)
  BeginTypeSection(5)
    OnTypeCount(1)
    OnFuncType(index: 0, params: [], results: [i32])
  EndTypeSection
  BeginFunctionSection(2)
    OnFunctionCount(1)
    OnFunction(index: 0, sig_index: 0)
  EndFunctionSection
  BeginTableSection(4)
    OnTableCount(1)
    OnTable(index: 0, elem_type: funcref, initial: 1)
  EndTableSection
  BeginGlobalSection(6)
    OnGlobalCount(1)
    BeginGlobal(index: 0, type: i32, mutable: false)
    BeginGlobalInitExpr(0)
    OnI32ConstExpr(0 (0x0))
    OnEndExpr
    EndGlobalInitExpr(0)
    EndGlobal(0)
  EndGlobalSection
  BeginExportSection(8)
    OnExportCount(1)
    OnExport(index: 0, kind: func, item_index: 0, name: "main")
  EndExportSection
  BeginElemSection(7)
    OnElemSegmentCount(1)
    BeginElemSegment(index: 0, table_index: 0, flags: 0)
    BeginElemSegmentInitExpr(0)
    OnGlobalGetExpr(index: 0)
    OnEndExpr
    EndElemSegmentInitExpr(0)
    OnElemSegmentElemType(index: 0, type: funcref)
    OnElemSegmentElemExprCount(index: 0, count: 1)
    BeginElemExpr(elem_index: 0, expr_index: 0)
    OnRefFuncExpr(0)
    OnEndExpr
    EndElemExpr(elem_index: 0, expr_index: 0)
    EndElemSegment(0)
  EndElemSection
  BeginCodeSection(6)
    OnFunctionBodyCount(1)
    BeginFunctionBody(0, size:4)
    OnLocalDeclCount(0)
    OnI32ConstExpr(1 (0x1))
    OnEndExpr
    EndFunctionBody(0)
  EndCodeSection
  BeginCustomSection('name', size: 14)
    BeginGenericCustomSection(14)
      OnGenericCustomSection(name: "name", size: 9)
    EndGenericCustomSection
    BeginNamesSection(14)
      OnNameSubsection(index: 0, type: function, size:7)
      OnFunctionNameSubsection(index:0, nametype:1, size:7)
      OnFunctionNamesCount(1)
      OnFunctionName(index: 0, name: "main")
    EndNamesSection
  EndCustomSection
EndModule
global.wasm:0000031: error: initializer expression can only reference an imported global

@Q1IQ
Copy link
Author

Q1IQ commented Jan 12, 2025

I think the actual behavior is as expected, because in wasm spec states:

Globals, however, are not recursive and not accessible within constant expressions when they are defined locally. The effect of defining the limited context
C' for validating certain definitions is that they can only access functions and imported globals and nothing else.

Also, from the wasm-validator result of your example:

/opt/wabt/bin/wasm-validate --verbose global.wasm                                                     
BeginModule(version: 1)
  BeginTypeSection(5)
    OnTypeCount(1)
    OnFuncType(index: 0, params: [], results: [i32])
  EndTypeSection
  BeginFunctionSection(2)
    OnFunctionCount(1)
    OnFunction(index: 0, sig_index: 0)
  EndFunctionSection
  BeginTableSection(4)
    OnTableCount(1)
    OnTable(index: 0, elem_type: funcref, initial: 1)
  EndTableSection
  BeginGlobalSection(6)
    OnGlobalCount(1)
    BeginGlobal(index: 0, type: i32, mutable: false)
    BeginGlobalInitExpr(0)
    OnI32ConstExpr(0 (0x0))
    OnEndExpr
    EndGlobalInitExpr(0)
    EndGlobal(0)
  EndGlobalSection
  BeginExportSection(8)
    OnExportCount(1)
    OnExport(index: 0, kind: func, item_index: 0, name: "main")
  EndExportSection
  BeginElemSection(7)
    OnElemSegmentCount(1)
    BeginElemSegment(index: 0, table_index: 0, flags: 0)
    BeginElemSegmentInitExpr(0)
    OnGlobalGetExpr(index: 0)
    OnEndExpr
    EndElemSegmentInitExpr(0)
    OnElemSegmentElemType(index: 0, type: funcref)
    OnElemSegmentElemExprCount(index: 0, count: 1)
    BeginElemExpr(elem_index: 0, expr_index: 0)
    OnRefFuncExpr(0)
    OnEndExpr
    EndElemExpr(elem_index: 0, expr_index: 0)
    EndElemSegment(0)
  EndElemSection
  BeginCodeSection(6)
    OnFunctionBodyCount(1)
    BeginFunctionBody(0, size:4)
    OnLocalDeclCount(0)
    OnI32ConstExpr(1 (0x1))
    OnEndExpr
    EndFunctionBody(0)
  EndCodeSection
  BeginCustomSection('name', size: 14)
    BeginGenericCustomSection(14)
      OnGenericCustomSection(name: "name", size: 9)
    EndGenericCustomSection
    BeginNamesSection(14)
      OnNameSubsection(index: 0, type: function, size:7)
      OnFunctionNameSubsection(index:0, nametype:1, size:7)
      OnFunctionNamesCount(1)
      OnFunctionName(index: 0, name: "main")
    EndNamesSection
  EndCustomSection
EndModule
global.wasm:0000031: error: initializer expression can only reference an imported global

The Wasm 3.0 specification relaxed the requirement from Wasm 1.0, making certain actions now valid. The element section, which comes after the global section, can now access all the globals defined there, with the only restriction being that these globals must be immutable.
https://webassembly.github.io/gc/core/valid/modules.html#globals

@TianlongLiang
Copy link
Collaborator

You are right! However, the core spec repo the corresponding spec test cases, and some toolchains have not yet been modified. It would be some extra effort to patch the spec tes cases if were to catch up wasm 3.0. So maybe it's a good idea to hold off on the wasm 3.0 modification for a while. I will keep you updated on the wasm 3.0 progress.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants