Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

perf tools kvm: Add missed memory allocation check and free

Current code allocates rec_argv[] array, but doesn't check if the
allocation is successful and explicitly free the rec_argv[] array.

Add them back.

Signed-off-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
Acked-by: Namhyung Kim <namhyung@kernel.org>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Ian Rogers <irogers@google.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Kan Liang <kan.liang@linux.intel.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

Dapeng Mi and committed by
Arnaldo Carvalho de Melo
9262fa24 f0015d81

+58 -23
+58 -23
tools/perf/builtin-kvm.c
··· 1638 1638 1639 1639 #define STRDUP_FAIL_EXIT(s) \ 1640 1640 ({ char *_p; \ 1641 - _p = strdup(s); \ 1642 - if (!_p) \ 1643 - return -ENOMEM; \ 1641 + _p = strdup(s); \ 1642 + if (!_p) { \ 1643 + ret = -ENOMEM; \ 1644 + goto EXIT; \ 1645 + } \ 1644 1646 _p; \ 1645 1647 }) 1646 1648 ··· 1690 1688 rec_argv[i] = STRDUP_FAIL_EXIT(record_args[i]); 1691 1689 1692 1690 for (j = 0; j < events_tp_size; j++) { 1693 - rec_argv[i++] = "-e"; 1691 + rec_argv[i++] = STRDUP_FAIL_EXIT("-e"); 1694 1692 rec_argv[i++] = STRDUP_FAIL_EXIT(kvm_events_tp[j]); 1695 1693 } 1696 1694 ··· 1698 1696 rec_argv[i++] = STRDUP_FAIL_EXIT(kvm->file_name); 1699 1697 1700 1698 for (j = 1; j < (unsigned int)argc; j++, i++) 1701 - rec_argv[i] = argv[j]; 1699 + rec_argv[i] = STRDUP_FAIL_EXIT(argv[j]); 1702 1700 1703 1701 set_option_flag(record_options, 'e', "event", PARSE_OPT_HIDDEN); 1704 1702 set_option_flag(record_options, 0, "filter", PARSE_OPT_HIDDEN); ··· 1721 1719 set_option_flag(record_options, 0, "transaction", PARSE_OPT_DISABLED); 1722 1720 1723 1721 record_usage = kvm_stat_record_usage; 1724 - return cmd_record(i, rec_argv); 1722 + ret = cmd_record(i, rec_argv); 1723 + 1724 + EXIT: 1725 + for (i = 0; i < rec_argc; i++) 1726 + free((void *)rec_argv[i]); 1727 + free(rec_argv); 1728 + return ret; 1725 1729 } 1726 1730 1727 1731 static int ··· 2014 2006 2015 2007 rec_argc = argc + 2; 2016 2008 rec_argv = calloc(rec_argc + 1, sizeof(char *)); 2017 - rec_argv[i++] = strdup("record"); 2018 - rec_argv[i++] = strdup("-o"); 2019 - rec_argv[i++] = strdup(file_name); 2009 + if (!rec_argv) 2010 + return -ENOMEM; 2011 + 2012 + rec_argv[i++] = STRDUP_FAIL_EXIT("record"); 2013 + rec_argv[i++] = STRDUP_FAIL_EXIT("-o"); 2014 + rec_argv[i++] = STRDUP_FAIL_EXIT(file_name); 2020 2015 for (j = 1; j < argc; j++, i++) 2021 - rec_argv[i] = argv[j]; 2016 + rec_argv[i] = STRDUP_FAIL_EXIT(argv[j]); 2022 2017 2023 2018 BUG_ON(i != rec_argc); 2024 2019 2025 - return cmd_record(i, rec_argv); 2020 + ret = cmd_record(i, rec_argv); 2021 + 2022 + EXIT: 2023 + for (i = 0; i < rec_argc; i++) 2024 + free((void *)rec_argv[i]); 2025 + free(rec_argv); 2026 + return ret; 2026 2027 } 2027 2028 2028 2029 static int __cmd_report(const char *file_name, int argc, const char **argv) 2029 2030 { 2030 - int rec_argc, i = 0, j; 2031 + int rec_argc, i = 0, j, ret; 2031 2032 const char **rec_argv; 2032 2033 2033 2034 rec_argc = argc + 2; 2034 2035 rec_argv = calloc(rec_argc + 1, sizeof(char *)); 2035 - rec_argv[i++] = strdup("report"); 2036 - rec_argv[i++] = strdup("-i"); 2037 - rec_argv[i++] = strdup(file_name); 2036 + if (!rec_argv) 2037 + return -ENOMEM; 2038 + 2039 + rec_argv[i++] = STRDUP_FAIL_EXIT("report"); 2040 + rec_argv[i++] = STRDUP_FAIL_EXIT("-i"); 2041 + rec_argv[i++] = STRDUP_FAIL_EXIT(file_name); 2038 2042 for (j = 1; j < argc; j++, i++) 2039 - rec_argv[i] = argv[j]; 2043 + rec_argv[i] = STRDUP_FAIL_EXIT(argv[j]); 2040 2044 2041 2045 BUG_ON(i != rec_argc); 2042 2046 2043 - return cmd_report(i, rec_argv); 2047 + ret = cmd_report(i, rec_argv); 2048 + 2049 + EXIT: 2050 + for (i = 0; i < rec_argc; i++) 2051 + free((void *)rec_argv[i]); 2052 + free(rec_argv); 2053 + return ret; 2044 2054 } 2045 2055 2046 2056 static int 2047 2057 __cmd_buildid_list(const char *file_name, int argc, const char **argv) 2048 2058 { 2049 - int rec_argc, i = 0, j; 2059 + int rec_argc, i = 0, j, ret; 2050 2060 const char **rec_argv; 2051 2061 2052 2062 rec_argc = argc + 2; 2053 2063 rec_argv = calloc(rec_argc + 1, sizeof(char *)); 2054 - rec_argv[i++] = strdup("buildid-list"); 2055 - rec_argv[i++] = strdup("-i"); 2056 - rec_argv[i++] = strdup(file_name); 2064 + if (!rec_argv) 2065 + return -ENOMEM; 2066 + 2067 + rec_argv[i++] = STRDUP_FAIL_EXIT("buildid-list"); 2068 + rec_argv[i++] = STRDUP_FAIL_EXIT("-i"); 2069 + rec_argv[i++] = STRDUP_FAIL_EXIT(file_name); 2057 2070 for (j = 1; j < argc; j++, i++) 2058 - rec_argv[i] = argv[j]; 2071 + rec_argv[i] = STRDUP_FAIL_EXIT(argv[j]); 2059 2072 2060 2073 BUG_ON(i != rec_argc); 2061 2074 2062 - return cmd_buildid_list(i, rec_argv); 2075 + ret = cmd_buildid_list(i, rec_argv); 2076 + 2077 + EXIT: 2078 + for (i = 0; i < rec_argc; i++) 2079 + free((void *)rec_argv[i]); 2080 + free(rec_argv); 2081 + return ret; 2063 2082 } 2064 2083 2065 2084 int cmd_kvm(int argc, const char **argv)