Commit baa60b59 authored by Vladislav Vaintroub's avatar Vladislav Vaintroub

MDEV-23038 Service registered with deprecated "mysqld.exe --install" crashes on startup

Services, which is registered with 2 arguments "C:\path\to\mysqld.exe service_name"
would pass non-null terminated command line to win_main(), and this
would crash in defaults handling.

Make sure win_main() gets null-terminated argv.
parent 7e19954b
...@@ -5822,6 +5822,31 @@ default_service_handling(char **argv, ...@@ -5822,6 +5822,31 @@ default_service_handling(char **argv,
return 1; return 1;
} }
/* Remove service name from the command line arguments, and pass
resulting command line to the service via opt_args.*/
#include <vector>
static void service_init_cmdline_args(int argc, char **argv)
{
start_mode= 1;
use_opt_args= 1;
if(argc == 1)
{
opt_argc= argc;
opt_argv= argv;
}
else
{
static std::vector<char *> argv_no_service;
for (int i= 0; argv[i]; i++)
argv_no_service.push_back(argv[i]);
// Remove the last argument, service name
argv_no_service[argv_no_service.size() - 1]= 0;
opt_argc= (int)argv_no_service.size() - 1;
opt_argv= &argv_no_service[0];
}
DBUG_ASSERT(!opt_argv[opt_argc]);
}
int mysqld_main(int argc, char **argv) int mysqld_main(int argc, char **argv)
{ {
...@@ -5853,6 +5878,7 @@ int mysqld_main(int argc, char **argv) ...@@ -5853,6 +5878,7 @@ int mysqld_main(int argc, char **argv)
my_path(file_path, argv[0], ""); /* Find name in path */ my_path(file_path, argv[0], ""); /* Find name in path */
fn_format(file_path,argv[0],file_path,"", MY_REPLACE_DIR | MY_UNPACK_FILENAME | MY_RESOLVE_SYMLINKS); fn_format(file_path,argv[0],file_path,"", MY_REPLACE_DIR | MY_UNPACK_FILENAME | MY_RESOLVE_SYMLINKS);
if (argc == 2) if (argc == 2)
{ {
if (!default_service_handling(argv, MYSQL_SERVICENAME, MYSQL_SERVICENAME, if (!default_service_handling(argv, MYSQL_SERVICENAME, MYSQL_SERVICENAME,
...@@ -5869,7 +5895,7 @@ int mysqld_main(int argc, char **argv) ...@@ -5869,7 +5895,7 @@ int mysqld_main(int argc, char **argv)
*/ */
if (my_strcasecmp(system_charset_info, argv[1],"mysql")) if (my_strcasecmp(system_charset_info, argv[1],"mysql"))
load_default_groups[load_default_groups_sz-2]= argv[1]; load_default_groups[load_default_groups_sz-2]= argv[1];
start_mode= 1; service_init_cmdline_args(argc, argv);
Service.Init(argv[1], mysql_service); Service.Init(argv[1], mysql_service);
return 0; return 0;
} }
...@@ -5885,12 +5911,9 @@ int mysqld_main(int argc, char **argv) ...@@ -5885,12 +5911,9 @@ int mysqld_main(int argc, char **argv)
mysqld was started as mysqld was started as
mysqld --defaults-file=my_path\my.ini service-name mysqld --defaults-file=my_path\my.ini service-name
*/ */
use_opt_args=1;
opt_argc= 2; // Skip service-name
opt_argv=argv;
start_mode= 1;
if (my_strcasecmp(system_charset_info, argv[2],"mysql")) if (my_strcasecmp(system_charset_info, argv[2],"mysql"))
load_default_groups[load_default_groups_sz-2]= argv[2]; load_default_groups[load_default_groups_sz-2]= argv[2];
service_init_cmdline_args(argc, argv);
Service.Init(argv[2], mysql_service); Service.Init(argv[2], mysql_service);
return 0; return 0;
} }
...@@ -5923,7 +5946,7 @@ int mysqld_main(int argc, char **argv) ...@@ -5923,7 +5946,7 @@ int mysqld_main(int argc, char **argv)
else if (argc == 1 && Service.IsService(MYSQL_SERVICENAME)) else if (argc == 1 && Service.IsService(MYSQL_SERVICENAME))
{ {
/* start the default service */ /* start the default service */
start_mode= 1; service_init_cmdline_args(argc, argv);
Service.Init(MYSQL_SERVICENAME, mysql_service); Service.Init(MYSQL_SERVICENAME, mysql_service);
return 0; return 0;
} }
......
...@@ -150,11 +150,8 @@ int get_mysql_service_properties(const wchar_t *bin_path, ...@@ -150,11 +150,8 @@ int get_mysql_service_properties(const wchar_t *bin_path,
There are rare cases where service config does not have There are rare cases where service config does not have
--defaults-file in the binary parth . There services were --defaults-file in the binary parth . There services were
registered with plain mysqld --install, the data directory is registered with plain mysqld --install, the data directory is
next to "bin" in this case. Service name (second parameter) next to "bin" in this case.
must be MySQL.
*/ */
if (wcscmp(args[1], L"MySQL") != 0)
goto end;
have_inifile= FALSE; have_inifile= FALSE;
} }
else if(numargs == 3) else if(numargs == 3)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment