summaryrefslogtreecommitdiffstats
path: root/player
diff options
context:
space:
mode:
authornanahi <130121847+na-na-hi@users.noreply.github.com>2024-03-19 00:38:58 -0400
committerKacper Michajłow <kasper93@gmail.com>2024-03-19 19:30:27 +0100
commit9a861c930bac32ee3febedc0b0653be4f6f66fef (patch)
treebc870607001bab657dc30885a6dd837902d89a66 /player
parentaa08e304c46dd25daa50a097fc8bbf74be13fc86 (diff)
downloadmpv-9a861c930bac32ee3febedc0b0653be4f6f66fef.tar.bz2
mpv-9a861c930bac32ee3febedc0b0653be4f6f66fef.tar.xz
image_writer: fix TOCTOU in screenshot filename generation
The screenshot command is documented to not overwrite existing files. However, there is a race window between the filename is generated with gen_fname and when the file is open to write. Specifically, the convert_image function in this window can be very time consuming depending on video and screenshot image format and size. This results in existing file being overwritten because the file writing functions don't check for the existance of file. Fix this be opening the file in exclusive mode. Add overwrite parameter to write_image for other operations that are documented to overwrite existing files, like screenshot-to-file. Note that for write_avif, checking existance is used instead because avio_open does not support exclusive open mode.
Diffstat (limited to 'player')
-rw-r--r--player/screenshot.c9
1 files changed, 5 insertions, 4 deletions
diff --git a/player/screenshot.c b/player/screenshot.c
index f537fc4604..aa637e6e63 100644
--- a/player/screenshot.c
+++ b/player/screenshot.c
@@ -77,7 +77,8 @@ static char *stripext(void *talloc_ctx, const char *s)
}
static bool write_screenshot(struct mp_cmd_ctx *cmd, struct mp_image *img,
- const char *filename, struct image_writer_opts *opts)
+ const char *filename, struct image_writer_opts *opts,
+ bool overwrite)
{
struct MPContext *mpctx = cmd->mpctx;
struct image_writer_opts *gopts = mpctx->opts->screenshot_image_opts;
@@ -88,7 +89,7 @@ static bool write_screenshot(struct mp_cmd_ctx *cmd, struct mp_image *img,
mp_core_unlock(mpctx);
bool ok = img && write_image(img, &opts_copy, filename, mpctx->global,
- mpctx->screenshot_ctx->log);
+ mpctx->screenshot_ctx->log, overwrite);
mp_core_lock(mpctx);
@@ -496,7 +497,7 @@ void cmd_screenshot_to_file(void *p)
cmd->success = false;
return;
}
- cmd->success = write_screenshot(cmd, image, filename, &opts);
+ cmd->success = write_screenshot(cmd, image, filename, &opts, true);
talloc_free(image);
}
@@ -537,7 +538,7 @@ void cmd_screenshot(void *p)
if (image) {
char *filename = gen_fname(cmd, image_writer_file_ext(opts));
if (filename) {
- cmd->success = write_screenshot(cmd, image, filename, NULL);
+ cmd->success = write_screenshot(cmd, image, filename, NULL, false);
if (cmd->success) {
node_init(res, MPV_FORMAT_NODE_MAP, NULL);
node_map_add_string(res, "filename", filename);