Skip to content

Null Pointer Dereference via -w*<option> Command-Line Argument #155

@momo-trip

Description

@momo-trip

Hi,
we have found a null pointer dereference and would like to report this issue.

Summary

A null pointer dereference occurs when -w*<option> is passed as a command-line argument, where <option> is any string listed in [Appendix A: List of Warning Classes](https://www.nasm.us/xdoc/2.16.03/html/nasmdoca.html).
Examples include -w*all or -w*db-empty.

Details

  • Vulnerability Type: Null pointer dereference

Reproduction

Tested Environment

  • Operating System: Ubuntu 24.04 LTS
  • Architecture: x86_64
  • Compiler: gcc with AddressSanitizer (gcc version: 13.3.0)

Reproduction Steps

# Setup
git clone https://github.com/netwide-assembler/nasm.git
cd nasm
git reset --hard 9ea92eab6e26b5527e2dc72424a886a1a4061a48

# Compile
sh configure --enable-debug --enable-sanitizer
make -j$(nproc)

# Execute 
./nasm -w*all

Output

asm/error.c:277:62: runtime error: member access within null pointer of type 'struct warning_stack'
AddressSanitizer:DEADLYSIGNAL
=================================================================
==10875==ERROR: AddressSanitizer: SEGV on unknown address 0x00000000002b (pc 0x60fe87c5e46f bp 0x7fff4d47cf00 sp 0x7fff4d47cec0 T0)
==10875==The signal is caused by a READ memory access.
==10875==Hint: address points to the zero page.
    #0 0x60fe87c5e46f in set_warning_status asm/error.c:277
    #1 0x60fe87c511ee in process_arg asm/nasm.c:1175
    #2 0x60fe87c53d3e in parse_cmdline asm/nasm.c:1528
    #3 0x60fe87c4dd5a in main asm/nasm.c:577
    #4 0x7181c37961c9 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
    #5 0x7181c379628a in __libc_start_main_impl ../csu/libc-start.c:360
    #6 0x60fe87c49e84 in _start (/tmp/nasm/nasm+0x2f1e84) (BuildId: 7bbd4136811f1c64a3445055037bf9ee7294a5ab)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV asm/error.c:277 in set_warning_status
==10875==ABORTING

Root Cause Analysis

The null pointer dereference occurs at the following location in the set_warning_status() function, where the static variable warning_state_init is null:

warning_state[i] |= warning_state_init->state[i] & mask;

            case WID_RESET:
                warning_state[i] &= ~mask;
                warning_state[i] |= warning_state_init->state[i] & mask;
                break;
            }

This code path is executed when -w*<option> is specified as a command-line argument. The caller is the following function invoked in main():

nasm/asm/nasm.c

Line 577 in 9ea92ea

parse_cmdline(argc, argv, 2);

    parse_cmdline(argc, argv, 2);

However, warning_state_init is initialized later, in the following function called after the above invocation:

nasm/asm/nasm.c

Line 585 in 9ea92ea

init_warnings();

    init_warnings();

void init_warnings(void)

void init_warnings(void)
{
	push_warnings();
	warning_state_init = warning_stack;
}

In other words, the root cause is that warning_state_init is being used before it is initialized.

Proposed Fix

When [-w](https://www.nasm.us/xdoc/2.16.03/html/nasmdoc2.html#section-2.1.26)*<option> is passed as a command-line argument, the first character of the string value passed to the bool set_warning_status(const char *value) function becomes *. However, the case where the first character of value is * should only be expected when used from the [WARNING] directive, not from the command-line argument -w. Therefore, when -w* is specified as a command-line argument, the program should exit.

diff --git a/asm/nasm.c b/asm/nasm.c
index 851f7cc..689a339 100644
--- a/asm/nasm.c
+++ b/asm/nasm.c
@@ -1171,8 +1171,13 @@ static bool process_arg(char *p, char *q, int pass)
         case 'w':
         case 'W':
-            if (pass == 2)
+            if (pass == 2) {
+                if (p[2] == '*') {
+                    help(stdout, "-w");
+                    exit(0);
+                }
                 set_warning_status(param);
+            }
         break;
         case 'M':

Note: This issue appears to have been previously reported and remains open:

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions