diff options
author | Gerald Combs <gerald@wireshark.org> | 2022-12-10 17:49:59 -0800 |
---|---|---|
committer | Gerald Combs <gerald@wireshark.org> | 2022-12-12 18:34:21 +0000 |
commit | cb420c79117225fa5f896b07210cfe0ea74ce094 (patch) | |
tree | ecc145dbcf86717c4da19c1b786f6b7371fdfe0c /wsutil | |
parent | 5aa1871ee0d0e87129d77328061aebace9983cde (diff) |
Extcap: Create our fifo in a temporary directory.
Instead of creating a temp file, unlinking it, and creating a fifo with
the same name, add create_tempdir() so that we can create a temporary
directory and create a fifo inside that.
This should avoid a race condition in Carbon Black Cloud antivirus,
which if the timing is right, will stat the initial temporary *file*,
miss the fact that it's been replaced with a *fifo*, and open and steal
data^W^W read from it, leaving dumpcap to contend with the truncated
remains.
Adding the unexpected magic number to cap_pipe_open_live()'s error
message helped to debug this. Leave it in since it's handy to have in
that case.
Ping #15587
Diffstat (limited to 'wsutil')
-rw-r--r-- | wsutil/tempfile.c | 64 | ||||
-rw-r--r-- | wsutil/tempfile.h | 14 |
2 files changed, 61 insertions, 17 deletions
diff --git a/wsutil/tempfile.c b/wsutil/tempfile.c index f93f96d538..165269f54f 100644 --- a/wsutil/tempfile.c +++ b/wsutil/tempfile.c @@ -15,6 +15,28 @@ #include "tempfile.h" #include "file_util.h" +static char * +sanitize_prefix(const char *prefix) +{ + if (!prefix) { + return NULL; + } + + /* The characters in "delimiters" come from: + * https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file#naming-conventions. + * Add to the list as necessary for other OS's. + */ + const gchar *delimiters = "<>:\"/\\|?*" + "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a" + "\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14" + "\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"; + + /* Sanitize the prefix to resolve bug 7877 */ + char *safe_prefx = g_strdup(prefix); + safe_prefx = g_strdelimit(safe_prefx, delimiters, '-'); + return safe_prefx; +} + /** * Create a tempfile with the given prefix (e.g. "wireshark"). The path * is created using g_file_open_tmp. @@ -32,22 +54,7 @@ int create_tempfile(const char *tempdir, gchar **namebuf, const char *pfx, const char *sfx, GError **err) { int fd; - gchar *safe_pfx = NULL; - - if (pfx) { - /* The characters in "delimiters" come from: - * https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file#naming-conventions. - * Add to the list as necessary for other OS's. - */ - const gchar *delimiters = "<>:\"/\\|?*" - "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a" - "\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14" - "\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"; - - /* Sanitize the pfx to resolve bug 7877 */ - safe_pfx = g_strdup(pfx); - safe_pfx = g_strdelimit(safe_pfx, delimiters, '-'); - } + gchar *safe_pfx = sanitize_prefix(pfx); if (tempdir == NULL || tempdir[0] == '\0') { /* Use OS default tempdir behaviour */ @@ -107,6 +114,31 @@ create_tempfile(const char *tempdir, gchar **namebuf, const char *pfx, const cha return fd; } +char * +create_tempdir(const gchar *parent_dir, const char *tmpl, GError **err) +{ + if (parent_dir == NULL || parent_dir[0] == '\0') { + parent_dir = g_get_tmp_dir(); + } + + gchar *safe_pfx = sanitize_prefix(tmpl); + if (safe_pfx == NULL) { + safe_pfx = g_strdup("wireshark_XXXXXX"); + } + + char *temp_subdir = g_build_path(G_DIR_SEPARATOR_S, parent_dir, safe_pfx, NULL); + g_free(safe_pfx); + if (g_mkdtemp(temp_subdir) == NULL) + { + g_free(temp_subdir); + g_set_error_literal(err, G_FILE_ERROR, + g_file_error_from_errno(errno), g_strerror(errno)); + return FALSE; + } + + return temp_subdir; +} + /* * Editor modelines - https://www.wireshark.org/tools/modelines.html * diff --git a/wsutil/tempfile.h b/wsutil/tempfile.h index 70031b5419..65e0c59898 100644 --- a/wsutil/tempfile.h +++ b/wsutil/tempfile.h @@ -27,7 +27,7 @@ extern "C" { * * @param tempdir [in] If not NULL, the directory in which to create the file. * @param namebuf [in,out] If not NULL, receives the full path of the temp file. - * Must be freed. + * Must be g_freed. * @param pfx [in] A prefix for the temporary file. * @param sfx [in] A file extension for the temporary file. NULL can be passed * if no file extension is needed @@ -36,6 +36,18 @@ extern "C" { */ WS_DLL_PUBLIC int create_tempfile(const gchar *tempdir, gchar **namebuf, const char *pfx, const char *sfx, GError **err); +/** + * Create a tempfile with the given parent directory (e.g. "/my/private/tmp"). The path + * is created using g_mkdtemp. + * + * @param parent_dir [in] If not NULL, the parent directory in which to create the subdirectory, + * otherwise the system temporary directory is used. + * @param tmpl [in] A template for the temporary directory. + * @param err [out] Any error returned by g_mkdtemp. May be NULL. + * @return The full path of the temporary directory or NULL on error. Must be g_freed. + */ +WS_DLL_PUBLIC char *create_tempdir(const gchar *parent_dir, const char *tmpl, GError **err); + #ifdef __cplusplus } #endif /* __cplusplus */ |