VYPR
Medium severityNVD Advisory· Published Jun 10, 2026

CVE-2026-49760

CVE-2026-49760

Description

Erlang OTP's erl_interface contains a stack buffer overflow in ei_s_print_term, exploitable for DoS via large integers.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

Erlang OTP's erl_interface contains a stack buffer overflow in ei_s_print_term, exploitable for DoS via large integers.

Vulnerability

A stack-based buffer overflow vulnerability exists in the ei_s_print_term function within Erlang OTP's erl_interface library, specifically in the file lib/erl_interface/src/misc/ei_printterm.c [2]. The function uses a 2000-character internal stack buffer for formatting terms. When provided with an encoded Erlang term containing a very large integer whose encoded representation exceeds 2000 characters, a buffer overflow occurs. This issue affects OTP versions from OTP 17.0 before 27.3.4.13, 28.5.0.2, and 29.0.2, corresponding to erl_interface versions from 3.7.16 before 5.5.2.1, 5.7.0.1, and 5.8.1 [2].

Exploitation

An attacker can trigger this vulnerability by calling the ei_s_print_term function with an encoded Erlang term containing a very large integer, at least 1000 bytes long, which is printed as 2000 hexadecimal digits [4]. The ei_s_print_term function can be called from separate port programs or from drivers/NIFs linked into the Erlang runtime beam. The necessary conditions include calling ei_s_print_term with either entirely untrusted data or data that has been specifically crafted to contain such a large integer [4].

Impact

The overflowed bytes are restricted to ASCII values of 0-9 and A-F, which limits the exploitation primarily to a Denial of Service (DoS) [2, 4]. Code execution beyond DoS is not expected due to these limitations [4]. The companion function ei_print_term, which writes to a FILE instead of a memory buffer, is not affected by this vulnerability [2, 4].

Mitigation

This vulnerability has been fixed in Erlang OTP. Versions of erl_interface that are unaffected include 5.5.2.1, 5.7.0.1, and 5.8.1, and corresponding OTP versions 27.3.4.13, 28.5.0.2, and 29.0.2 [2]. A commit addressing this issue is available on GitHub [3]. As a workaround, systems should avoid calling ei_s_print_term with untrusted data larger than 2000 bytes [4]. Versions prior to OTP 17.0 are also likely affected but are not explicitly listed due to the versioning scheme [4].

AI Insight generated on Jun 10, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected products

3

Patches

1
0bef277b2d39

erl_interface: Fix stack overflow in ei_s_print_term

https://github.com/erlang/otpSverker ErikssonJun 1, 2026via body-scan
2 files changed · +43 21
  • lib/erl_interface/src/misc/ei_printterm.c+8 5 modified
    @@ -58,12 +58,15 @@ static void xputc(char c, FILE* fp, ei_x_buff* x)
     	ei_x_append_buf(x, &c, 1);
     }
     
    -static void xputs(const char* s, FILE* fp, ei_x_buff* x)
    +static int xputs(const char* s, FILE* fp, ei_x_buff* x)
     {
    +    const int slen = strlen(s);
    +
         if (fp != NULL)
     	fputs(s, fp);
         else
    -	ei_x_append_buf(x, s, strlen(s));
    +        ei_x_append_buf(x, s, slen);
    +    return slen;
     }
     
     static int xprintf(FILE* fp, ei_x_buff* x, const char* fmt, ...)
    @@ -74,9 +77,9 @@ static int xprintf(FILE* fp, ei_x_buff* x, const char* fmt, ...)
         if (fp != NULL) {
     	r = vfprintf(fp, fmt, ap);
         } else {
    -	/* FIXME always enough in buffer??? */
    +        /* We assume output is reasonable bounded */
     	char tmpbuf[2000];
    -	r = vsprintf(tmpbuf, fmt, ap);
    +        r = vsnprintf(tmpbuf, sizeof(tmpbuf), fmt, ap);
     	ei_x_append_buf(x, tmpbuf, strlen(tmpbuf));
         }
         va_end(ap);
    @@ -353,7 +356,7 @@ static int print_term(FILE* fp, ei_x_buff* x,
                     goto err;
                 }
                 
    -            ch_written += xprintf(fp, x, ds);
    +            ch_written += xputs(ds, fp, x);
                 free(ds);
                 ei_free_big(b);
                 
    
  • lib/erl_interface/test/ei_print_SUITE_data/ei_print_test.c+35 16 modified
    @@ -31,11 +31,12 @@
     static void
     send_printed_buf(ei_x_buff* x)
     {
    -    char* b = NULL;
         char fn[256];
         char *tmp = getenv("temp");
    -    FILE* f;
    -    int n, index = 0, ver;
    +    FILE* f = NULL;
    +    int n, n_s, index = 0, index_s, ver;
    +    char* f_buf = NULL;
    +    char* s_buf = NULL;
     
         if (tmp == NULL) {
             tmp = "/tmp";
    @@ -44,22 +45,40 @@ send_printed_buf(ei_x_buff* x)
         strcat(fn, "/ei_print_test.txt");
         f = fopen(fn, "w+");
         ei_decode_version(x->buff, &index, &ver);
    +    index_s = index;
         n = ei_print_term(f, x->buff, &index);
    -    if (n < 0) {
    -        fclose(f);
    -        x->index = 0;
    -        ei_x_format(x, "~s", "ERROR: term decoding failed");
    -        send_bin_term(x);
    -    } else {
    +    n_s = ei_s_print_term(&s_buf, x->buff, &index_s);
    +    x->index = 0;
    +    if (n != n_s) {
    +        ei_x_format(x, "{~s,~i,~i}",
    +                    "ERROR: ei_print_term return values differ",
    +                    n, n_s);
    +    }
    +    else if (n < 0) {
    +        ei_x_format(x, "{~s,~i}", "ERROR: term decoding failed", n);
    +    }
    +    else {
             fseek(f, 0, SEEK_SET);
    -        b = malloc(n+1);
    -        fread(b, 1, n, f);
    -        b[n] = '\0';
    +        f_buf = malloc(n+1);
    +        fread(f_buf, 1, n, f);
    +        f_buf[n] = '\0';
    +        if (strcmp(f_buf, s_buf) != 0) {
    +            ei_x_format(x, "{~s,~s,~s}", "ERROR: ei_print_term results differ", f_buf, s_buf);
    +        }
    +        else {
    +            ei_x_format(x, "~s", f_buf);
    +        }
    +    }
    +    send_bin_term(x);
    +
    +    if (f) {
             fclose(f);
    -        x->index = 0;
    -        ei_x_format(x, "~s", b);
    -        send_bin_term(x);
    -        free(b);
    +    }
    +    if (f_buf) {
    +        free(f_buf);
    +    }
    +    if (s_buf) {
    +        free(s_buf);
         }
     }
     
    

Vulnerability mechanics

Root cause

"The function `ei_s_print_term` uses a fixed-size stack buffer that can be overflowed by a large integer input."

Attack vector

An attacker can trigger this vulnerability by providing an encoded Erlang term containing a very large integer to the `ei_s_print_term` function. The encoded representation of this integer must exceed 2000 characters to cause the buffer overflow. This overflow is limited to ASCII values of 0-9 and A-F, restricting exploitation to denial of service [ref_id=1].

Affected code

The vulnerability resides in the `ei_s_print_term` function within the file `lib/erl_interface/src/misc/ei_printterm.c`. Specifically, the use of a 2000-character stack buffer in this function is susceptible to overflow when formatting very large integers [ref_id=1]. The patch modifies the `xputs` and `xprintf` helper functions and their usage within `print_term` [patch_id=5502025].

What the fix does

The patch modifies the `xputs` function to return the number of characters written and uses `vsnprintf` instead of `vsprintf` within `xprintf` to prevent buffer overflows [patch_id=5502025]. Additionally, the `ei_s_print_term` function now uses `xputs` for bignums, bypassing the problematic temporary buffer copy. This change ensures that the function handles large integers safely, preventing the stack overflow.

Preconditions

  • inputAn encoded Erlang term containing a very large integer (representation exceeding 2000 characters).

Generated on Jun 10, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

5

News mentions

1