aboutsummaryrefslogtreecommitdiffstats
path: root/lib-src
diff options
context:
space:
mode:
authorAndreas Schwab2012-03-11 12:15:25 +0100
committerAndreas Schwab2012-03-11 12:15:25 +0100
commit6b0c89847a6291b41f73658a4a9c5d54761b2ab9 (patch)
treef9b92f60981a8ae940031eb5dd1b228f87393bf5 /lib-src
parent300e8fa5624c0670553c1215409c9d31075901d1 (diff)
downloademacs-6b0c89847a6291b41f73658a4a9c5d54761b2ab9.tar.gz
emacs-6b0c89847a6291b41f73658a4a9c5d54761b2ab9.zip
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.
Diffstat (limited to 'lib-src')
-rw-r--r--lib-src/ChangeLog13
-rw-r--r--lib-src/emacsclient.c114
2 files changed, 59 insertions, 68 deletions
diff --git a/lib-src/ChangeLog b/lib-src/ChangeLog
index 32054e68db2..b349533f87f 100644
--- a/lib-src/ChangeLog
+++ b/lib-src/ChangeLog
@@ -1,3 +1,16 @@
12012-03-11 Andreas Schwab <schwab@linux-m68k.org>
2
3 * emacsclient.c (socket_name): Add const.
4 (get_server_config): Add parameter config_file, use it instead of
5 global server_file.
6 (set_tcp_socket): Add parameter local_server_file, pass it down to
7 get_server_config.
8 (set_local_socket): Add parameter local_socket_name, use it
9 instead of global socket_name.
10 (set_socket): Adjust calls to set_local_socket and set_tcp_socket.
11 Don't clobber global server_file or socket_name.
12 (main): No longer reset server_file or socket_name.
13
12012-01-05 Glenn Morris <rgm@gnu.org> 142012-01-05 Glenn Morris <rgm@gnu.org>
2 15
3 * ebrowse.c (version) <emacs_copyright>: 16 * ebrowse.c (version) <emacs_copyright>:
diff --git a/lib-src/emacsclient.c b/lib-src/emacsclient.c
index 11eba2792d6..8779309f9b3 100644
--- a/lib-src/emacsclient.c
+++ b/lib-src/emacsclient.c
@@ -152,7 +152,7 @@ int tty = 0;
152const char *alternate_editor = NULL; 152const char *alternate_editor = NULL;
153 153
154/* If non-NULL, the filename of the UNIX socket. */ 154/* If non-NULL, the filename of the UNIX socket. */
155char *socket_name = NULL; 155const char *socket_name = NULL;
156 156
157/* If non-NULL, the filename of the authentication file. */ 157/* If non-NULL, the filename of the authentication file. */
158const char *server_file = NULL; 158const char *server_file = NULL;
@@ -955,36 +955,37 @@ initialize_sockets (void)
955 * the Emacs server: host, port, and authentication string. 955 * the Emacs server: host, port, and authentication string.
956 */ 956 */
957static int 957static int
958get_server_config (struct sockaddr_in *server, char *authentication) 958get_server_config (const char *config_file, struct sockaddr_in *server,
959 char *authentication)
959{ 960{
960 char dotted[32]; 961 char dotted[32];
961 char *port; 962 char *port;
962 FILE *config = NULL; 963 FILE *config = NULL;
963 964
964 if (file_name_absolute_p (server_file)) 965 if (file_name_absolute_p (config_file))
965 config = fopen (server_file, "rb"); 966 config = fopen (config_file, "rb");
966 else 967 else
967 { 968 {
968 const char *home = egetenv ("HOME"); 969 const char *home = egetenv ("HOME");
969 970
970 if (home) 971 if (home)
971 { 972 {
972 char *path = xmalloc (strlen (home) + strlen (server_file) 973 char *path = xmalloc (strlen (home) + strlen (config_file)
973 + EXTRA_SPACE); 974 + EXTRA_SPACE);
974 strcpy (path, home); 975 strcpy (path, home);
975 strcat (path, "/.emacs.d/server/"); 976 strcat (path, "/.emacs.d/server/");
976 strcat (path, server_file); 977 strcat (path, config_file);
977 config = fopen (path, "rb"); 978 config = fopen (path, "rb");
978 free (path); 979 free (path);
979 } 980 }
980#ifdef WINDOWSNT 981#ifdef WINDOWSNT
981 if (!config && (home = egetenv ("APPDATA"))) 982 if (!config && (home = egetenv ("APPDATA")))
982 { 983 {
983 char *path = xmalloc (strlen (home) + strlen (server_file) 984 char *path = xmalloc (strlen (home) + strlen (config_file)
984 + EXTRA_SPACE); 985 + EXTRA_SPACE);
985 strcpy (path, home); 986 strcpy (path, home);
986 strcat (path, "/.emacs.d/server/"); 987 strcat (path, "/.emacs.d/server/");
987 strcat (path, server_file); 988 strcat (path, config_file);
988 config = fopen (path, "rb"); 989 config = fopen (path, "rb");
989 free (path); 990 free (path);
990 } 991 }
@@ -1019,14 +1020,14 @@ get_server_config (struct sockaddr_in *server, char *authentication)
1019} 1020}
1020 1021
1021static HSOCKET 1022static HSOCKET
1022set_tcp_socket (void) 1023set_tcp_socket (const char *local_server_file)
1023{ 1024{
1024 HSOCKET s; 1025 HSOCKET s;
1025 struct sockaddr_in server; 1026 struct sockaddr_in server;
1026 struct linger l_arg = {1, 1}; 1027 struct linger l_arg = {1, 1};
1027 char auth_string[AUTH_KEY_LENGTH + 1]; 1028 char auth_string[AUTH_KEY_LENGTH + 1];
1028 1029
1029 if (! get_server_config (&server, auth_string)) 1030 if (! get_server_config (local_server_file, &server, auth_string))
1030 return INVALID_SOCKET; 1031 return INVALID_SOCKET;
1031 1032
1032 if (server.sin_addr.s_addr != inet_addr ("127.0.0.1") && !quiet) 1033 if (server.sin_addr.s_addr != inet_addr ("127.0.0.1") && !quiet)
@@ -1236,7 +1237,7 @@ init_signals (void)
1236 1237
1237 1238
1238static HSOCKET 1239static HSOCKET
1239set_local_socket (void) 1240set_local_socket (const char *local_socket_name)
1240{ 1241{
1241 HSOCKET s; 1242 HSOCKET s;
1242 struct sockaddr_un server; 1243 struct sockaddr_un server;
@@ -1254,27 +1255,20 @@ set_local_socket (void)
1254 server.sun_family = AF_UNIX; 1255 server.sun_family = AF_UNIX;
1255 1256
1256 { 1257 {
1257 int sock_status = 0; 1258 int sock_status;
1258 int default_sock = !socket_name; 1259 int use_tmpdir = 0;
1259 int saved_errno = 0; 1260 int saved_errno;
1260 const char *server_name = "server"; 1261 const char *server_name = local_socket_name;
1261 const char *tmpdir IF_LINT ( = NULL); 1262 const char *tmpdir IF_LINT ( = NULL);
1262 char *tmpdir_storage = NULL; 1263 char *tmpdir_storage = NULL;
1263 char *socket_name_storage = NULL; 1264 char *socket_name_storage = NULL;
1264 1265
1265 if (socket_name && !strchr (socket_name, '/') 1266 if (!strchr (local_socket_name, '/') && !strchr (local_socket_name, '\\'))
1266 && !strchr (socket_name, '\\'))
1267 { 1267 {
1268 /* socket_name is a file name component. */ 1268 /* socket_name is a file name component. */
1269 server_name = socket_name;
1270 socket_name = NULL;
1271 default_sock = 1; /* Try both UIDs. */
1272 }
1273
1274 if (default_sock)
1275 {
1276 long uid = geteuid (); 1269 long uid = geteuid ();
1277 ptrdiff_t tmpdirlen; 1270 ptrdiff_t tmpdirlen;
1271 use_tmpdir = 1;
1278 tmpdir = egetenv ("TMPDIR"); 1272 tmpdir = egetenv ("TMPDIR");
1279 if (!tmpdir) 1273 if (!tmpdir)
1280 { 1274 {
@@ -1293,26 +1287,27 @@ set_local_socket (void)
1293 tmpdir = "/tmp"; 1287 tmpdir = "/tmp";
1294 } 1288 }
1295 tmpdirlen = strlen (tmpdir); 1289 tmpdirlen = strlen (tmpdir);
1296 socket_name = socket_name_storage = 1290 socket_name_storage =
1297 xmalloc (tmpdirlen + strlen (server_name) + EXTRA_SPACE); 1291 xmalloc (tmpdirlen + strlen (server_name) + EXTRA_SPACE);
1298 strcpy (socket_name, tmpdir); 1292 strcpy (socket_name_storage, tmpdir);
1299 sprintf (socket_name + tmpdirlen, "/emacs%ld/", uid); 1293 sprintf (socket_name_storage + tmpdirlen, "/emacs%ld/", uid);
1300 strcat (socket_name + tmpdirlen, server_name); 1294 strcat (socket_name_storage + tmpdirlen, server_name);
1295 local_socket_name = socket_name_storage;
1301 } 1296 }
1302 1297
1303 if (strlen (socket_name) < sizeof (server.sun_path)) 1298 if (strlen (local_socket_name) < sizeof (server.sun_path))
1304 strcpy (server.sun_path, socket_name); 1299 strcpy (server.sun_path, local_socket_name);
1305 else 1300 else
1306 { 1301 {
1307 message (TRUE, "%s: socket-name %s too long\n", 1302 message (TRUE, "%s: socket-name %s too long\n",
1308 progname, socket_name); 1303 progname, local_socket_name);
1309 fail (); 1304 fail ();
1310 } 1305 }
1311 1306
1312 /* See if the socket exists, and if it's owned by us. */ 1307 /* See if the socket exists, and if it's owned by us. */
1313 sock_status = socket_status (server.sun_path); 1308 sock_status = socket_status (server.sun_path);
1314 saved_errno = errno; 1309 saved_errno = errno;
1315 if (sock_status && default_sock) 1310 if (sock_status && use_tmpdir)
1316 { 1311 {
1317 /* Failing that, see if LOGNAME or USER exist and differ from 1312 /* Failing that, see if LOGNAME or USER exist and differ from
1318 our euid. If so, look for a socket based on the UID 1313 our euid. If so, look for a socket based on the UID
@@ -1333,21 +1328,21 @@ set_local_socket (void)
1333 /* We're running under su, apparently. */ 1328 /* We're running under su, apparently. */
1334 long uid = pw->pw_uid; 1329 long uid = pw->pw_uid;
1335 ptrdiff_t tmpdirlen = strlen (tmpdir); 1330 ptrdiff_t tmpdirlen = strlen (tmpdir);
1336 socket_name = xmalloc (tmpdirlen + strlen (server_name) 1331 char *user_socket_name
1337 + EXTRA_SPACE); 1332 = xmalloc (tmpdirlen + strlen (server_name) + EXTRA_SPACE);
1338 strcpy (socket_name, tmpdir); 1333 strcpy (user_socket_name, tmpdir);
1339 sprintf (socket_name + tmpdirlen, "/emacs%ld/", uid); 1334 sprintf (user_socket_name + tmpdirlen, "/emacs%ld/", uid);
1340 strcat (socket_name + tmpdirlen, server_name); 1335 strcat (user_socket_name + tmpdirlen, server_name);
1341 1336
1342 if (strlen (socket_name) < sizeof (server.sun_path)) 1337 if (strlen (user_socket_name) < sizeof (server.sun_path))
1343 strcpy (server.sun_path, socket_name); 1338 strcpy (server.sun_path, user_socket_name);
1344 else 1339 else
1345 { 1340 {
1346 message (TRUE, "%s: socket-name %s too long\n", 1341 message (TRUE, "%s: socket-name %s too long\n",
1347 progname, socket_name); 1342 progname, user_socket_name);
1348 exit (EXIT_FAILURE); 1343 exit (EXIT_FAILURE);
1349 } 1344 }
1350 free (socket_name); 1345 free (user_socket_name);
1351 1346
1352 sock_status = socket_status (server.sun_path); 1347 sock_status = socket_status (server.sun_path);
1353 saved_errno = errno; 1348 saved_errno = errno;
@@ -1401,6 +1396,7 @@ static HSOCKET
1401set_socket (int no_exit_if_error) 1396set_socket (int no_exit_if_error)
1402{ 1397{
1403 HSOCKET s; 1398 HSOCKET s;
1399 const char *local_server_file = server_file;
1404 1400
1405 INITIALIZE (); 1401 INITIALIZE ();
1406 1402
@@ -1408,7 +1404,7 @@ set_socket (int no_exit_if_error)
1408 /* Explicit --socket-name argument. */ 1404 /* Explicit --socket-name argument. */
1409 if (socket_name) 1405 if (socket_name)
1410 { 1406 {
1411 s = set_local_socket (); 1407 s = set_local_socket (socket_name);
1412 if ((s != INVALID_SOCKET) || no_exit_if_error) 1408 if ((s != INVALID_SOCKET) || no_exit_if_error)
1413 return s; 1409 return s;
1414 message (TRUE, "%s: error accessing socket \"%s\"\n", 1410 message (TRUE, "%s: error accessing socket \"%s\"\n",
@@ -1418,30 +1414,29 @@ set_socket (int no_exit_if_error)
1418#endif 1414#endif
1419 1415
1420 /* Explicit --server-file arg or EMACS_SERVER_FILE variable. */ 1416 /* Explicit --server-file arg or EMACS_SERVER_FILE variable. */
1421 if (!server_file) 1417 if (!local_server_file)
1422 server_file = egetenv ("EMACS_SERVER_FILE"); 1418 local_server_file = egetenv ("EMACS_SERVER_FILE");
1423 1419
1424 if (server_file) 1420 if (local_server_file)
1425 { 1421 {
1426 s = set_tcp_socket (); 1422 s = set_tcp_socket (local_server_file);
1427 if ((s != INVALID_SOCKET) || no_exit_if_error) 1423 if ((s != INVALID_SOCKET) || no_exit_if_error)
1428 return s; 1424 return s;
1429 1425
1430 message (TRUE, "%s: error accessing server file \"%s\"\n", 1426 message (TRUE, "%s: error accessing server file \"%s\"\n",
1431 progname, server_file); 1427 progname, local_server_file);
1432 exit (EXIT_FAILURE); 1428 exit (EXIT_FAILURE);
1433 } 1429 }
1434 1430
1435#ifndef NO_SOCKETS_IN_FILE_SYSTEM 1431#ifndef NO_SOCKETS_IN_FILE_SYSTEM
1436 /* Implicit local socket. */ 1432 /* Implicit local socket. */
1437 s = set_local_socket (); 1433 s = set_local_socket ("server");
1438 if (s != INVALID_SOCKET) 1434 if (s != INVALID_SOCKET)
1439 return s; 1435 return s;
1440#endif 1436#endif
1441 1437
1442 /* Implicit server file. */ 1438 /* Implicit server file. */
1443 server_file = "server"; 1439 s = set_tcp_socket ("server");
1444 s = set_tcp_socket ();
1445 if ((s != INVALID_SOCKET) || no_exit_if_error) 1440 if ((s != INVALID_SOCKET) || no_exit_if_error)
1446 return s; 1441 return s;
1447 1442
@@ -1573,8 +1568,6 @@ main (int argc, char **argv)
1573 int rl = 0, needlf = 0; 1568 int rl = 0, needlf = 0;
1574 char *cwd, *str; 1569 char *cwd, *str;
1575 char string[BUFSIZ+1]; 1570 char string[BUFSIZ+1];
1576 int null_socket_name IF_LINT ( = 0);
1577 int null_server_file IF_LINT ( = 0);
1578 int start_daemon_if_needed; 1571 int start_daemon_if_needed;
1579 int exit_status = EXIT_SUCCESS; 1572 int exit_status = EXIT_SUCCESS;
1580 1573
@@ -1602,14 +1595,6 @@ main (int argc, char **argv)
1602 in case of failure to connect. */ 1595 in case of failure to connect. */
1603 start_daemon_if_needed = (alternate_editor 1596 start_daemon_if_needed = (alternate_editor
1604 && (alternate_editor[0] == '\0')); 1597 && (alternate_editor[0] == '\0'));
1605 if (start_daemon_if_needed)
1606 {
1607 /* set_socket changes the values for socket_name and
1608 server_file, we need to reset them, if they were NULL before
1609 for the second call to set_socket. */
1610 null_socket_name = (socket_name == NULL);
1611 null_server_file = (server_file == NULL);
1612 }
1613 1598
1614 emacs_socket = set_socket (alternate_editor || start_daemon_if_needed); 1599 emacs_socket = set_socket (alternate_editor || start_daemon_if_needed);
1615 if (emacs_socket == INVALID_SOCKET) 1600 if (emacs_socket == INVALID_SOCKET)
@@ -1617,13 +1602,6 @@ main (int argc, char **argv)
1617 if (! start_daemon_if_needed) 1602 if (! start_daemon_if_needed)
1618 fail (); 1603 fail ();
1619 1604
1620 /* Reset socket_name and server_file if they were NULL
1621 before the set_socket call. */
1622 if (null_socket_name)
1623 socket_name = NULL;
1624 if (null_server_file)
1625 server_file = NULL;
1626
1627 start_daemon_and_retry_set_socket (); 1605 start_daemon_and_retry_set_socket ();
1628 } 1606 }
1629 1607