diff options
| author | Peter Marko <peter.marko@siemens.com> | 2025-05-06 22:46:08 +0200 |
|---|---|---|
| committer | Khem Raj <raj.khem@gmail.com> | 2025-05-06 14:29:21 -0700 |
| commit | ab37d6ffba4043ccb16d910199dcd06522fb42c4 (patch) | |
| tree | dc8835c74671611b0f73f68cdd466d0250694a02 | |
| parent | bf2b63535ebafae27b95b370df95749d5bde6b04 (diff) | |
| download | meta-openembedded-ab37d6ffba4043ccb16d910199dcd06522fb42c4.tar.gz | |
fontforge: patch CVE-2024-25081 and CVE-2024-25082
Pick commit from PR [1] linked from [2] and [3] which mlso entions both
these CVEs.
[1] https://github.com/fontforge/fontforge/pull/5367
[2] https://nvd.nist.gov/vuln/detail/CVE-2024-25081
[3] https://nvd.nist.gov/vuln/detail/CVE-2024-25082
Signed-off-by: Peter Marko <peter.marko@siemens.com>
Signed-off-by: Khem Raj <raj.khem@gmail.com>
| -rw-r--r-- | meta-oe/recipes-graphics/fontforge/fontforge/CVE-2024-25081_CVE-2024-25082.patch | 181 | ||||
| -rw-r--r-- | meta-oe/recipes-graphics/fontforge/fontforge_20230101.bb | 1 |
2 files changed, 182 insertions, 0 deletions
diff --git a/meta-oe/recipes-graphics/fontforge/fontforge/CVE-2024-25081_CVE-2024-25082.patch b/meta-oe/recipes-graphics/fontforge/fontforge/CVE-2024-25081_CVE-2024-25082.patch new file mode 100644 index 0000000000..40f85e9f33 --- /dev/null +++ b/meta-oe/recipes-graphics/fontforge/fontforge/CVE-2024-25081_CVE-2024-25082.patch | |||
| @@ -0,0 +1,181 @@ | |||
| 1 | From 216eb14b558df344b206bf82e2bdaf03a1f2f429 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Peter Kydas <pk@canva.com> | ||
| 3 | Date: Tue, 6 Feb 2024 20:03:04 +1100 | ||
| 4 | Subject: [PATCH] fix splinefont shell command injection (#5367) | ||
| 5 | |||
| 6 | CVE: CVE-2024-25081 | ||
| 7 | CVE: CVE-2024-25082 | ||
| 8 | Upstream-Status: Backport [https://github.com/fontforge/fontforge/commit/216eb14b558df344b206bf82e2bdaf03a1f2f429] | ||
| 9 | Signed-off-by: Peter Marko <peter.marko@siemens.com> | ||
| 10 | --- | ||
| 11 | fontforge/splinefont.c | 123 +++++++++++++++++++++++++++++------------ | ||
| 12 | 1 file changed, 89 insertions(+), 34 deletions(-) | ||
| 13 | |||
| 14 | diff --git a/fontforge/splinefont.c b/fontforge/splinefont.c | ||
| 15 | index 239fdc035..647daee10 100644 | ||
| 16 | --- a/fontforge/splinefont.c | ||
| 17 | +++ b/fontforge/splinefont.c | ||
| 18 | @@ -788,11 +788,14 @@ return( name ); | ||
| 19 | |||
| 20 | char *Unarchive(char *name, char **_archivedir) { | ||
| 21 | char *dir = getenv("TMPDIR"); | ||
| 22 | - char *pt, *archivedir, *listfile, *listcommand, *unarchivecmd, *desiredfile; | ||
| 23 | + char *pt, *archivedir, *listfile, *desiredfile; | ||
| 24 | char *finalfile; | ||
| 25 | int i; | ||
| 26 | int doall=false; | ||
| 27 | static int cnt=0; | ||
| 28 | + gchar *command[5]; | ||
| 29 | + gchar *stdoutresponse = NULL; | ||
| 30 | + gchar *stderrresponse = NULL; | ||
| 31 | |||
| 32 | *_archivedir = NULL; | ||
| 33 | |||
| 34 | @@ -827,18 +830,30 @@ return( NULL ); | ||
| 35 | listfile = malloc(strlen(archivedir)+strlen("/" TOC_NAME)+1); | ||
| 36 | sprintf( listfile, "%s/" TOC_NAME, archivedir ); | ||
| 37 | |||
| 38 | - listcommand = malloc( strlen(archivers[i].unarchive) + 1 + | ||
| 39 | - strlen( archivers[i].listargs) + 1 + | ||
| 40 | - strlen( name ) + 3 + | ||
| 41 | - strlen( listfile ) +4 ); | ||
| 42 | - sprintf( listcommand, "%s %s %s > %s", archivers[i].unarchive, | ||
| 43 | - archivers[i].listargs, name, listfile ); | ||
| 44 | - if ( system(listcommand)!=0 ) { | ||
| 45 | - free(listcommand); free(listfile); | ||
| 46 | - ArchiveCleanup(archivedir); | ||
| 47 | -return( NULL ); | ||
| 48 | + command[0] = archivers[i].unarchive; | ||
| 49 | + command[1] = archivers[i].listargs; | ||
| 50 | + command[2] = name; | ||
| 51 | + command[3] = NULL; // command args need to be NULL-terminated | ||
| 52 | + | ||
| 53 | + if ( g_spawn_sync( | ||
| 54 | + NULL, | ||
| 55 | + command, | ||
| 56 | + NULL, | ||
| 57 | + G_SPAWN_SEARCH_PATH, | ||
| 58 | + NULL, | ||
| 59 | + NULL, | ||
| 60 | + &stdoutresponse, | ||
| 61 | + &stderrresponse, | ||
| 62 | + NULL, | ||
| 63 | + NULL | ||
| 64 | + ) == FALSE) { // did not successfully execute | ||
| 65 | + ArchiveCleanup(archivedir); | ||
| 66 | + return( NULL ); | ||
| 67 | } | ||
| 68 | - free(listcommand); | ||
| 69 | + // Write out the listfile to be read in later | ||
| 70 | + FILE *fp = fopen(listfile, "wb"); | ||
| 71 | + fwrite(stdoutresponse, strlen(stdoutresponse), 1, fp); | ||
| 72 | + fclose(fp); | ||
| 73 | |||
| 74 | desiredfile = ArchiveParseTOC(listfile, archivers[i].ars, &doall); | ||
| 75 | free(listfile); | ||
| 76 | @@ -847,22 +862,28 @@ return( NULL ); | ||
| 77 | return( NULL ); | ||
| 78 | } | ||
| 79 | |||
| 80 | - /* I tried sending everything to stdout, but that doesn't work if the */ | ||
| 81 | - /* output is a directory file (ufo, sfdir) */ | ||
| 82 | - unarchivecmd = malloc( strlen(archivers[i].unarchive) + 1 + | ||
| 83 | - strlen( archivers[i].listargs) + 1 + | ||
| 84 | - strlen( name ) + 1 + | ||
| 85 | - strlen( desiredfile ) + 3 + | ||
| 86 | - strlen( archivedir ) + 30 ); | ||
| 87 | - sprintf( unarchivecmd, "( cd %s ; %s %s %s %s ) > /dev/null", archivedir, | ||
| 88 | - archivers[i].unarchive, | ||
| 89 | - archivers[i].extractargs, name, doall ? "" : desiredfile ); | ||
| 90 | - if ( system(unarchivecmd)!=0 ) { | ||
| 91 | - free(unarchivecmd); free(desiredfile); | ||
| 92 | - ArchiveCleanup(archivedir); | ||
| 93 | -return( NULL ); | ||
| 94 | + command[0] = archivers[i].unarchive; | ||
| 95 | + command[1] = archivers[i].extractargs; | ||
| 96 | + command[2] = name; | ||
| 97 | + command[3] = doall ? "" : desiredfile; | ||
| 98 | + command[4] = NULL; | ||
| 99 | + | ||
| 100 | + if ( g_spawn_sync( | ||
| 101 | + (gchar*)archivedir, | ||
| 102 | + command, | ||
| 103 | + NULL, | ||
| 104 | + G_SPAWN_SEARCH_PATH, | ||
| 105 | + NULL, | ||
| 106 | + NULL, | ||
| 107 | + &stdoutresponse, | ||
| 108 | + &stderrresponse, | ||
| 109 | + NULL, | ||
| 110 | + NULL | ||
| 111 | + ) == FALSE) { // did not successfully execute | ||
| 112 | + free(desiredfile); | ||
| 113 | + ArchiveCleanup(archivedir); | ||
| 114 | + return( NULL ); | ||
| 115 | } | ||
| 116 | - free(unarchivecmd); | ||
| 117 | |||
| 118 | finalfile = malloc( strlen(archivedir) + 1 + strlen(desiredfile) + 1); | ||
| 119 | sprintf( finalfile, "%s/%s", archivedir, desiredfile ); | ||
| 120 | @@ -885,20 +906,54 @@ struct compressors compressors[] = { | ||
| 121 | |||
| 122 | char *Decompress(char *name, int compression) { | ||
| 123 | char *dir = getenv("TMPDIR"); | ||
| 124 | - char buf[1500]; | ||
| 125 | char *tmpfn; | ||
| 126 | - | ||
| 127 | + gchar *command[4]; | ||
| 128 | + gint stdout_pipe; | ||
| 129 | + gchar buffer[4096]; | ||
| 130 | + gssize bytes_read; | ||
| 131 | + GByteArray *binary_data = g_byte_array_new(); | ||
| 132 | + | ||
| 133 | if ( dir==NULL ) dir = P_tmpdir; | ||
| 134 | tmpfn = malloc(strlen(dir)+strlen(GFileNameTail(name))+2); | ||
| 135 | strcpy(tmpfn,dir); | ||
| 136 | strcat(tmpfn,"/"); | ||
| 137 | strcat(tmpfn,GFileNameTail(name)); | ||
| 138 | *strrchr(tmpfn,'.') = '\0'; | ||
| 139 | - snprintf( buf, sizeof(buf), "%s < %s > %s", compressors[compression].decomp, name, tmpfn ); | ||
| 140 | - if ( system(buf)==0 ) | ||
| 141 | -return( tmpfn ); | ||
| 142 | - free(tmpfn); | ||
| 143 | -return( NULL ); | ||
| 144 | + | ||
| 145 | + command[0] = compressors[compression].decomp; | ||
| 146 | + command[1] = "-c"; | ||
| 147 | + command[2] = name; | ||
| 148 | + command[3] = NULL; | ||
| 149 | + | ||
| 150 | + // Have to use async because g_spawn_sync doesn't handle nul-bytes in the output (which happens with binary data) | ||
| 151 | + if (g_spawn_async_with_pipes( | ||
| 152 | + NULL, | ||
| 153 | + command, | ||
| 154 | + NULL, | ||
| 155 | + G_SPAWN_DO_NOT_REAP_CHILD | G_SPAWN_SEARCH_PATH, | ||
| 156 | + NULL, | ||
| 157 | + NULL, | ||
| 158 | + NULL, | ||
| 159 | + NULL, | ||
| 160 | + &stdout_pipe, | ||
| 161 | + NULL, | ||
| 162 | + NULL) == FALSE) { | ||
| 163 | + //command has failed | ||
| 164 | + return( NULL ); | ||
| 165 | + } | ||
| 166 | + | ||
| 167 | + // Read binary data from pipe and output to file | ||
| 168 | + while ((bytes_read = read(stdout_pipe, buffer, sizeof(buffer))) > 0) { | ||
| 169 | + g_byte_array_append(binary_data, (guint8 *)buffer, bytes_read); | ||
| 170 | + } | ||
| 171 | + close(stdout_pipe); | ||
| 172 | + | ||
| 173 | + FILE *fp = fopen(tmpfn, "wb"); | ||
| 174 | + fwrite(binary_data->data, sizeof(gchar), binary_data->len, fp); | ||
| 175 | + fclose(fp); | ||
| 176 | + g_byte_array_free(binary_data, TRUE); | ||
| 177 | + | ||
| 178 | + return(tmpfn); | ||
| 179 | } | ||
| 180 | |||
| 181 | static char *ForceFileToHaveName(FILE *file, char *exten) { | ||
diff --git a/meta-oe/recipes-graphics/fontforge/fontforge_20230101.bb b/meta-oe/recipes-graphics/fontforge/fontforge_20230101.bb index 31dd495fd7..d470ff12d4 100644 --- a/meta-oe/recipes-graphics/fontforge/fontforge_20230101.bb +++ b/meta-oe/recipes-graphics/fontforge/fontforge_20230101.bb | |||
| @@ -20,6 +20,7 @@ SRC_URI = "git://github.com/${BPN}/${BPN}.git;branch=master;protocol=https \ | |||
| 20 | file://0001-fontforgeexe-Use-env-to-find-fontforge.patch \ | 20 | file://0001-fontforgeexe-Use-env-to-find-fontforge.patch \ |
| 21 | file://0001-cmake-Use-alternate-way-to-detect-libm.patch \ | 21 | file://0001-cmake-Use-alternate-way-to-detect-libm.patch \ |
| 22 | file://0001-Fix-Translations-containing-invalid-directives-hs.patch \ | 22 | file://0001-Fix-Translations-containing-invalid-directives-hs.patch \ |
| 23 | file://CVE-2024-25081_CVE-2024-25082.patch \ | ||
| 23 | " | 24 | " |
| 24 | S = "${WORKDIR}/git" | 25 | S = "${WORKDIR}/git" |
| 25 | 26 | ||
