compose: Ensure we mmap only regular files

Currently we do not check that the Compose files we try successively are
*regular* files. This may result in an error, while we should just really
just skip the corresponding path.

Fixed by adding the new utily function `open_file`.
master
Pierre Le Marre 2024-02-05 11:55:39 +01:00 committed by Wismill
parent 54f073ce17
commit 1731c6b3ef
4 changed files with 65 additions and 22 deletions

View File

@ -176,35 +176,27 @@ xkb_compose_table_new_from_locale(struct xkb_context *ctx,
return NULL; return NULL;
path = get_xcomposefile_path(ctx); path = get_xcomposefile_path(ctx);
if (path) { file = open_file(path);
file = fopen(path, "rb");
if (file) if (file)
goto found_path; goto found_path;
}
free(path); free(path);
path = get_xdg_xcompose_file_path(ctx); path = get_xdg_xcompose_file_path(ctx);
if (path) { file = open_file(path);
file = fopen(path, "rb");
if (file) if (file)
goto found_path; goto found_path;
}
free(path); free(path);
path = get_home_xcompose_file_path(ctx); path = get_home_xcompose_file_path(ctx);
if (path) { file = open_file(path);
file = fopen(path, "rb");
if (file) if (file)
goto found_path; goto found_path;
}
free(path); free(path);
path = get_locale_compose_file_path(ctx, table->locale); path = get_locale_compose_file_path(ctx, table->locale);
if (path) { file = open_file(path);
file = fopen(path, "rb");
if (file) if (file)
goto found_path; goto found_path;
}
free(path); free(path);
log_err(ctx, XKB_LOG_MESSAGE_NO_ID, log_err(ctx, XKB_LOG_MESSAGE_NO_ID,

View File

@ -23,14 +23,14 @@
#include "config.h" #include "config.h"
#include <sys/stat.h>
#include <fcntl.h>
#include "utils.h" #include "utils.h"
#ifdef HAVE_MMAP #ifdef HAVE_MMAP
#include <fcntl.h>
#include <unistd.h> #include <unistd.h>
#include <sys/mman.h> #include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h> #include <sys/types.h>
bool bool
@ -111,6 +111,38 @@ unmap_file(char *str, size_t size)
#endif #endif
/* Open a file and ensure it is a regular file.
* Returns NULL in case of error. */
FILE*
open_file(const char *path)
{
if (!path)
return NULL;
int fd = open(path, O_RDONLY);
if (fd < 0)
return NULL;
struct stat stat_buf;
int err = fstat(fd, &stat_buf);
if (err != 0 || !S_ISREG(stat_buf.st_mode)) {
close(fd);
return NULL;
}
/* While unlikely to happen, if `fp` is NULL then we must close the file
* descriptor. This is poorly documented and missing from the man page; see instead:
* https://www.ibm.com/docs/en/i/7.3?topic=functions-fdopen-associates-stream-file-descriptor)
* Confirmed by Peter to be necessary in glibc. */
FILE *fp = fdopen(fd, "rb");
if (fp == NULL) {
close(fd);
}
return fp;
}
// ASCII lower-case map. // ASCII lower-case map.
static const unsigned char lower_map[] = { static const unsigned char lower_map[] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,

View File

@ -47,6 +47,9 @@
# ifndef S_ISDIR # ifndef S_ISDIR
# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) # define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
# endif # endif
# ifndef S_ISREG
# define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
# endif
typedef SSIZE_T ssize_t; typedef SSIZE_T ssize_t;
#endif #endif
@ -263,6 +266,9 @@ check_eaccess(const char *path, int mode)
return true; return true;
} }
FILE*
open_file(const char *path);
#if defined(HAVE_SECURE_GETENV) #if defined(HAVE_SECURE_GETENV)
# define secure_getenv secure_getenv # define secure_getenv secure_getenv
#elif defined(HAVE___SECURE_GETENV) #elif defined(HAVE___SECURE_GETENV)

View File

@ -23,6 +23,7 @@
#include "config.h" #include "config.h"
#include <time.h> #include <time.h>
#include <errno.h>
#include "xkbcommon/xkbcommon-compose.h" #include "xkbcommon/xkbcommon-compose.h"
@ -499,6 +500,18 @@ test_XCOMPOSEFILE(struct xkb_context *ctx)
struct xkb_compose_table *table; struct xkb_compose_table *table;
char *path; char *path;
/* Error: directory */
path = test_get_path("locale/en_US.UTF-8");
setenv("XCOMPOSEFILE", path, 1);
free(path);
table = xkb_compose_table_new_from_locale(ctx, "blabla",
XKB_COMPOSE_COMPILE_NO_FLAGS);
assert_printf(errno != ENODEV && errno != EISDIR,
"Should not be an error from `map_file`\n");
assert(!table);
/* OK: regular file */
path = test_get_path("locale/en_US.UTF-8/Compose"); path = test_get_path("locale/en_US.UTF-8/Compose");
setenv("XCOMPOSEFILE", path, 1); setenv("XCOMPOSEFILE", path, 1);
free(path); free(path);