[Nasm-bugs] [Bug 3392776] uninitialized value use

noreply-nasm at dev.nasm.us noreply-nasm at dev.nasm.us
Mon Sep 20 09:19:59 PDT 2021


https://bugzilla.nasm.us/show_bug.cgi?id=3392776

Andrew Bao <xiaobaozidi at gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |xiaobaozidi at gmail.com

--- Comment #1 from Andrew Bao <xiaobaozidi at gmail.com> ---
Hi, 
I reviewed the source code of nasm and pinpoint the vulnerable code causing
this issue. 

It is in asm/parser.c
959         value = evaluate(stdscan, NULL, &tokval,
 960                          &op->opflags, critical, &hints);
 961         i = tokval.t_type;
 962         if (op->opflags & OPFLAG_FORWARD) {
 963             result->forw_ref = true;
 964         }
 965         if (!value)                  /* Error in evaluator */
 966             goto fail;
 967 
 968         if (i == '[' && !bracket) {
 969             /* displacement[regs] syntax */
 970             mref = true;
 971             parse_mref(op, value); /* Process what we have so far */
 972             goto mref_more;
 973         }
 974 
 975         if (i == ':' && (mref || !far_jmp_ok)) {
 976             /* segment override? */
 977             mref = true;
 978 
 979             /*
 980              * Process the segment override.
 981              */
 982             if (value[1].type   != 0    ||
 983                 value->value    != 1    ||
 984                 !IS_SREG(value->type))
 985                 nasm_nonfatal("invalid segment override");
 986             else if (result->prefixes[PPS_SEG])
 987                 nasm_nonfatal("instruction has conflicting segment
overrides");
 988             else {
 989                 result->prefixes[PPS_SEG] = value->type;
 990                 if (IS_FSGS(value->type))
 991                     op->eaflags |= EAF_FSGS;
 992             } 


in line 959, value is assigned. In line 982, value[1].type !=0 is uninitialized
value use. The reason is in when value is assigned in line 959, it will call
finishtemp():

051                 nasm_nonfatal("invalid right-hand operand to WRT");
1052                 return NULL;
1053             }
1054             value = reloc_seg(f);
1055             if (value == NO_SEG)
1056                 value = reloc_value(f) | SEG_ABS;
1057             else if (!(value & SEG_ABS) && !(value % 2) && critical) {
1058                 nasm_nonfatal("invalid right-hand operand to WRT");
1059                 return NULL;
1060             }
1061             addtotemp(EXPR_WRT, value);
1062             g = finishtemp();
1063         }
1064         e = add_vectors(e, g);
1065     }
1066     return e;


Then finishtemp will call addtotemp:
106 static expr *finishtemp(void)
 107 {
 108     addtotemp(0L, 0L);          /* terminate */
 109     while (ntempexprs >= tempexprs_size) {
 110         tempexprs_size += TEMPEXPRS_DELTA;
 111         tempexprs = nasm_realloc(tempexprs,
 112                                  tempexprs_size * sizeof(*tempexprs));
 113     }
 114     return tempexprs[ntempexprs++] = tempexpr;
 115 }

Let us look at addtotemp():
 95 static void addtotemp(int32_t type, int64_t value)
  96 {
  97     while (ntempexpr >= tempexpr_size) {
  98         tempexpr_size += TEMPEXPR_DELTA;
  99         tempexpr = nasm_realloc(tempexpr,
 100                                 tempexpr_size * sizeof(*tempexpr));
 101     }
 102     tempexpr[ntempexpr].type = type;
 103     tempexpr[ntempexpr++].value = value;
 104 }


addtotemp() and finishtemp() will call nasm_realloc(). However, since
nasm_realloc does not zero out the memory it allocate. After a few
initialization operations:
 102     tempexpr[ntempexpr].type = type;
 103     tempexpr[ntempexpr++].value = value;

It still leave most part of memory uninitialized. Thus once the program reach
out of initialization size bound. eg:

982             if (value[1].type   != 0    |



Suggested Fix:
in function addtotemp(), finishtemp()
after:
99         tempexpr = nasm_realloc(tempexpr,
100                                 tempexpr_size * sizeof(*tempexpr));

memset(temexpr, 0, tempexpr_size * sizeof(*tempexpr));

-- 
You are receiving this mail because:
You are watching all bug changes.
You are on the CC list for the bug.


More information about the Nasm-bugs mailing list