From 6bdf50c5a5a30b45df04977e2e9caa83639de765 Mon Sep 17 00:00:00 2001 From: Slava Zanko Date: Fri, 5 Oct 2012 18:14:28 +0300 Subject: [PATCH] Ticket #2913: CVE-2012-4463 mc-4.8.5: Does not sanitize MC_EXT_SELECTED variable properly Paul Hartman reported the following (minor) security flaw into Gentoo's bugzilla: https://bugs.gentoo.org/show_bug.cgi?id=436518 When multiple files are selected and F3 / Enter key is pressed on some of the files, MC_EXT_SELECTED variable does not sanitize the whitespace characters properly (leading into situation when first file is used as the actual value of MC_EXT_SELECTED variable and the remaining files from the list are used as arguments passed to the temporary script, created to handle F3 / Enter action on the first file). A remote attacker could provide a specially-crafted archive and trick the local Midnight Commander user into expanding and viewing it, which under certain circumstances could lead to arbitrary code execution with the privileges of the user running the mc executable. Signed-off-by: Slava Zanko --- tests/src/filemanager/Makefile.am | 6 +- .../filemanager/exec_get_export_variables_ext.c | 136 +++++++++++++++++++++ 2 files changed, 141 insertions(+), 1 deletion(-) create mode 100644 tests/src/filemanager/exec_get_export_variables_ext.c diff --git a/tests/src/filemanager/Makefile.am b/tests/src/filemanager/Makefile.am index 4d754b298..26cdcfa1d 100644 --- a/tests/src/filemanager/Makefile.am +++ b/tests/src/filemanager/Makefile.am @@ -14,7 +14,8 @@ endif TESTS = \ do_panel_cd \ - examine_cd + examine_cd \ + exec_get_export_variables_ext check_PROGRAMS = $(TESTS) @@ -23,3 +24,6 @@ do_panel_cd_SOURCES = \ examine_cd_SOURCES = \ examine_cd.c + +exec_get_export_variables_ext_SOURCES = \ + exec_get_export_variables_ext.c diff --git a/tests/src/filemanager/exec_get_export_variables_ext.c b/tests/src/filemanager/exec_get_export_variables_ext.c new file mode 100644 index 000000000..03993a33a --- /dev/null +++ b/tests/src/filemanager/exec_get_export_variables_ext.c @@ -0,0 +1,136 @@ +/* + src/filemanager - filemanager functions + + Copyright (C) 2011 + The Free Software Foundation, Inc. + + Written by: + Slava Zanko , 2012 + + This file is part of the Midnight Commander. + + The Midnight Commander is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + The Midnight Commander is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#define TEST_SUITE_NAME "/src/filemanager" + +#include + +#include + +#include "lib/global.h" +#include "src/vfs/local/local.c" + +#include "src/filemanager/midnight.c" + +#include "src/filemanager/ext.c" + +/* --------------------------------------------------------------------------------------------- */ +/* mocked functions */ + + +/* --------------------------------------------------------------------------------------------- */ + +static void +setup (void) +{ + str_init_strings (NULL); + + vfs_init (); + init_localfs (); + vfs_setup_work_dir (); + + mc_global.mc_run_mode = MC_RUN_FULL; + current_panel = g_new0(struct WPanel, 1); + current_panel->cwd_vpath = vfs_path_from_str("/home"); + current_panel->dir.list = g_new (file_entry, MIN_FILES); + current_panel->dir.size = MIN_FILES; +} + +static void +teardown (void) +{ + vfs_shut (); + str_uninit_strings (); +} + +/* --------------------------------------------------------------------------------------------- */ + +START_TEST (sanitize_variables) +{ + // given + vfs_path_t * filename_vpath; + char *actual_string; + const char *expected_string; + + current_panel->selected = 0; + current_panel->dir.list[0].fname = (char*) "selected file.txt"; + current_panel->dir.list[1].fname = (char*) "tagged file1.txt"; + current_panel->dir.list[1].f.marked = TRUE; + current_panel->dir.list[2].fname = (char*) "tagged file2.txt"; + current_panel->dir.list[2].f.marked = TRUE; + current_panel->count = 3; + + // when + filename_vpath = vfs_path_from_str("/tmp/blabla.txt"); + actual_string = exec_get_export_variables (filename_vpath); + vfs_path_free (filename_vpath); + + // then + expected_string = "\ +MC_EXT_FILENAME=/tmp/blabla.txt\n\ +export MC_EXT_FILENAME\n\ +MC_EXT_BASENAME=selected\\ file.txt\n\ +export MC_EXT_BASENAME\n\ +MC_EXT_CURRENTDIR=/home\n\ +export MC_EXT_CURRENTDIR\n\ +MC_EXT_SELECTED=selected\\ file.txt\n\ +export MC_EXT_SELECTED\n\ +MC_EXT_ONLYTAGGED=tagged\\ file1.txt tagged\\ file2.txt \n\ +export MC_EXT_ONLYTAGGED\n"; + + g_assert_cmpstr (actual_string, ==, expected_string); + + g_free (actual_string); +} + +END_TEST + +/* --------------------------------------------------------------------------------------------- */ + +int +main (void) +{ + int number_failed; + + Suite *s = suite_create (TEST_SUITE_NAME); + TCase *tc_core = tcase_create ("Core"); + SRunner *sr; + + tcase_add_checked_fixture (tc_core, setup, teardown); + + /* Add new tests here: *************** */ + tcase_add_test (tc_core, sanitize_variables); + /* *********************************** */ + + suite_add_tcase (s, tc_core); + sr = srunner_create (s); + srunner_set_log (sr, "do_panel_cd.log"); + srunner_run_all (sr, CK_NORMAL); + number_failed = srunner_ntests_failed (sr); + srunner_free (sr); + return (number_failed == 0) ? 0 : 1; +} + +/* --------------------------------------------------------------------------------------------- */ -- 2.11.4.GIT