mirror of
https://git.savannah.gnu.org/git/emacs.git
synced 2025-01-19 18:13:55 +00:00
Don't access freed memory in emacsclient
* emacsclient.c (socket_name): Add const. (get_server_config): Add parameter config_file, use it instead of global server_file. (set_tcp_socket): Add parameter local_server_file, pass it down to get_server_config. (set_local_socket): Add parameter local_socket_name, use it instead of global socket_name. (set_socket): Adjust calls to set_local_socket and set_tcp_socket. Don't clobber global server_file or socket_name. (main): No longer reset server_file or socket_name.
This commit is contained in:
parent
300e8fa562
commit
6b0c89847a
@ -1,3 +1,16 @@
|
||||
2012-03-11 Andreas Schwab <schwab@linux-m68k.org>
|
||||
|
||||
* emacsclient.c (socket_name): Add const.
|
||||
(get_server_config): Add parameter config_file, use it instead of
|
||||
global server_file.
|
||||
(set_tcp_socket): Add parameter local_server_file, pass it down to
|
||||
get_server_config.
|
||||
(set_local_socket): Add parameter local_socket_name, use it
|
||||
instead of global socket_name.
|
||||
(set_socket): Adjust calls to set_local_socket and set_tcp_socket.
|
||||
Don't clobber global server_file or socket_name.
|
||||
(main): No longer reset server_file or socket_name.
|
||||
|
||||
2012-01-05 Glenn Morris <rgm@gnu.org>
|
||||
|
||||
* ebrowse.c (version) <emacs_copyright>:
|
||||
|
@ -152,7 +152,7 @@ int tty = 0;
|
||||
const char *alternate_editor = NULL;
|
||||
|
||||
/* If non-NULL, the filename of the UNIX socket. */
|
||||
char *socket_name = NULL;
|
||||
const char *socket_name = NULL;
|
||||
|
||||
/* If non-NULL, the filename of the authentication file. */
|
||||
const char *server_file = NULL;
|
||||
@ -955,36 +955,37 @@ initialize_sockets (void)
|
||||
* the Emacs server: host, port, and authentication string.
|
||||
*/
|
||||
static int
|
||||
get_server_config (struct sockaddr_in *server, char *authentication)
|
||||
get_server_config (const char *config_file, struct sockaddr_in *server,
|
||||
char *authentication)
|
||||
{
|
||||
char dotted[32];
|
||||
char *port;
|
||||
FILE *config = NULL;
|
||||
|
||||
if (file_name_absolute_p (server_file))
|
||||
config = fopen (server_file, "rb");
|
||||
if (file_name_absolute_p (config_file))
|
||||
config = fopen (config_file, "rb");
|
||||
else
|
||||
{
|
||||
const char *home = egetenv ("HOME");
|
||||
|
||||
if (home)
|
||||
{
|
||||
char *path = xmalloc (strlen (home) + strlen (server_file)
|
||||
char *path = xmalloc (strlen (home) + strlen (config_file)
|
||||
+ EXTRA_SPACE);
|
||||
strcpy (path, home);
|
||||
strcat (path, "/.emacs.d/server/");
|
||||
strcat (path, server_file);
|
||||
strcat (path, config_file);
|
||||
config = fopen (path, "rb");
|
||||
free (path);
|
||||
}
|
||||
#ifdef WINDOWSNT
|
||||
if (!config && (home = egetenv ("APPDATA")))
|
||||
{
|
||||
char *path = xmalloc (strlen (home) + strlen (server_file)
|
||||
char *path = xmalloc (strlen (home) + strlen (config_file)
|
||||
+ EXTRA_SPACE);
|
||||
strcpy (path, home);
|
||||
strcat (path, "/.emacs.d/server/");
|
||||
strcat (path, server_file);
|
||||
strcat (path, config_file);
|
||||
config = fopen (path, "rb");
|
||||
free (path);
|
||||
}
|
||||
@ -1019,14 +1020,14 @@ get_server_config (struct sockaddr_in *server, char *authentication)
|
||||
}
|
||||
|
||||
static HSOCKET
|
||||
set_tcp_socket (void)
|
||||
set_tcp_socket (const char *local_server_file)
|
||||
{
|
||||
HSOCKET s;
|
||||
struct sockaddr_in server;
|
||||
struct linger l_arg = {1, 1};
|
||||
char auth_string[AUTH_KEY_LENGTH + 1];
|
||||
|
||||
if (! get_server_config (&server, auth_string))
|
||||
if (! get_server_config (local_server_file, &server, auth_string))
|
||||
return INVALID_SOCKET;
|
||||
|
||||
if (server.sin_addr.s_addr != inet_addr ("127.0.0.1") && !quiet)
|
||||
@ -1236,7 +1237,7 @@ init_signals (void)
|
||||
|
||||
|
||||
static HSOCKET
|
||||
set_local_socket (void)
|
||||
set_local_socket (const char *local_socket_name)
|
||||
{
|
||||
HSOCKET s;
|
||||
struct sockaddr_un server;
|
||||
@ -1254,27 +1255,20 @@ set_local_socket (void)
|
||||
server.sun_family = AF_UNIX;
|
||||
|
||||
{
|
||||
int sock_status = 0;
|
||||
int default_sock = !socket_name;
|
||||
int saved_errno = 0;
|
||||
const char *server_name = "server";
|
||||
int sock_status;
|
||||
int use_tmpdir = 0;
|
||||
int saved_errno;
|
||||
const char *server_name = local_socket_name;
|
||||
const char *tmpdir IF_LINT ( = NULL);
|
||||
char *tmpdir_storage = NULL;
|
||||
char *socket_name_storage = NULL;
|
||||
|
||||
if (socket_name && !strchr (socket_name, '/')
|
||||
&& !strchr (socket_name, '\\'))
|
||||
if (!strchr (local_socket_name, '/') && !strchr (local_socket_name, '\\'))
|
||||
{
|
||||
/* socket_name is a file name component. */
|
||||
server_name = socket_name;
|
||||
socket_name = NULL;
|
||||
default_sock = 1; /* Try both UIDs. */
|
||||
}
|
||||
|
||||
if (default_sock)
|
||||
{
|
||||
long uid = geteuid ();
|
||||
ptrdiff_t tmpdirlen;
|
||||
use_tmpdir = 1;
|
||||
tmpdir = egetenv ("TMPDIR");
|
||||
if (!tmpdir)
|
||||
{
|
||||
@ -1293,26 +1287,27 @@ set_local_socket (void)
|
||||
tmpdir = "/tmp";
|
||||
}
|
||||
tmpdirlen = strlen (tmpdir);
|
||||
socket_name = socket_name_storage =
|
||||
socket_name_storage =
|
||||
xmalloc (tmpdirlen + strlen (server_name) + EXTRA_SPACE);
|
||||
strcpy (socket_name, tmpdir);
|
||||
sprintf (socket_name + tmpdirlen, "/emacs%ld/", uid);
|
||||
strcat (socket_name + tmpdirlen, server_name);
|
||||
strcpy (socket_name_storage, tmpdir);
|
||||
sprintf (socket_name_storage + tmpdirlen, "/emacs%ld/", uid);
|
||||
strcat (socket_name_storage + tmpdirlen, server_name);
|
||||
local_socket_name = socket_name_storage;
|
||||
}
|
||||
|
||||
if (strlen (socket_name) < sizeof (server.sun_path))
|
||||
strcpy (server.sun_path, socket_name);
|
||||
if (strlen (local_socket_name) < sizeof (server.sun_path))
|
||||
strcpy (server.sun_path, local_socket_name);
|
||||
else
|
||||
{
|
||||
message (TRUE, "%s: socket-name %s too long\n",
|
||||
progname, socket_name);
|
||||
progname, local_socket_name);
|
||||
fail ();
|
||||
}
|
||||
|
||||
/* See if the socket exists, and if it's owned by us. */
|
||||
sock_status = socket_status (server.sun_path);
|
||||
saved_errno = errno;
|
||||
if (sock_status && default_sock)
|
||||
if (sock_status && use_tmpdir)
|
||||
{
|
||||
/* Failing that, see if LOGNAME or USER exist and differ from
|
||||
our euid. If so, look for a socket based on the UID
|
||||
@ -1333,21 +1328,21 @@ set_local_socket (void)
|
||||
/* We're running under su, apparently. */
|
||||
long uid = pw->pw_uid;
|
||||
ptrdiff_t tmpdirlen = strlen (tmpdir);
|
||||
socket_name = xmalloc (tmpdirlen + strlen (server_name)
|
||||
+ EXTRA_SPACE);
|
||||
strcpy (socket_name, tmpdir);
|
||||
sprintf (socket_name + tmpdirlen, "/emacs%ld/", uid);
|
||||
strcat (socket_name + tmpdirlen, server_name);
|
||||
char *user_socket_name
|
||||
= xmalloc (tmpdirlen + strlen (server_name) + EXTRA_SPACE);
|
||||
strcpy (user_socket_name, tmpdir);
|
||||
sprintf (user_socket_name + tmpdirlen, "/emacs%ld/", uid);
|
||||
strcat (user_socket_name + tmpdirlen, server_name);
|
||||
|
||||
if (strlen (socket_name) < sizeof (server.sun_path))
|
||||
strcpy (server.sun_path, socket_name);
|
||||
if (strlen (user_socket_name) < sizeof (server.sun_path))
|
||||
strcpy (server.sun_path, user_socket_name);
|
||||
else
|
||||
{
|
||||
message (TRUE, "%s: socket-name %s too long\n",
|
||||
progname, socket_name);
|
||||
progname, user_socket_name);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
free (socket_name);
|
||||
free (user_socket_name);
|
||||
|
||||
sock_status = socket_status (server.sun_path);
|
||||
saved_errno = errno;
|
||||
@ -1401,6 +1396,7 @@ static HSOCKET
|
||||
set_socket (int no_exit_if_error)
|
||||
{
|
||||
HSOCKET s;
|
||||
const char *local_server_file = server_file;
|
||||
|
||||
INITIALIZE ();
|
||||
|
||||
@ -1408,7 +1404,7 @@ set_socket (int no_exit_if_error)
|
||||
/* Explicit --socket-name argument. */
|
||||
if (socket_name)
|
||||
{
|
||||
s = set_local_socket ();
|
||||
s = set_local_socket (socket_name);
|
||||
if ((s != INVALID_SOCKET) || no_exit_if_error)
|
||||
return s;
|
||||
message (TRUE, "%s: error accessing socket \"%s\"\n",
|
||||
@ -1418,30 +1414,29 @@ set_socket (int no_exit_if_error)
|
||||
#endif
|
||||
|
||||
/* Explicit --server-file arg or EMACS_SERVER_FILE variable. */
|
||||
if (!server_file)
|
||||
server_file = egetenv ("EMACS_SERVER_FILE");
|
||||
if (!local_server_file)
|
||||
local_server_file = egetenv ("EMACS_SERVER_FILE");
|
||||
|
||||
if (server_file)
|
||||
if (local_server_file)
|
||||
{
|
||||
s = set_tcp_socket ();
|
||||
s = set_tcp_socket (local_server_file);
|
||||
if ((s != INVALID_SOCKET) || no_exit_if_error)
|
||||
return s;
|
||||
|
||||
message (TRUE, "%s: error accessing server file \"%s\"\n",
|
||||
progname, server_file);
|
||||
progname, local_server_file);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
#ifndef NO_SOCKETS_IN_FILE_SYSTEM
|
||||
/* Implicit local socket. */
|
||||
s = set_local_socket ();
|
||||
s = set_local_socket ("server");
|
||||
if (s != INVALID_SOCKET)
|
||||
return s;
|
||||
#endif
|
||||
|
||||
/* Implicit server file. */
|
||||
server_file = "server";
|
||||
s = set_tcp_socket ();
|
||||
s = set_tcp_socket ("server");
|
||||
if ((s != INVALID_SOCKET) || no_exit_if_error)
|
||||
return s;
|
||||
|
||||
@ -1573,8 +1568,6 @@ main (int argc, char **argv)
|
||||
int rl = 0, needlf = 0;
|
||||
char *cwd, *str;
|
||||
char string[BUFSIZ+1];
|
||||
int null_socket_name IF_LINT ( = 0);
|
||||
int null_server_file IF_LINT ( = 0);
|
||||
int start_daemon_if_needed;
|
||||
int exit_status = EXIT_SUCCESS;
|
||||
|
||||
@ -1602,14 +1595,6 @@ main (int argc, char **argv)
|
||||
in case of failure to connect. */
|
||||
start_daemon_if_needed = (alternate_editor
|
||||
&& (alternate_editor[0] == '\0'));
|
||||
if (start_daemon_if_needed)
|
||||
{
|
||||
/* set_socket changes the values for socket_name and
|
||||
server_file, we need to reset them, if they were NULL before
|
||||
for the second call to set_socket. */
|
||||
null_socket_name = (socket_name == NULL);
|
||||
null_server_file = (server_file == NULL);
|
||||
}
|
||||
|
||||
emacs_socket = set_socket (alternate_editor || start_daemon_if_needed);
|
||||
if (emacs_socket == INVALID_SOCKET)
|
||||
@ -1617,13 +1602,6 @@ main (int argc, char **argv)
|
||||
if (! start_daemon_if_needed)
|
||||
fail ();
|
||||
|
||||
/* Reset socket_name and server_file if they were NULL
|
||||
before the set_socket call. */
|
||||
if (null_socket_name)
|
||||
socket_name = NULL;
|
||||
if (null_server_file)
|
||||
server_file = NULL;
|
||||
|
||||
start_daemon_and_retry_set_socket ();
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user