diff mbox series

[[kirkstone,v2] xterm : Fix CVE-2022-45063 code execution via OSC 50 input sequences] CVE-2022-45063

Message ID 20221222102141.160351-1-user@mv-Latitude-3420
State New, archived
Headers show
Series [[kirkstone,v2] xterm : Fix CVE-2022-45063 code execution via OSC 50 input sequences] CVE-2022-45063 | expand

Commit Message

Siddharth Doshi Dec. 22, 2022, 10:21 a.m. UTC
From: Siddharth Doshi <sdoshi@mvista.com>

Upstream-Status: Backport
[https://github.com/ThomasDickey/xterm-snapshots/commit/787636674918873a091e7a4ef5977263ba982322]
CVE: CVE-2022-45063

Signed-off-by: Siddharth Doshi <sdoshi@mvista.com>
---
 .../xorg-app/xterm/CVE-2022-45063.patch       | 763 ++++++++++++++++++
 .../recipes-graphics/xorg-app/xterm_372.bb    |   1 +
 2 files changed, 764 insertions(+)
 create mode 100644 meta-oe/recipes-graphics/xorg-app/xterm/CVE-2022-45063.patch

Comments

Steve Sakoman Dec. 22, 2022, 2:39 p.m. UTC | #1
On Thu, Dec 22, 2022 at 12:21 AM mv <sdoshi@mvista.com> wrote:
>
> From: Siddharth Doshi <sdoshi@mvista.com>
>
> Upstream-Status: Backport
> [https://github.com/ThomasDickey/xterm-snapshots/commit/787636674918873a091e7a4ef5977263ba982322]
> CVE: CVE-2022-45063
>
> Signed-off-by: Siddharth Doshi <sdoshi@mvista.com>
> ---
>  .../xorg-app/xterm/CVE-2022-45063.patch       | 763 ++++++++++++++++++
>  .../recipes-graphics/xorg-app/xterm_372.bb    |   1 +
>  2 files changed, 764 insertions(+)
>  create mode 100644 meta-oe/recipes-graphics/xorg-app/xterm/CVE-2022-45063.patch
>
> diff --git a/meta-oe/recipes-graphics/xorg-app/xterm/CVE-2022-45063.patch b/meta-oe/recipes-graphics/xorg-app/xterm/CVE-2022-45063.patch
> new file mode 100644
> index 000000000..8e43553c1
> --- /dev/null
> +++ b/meta-oe/recipes-graphics/xorg-app/xterm/CVE-2022-45063.patch
> @@ -0,0 +1,763 @@
> +From 03991a63d4409ad851fc0fc4754c3acde9fa68a5 Wed Dec 21 15:15:00 2022
> +From: Siddharth Doshi <sdoshi@mvista.com>
> +Date: Wed, 21 Dec 2022 14:49:33 +0000
> +Subject: [PATCH] CVE-2022-45063
> +
> +Upstream-Status: https://github.com/ThomasDickey/xterm-snapshots/commit/787636674918873a091e7a4ef5977263ba982322
> +
Missing CVE: tag.

Please submit a V3 for kirkstone.

Thanks,

Steve

> +Signed-off-by: Siddharth Doshi <sdoshi@mvista.com>
> +---
> + button.c    |  14 +--
> + charproc.c  |   9 +-
> + doublechr.c |   4 +-
> + fontutils.c | 266 ++++++++++++++++++++++++++++------------------------
> + fontutils.h |   4 +-
> + misc.c      |   7 +-
> + screen.c    |   2 +-
> + xterm.h     |   2 +-
> + 8 files changed, 157 insertions(+), 151 deletions(-)
> +
> +diff --git a/button.c b/button.c
> +index f10092a..0bbf76e 100644
> +--- a/button.c
> ++++ b/button.c
> +@@ -2051,13 +2051,8 @@ void
> + UnmapSelections(XtermWidget xw)
> + {
> +     TScreen *screen = TScreenOf(xw);
> +-    Cardinal n;
> +
> +-    if (screen->mappedSelect) {
> +-      for (n = 0; screen->mappedSelect[n] != 0; ++n)
> +-          free((void *) screen->mappedSelect[n]);
> +-      FreeAndNull(screen->mappedSelect);
> +-    }
> ++    FreeAndNull(screen->mappedSelect);
> + }
> +
> + /*
> +@@ -2093,14 +2088,11 @@ MapSelections(XtermWidget xw, String *params, Cardinal num_params)
> +           if ((result = TypeMallocN(String, num_params + 1)) != 0) {
> +               result[num_params] = 0;
> +               for (j = 0; j < num_params; ++j) {
> +-                  result[j] = x_strdup((isSELECT(params[j])
> ++                  result[j] = (String) (isSELECT(params[j])
> +                                         ? mapTo
> +-                                        : params[j]));
> ++                                        : params[j]);
> +                   if (result[j] == 0) {
> +                       UnmapSelections(xw);
> +-                      while (j != 0) {
> +-                          free((void *) result[--j]);
> +-                      }
> +                       FreeAndNull(result);
> +                       break;
> +                   }
> +diff --git a/charproc.c b/charproc.c
> +index 2a3c69a..91cbcea 100644
> +--- a/charproc.c
> ++++ b/charproc.c
> +@@ -13605,7 +13605,6 @@ DoSetSelectedFont(Widget w,
> +       Bell(xw, XkbBI_MinorError, 0);
> +     } else {
> +       Boolean failed = False;
> +-      int oldFont = TScreenOf(xw)->menu_font_number;
> +       char *save = TScreenOf(xw)->SelectFontName();
> +       char *val;
> +       char *test;
> +@@ -13650,10 +13649,6 @@ DoSetSelectedFont(Widget w,
> +               failed = True;
> +           }
> +           if (failed) {
> +-              (void) xtermLoadFont(xw,
> +-                                   xtermFontName(TScreenOf(xw)->MenuFontName(oldFont)),
> +-                                   True,
> +-                                   oldFont);
> +               Bell(xw, XkbBI_MinorError, 0);
> +           }
> +           free(used);
> +@@ -13662,7 +13657,7 @@ DoSetSelectedFont(Widget w,
> +     }
> + }
> +
> +-void
> ++Bool
> + FindFontSelection(XtermWidget xw, const char *atom_name, Bool justprobe)
> + {
> +     TScreen *screen = TScreenOf(xw);
> +@@ -13702,7 +13697,7 @@ FindFontSelection(XtermWidget xw, const char *atom_name, Bool justprobe)
> +                           DoSetSelectedFont, NULL,
> +                           XtLastTimestampProcessed(XtDisplay(xw)));
> +     }
> +-    return;
> ++    return (screen->SelectFontName() != NULL) ? True : False;
> + }
> +
> + Bool
> +diff --git a/doublechr.c b/doublechr.c
> +index a802e32..6416849 100644
> +--- a/doublechr.c
> ++++ b/doublechr.c
> +@@ -295,7 +295,7 @@ xterm_DoubleGC(XTermDraw * params, GC old_gc, int *inxp)
> +           temp.flags = (params->attr_flags & BOLD);
> +           temp.warn = fwResource;
> +
> +-          if (!xtermOpenFont(params->xw, name, &temp, False)) {
> ++          if (!xtermOpenFont(params->xw, name, &temp, NULL, False)) {
> +               XTermDraw local = *params;
> +               char *nname;
> +
> +@@ -304,7 +304,7 @@ xterm_DoubleGC(XTermDraw * params, GC old_gc, int *inxp)
> +               nname = xtermSpecialFont(&local);
> +               if (nname != 0) {
> +                   found = (Boolean) xtermOpenFont(params->xw, nname, &temp,
> +-                                                  False);
> ++                                                  NULL, False);
> +                   free(nname);
> +               }
> +           } else {
> +diff --git a/fontutils.c b/fontutils.c
> +index 1646b4b..71f4ec2 100644
> +--- a/fontutils.c
> ++++ b/fontutils.c
> +@@ -92,9 +92,9 @@
> + }
> +
> + #define FREE_FNAME(field) \
> +-          if (fonts == 0 || myfonts.field != fonts->field) { \
> +-              FREE_STRING(myfonts.field); \
> +-              myfonts.field = 0; \
> ++          if (fonts == 0 || new_fnames.field != fonts->field) { \
> ++              FREE_STRING(new_fnames.field); \
> ++              new_fnames.field = 0; \
> +           }
> +
> + /*
> +@@ -573,7 +573,7 @@ open_italic_font(XtermWidget xw, int n, FontNameProperties *fp, XTermFonts * dat
> +       if ((name = italic_font_name(fp, slant[pass])) != 0) {
> +           TRACE(("open_italic_font %s %s\n",
> +                  whichFontEnum((VTFontEnum) n), name));
> +-          if (xtermOpenFont(xw, name, data, False)) {
> ++          if (xtermOpenFont(xw, name, data, NULL, False)) {
> +               result = (data->fs != 0);
> + #if OPT_REPORT_FONTS
> +               if (resource.reportFonts) {
> +@@ -1037,20 +1037,26 @@ xtermLoadQueryFont(XtermWidget xw, const char *name)
> + }
> +
> + /*
> +- * Open the given font and verify that it is non-empty.  Return a null on
> ++ * Open the given font and verify that it is non-empty.  Return false on
> +  * failure.
> +  */
> + Bool
> + xtermOpenFont(XtermWidget xw,
> +             const char *name,
> +             XTermFonts * result,
> ++            XTermFonts * current,
> +             Bool force)
> + {
> +     Bool code = False;
> +
> +     TRACE(("xtermOpenFont %d:%d '%s'\n",
> +          result->warn, xw->misc.fontWarnings, NonNull(name)));
> ++
> +     if (!IsEmpty(name)) {
> ++      Bool existing = (current != NULL
> ++                       && current->fs != NULL
> ++                       && current->fn != NULL);
> ++
> +       if ((result->fs = xtermLoadQueryFont(xw, name)) != 0) {
> +           code = True;
> +           if (EmptyFont(result->fs)) {
> +@@ -1069,9 +1075,13 @@ xtermOpenFont(XtermWidget xw,
> +           } else {
> +               TRACE(("xtermOpenFont: cannot load font '%s'\n", name));
> +           }
> +-          if (force) {
> ++          if (existing) {
> ++              TRACE(("...continue using font '%s'\n", current->fn));
> ++              result->fn = x_strdup(current->fn);
> ++              result->fs = current->fs;
> ++          } else if (force) {
> +               NoFontWarning(result);
> +-              code = xtermOpenFont(xw, DEFFONT, result, True);
> ++              code = xtermOpenFont(xw, DEFFONT, result, NULL, True);
> +           }
> +       }
> +     }
> +@@ -1321,6 +1331,7 @@ static Bool
> + loadNormFP(XtermWidget xw,
> +          char **nameOutP,
> +          XTermFonts * infoOut,
> ++         XTermFonts * current,
> +          int fontnum)
> + {
> +     Bool status = True;
> +@@ -1330,7 +1341,7 @@ loadNormFP(XtermWidget xw,
> +     if (!xtermOpenFont(xw,
> +                      *nameOutP,
> +                      infoOut,
> +-                     (fontnum == fontMenu_default))) {
> ++                     current, (fontnum == fontMenu_default))) {
> +       /*
> +        * If we are opening the default font, and it happens to be missing,
> +        * force that to the compiled-in default font, e.g., "fixed".  If we
> +@@ -1365,10 +1376,10 @@ loadBoldFP(XtermWidget xw,
> +       if (fp != 0) {
> +           NoFontWarning(infoOut);
> +           *nameOutP = bold_font_name(fp, fp->average_width);
> +-          if (!xtermOpenFont(xw, *nameOutP, infoOut, False)) {
> ++          if (!xtermOpenFont(xw, *nameOutP, infoOut, NULL, False)) {
> +               free(*nameOutP);
> +               *nameOutP = bold_font_name(fp, -1);
> +-              xtermOpenFont(xw, *nameOutP, infoOut, False);
> ++              xtermOpenFont(xw, *nameOutP, infoOut, NULL, False);
> +           }
> +           TRACE(("...derived bold '%s'\n", NonNull(*nameOutP)));
> +       }
> +@@ -1386,7 +1397,7 @@ loadBoldFP(XtermWidget xw,
> +           TRACE(("...did not get a matching bold font\n"));
> +       }
> +       free(normal);
> +-    } else if (!xtermOpenFont(xw, *nameOutP, infoOut, False)) {
> ++    } else if (!xtermOpenFont(xw, *nameOutP, infoOut, NULL, False)) {
> +       xtermCopyFontInfo(infoOut, infoRef);
> +       TRACE(("...cannot load bold font '%s'\n", NonNull(*nameOutP)));
> +     } else {
> +@@ -1440,7 +1451,7 @@ loadWideFP(XtermWidget xw,
> +     }
> +
> +     if (check_fontname(*nameOutP)) {
> +-      if (xtermOpenFont(xw, *nameOutP, infoOut, False)
> ++      if (xtermOpenFont(xw, *nameOutP, infoOut, NULL, False)
> +           && is_derived_font_name(*nameOutP)
> +           && EmptyFont(infoOut->fs)) {
> +           xtermCloseFont2(xw, infoOut - fWide, fWide);
> +@@ -1493,7 +1504,7 @@ loadWBoldFP(XtermWidget xw,
> +
> +     if (check_fontname(*nameOutP)) {
> +
> +-      if (xtermOpenFont(xw, *nameOutP, infoOut, False)
> ++      if (xtermOpenFont(xw, *nameOutP, infoOut, NULL, False)
> +           && is_derived_font_name(*nameOutP)
> +           && !compatibleWideCounts(wideInfoRef->fs, infoOut->fs)) {
> +           xtermCloseFont2(xw, infoOut - fWBold, fWBold);
> +@@ -1546,6 +1557,10 @@ loadWBoldFP(XtermWidget xw,
> + }
> + #endif
> +
> ++/*
> ++ * Load a given bitmap font, along with the bold/wide variants.
> ++ * Returns nonzero on success.
> ++ */
> + int
> + xtermLoadFont(XtermWidget xw,
> +             const VTFontNames * fonts,
> +@@ -1555,33 +1570,37 @@ xtermLoadFont(XtermWidget xw,
> +     TScreen *screen = TScreenOf(xw);
> +     VTwin *win = WhichVWin(screen);
> +
> +-    VTFontNames myfonts;
> +-    XTermFonts fnts[fMAX];
> ++    VTFontNames new_fnames;
> ++    XTermFonts new_fonts[fMAX];
> ++    XTermFonts old_fonts[fMAX];
> +     char *tmpname = NULL;
> +     Boolean proportional = False;
> ++    Boolean recovered;
> ++    int code = 0;
> +
> +-    memset(&myfonts, 0, sizeof(myfonts));
> +-    memset(fnts, 0, sizeof(fnts));
> ++    memset(&new_fnames, 0, sizeof(new_fnames));
> ++    memset(new_fonts, 0, sizeof(new_fonts));
> ++    memcpy(&old_fonts, screen->fnts, sizeof(old_fonts));
> +
> +     if (fonts != 0)
> +-      myfonts = *fonts;
> +-    if (!check_fontname(myfonts.f_n))
> +-      return 0;
> ++      new_fnames = *fonts;
> ++    if (!check_fontname(new_fnames.f_n))
> ++      return code;
> +
> +     if (fontnum == fontMenu_fontescape
> +-      && myfonts.f_n != screen->MenuFontName(fontnum)) {
> +-      if ((tmpname = x_strdup(myfonts.f_n)) == 0)
> +-          return 0;
> ++      && new_fnames.f_n != screen->MenuFontName(fontnum)) {
> ++      if ((tmpname = x_strdup(new_fnames.f_n)) == 0)
> ++          return code;
> +     }
> +
> +-    TRACE(("Begin Cgs - xtermLoadFont(%s)\n", myfonts.f_n));
> ++    TRACE(("Begin Cgs - xtermLoadFont(%s)\n", new_fnames.f_n));
> +     releaseWindowGCs(xw, win);
> +
> + #define DbgResource(name, field, index) \
> +     TRACE(("xtermLoadFont #%d "name" %s%s\n", \
> +          fontnum, \
> +-         (fnts[index].warn == fwResource) ? "*" : " ", \
> +-         NonNull(myfonts.field)))
> ++         (new_fonts[index].warn == fwResource) ? "*" : " ", \
> ++         NonNull(new_fnames.field)))
> +     DbgResource("normal", f_n, fNorm);
> +     DbgResource("bold  ", f_b, fBold);
> + #if OPT_WIDE_CHARS
> +@@ -1590,16 +1609,17 @@ xtermLoadFont(XtermWidget xw,
> + #endif
> +
> +     if (!loadNormFP(xw,
> +-                  &myfonts.f_n,
> +-                  &fnts[fNorm],
> ++                  &new_fnames.f_n,
> ++                  &new_fonts[fNorm],
> ++                  &old_fonts[fNorm],
> +                   fontnum))
> +       goto bad;
> +
> +     if (!loadBoldFP(xw,
> +-                  &myfonts.f_b,
> +-                  &fnts[fBold],
> +-                  myfonts.f_n,
> +-                  &fnts[fNorm],
> ++                  &new_fnames.f_b,
> ++                  &new_fonts[fBold],
> ++                  new_fnames.f_n,
> ++                  &new_fonts[fNorm],
> +                   fontnum))
> +       goto bad;
> +
> +@@ -1611,20 +1631,20 @@ xtermLoadFont(XtermWidget xw,
> +     if_OPT_WIDE_CHARS(screen, {
> +
> +       if (!loadWideFP(xw,
> +-                      &myfonts.f_w,
> +-                      &fnts[fWide],
> +-                      myfonts.f_n,
> +-                      &fnts[fNorm],
> ++                      &new_fnames.f_w,
> ++                      &new_fonts[fWide],
> ++                      new_fnames.f_n,
> ++                      &new_fonts[fNorm],
> +                       fontnum))
> +           goto bad;
> +
> +       if (!loadWBoldFP(xw,
> +-                       &myfonts.f_wb,
> +-                       &fnts[fWBold],
> +-                       myfonts.f_w,
> +-                       &fnts[fWide],
> +-                       myfonts.f_b,
> +-                       &fnts[fBold],
> ++                       &new_fnames.f_wb,
> ++                       &new_fonts[fWBold],
> ++                       new_fnames.f_w,
> ++                       &new_fonts[fWide],
> ++                       new_fnames.f_b,
> ++                       &new_fonts[fBold],
> +                        fontnum))
> +           goto bad;
> +
> +@@ -1634,30 +1654,30 @@ xtermLoadFont(XtermWidget xw,
> +      * Normal/bold fonts should be the same width.  Also, the min/max
> +      * values should be the same.
> +      */
> +-    if (fnts[fNorm].fs != 0
> +-      && fnts[fBold].fs != 0
> +-      && (!is_fixed_font(fnts[fNorm].fs)
> +-          || !is_fixed_font(fnts[fBold].fs)
> +-          || differing_widths(fnts[fNorm].fs, fnts[fBold].fs))) {
> ++    if (new_fonts[fNorm].fs != 0
> ++      && new_fonts[fBold].fs != 0
> ++      && (!is_fixed_font(new_fonts[fNorm].fs)
> ++          || !is_fixed_font(new_fonts[fBold].fs)
> ++          || differing_widths(new_fonts[fNorm].fs, new_fonts[fBold].fs))) {
> +       TRACE(("Proportional font! normal %d/%d, bold %d/%d\n",
> +-             fnts[fNorm].fs->min_bounds.width,
> +-             fnts[fNorm].fs->max_bounds.width,
> +-             fnts[fBold].fs->min_bounds.width,
> +-             fnts[fBold].fs->max_bounds.width));
> ++             new_fonts[fNorm].fs->min_bounds.width,
> ++             new_fonts[fNorm].fs->max_bounds.width,
> ++             new_fonts[fBold].fs->min_bounds.width,
> ++             new_fonts[fBold].fs->max_bounds.width));
> +       proportional = True;
> +     }
> +
> +     if_OPT_WIDE_CHARS(screen, {
> +-      if (fnts[fWide].fs != 0
> +-          && fnts[fWBold].fs != 0
> +-          && (!is_fixed_font(fnts[fWide].fs)
> +-              || !is_fixed_font(fnts[fWBold].fs)
> +-              || differing_widths(fnts[fWide].fs, fnts[fWBold].fs))) {
> ++      if (new_fonts[fWide].fs != 0
> ++          && new_fonts[fWBold].fs != 0
> ++          && (!is_fixed_font(new_fonts[fWide].fs)
> ++              || !is_fixed_font(new_fonts[fWBold].fs)
> ++              || differing_widths(new_fonts[fWide].fs, new_fonts[fWBold].fs))) {
> +           TRACE(("Proportional font! wide %d/%d, wide bold %d/%d\n",
> +-                 fnts[fWide].fs->min_bounds.width,
> +-                 fnts[fWide].fs->max_bounds.width,
> +-                 fnts[fWBold].fs->min_bounds.width,
> +-                 fnts[fWBold].fs->max_bounds.width));
> ++                 new_fonts[fWide].fs->min_bounds.width,
> ++                 new_fonts[fWide].fs->max_bounds.width,
> ++                 new_fonts[fWBold].fs->min_bounds.width,
> ++                 new_fonts[fWBold].fs->max_bounds.width));
> +           proportional = True;
> +       }
> +     });
> +@@ -1676,13 +1696,13 @@ xtermLoadFont(XtermWidget xw,
> +     screen->ifnts_ok = False;
> + #endif
> +
> +-    xtermCopyFontInfo(GetNormalFont(screen, fNorm), &fnts[fNorm]);
> +-    xtermCopyFontInfo(GetNormalFont(screen, fBold), &fnts[fBold]);
> ++    xtermCopyFontInfo(GetNormalFont(screen, fNorm), &new_fonts[fNorm]);
> ++    xtermCopyFontInfo(GetNormalFont(screen, fBold), &new_fonts[fBold]);
> + #if OPT_WIDE_CHARS
> +-    xtermCopyFontInfo(GetNormalFont(screen, fWide), &fnts[fWide]);
> +-    if (fnts[fWBold].fs == NULL)
> +-      xtermCopyFontInfo(GetNormalFont(screen, fWide), &fnts[fWide]);
> +-    xtermCopyFontInfo(GetNormalFont(screen, fWBold), &fnts[fWBold]);
> ++    xtermCopyFontInfo(GetNormalFont(screen, fWide), &new_fonts[fWide]);
> ++    if (new_fonts[fWBold].fs == NULL)
> ++      xtermCopyFontInfo(GetNormalFont(screen, fWide), &new_fonts[fWide]);
> ++    xtermCopyFontInfo(GetNormalFont(screen, fWBold), &new_fonts[fWBold]);
> + #endif
> +
> +     xtermUpdateFontGCs(xw, getNormalFont);
> +@@ -1713,7 +1733,7 @@ xtermLoadFont(XtermWidget xw,
> +       unsigned ch;
> +
> + #if OPT_TRACE
> +-#define TRACE_MISS(index) show_font_misses(#index, &fnts[index])
> ++#define TRACE_MISS(index) show_font_misses(#index, &new_fonts[index])
> +       TRACE_MISS(fNorm);
> +       TRACE_MISS(fBold);
> + #if OPT_WIDE_CHARS
> +@@ -1730,8 +1750,8 @@ xtermLoadFont(XtermWidget xw,
> +               if ((n != UCS_REPL)
> +                   && (n != ch)
> +                   && (screen->fnt_boxes & 2)) {
> +-                  if (xtermMissingChar(n, &fnts[fNorm]) ||
> +-                      xtermMissingChar(n, &fnts[fBold])) {
> ++                  if (xtermMissingChar(n, &new_fonts[fNorm]) ||
> ++                      xtermMissingChar(n, &new_fonts[fBold])) {
> +                       UIntClr(screen->fnt_boxes, 2);
> +                       TRACE(("missing graphics character #%d, U+%04X\n",
> +                              ch, n));
> +@@ -1743,12 +1763,12 @@ xtermLoadFont(XtermWidget xw,
> + #endif
> +
> +       for (ch = 1; ch < 32; ch++) {
> +-          if (xtermMissingChar(ch, &fnts[fNorm])) {
> ++          if (xtermMissingChar(ch, &new_fonts[fNorm])) {
> +               TRACE(("missing normal char #%d\n", ch));
> +               UIntClr(screen->fnt_boxes, 1);
> +               break;
> +           }
> +-          if (xtermMissingChar(ch, &fnts[fBold])) {
> ++          if (xtermMissingChar(ch, &new_fonts[fBold])) {
> +               TRACE(("missing bold   char #%d\n", ch));
> +               UIntClr(screen->fnt_boxes, 1);
> +               break;
> +@@ -1765,8 +1785,8 @@ xtermLoadFont(XtermWidget xw,
> +       screen->enbolden = screen->bold_mode;
> +     } else {
> +       screen->enbolden = screen->bold_mode
> +-          && ((fnts[fNorm].fs == fnts[fBold].fs)
> +-              || same_font_name(myfonts.f_n, myfonts.f_b));
> ++          && ((new_fonts[fNorm].fs == new_fonts[fBold].fs)
> ++              || same_font_name(new_fnames.f_n, new_fnames.f_b));
> +     }
> +     TRACE(("Will %suse 1-pixel offset/overstrike to simulate bold\n",
> +          screen->enbolden ? "" : "not "));
> +@@ -1782,7 +1802,7 @@ xtermLoadFont(XtermWidget xw,
> +           update_font_escape();
> +       }
> + #if OPT_SHIFT_FONTS
> +-      screen->menu_font_sizes[fontnum] = FontSize(fnts[fNorm].fs);
> ++      screen->menu_font_sizes[fontnum] = FontSize(new_fonts[fNorm].fs);
> + #endif
> +     }
> +     set_cursor_gcs(xw);
> +@@ -1797,20 +1817,21 @@ xtermLoadFont(XtermWidget xw,
> +     FREE_FNAME(f_w);
> +     FREE_FNAME(f_wb);
> + #endif
> +-    if (fnts[fNorm].fn == fnts[fBold].fn) {
> +-      free(fnts[fNorm].fn);
> ++    if (new_fonts[fNorm].fn == new_fonts[fBold].fn) {
> ++      free(new_fonts[fNorm].fn);
> +     } else {
> +-      free(fnts[fNorm].fn);
> +-      free(fnts[fBold].fn);
> ++      free(new_fonts[fNorm].fn);
> ++      free(new_fonts[fBold].fn);
> +     }
> + #if OPT_WIDE_CHARS
> +-    free(fnts[fWide].fn);
> +-    free(fnts[fWBold].fn);
> ++    free(new_fonts[fWide].fn);
> ++    free(new_fonts[fWBold].fn);
> + #endif
> +     xtermSetWinSize(xw);
> +     return 1;
> +
> +   bad:
> ++    recovered = False;
> +     free(tmpname);
> +
> + #if OPT_RENDERFONT
> +@@ -1820,15 +1841,15 @@ xtermLoadFont(XtermWidget xw,
> +       SetItemSensitivity(fontMenuEntries[fontnum].widget, True);
> + #endif
> +       Bell(xw, XkbBI_MinorError, 0);
> +-      myfonts.f_n = screen->MenuFontName(old_fontnum);
> +-      return xtermLoadFont(xw, &myfonts, doresize, old_fontnum);
> +-    } else if (x_strcasecmp(myfonts.f_n, DEFFONT)) {
> +-      int code;
> +-
> +-      myfonts.f_n = x_strdup(DEFFONT);
> +-      TRACE(("...recovering for TrueType fonts\n"));
> +-      code = xtermLoadFont(xw, &myfonts, doresize, fontnum);
> +-      if (code) {
> ++      new_fnames.f_n = screen->MenuFontName(old_fontnum);
> ++      if (xtermLoadFont(xw, &new_fnames, doresize, old_fontnum))
> ++          recovered = True;
> ++    } else if (x_strcasecmp(new_fnames.f_n, DEFFONT)
> ++             && x_strcasecmp(new_fnames.f_n, old_fonts[fNorm].fn)) {
> ++      new_fnames.f_n = x_strdup(old_fonts[fNorm].fn);
> ++      TRACE(("...recovering from failed font-load\n"));
> ++      if (xtermLoadFont(xw, &new_fnames, doresize, fontnum)) {
> ++          recovered = True;
> +           if (fontnum != fontMenu_fontsel) {
> +               SetItemSensitivity(fontMenuEntries[fontnum].widget,
> +                                  UsingRenderFont(xw));
> +@@ -1837,15 +1858,15 @@ xtermLoadFont(XtermWidget xw,
> +                  FontHeight(screen),
> +                  FontWidth(screen)));
> +       }
> +-      return code;
> +     }
> + #endif
> +-
> +-    releaseWindowGCs(xw, win);
> +-
> +-    xtermCloseFonts(xw, fnts);
> +-    TRACE(("Fail Cgs - xtermLoadFont\n"));
> +-    return 0;
> ++    if (!recovered) {
> ++      releaseWindowGCs(xw, win);
> ++      xtermCloseFonts(xw, new_fonts);
> ++      TRACE(("Fail Cgs - xtermLoadFont\n"));
> ++      code = 0;
> ++    }
> ++    return code;
> + }
> +
> + #if OPT_WIDE_ATTRS
> +@@ -1893,7 +1914,7 @@ xtermLoadItalics(XtermWidget xw)
> +                       } else {
> +                           xtermOpenFont(xw,
> +                                         getNormalFont(screen, n)->fn,
> +-                                        data, False);
> ++                                        data, NULL, False);
> +                       }
> +                   }
> +               }
> +@@ -4250,6 +4271,8 @@ findXftGlyph(XtermWidget xw, XftFont *given, unsigned wc)
> +                   }
> + #endif
> +                   if (foundXftGlyph(xw, check, wc)) {
> ++          (void) added;
> ++          (void) actual;
> +                       markXftOpened(xw, which, n, wc);
> +                       reportXftFonts(xw, check, "fallback", tag, myReport);
> +                       result = check;
> +@@ -4451,7 +4474,7 @@ lookupOneFontSize(XtermWidget xw, int fontnum)
> +
> +       memset(&fnt, 0, sizeof(fnt));
> +       screen->menu_font_sizes[fontnum] = -1;
> +-      if (xtermOpenFont(xw, screen->MenuFontName(fontnum), &fnt, True)) {
> ++      if (xtermOpenFont(xw, screen->MenuFontName(fontnum), &fnt, NULL, True)) {
> +           if (fontnum <= fontMenu_lastBuiltin
> +               || strcmp(fnt.fn, DEFFONT)) {
> +               screen->menu_font_sizes[fontnum] = FontSize(fnt.fs);
> +@@ -4864,13 +4887,14 @@ HandleSetFont(Widget w,
> +     }
> + }
> +
> +-void
> ++Bool
> + SetVTFont(XtermWidget xw,
> +         int which,
> +         Bool doresize,
> +         const VTFontNames * fonts)
> + {
> +     TScreen *screen = TScreenOf(xw);
> ++    Bool result = False;
> +
> +     TRACE(("SetVTFont(which=%d, f_n=%s, f_b=%s)\n", which,
> +          (fonts && fonts->f_n) ? fonts->f_n : "<null>",
> +@@ -4879,34 +4903,31 @@ SetVTFont(XtermWidget xw,
> +     if (IsIcon(screen)) {
> +       Bell(xw, XkbBI_MinorError, 0);
> +     } else if (which >= 0 && which < NMENUFONTS) {
> +-      VTFontNames myfonts;
> ++      VTFontNames new_fnames;
> +
> +-      memset(&myfonts, 0, sizeof(myfonts));
> ++      memset(&new_fnames, 0, sizeof(new_fnames));
> +       if (fonts != 0)
> +-          myfonts = *fonts;
> ++          new_fnames = *fonts;
> +
> +       if (which == fontMenu_fontsel) {        /* go get the selection */
> +-          FindFontSelection(xw, myfonts.f_n, False);
> ++          result = FindFontSelection(xw, new_fnames.f_n, False);
> +       } else {
> +-          int oldFont = screen->menu_font_number;
> +-
> + #define USE_CACHED(field, name) \
> +-          if (myfonts.field == 0) { \
> +-              myfonts.field = x_strdup(screen->menu_font_names[which][name]); \
> +-              TRACE(("set myfonts." #field " from menu_font_names[%d][" #name "] %s\n", \
> +-                     which, NonNull(myfonts.field))); \
> ++          if (new_fnames.field == NULL) { \
> ++              new_fnames.field = x_strdup(screen->menu_font_names[which][name]); \
> ++              TRACE(("set new_fnames." #field " from menu_font_names[%d][" #name "] %s\n", \
> ++                     which, NonNull(new_fnames.field))); \
> +           } else { \
> +-              TRACE(("set myfonts." #field " reused\n")); \
> ++              TRACE(("set new_fnames." #field " reused\n")); \
> +           }
> + #define SAVE_FNAME(field, name) \
> +-          if (myfonts.field != 0) { \
> +-              if (screen->menu_font_names[which][name] == 0 \
> +-               || strcmp(screen->menu_font_names[which][name], myfonts.field)) { \
> +-                  TRACE(("updating menu_font_names[%d][" #name "] to \"%s\"\n", \
> +-                         which, myfonts.field)); \
> +-                  FREE_STRING(screen->menu_font_names[which][name]); \
> +-                  screen->menu_font_names[which][name] = x_strdup(myfonts.field); \
> +-              } \
> ++          if (new_fnames.field != NULL \
> ++              && (screen->menu_font_names[which][name] == NULL \
> ++               || strcmp(screen->menu_font_names[which][name], new_fnames.field))) { \
> ++              TRACE(("updating menu_font_names[%d][" #name "] to \"%s\"\n", \
> ++                     which, new_fnames.field)); \
> ++              FREE_STRING(screen->menu_font_names[which][name]); \
> ++              screen->menu_font_names[which][name] = x_strdup(new_fnames.field); \
> +           }
> +
> +           USE_CACHED(f_n, fNorm);
> +@@ -4916,7 +4937,7 @@ SetVTFont(XtermWidget xw,
> +           USE_CACHED(f_wb, fWBold);
> + #endif
> +           if (xtermLoadFont(xw,
> +-                            &myfonts,
> ++                            &new_fnames,
> +                             doresize, which)) {
> +               /*
> +                * If successful, save the data so that a subsequent query via
> +@@ -4928,10 +4949,8 @@ SetVTFont(XtermWidget xw,
> +               SAVE_FNAME(f_w, fWide);
> +               SAVE_FNAME(f_wb, fWBold);
> + #endif
> ++              result = True;
> +           } else {
> +-              (void) xtermLoadFont(xw,
> +-                                   xtermFontName(screen->MenuFontName(oldFont)),
> +-                                   doresize, oldFont);
> +               Bell(xw, XkbBI_MinorError, 0);
> +           }
> +           FREE_FNAME(f_n);
> +@@ -4944,7 +4963,8 @@ SetVTFont(XtermWidget xw,
> +     } else {
> +       Bell(xw, XkbBI_MinorError, 0);
> +     }
> +-    return;
> ++    TRACE(("...SetVTFont: %d\n", result));
> ++    return result;
> + }
> +
> + #if OPT_RENDERFONT
> +diff --git a/fontutils.h b/fontutils.h
> +index 2267f24..5b3afe0 100644
> +--- a/fontutils.h
> ++++ b/fontutils.h
> +@@ -37,7 +37,7 @@
> + /* *INDENT-OFF* */
> +
> + extern Bool xtermLoadDefaultFonts (XtermWidget /* xw */);
> +-extern Bool xtermOpenFont (XtermWidget /* xw */, const char */* name */, XTermFonts * /* result */, Bool /* force */);
> ++extern Bool xtermOpenFont (XtermWidget /* xw */, const char */* name */, XTermFonts * /* result */, XTermFonts * /* current */, Bool /* force */);
> + extern XFontStruct * xtermLoadQueryFont(XtermWidget /* xw */, const char * /*name */);
> + extern XTermFonts * getDoubleFont (TScreen * /* screen */, int /* which */);
> + extern XTermFonts * getItalicFont (TScreen * /* screen */, int /* which */);
> +@@ -51,7 +51,7 @@ extern int lookupRelativeFontSize (XtermWidget /* xw */, int /* old */, int /* r
> + extern int xtermGetFont (const char * /* param */);
> + extern int xtermLoadFont (XtermWidget /* xw */, const VTFontNames */* fonts */, Bool /* doresize */, int /* fontnum */);
> + extern void HandleSetFont PROTO_XT_ACTIONS_ARGS;
> +-extern void SetVTFont (XtermWidget /* xw */, int /* i */, Bool /* doresize */, const VTFontNames */* fonts */);
> ++extern Bool SetVTFont (XtermWidget /* xw */, int /* i */, Bool /* doresize */, const VTFontNames */* fonts */);
> + extern void allocFontList (XtermWidget /* xw */, const char * /* name */, XtermFontNames * /* target */, VTFontEnum /* which */, const char * /* source */, Bool /* ttf */);
> + extern void copyFontList (char *** /* targetp */, char ** /* source */);
> + extern void initFontLists (XtermWidget /* xw */);
> +diff --git a/misc.c b/misc.c
> +index cbb2679..aafbb08 100644
> +--- a/misc.c
> ++++ b/misc.c
> +@@ -3941,9 +3941,9 @@ ChangeFontRequest(XtermWidget xw, String buf)
> +           {
> +               memset(&fonts, 0, sizeof(fonts));
> +               fonts.f_n = name;
> +-              SetVTFont(xw, num, True, &fonts);
> +-              if (num == screen->menu_font_number &&
> +-                  num != fontMenu_fontescape) {
> ++              if (SetVTFont(xw, num, True, &fonts)
> ++                  && num == screen->menu_font_number
> ++                  && num != fontMenu_fontescape) {
> +                   screen->EscapeFontName() = x_strdup(name);
> +               }
> +           }
> +@@ -6422,7 +6422,6 @@ xtermSetenv(const char *var, const char *value)
> +
> +           found = envindex;
> +           environ[found + 1] = NULL;
> +-          environ = environ;
> +       }
> +
> +       environ[found] = malloc(2 + len + strlen(value));
> +diff --git a/screen.c b/screen.c
> +index 93e36b3..f82ee44 100644
> +--- a/screen.c
> ++++ b/screen.c
> +@@ -1454,7 +1454,7 @@ ScrnRefresh(XtermWidget xw,
> +       maxrow += StatusLineRows;
> +     }
> + #endif
> +-
> ++    (void) recurse;
> +     ++recurse;
> +
> +     if (screen->cursorp.col >= leftcol
> +diff --git a/xterm.h b/xterm.h
> +index e6bd123..c4fe811 100644
> +--- a/xterm.h
> ++++ b/xterm.h
> +@@ -999,7 +999,7 @@ extern Bool CheckBufPtrs (TScreen * /* screen */);
> + extern Bool set_cursor_gcs (XtermWidget /* xw */);
> + extern char * vt100ResourceToString (XtermWidget /* xw */, const char * /* name */);
> + extern int VTInit (XtermWidget /* xw */);
> +-extern void FindFontSelection (XtermWidget /* xw */, const char * /* atom_name */, Bool  /* justprobe */);
> ++extern Bool FindFontSelection (XtermWidget /* xw */, const char * /* atom_name */, Bool  /* justprobe */);
> + extern void HideCursor (XtermWidget /* xw */);
> + extern void RestartBlinking(XtermWidget /* xw */);
> + extern void ShowCursor (XtermWidget /* xw */);
> +--
> +2.25.1
> +
> diff --git a/meta-oe/recipes-graphics/xorg-app/xterm_372.bb b/meta-oe/recipes-graphics/xorg-app/xterm_372.bb
> index 3e1e9d704..223bc0a49 100644
> --- a/meta-oe/recipes-graphics/xorg-app/xterm_372.bb
> +++ b/meta-oe/recipes-graphics/xorg-app/xterm_372.bb
> @@ -6,6 +6,7 @@ LIC_FILES_CHKSUM = "file://xterm.h;beginline=3;endline=31;md5=5ec6748ed90e588caa
>
>  SRC_URI = "http://invisible-mirror.net/archives/${BPN}/${BP}.tgz \
>             file://0001-Add-configure-time-check-for-setsid.patch \
> +           file://CVE-2022-45063.patch \
>            "
>
>  SRC_URI[sha256sum] = "c6d08127cb2409c3a04bcae559b7025196ed770bb7bf26630abcb45d95f60ab1"
> --
> 2.25.1
>
>
> -=-=-=-=-=-=-=-=-=-=-=-
> Links: You receive all messages sent to this group.
> View/Reply Online (#174959): https://lists.openembedded.org/g/openembedded-core/message/174959
> Mute This Topic: https://lists.openembedded.org/mt/95823724/3620601
> Group Owner: openembedded-core+owner@lists.openembedded.org
> Unsubscribe: https://lists.openembedded.org/g/openembedded-core/unsub [steve@sakoman.com]
> -=-=-=-=-=-=-=-=-=-=-=-
>
diff mbox series

Patch

diff --git a/meta-oe/recipes-graphics/xorg-app/xterm/CVE-2022-45063.patch b/meta-oe/recipes-graphics/xorg-app/xterm/CVE-2022-45063.patch
new file mode 100644
index 000000000..8e43553c1
--- /dev/null
+++ b/meta-oe/recipes-graphics/xorg-app/xterm/CVE-2022-45063.patch
@@ -0,0 +1,763 @@ 
+From 03991a63d4409ad851fc0fc4754c3acde9fa68a5 Wed Dec 21 15:15:00 2022
+From: Siddharth Doshi <sdoshi@mvista.com>
+Date: Wed, 21 Dec 2022 14:49:33 +0000
+Subject: [PATCH] CVE-2022-45063
+
+Upstream-Status: https://github.com/ThomasDickey/xterm-snapshots/commit/787636674918873a091e7a4ef5977263ba982322
+
+Signed-off-by: Siddharth Doshi <sdoshi@mvista.com>
+---
+ button.c    |  14 +--
+ charproc.c  |   9 +-
+ doublechr.c |   4 +-
+ fontutils.c | 266 ++++++++++++++++++++++++++++------------------------
+ fontutils.h |   4 +-
+ misc.c      |   7 +-
+ screen.c    |   2 +-
+ xterm.h     |   2 +-
+ 8 files changed, 157 insertions(+), 151 deletions(-)
+
+diff --git a/button.c b/button.c
+index f10092a..0bbf76e 100644
+--- a/button.c
++++ b/button.c
+@@ -2051,13 +2051,8 @@ void
+ UnmapSelections(XtermWidget xw)
+ {
+     TScreen *screen = TScreenOf(xw);
+-    Cardinal n;
+ 
+-    if (screen->mappedSelect) {
+-	for (n = 0; screen->mappedSelect[n] != 0; ++n)
+-	    free((void *) screen->mappedSelect[n]);
+-	FreeAndNull(screen->mappedSelect);
+-    }
++    FreeAndNull(screen->mappedSelect);
+ }
+ 
+ /*
+@@ -2093,14 +2088,11 @@ MapSelections(XtermWidget xw, String *params, Cardinal num_params)
+ 	    if ((result = TypeMallocN(String, num_params + 1)) != 0) {
+ 		result[num_params] = 0;
+ 		for (j = 0; j < num_params; ++j) {
+-		    result[j] = x_strdup((isSELECT(params[j])
++		    result[j] = (String) (isSELECT(params[j])
+ 					  ? mapTo
+-					  : params[j]));
++					  : params[j]);
+ 		    if (result[j] == 0) {
+ 			UnmapSelections(xw);
+-			while (j != 0) {
+-			    free((void *) result[--j]);
+-			}
+ 			FreeAndNull(result);
+ 			break;
+ 		    }
+diff --git a/charproc.c b/charproc.c
+index 2a3c69a..91cbcea 100644
+--- a/charproc.c
++++ b/charproc.c
+@@ -13605,7 +13605,6 @@ DoSetSelectedFont(Widget w,
+ 	Bell(xw, XkbBI_MinorError, 0);
+     } else {
+ 	Boolean failed = False;
+-	int oldFont = TScreenOf(xw)->menu_font_number;
+ 	char *save = TScreenOf(xw)->SelectFontName();
+ 	char *val;
+ 	char *test;
+@@ -13650,10 +13649,6 @@ DoSetSelectedFont(Widget w,
+ 		failed = True;
+ 	    }
+ 	    if (failed) {
+-		(void) xtermLoadFont(xw,
+-				     xtermFontName(TScreenOf(xw)->MenuFontName(oldFont)),
+-				     True,
+-				     oldFont);
+ 		Bell(xw, XkbBI_MinorError, 0);
+ 	    }
+ 	    free(used);
+@@ -13662,7 +13657,7 @@ DoSetSelectedFont(Widget w,
+     }
+ }
+ 
+-void
++Bool
+ FindFontSelection(XtermWidget xw, const char *atom_name, Bool justprobe)
+ {
+     TScreen *screen = TScreenOf(xw);
+@@ -13702,7 +13697,7 @@ FindFontSelection(XtermWidget xw, const char *atom_name, Bool justprobe)
+ 			    DoSetSelectedFont, NULL,
+ 			    XtLastTimestampProcessed(XtDisplay(xw)));
+     }
+-    return;
++    return (screen->SelectFontName() != NULL) ? True : False;
+ }
+ 
+ Bool
+diff --git a/doublechr.c b/doublechr.c
+index a802e32..6416849 100644
+--- a/doublechr.c
++++ b/doublechr.c
+@@ -295,7 +295,7 @@ xterm_DoubleGC(XTermDraw * params, GC old_gc, int *inxp)
+ 	    temp.flags = (params->attr_flags & BOLD);
+ 	    temp.warn = fwResource;
+ 
+-	    if (!xtermOpenFont(params->xw, name, &temp, False)) {
++	    if (!xtermOpenFont(params->xw, name, &temp, NULL, False)) {
+ 		XTermDraw local = *params;
+ 		char *nname;
+ 
+@@ -304,7 +304,7 @@ xterm_DoubleGC(XTermDraw * params, GC old_gc, int *inxp)
+ 		nname = xtermSpecialFont(&local);
+ 		if (nname != 0) {
+ 		    found = (Boolean) xtermOpenFont(params->xw, nname, &temp,
+-						    False);
++						    NULL, False);
+ 		    free(nname);
+ 		}
+ 	    } else {
+diff --git a/fontutils.c b/fontutils.c
+index 1646b4b..71f4ec2 100644
+--- a/fontutils.c
++++ b/fontutils.c
+@@ -92,9 +92,9 @@
+ }
+ 
+ #define FREE_FNAME(field) \
+-	    if (fonts == 0 || myfonts.field != fonts->field) { \
+-		FREE_STRING(myfonts.field); \
+-		myfonts.field = 0; \
++	    if (fonts == 0 || new_fnames.field != fonts->field) { \
++		FREE_STRING(new_fnames.field); \
++		new_fnames.field = 0; \
+ 	    }
+ 
+ /*
+@@ -573,7 +573,7 @@ open_italic_font(XtermWidget xw, int n, FontNameProperties *fp, XTermFonts * dat
+ 	if ((name = italic_font_name(fp, slant[pass])) != 0) {
+ 	    TRACE(("open_italic_font %s %s\n",
+ 		   whichFontEnum((VTFontEnum) n), name));
+-	    if (xtermOpenFont(xw, name, data, False)) {
++	    if (xtermOpenFont(xw, name, data, NULL, False)) {
+ 		result = (data->fs != 0);
+ #if OPT_REPORT_FONTS
+ 		if (resource.reportFonts) {
+@@ -1037,20 +1037,26 @@ xtermLoadQueryFont(XtermWidget xw, const char *name)
+ }
+ 
+ /*
+- * Open the given font and verify that it is non-empty.  Return a null on
++ * Open the given font and verify that it is non-empty.  Return false on
+  * failure.
+  */
+ Bool
+ xtermOpenFont(XtermWidget xw,
+ 	      const char *name,
+ 	      XTermFonts * result,
++	      XTermFonts * current,
+ 	      Bool force)
+ {
+     Bool code = False;
+ 
+     TRACE(("xtermOpenFont %d:%d '%s'\n",
+ 	   result->warn, xw->misc.fontWarnings, NonNull(name)));
++
+     if (!IsEmpty(name)) {
++	Bool existing = (current != NULL
++			 && current->fs != NULL
++			 && current->fn != NULL);
++
+ 	if ((result->fs = xtermLoadQueryFont(xw, name)) != 0) {
+ 	    code = True;
+ 	    if (EmptyFont(result->fs)) {
+@@ -1069,9 +1075,13 @@ xtermOpenFont(XtermWidget xw,
+ 	    } else {
+ 		TRACE(("xtermOpenFont: cannot load font '%s'\n", name));
+ 	    }
+-	    if (force) {
++	    if (existing) {
++		TRACE(("...continue using font '%s'\n", current->fn));
++		result->fn = x_strdup(current->fn);
++		result->fs = current->fs;
++	    } else if (force) {
+ 		NoFontWarning(result);
+-		code = xtermOpenFont(xw, DEFFONT, result, True);
++		code = xtermOpenFont(xw, DEFFONT, result, NULL, True);
+ 	    }
+ 	}
+     }
+@@ -1321,6 +1331,7 @@ static Bool
+ loadNormFP(XtermWidget xw,
+ 	   char **nameOutP,
+ 	   XTermFonts * infoOut,
++	   XTermFonts * current,
+ 	   int fontnum)
+ {
+     Bool status = True;
+@@ -1330,7 +1341,7 @@ loadNormFP(XtermWidget xw,
+     if (!xtermOpenFont(xw,
+ 		       *nameOutP,
+ 		       infoOut,
+-		       (fontnum == fontMenu_default))) {
++		       current, (fontnum == fontMenu_default))) {
+ 	/*
+ 	 * If we are opening the default font, and it happens to be missing,
+ 	 * force that to the compiled-in default font, e.g., "fixed".  If we
+@@ -1365,10 +1376,10 @@ loadBoldFP(XtermWidget xw,
+ 	if (fp != 0) {
+ 	    NoFontWarning(infoOut);
+ 	    *nameOutP = bold_font_name(fp, fp->average_width);
+-	    if (!xtermOpenFont(xw, *nameOutP, infoOut, False)) {
++	    if (!xtermOpenFont(xw, *nameOutP, infoOut, NULL, False)) {
+ 		free(*nameOutP);
+ 		*nameOutP = bold_font_name(fp, -1);
+-		xtermOpenFont(xw, *nameOutP, infoOut, False);
++		xtermOpenFont(xw, *nameOutP, infoOut, NULL, False);
+ 	    }
+ 	    TRACE(("...derived bold '%s'\n", NonNull(*nameOutP)));
+ 	}
+@@ -1386,7 +1397,7 @@ loadBoldFP(XtermWidget xw,
+ 	    TRACE(("...did not get a matching bold font\n"));
+ 	}
+ 	free(normal);
+-    } else if (!xtermOpenFont(xw, *nameOutP, infoOut, False)) {
++    } else if (!xtermOpenFont(xw, *nameOutP, infoOut, NULL, False)) {
+ 	xtermCopyFontInfo(infoOut, infoRef);
+ 	TRACE(("...cannot load bold font '%s'\n", NonNull(*nameOutP)));
+     } else {
+@@ -1440,7 +1451,7 @@ loadWideFP(XtermWidget xw,
+     }
+ 
+     if (check_fontname(*nameOutP)) {
+-	if (xtermOpenFont(xw, *nameOutP, infoOut, False)
++	if (xtermOpenFont(xw, *nameOutP, infoOut, NULL, False)
+ 	    && is_derived_font_name(*nameOutP)
+ 	    && EmptyFont(infoOut->fs)) {
+ 	    xtermCloseFont2(xw, infoOut - fWide, fWide);
+@@ -1493,7 +1504,7 @@ loadWBoldFP(XtermWidget xw,
+ 
+     if (check_fontname(*nameOutP)) {
+ 
+-	if (xtermOpenFont(xw, *nameOutP, infoOut, False)
++	if (xtermOpenFont(xw, *nameOutP, infoOut, NULL, False)
+ 	    && is_derived_font_name(*nameOutP)
+ 	    && !compatibleWideCounts(wideInfoRef->fs, infoOut->fs)) {
+ 	    xtermCloseFont2(xw, infoOut - fWBold, fWBold);
+@@ -1546,6 +1557,10 @@ loadWBoldFP(XtermWidget xw,
+ }
+ #endif
+ 
++/*
++ * Load a given bitmap font, along with the bold/wide variants.
++ * Returns nonzero on success.
++ */
+ int
+ xtermLoadFont(XtermWidget xw,
+ 	      const VTFontNames * fonts,
+@@ -1555,33 +1570,37 @@ xtermLoadFont(XtermWidget xw,
+     TScreen *screen = TScreenOf(xw);
+     VTwin *win = WhichVWin(screen);
+ 
+-    VTFontNames myfonts;
+-    XTermFonts fnts[fMAX];
++    VTFontNames new_fnames;
++    XTermFonts new_fonts[fMAX];
++    XTermFonts old_fonts[fMAX];
+     char *tmpname = NULL;
+     Boolean proportional = False;
++    Boolean recovered;
++    int code = 0;
+ 
+-    memset(&myfonts, 0, sizeof(myfonts));
+-    memset(fnts, 0, sizeof(fnts));
++    memset(&new_fnames, 0, sizeof(new_fnames));
++    memset(new_fonts, 0, sizeof(new_fonts));
++    memcpy(&old_fonts, screen->fnts, sizeof(old_fonts));
+ 
+     if (fonts != 0)
+-	myfonts = *fonts;
+-    if (!check_fontname(myfonts.f_n))
+-	return 0;
++	new_fnames = *fonts;
++    if (!check_fontname(new_fnames.f_n))
++	return code;
+ 
+     if (fontnum == fontMenu_fontescape
+-	&& myfonts.f_n != screen->MenuFontName(fontnum)) {
+-	if ((tmpname = x_strdup(myfonts.f_n)) == 0)
+-	    return 0;
++	&& new_fnames.f_n != screen->MenuFontName(fontnum)) {
++	if ((tmpname = x_strdup(new_fnames.f_n)) == 0)
++	    return code;
+     }
+ 
+-    TRACE(("Begin Cgs - xtermLoadFont(%s)\n", myfonts.f_n));
++    TRACE(("Begin Cgs - xtermLoadFont(%s)\n", new_fnames.f_n));
+     releaseWindowGCs(xw, win);
+ 
+ #define DbgResource(name, field, index) \
+     TRACE(("xtermLoadFont #%d "name" %s%s\n", \
+     	   fontnum, \
+-	   (fnts[index].warn == fwResource) ? "*" : " ", \
+-	   NonNull(myfonts.field)))
++	   (new_fonts[index].warn == fwResource) ? "*" : " ", \
++	   NonNull(new_fnames.field)))
+     DbgResource("normal", f_n, fNorm);
+     DbgResource("bold  ", f_b, fBold);
+ #if OPT_WIDE_CHARS
+@@ -1590,16 +1609,17 @@ xtermLoadFont(XtermWidget xw,
+ #endif
+ 
+     if (!loadNormFP(xw,
+-		    &myfonts.f_n,
+-		    &fnts[fNorm],
++		    &new_fnames.f_n,
++		    &new_fonts[fNorm],
++		    &old_fonts[fNorm],
+ 		    fontnum))
+ 	goto bad;
+ 
+     if (!loadBoldFP(xw,
+-		    &myfonts.f_b,
+-		    &fnts[fBold],
+-		    myfonts.f_n,
+-		    &fnts[fNorm],
++		    &new_fnames.f_b,
++		    &new_fonts[fBold],
++		    new_fnames.f_n,
++		    &new_fonts[fNorm],
+ 		    fontnum))
+ 	goto bad;
+ 
+@@ -1611,20 +1631,20 @@ xtermLoadFont(XtermWidget xw,
+     if_OPT_WIDE_CHARS(screen, {
+ 
+ 	if (!loadWideFP(xw,
+-			&myfonts.f_w,
+-			&fnts[fWide],
+-			myfonts.f_n,
+-			&fnts[fNorm],
++			&new_fnames.f_w,
++			&new_fonts[fWide],
++			new_fnames.f_n,
++			&new_fonts[fNorm],
+ 			fontnum))
+ 	    goto bad;
+ 
+ 	if (!loadWBoldFP(xw,
+-			 &myfonts.f_wb,
+-			 &fnts[fWBold],
+-			 myfonts.f_w,
+-			 &fnts[fWide],
+-			 myfonts.f_b,
+-			 &fnts[fBold],
++			 &new_fnames.f_wb,
++			 &new_fonts[fWBold],
++			 new_fnames.f_w,
++			 &new_fonts[fWide],
++			 new_fnames.f_b,
++			 &new_fonts[fBold],
+ 			 fontnum))
+ 	    goto bad;
+ 
+@@ -1634,30 +1654,30 @@ xtermLoadFont(XtermWidget xw,
+      * Normal/bold fonts should be the same width.  Also, the min/max
+      * values should be the same.
+      */
+-    if (fnts[fNorm].fs != 0
+-	&& fnts[fBold].fs != 0
+-	&& (!is_fixed_font(fnts[fNorm].fs)
+-	    || !is_fixed_font(fnts[fBold].fs)
+-	    || differing_widths(fnts[fNorm].fs, fnts[fBold].fs))) {
++    if (new_fonts[fNorm].fs != 0
++	&& new_fonts[fBold].fs != 0
++	&& (!is_fixed_font(new_fonts[fNorm].fs)
++	    || !is_fixed_font(new_fonts[fBold].fs)
++	    || differing_widths(new_fonts[fNorm].fs, new_fonts[fBold].fs))) {
+ 	TRACE(("Proportional font! normal %d/%d, bold %d/%d\n",
+-	       fnts[fNorm].fs->min_bounds.width,
+-	       fnts[fNorm].fs->max_bounds.width,
+-	       fnts[fBold].fs->min_bounds.width,
+-	       fnts[fBold].fs->max_bounds.width));
++	       new_fonts[fNorm].fs->min_bounds.width,
++	       new_fonts[fNorm].fs->max_bounds.width,
++	       new_fonts[fBold].fs->min_bounds.width,
++	       new_fonts[fBold].fs->max_bounds.width));
+ 	proportional = True;
+     }
+ 
+     if_OPT_WIDE_CHARS(screen, {
+-	if (fnts[fWide].fs != 0
+-	    && fnts[fWBold].fs != 0
+-	    && (!is_fixed_font(fnts[fWide].fs)
+-		|| !is_fixed_font(fnts[fWBold].fs)
+-		|| differing_widths(fnts[fWide].fs, fnts[fWBold].fs))) {
++	if (new_fonts[fWide].fs != 0
++	    && new_fonts[fWBold].fs != 0
++	    && (!is_fixed_font(new_fonts[fWide].fs)
++		|| !is_fixed_font(new_fonts[fWBold].fs)
++		|| differing_widths(new_fonts[fWide].fs, new_fonts[fWBold].fs))) {
+ 	    TRACE(("Proportional font! wide %d/%d, wide bold %d/%d\n",
+-		   fnts[fWide].fs->min_bounds.width,
+-		   fnts[fWide].fs->max_bounds.width,
+-		   fnts[fWBold].fs->min_bounds.width,
+-		   fnts[fWBold].fs->max_bounds.width));
++		   new_fonts[fWide].fs->min_bounds.width,
++		   new_fonts[fWide].fs->max_bounds.width,
++		   new_fonts[fWBold].fs->min_bounds.width,
++		   new_fonts[fWBold].fs->max_bounds.width));
+ 	    proportional = True;
+ 	}
+     });
+@@ -1676,13 +1696,13 @@ xtermLoadFont(XtermWidget xw,
+     screen->ifnts_ok = False;
+ #endif
+ 
+-    xtermCopyFontInfo(GetNormalFont(screen, fNorm), &fnts[fNorm]);
+-    xtermCopyFontInfo(GetNormalFont(screen, fBold), &fnts[fBold]);
++    xtermCopyFontInfo(GetNormalFont(screen, fNorm), &new_fonts[fNorm]);
++    xtermCopyFontInfo(GetNormalFont(screen, fBold), &new_fonts[fBold]);
+ #if OPT_WIDE_CHARS
+-    xtermCopyFontInfo(GetNormalFont(screen, fWide), &fnts[fWide]);
+-    if (fnts[fWBold].fs == NULL)
+-	xtermCopyFontInfo(GetNormalFont(screen, fWide), &fnts[fWide]);
+-    xtermCopyFontInfo(GetNormalFont(screen, fWBold), &fnts[fWBold]);
++    xtermCopyFontInfo(GetNormalFont(screen, fWide), &new_fonts[fWide]);
++    if (new_fonts[fWBold].fs == NULL)
++	xtermCopyFontInfo(GetNormalFont(screen, fWide), &new_fonts[fWide]);
++    xtermCopyFontInfo(GetNormalFont(screen, fWBold), &new_fonts[fWBold]);
+ #endif
+ 
+     xtermUpdateFontGCs(xw, getNormalFont);
+@@ -1713,7 +1733,7 @@ xtermLoadFont(XtermWidget xw,
+ 	unsigned ch;
+ 
+ #if OPT_TRACE
+-#define TRACE_MISS(index) show_font_misses(#index, &fnts[index])
++#define TRACE_MISS(index) show_font_misses(#index, &new_fonts[index])
+ 	TRACE_MISS(fNorm);
+ 	TRACE_MISS(fBold);
+ #if OPT_WIDE_CHARS
+@@ -1730,8 +1750,8 @@ xtermLoadFont(XtermWidget xw,
+ 		if ((n != UCS_REPL)
+ 		    && (n != ch)
+ 		    && (screen->fnt_boxes & 2)) {
+-		    if (xtermMissingChar(n, &fnts[fNorm]) ||
+-			xtermMissingChar(n, &fnts[fBold])) {
++		    if (xtermMissingChar(n, &new_fonts[fNorm]) ||
++			xtermMissingChar(n, &new_fonts[fBold])) {
+ 			UIntClr(screen->fnt_boxes, 2);
+ 			TRACE(("missing graphics character #%d, U+%04X\n",
+ 			       ch, n));
+@@ -1743,12 +1763,12 @@ xtermLoadFont(XtermWidget xw,
+ #endif
+ 
+ 	for (ch = 1; ch < 32; ch++) {
+-	    if (xtermMissingChar(ch, &fnts[fNorm])) {
++	    if (xtermMissingChar(ch, &new_fonts[fNorm])) {
+ 		TRACE(("missing normal char #%d\n", ch));
+ 		UIntClr(screen->fnt_boxes, 1);
+ 		break;
+ 	    }
+-	    if (xtermMissingChar(ch, &fnts[fBold])) {
++	    if (xtermMissingChar(ch, &new_fonts[fBold])) {
+ 		TRACE(("missing bold   char #%d\n", ch));
+ 		UIntClr(screen->fnt_boxes, 1);
+ 		break;
+@@ -1765,8 +1785,8 @@ xtermLoadFont(XtermWidget xw,
+ 	screen->enbolden = screen->bold_mode;
+     } else {
+ 	screen->enbolden = screen->bold_mode
+-	    && ((fnts[fNorm].fs == fnts[fBold].fs)
+-		|| same_font_name(myfonts.f_n, myfonts.f_b));
++	    && ((new_fonts[fNorm].fs == new_fonts[fBold].fs)
++		|| same_font_name(new_fnames.f_n, new_fnames.f_b));
+     }
+     TRACE(("Will %suse 1-pixel offset/overstrike to simulate bold\n",
+ 	   screen->enbolden ? "" : "not "));
+@@ -1782,7 +1802,7 @@ xtermLoadFont(XtermWidget xw,
+ 	    update_font_escape();
+ 	}
+ #if OPT_SHIFT_FONTS
+-	screen->menu_font_sizes[fontnum] = FontSize(fnts[fNorm].fs);
++	screen->menu_font_sizes[fontnum] = FontSize(new_fonts[fNorm].fs);
+ #endif
+     }
+     set_cursor_gcs(xw);
+@@ -1797,20 +1817,21 @@ xtermLoadFont(XtermWidget xw,
+     FREE_FNAME(f_w);
+     FREE_FNAME(f_wb);
+ #endif
+-    if (fnts[fNorm].fn == fnts[fBold].fn) {
+-	free(fnts[fNorm].fn);
++    if (new_fonts[fNorm].fn == new_fonts[fBold].fn) {
++	free(new_fonts[fNorm].fn);
+     } else {
+-	free(fnts[fNorm].fn);
+-	free(fnts[fBold].fn);
++	free(new_fonts[fNorm].fn);
++	free(new_fonts[fBold].fn);
+     }
+ #if OPT_WIDE_CHARS
+-    free(fnts[fWide].fn);
+-    free(fnts[fWBold].fn);
++    free(new_fonts[fWide].fn);
++    free(new_fonts[fWBold].fn);
+ #endif
+     xtermSetWinSize(xw);
+     return 1;
+ 
+   bad:
++    recovered = False;
+     free(tmpname);
+ 
+ #if OPT_RENDERFONT
+@@ -1820,15 +1841,15 @@ xtermLoadFont(XtermWidget xw,
+ 	SetItemSensitivity(fontMenuEntries[fontnum].widget, True);
+ #endif
+ 	Bell(xw, XkbBI_MinorError, 0);
+-	myfonts.f_n = screen->MenuFontName(old_fontnum);
+-	return xtermLoadFont(xw, &myfonts, doresize, old_fontnum);
+-    } else if (x_strcasecmp(myfonts.f_n, DEFFONT)) {
+-	int code;
+-
+-	myfonts.f_n = x_strdup(DEFFONT);
+-	TRACE(("...recovering for TrueType fonts\n"));
+-	code = xtermLoadFont(xw, &myfonts, doresize, fontnum);
+-	if (code) {
++	new_fnames.f_n = screen->MenuFontName(old_fontnum);
++	if (xtermLoadFont(xw, &new_fnames, doresize, old_fontnum))
++	    recovered = True;
++    } else if (x_strcasecmp(new_fnames.f_n, DEFFONT)
++	       && x_strcasecmp(new_fnames.f_n, old_fonts[fNorm].fn)) {
++	new_fnames.f_n = x_strdup(old_fonts[fNorm].fn);
++	TRACE(("...recovering from failed font-load\n"));
++	if (xtermLoadFont(xw, &new_fnames, doresize, fontnum)) {
++	    recovered = True;
+ 	    if (fontnum != fontMenu_fontsel) {
+ 		SetItemSensitivity(fontMenuEntries[fontnum].widget,
+ 				   UsingRenderFont(xw));
+@@ -1837,15 +1858,15 @@ xtermLoadFont(XtermWidget xw,
+ 		   FontHeight(screen),
+ 		   FontWidth(screen)));
+ 	}
+-	return code;
+     }
+ #endif
+-
+-    releaseWindowGCs(xw, win);
+-
+-    xtermCloseFonts(xw, fnts);
+-    TRACE(("Fail Cgs - xtermLoadFont\n"));
+-    return 0;
++    if (!recovered) {
++	releaseWindowGCs(xw, win);
++	xtermCloseFonts(xw, new_fonts);
++	TRACE(("Fail Cgs - xtermLoadFont\n"));
++	code = 0;
++    }
++    return code;
+ }
+ 
+ #if OPT_WIDE_ATTRS
+@@ -1893,7 +1914,7 @@ xtermLoadItalics(XtermWidget xw)
+ 			} else {
+ 			    xtermOpenFont(xw,
+ 					  getNormalFont(screen, n)->fn,
+-					  data, False);
++					  data, NULL, False);
+ 			}
+ 		    }
+ 		}
+@@ -4250,6 +4271,8 @@ findXftGlyph(XtermWidget xw, XftFont *given, unsigned wc)
+ 		    }
+ #endif
+ 		    if (foundXftGlyph(xw, check, wc)) {
++	    (void) added;
++	    (void) actual;
+ 			markXftOpened(xw, which, n, wc);
+ 			reportXftFonts(xw, check, "fallback", tag, myReport);
+ 			result = check;
+@@ -4451,7 +4474,7 @@ lookupOneFontSize(XtermWidget xw, int fontnum)
+ 
+ 	memset(&fnt, 0, sizeof(fnt));
+ 	screen->menu_font_sizes[fontnum] = -1;
+-	if (xtermOpenFont(xw, screen->MenuFontName(fontnum), &fnt, True)) {
++	if (xtermOpenFont(xw, screen->MenuFontName(fontnum), &fnt, NULL, True)) {
+ 	    if (fontnum <= fontMenu_lastBuiltin
+ 		|| strcmp(fnt.fn, DEFFONT)) {
+ 		screen->menu_font_sizes[fontnum] = FontSize(fnt.fs);
+@@ -4864,13 +4887,14 @@ HandleSetFont(Widget w,
+     }
+ }
+ 
+-void
++Bool
+ SetVTFont(XtermWidget xw,
+ 	  int which,
+ 	  Bool doresize,
+ 	  const VTFontNames * fonts)
+ {
+     TScreen *screen = TScreenOf(xw);
++    Bool result = False;
+ 
+     TRACE(("SetVTFont(which=%d, f_n=%s, f_b=%s)\n", which,
+ 	   (fonts && fonts->f_n) ? fonts->f_n : "<null>",
+@@ -4879,34 +4903,31 @@ SetVTFont(XtermWidget xw,
+     if (IsIcon(screen)) {
+ 	Bell(xw, XkbBI_MinorError, 0);
+     } else if (which >= 0 && which < NMENUFONTS) {
+-	VTFontNames myfonts;
++	VTFontNames new_fnames;
+ 
+-	memset(&myfonts, 0, sizeof(myfonts));
++	memset(&new_fnames, 0, sizeof(new_fnames));
+ 	if (fonts != 0)
+-	    myfonts = *fonts;
++	    new_fnames = *fonts;
+ 
+ 	if (which == fontMenu_fontsel) {	/* go get the selection */
+-	    FindFontSelection(xw, myfonts.f_n, False);
++	    result = FindFontSelection(xw, new_fnames.f_n, False);
+ 	} else {
+-	    int oldFont = screen->menu_font_number;
+-
+ #define USE_CACHED(field, name) \
+-	    if (myfonts.field == 0) { \
+-		myfonts.field = x_strdup(screen->menu_font_names[which][name]); \
+-		TRACE(("set myfonts." #field " from menu_font_names[%d][" #name "] %s\n", \
+-		       which, NonNull(myfonts.field))); \
++	    if (new_fnames.field == NULL) { \
++		new_fnames.field = x_strdup(screen->menu_font_names[which][name]); \
++		TRACE(("set new_fnames." #field " from menu_font_names[%d][" #name "] %s\n", \
++		       which, NonNull(new_fnames.field))); \
+ 	    } else { \
+-		TRACE(("set myfonts." #field " reused\n")); \
++		TRACE(("set new_fnames." #field " reused\n")); \
+ 	    }
+ #define SAVE_FNAME(field, name) \
+-	    if (myfonts.field != 0) { \
+-		if (screen->menu_font_names[which][name] == 0 \
+-		 || strcmp(screen->menu_font_names[which][name], myfonts.field)) { \
+-		    TRACE(("updating menu_font_names[%d][" #name "] to \"%s\"\n", \
+-			   which, myfonts.field)); \
+-		    FREE_STRING(screen->menu_font_names[which][name]); \
+-		    screen->menu_font_names[which][name] = x_strdup(myfonts.field); \
+-		} \
++	    if (new_fnames.field != NULL \
++		&& (screen->menu_font_names[which][name] == NULL \
++		 || strcmp(screen->menu_font_names[which][name], new_fnames.field))) { \
++		TRACE(("updating menu_font_names[%d][" #name "] to \"%s\"\n", \
++		       which, new_fnames.field)); \
++		FREE_STRING(screen->menu_font_names[which][name]); \
++		screen->menu_font_names[which][name] = x_strdup(new_fnames.field); \
+ 	    }
+ 
+ 	    USE_CACHED(f_n, fNorm);
+@@ -4916,7 +4937,7 @@ SetVTFont(XtermWidget xw,
+ 	    USE_CACHED(f_wb, fWBold);
+ #endif
+ 	    if (xtermLoadFont(xw,
+-			      &myfonts,
++			      &new_fnames,
+ 			      doresize, which)) {
+ 		/*
+ 		 * If successful, save the data so that a subsequent query via
+@@ -4928,10 +4949,8 @@ SetVTFont(XtermWidget xw,
+ 		SAVE_FNAME(f_w, fWide);
+ 		SAVE_FNAME(f_wb, fWBold);
+ #endif
++		result = True;
+ 	    } else {
+-		(void) xtermLoadFont(xw,
+-				     xtermFontName(screen->MenuFontName(oldFont)),
+-				     doresize, oldFont);
+ 		Bell(xw, XkbBI_MinorError, 0);
+ 	    }
+ 	    FREE_FNAME(f_n);
+@@ -4944,7 +4963,8 @@ SetVTFont(XtermWidget xw,
+     } else {
+ 	Bell(xw, XkbBI_MinorError, 0);
+     }
+-    return;
++    TRACE(("...SetVTFont: %d\n", result));
++    return result;
+ }
+ 
+ #if OPT_RENDERFONT
+diff --git a/fontutils.h b/fontutils.h
+index 2267f24..5b3afe0 100644
+--- a/fontutils.h
++++ b/fontutils.h
+@@ -37,7 +37,7 @@
+ /* *INDENT-OFF* */
+ 
+ extern Bool xtermLoadDefaultFonts (XtermWidget /* xw */);
+-extern Bool xtermOpenFont (XtermWidget /* xw */, const char */* name */, XTermFonts * /* result */, Bool /* force */);
++extern Bool xtermOpenFont (XtermWidget /* xw */, const char */* name */, XTermFonts * /* result */, XTermFonts * /* current */, Bool /* force */);
+ extern XFontStruct * xtermLoadQueryFont(XtermWidget /* xw */, const char * /*name */);
+ extern XTermFonts * getDoubleFont (TScreen * /* screen */, int /* which */);
+ extern XTermFonts * getItalicFont (TScreen * /* screen */, int /* which */);
+@@ -51,7 +51,7 @@ extern int lookupRelativeFontSize (XtermWidget /* xw */, int /* old */, int /* r
+ extern int xtermGetFont (const char * /* param */);
+ extern int xtermLoadFont (XtermWidget /* xw */, const VTFontNames */* fonts */, Bool /* doresize */, int /* fontnum */);
+ extern void HandleSetFont PROTO_XT_ACTIONS_ARGS;
+-extern void SetVTFont (XtermWidget /* xw */, int /* i */, Bool /* doresize */, const VTFontNames */* fonts */);
++extern Bool SetVTFont (XtermWidget /* xw */, int /* i */, Bool /* doresize */, const VTFontNames */* fonts */);
+ extern void allocFontList (XtermWidget /* xw */, const char * /* name */, XtermFontNames * /* target */, VTFontEnum /* which */, const char * /* source */, Bool /* ttf */);
+ extern void copyFontList (char *** /* targetp */, char ** /* source */);
+ extern void initFontLists (XtermWidget /* xw */);
+diff --git a/misc.c b/misc.c
+index cbb2679..aafbb08 100644
+--- a/misc.c
++++ b/misc.c
+@@ -3941,9 +3941,9 @@ ChangeFontRequest(XtermWidget xw, String buf)
+ 	    {
+ 		memset(&fonts, 0, sizeof(fonts));
+ 		fonts.f_n = name;
+-		SetVTFont(xw, num, True, &fonts);
+-		if (num == screen->menu_font_number &&
+-		    num != fontMenu_fontescape) {
++		if (SetVTFont(xw, num, True, &fonts)
++		    && num == screen->menu_font_number
++		    && num != fontMenu_fontescape) {
+ 		    screen->EscapeFontName() = x_strdup(name);
+ 		}
+ 	    }
+@@ -6422,7 +6422,6 @@ xtermSetenv(const char *var, const char *value)
+ 
+ 	    found = envindex;
+ 	    environ[found + 1] = NULL;
+-	    environ = environ;
+ 	}
+ 
+ 	environ[found] = malloc(2 + len + strlen(value));
+diff --git a/screen.c b/screen.c
+index 93e36b3..f82ee44 100644
+--- a/screen.c
++++ b/screen.c
+@@ -1454,7 +1454,7 @@ ScrnRefresh(XtermWidget xw,
+ 	maxrow += StatusLineRows;
+     }
+ #endif
+-
++    (void) recurse;
+     ++recurse;
+ 
+     if (screen->cursorp.col >= leftcol
+diff --git a/xterm.h b/xterm.h
+index e6bd123..c4fe811 100644
+--- a/xterm.h
++++ b/xterm.h
+@@ -999,7 +999,7 @@ extern Bool CheckBufPtrs (TScreen * /* screen */);
+ extern Bool set_cursor_gcs (XtermWidget /* xw */);
+ extern char * vt100ResourceToString (XtermWidget /* xw */, const char * /* name */);
+ extern int VTInit (XtermWidget /* xw */);
+-extern void FindFontSelection (XtermWidget /* xw */, const char * /* atom_name */, Bool  /* justprobe */);
++extern Bool FindFontSelection (XtermWidget /* xw */, const char * /* atom_name */, Bool  /* justprobe */);
+ extern void HideCursor (XtermWidget /* xw */);
+ extern void RestartBlinking(XtermWidget /* xw */);
+ extern void ShowCursor (XtermWidget /* xw */);
+-- 
+2.25.1
+
diff --git a/meta-oe/recipes-graphics/xorg-app/xterm_372.bb b/meta-oe/recipes-graphics/xorg-app/xterm_372.bb
index 3e1e9d704..223bc0a49 100644
--- a/meta-oe/recipes-graphics/xorg-app/xterm_372.bb
+++ b/meta-oe/recipes-graphics/xorg-app/xterm_372.bb
@@ -6,6 +6,7 @@  LIC_FILES_CHKSUM = "file://xterm.h;beginline=3;endline=31;md5=5ec6748ed90e588caa
 
 SRC_URI = "http://invisible-mirror.net/archives/${BPN}/${BP}.tgz \
            file://0001-Add-configure-time-check-for-setsid.patch \
+           file://CVE-2022-45063.patch \
           "
 
 SRC_URI[sha256sum] = "c6d08127cb2409c3a04bcae559b7025196ed770bb7bf26630abcb45d95f60ab1"