diff options
| author | Paul Eggert | 2013-07-20 08:33:00 -0700 |
|---|---|---|
| committer | Paul Eggert | 2013-07-20 08:33:00 -0700 |
| commit | 6496aec9e948e0e5e6646aff408391d78f3516cc (patch) | |
| tree | d3e3afc92e5189ef1b1a8d2814965f003c13f96f /src/process.c | |
| parent | b2a069c2f80cb2fdd683f5e044642b058c4d2326 (diff) | |
| download | emacs-6496aec9e948e0e5e6646aff408391d78f3516cc.tar.gz emacs-6496aec9e948e0e5e6646aff408391d78f3516cc.zip | |
Fix array bounds violation when pty allocation fails.
* configure.ac (PTY_TTY_NAME_SPRINTF): Use PTY_NAME_SIZE,
not sizeof pty_name, since pty_name is now a pointer to the array.
* src/process.c (PTY_NAME_SIZE): New constant.
(pty_name): Remove static variable; it's now auto.
(allocate_pty): Define even if !HAVE_PTYS; that's simpler.
Take pty_name as an arg rather than using a static variable.
All callers changed.
(create_process): Recover pty_flag from process, not from volatile local.
(create_pty): Stay inside array even when pty allocation fails.
(Fmake_serial_process): Omit unnecessary initializaiton of pty_flag.
Diffstat (limited to 'src/process.c')
| -rw-r--r-- | src/process.c | 87 |
1 files changed, 38 insertions, 49 deletions
diff --git a/src/process.c b/src/process.c index f4ae662468b..12035da7b58 100644 --- a/src/process.c +++ b/src/process.c | |||
| @@ -640,19 +640,16 @@ status_message (struct Lisp_Process *p) | |||
| 640 | return Fcopy_sequence (Fsymbol_name (symbol)); | 640 | return Fcopy_sequence (Fsymbol_name (symbol)); |
| 641 | } | 641 | } |
| 642 | 642 | ||
| 643 | #ifdef HAVE_PTYS | 643 | enum { PTY_NAME_SIZE = 24 }; |
| 644 | |||
| 645 | /* The file name of the pty opened by allocate_pty. */ | ||
| 646 | static char pty_name[24]; | ||
| 647 | 644 | ||
| 648 | /* Open an available pty, returning a file descriptor. | 645 | /* Open an available pty, returning a file descriptor. |
| 649 | Return -1 on failure. | 646 | Store into PTY_NAME the file name of the terminal corresponding to the pty. |
| 650 | The file name of the terminal corresponding to the pty | 647 | Return -1 on failure. */ |
| 651 | is left in the variable pty_name. */ | ||
| 652 | 648 | ||
| 653 | static int | 649 | static int |
| 654 | allocate_pty (void) | 650 | allocate_pty (char pty_name[PTY_NAME_SIZE]) |
| 655 | { | 651 | { |
| 652 | #ifdef HAVE_PTYS | ||
| 656 | int fd; | 653 | int fd; |
| 657 | 654 | ||
| 658 | #ifdef PTY_ITERATION | 655 | #ifdef PTY_ITERATION |
| @@ -697,9 +694,9 @@ allocate_pty (void) | |||
| 697 | return fd; | 694 | return fd; |
| 698 | } | 695 | } |
| 699 | } | 696 | } |
| 697 | #endif /* HAVE_PTYS */ | ||
| 700 | return -1; | 698 | return -1; |
| 701 | } | 699 | } |
| 702 | #endif /* HAVE_PTYS */ | ||
| 703 | 700 | ||
| 704 | static Lisp_Object | 701 | static Lisp_Object |
| 705 | make_process (Lisp_Object name) | 702 | make_process (Lisp_Object name) |
| @@ -1621,14 +1618,14 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1621 | #endif | 1618 | #endif |
| 1622 | int forkin, forkout; | 1619 | int forkin, forkout; |
| 1623 | bool pty_flag = 0; | 1620 | bool pty_flag = 0; |
| 1621 | char pty_name[PTY_NAME_SIZE]; | ||
| 1624 | Lisp_Object lisp_pty_name = Qnil; | 1622 | Lisp_Object lisp_pty_name = Qnil; |
| 1625 | Lisp_Object encoded_current_dir; | 1623 | Lisp_Object encoded_current_dir; |
| 1626 | 1624 | ||
| 1627 | inchannel = outchannel = -1; | 1625 | inchannel = outchannel = -1; |
| 1628 | 1626 | ||
| 1629 | #ifdef HAVE_PTYS | ||
| 1630 | if (!NILP (Vprocess_connection_type)) | 1627 | if (!NILP (Vprocess_connection_type)) |
| 1631 | outchannel = inchannel = allocate_pty (); | 1628 | outchannel = inchannel = allocate_pty (pty_name); |
| 1632 | 1629 | ||
| 1633 | if (inchannel >= 0) | 1630 | if (inchannel >= 0) |
| 1634 | { | 1631 | { |
| @@ -1647,7 +1644,6 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1647 | lisp_pty_name = build_string (pty_name); | 1644 | lisp_pty_name = build_string (pty_name); |
| 1648 | } | 1645 | } |
| 1649 | else | 1646 | else |
| 1650 | #endif /* HAVE_PTYS */ | ||
| 1651 | { | 1647 | { |
| 1652 | if (emacs_pipe (sv) != 0) | 1648 | if (emacs_pipe (sv) != 0) |
| 1653 | report_file_error ("Creating pipe", Qnil); | 1649 | report_file_error ("Creating pipe", Qnil); |
| @@ -1704,7 +1700,6 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1704 | Lisp_Object volatile encoded_current_dir_volatile = encoded_current_dir; | 1700 | Lisp_Object volatile encoded_current_dir_volatile = encoded_current_dir; |
| 1705 | Lisp_Object volatile lisp_pty_name_volatile = lisp_pty_name; | 1701 | Lisp_Object volatile lisp_pty_name_volatile = lisp_pty_name; |
| 1706 | Lisp_Object volatile process_volatile = process; | 1702 | Lisp_Object volatile process_volatile = process; |
| 1707 | bool volatile pty_flag_volatile = pty_flag; | ||
| 1708 | char **volatile new_argv_volatile = new_argv; | 1703 | char **volatile new_argv_volatile = new_argv; |
| 1709 | int volatile forkin_volatile = forkin; | 1704 | int volatile forkin_volatile = forkin; |
| 1710 | int volatile forkout_volatile = forkout; | 1705 | int volatile forkout_volatile = forkout; |
| @@ -1716,12 +1711,13 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1716 | encoded_current_dir = encoded_current_dir_volatile; | 1711 | encoded_current_dir = encoded_current_dir_volatile; |
| 1717 | lisp_pty_name = lisp_pty_name_volatile; | 1712 | lisp_pty_name = lisp_pty_name_volatile; |
| 1718 | process = process_volatile; | 1713 | process = process_volatile; |
| 1719 | pty_flag = pty_flag_volatile; | ||
| 1720 | new_argv = new_argv_volatile; | 1714 | new_argv = new_argv_volatile; |
| 1721 | forkin = forkin_volatile; | 1715 | forkin = forkin_volatile; |
| 1722 | forkout = forkout_volatile; | 1716 | forkout = forkout_volatile; |
| 1723 | wait_child_setup[0] = wait_child_setup_0_volatile; | 1717 | wait_child_setup[0] = wait_child_setup_0_volatile; |
| 1724 | wait_child_setup[1] = wait_child_setup_1_volatile; | 1718 | wait_child_setup[1] = wait_child_setup_1_volatile; |
| 1719 | |||
| 1720 | pty_flag = XPROCESS (process)->pty_flag; | ||
| 1725 | } | 1721 | } |
| 1726 | 1722 | ||
| 1727 | if (pid == 0) | 1723 | if (pid == 0) |
| @@ -1791,15 +1787,15 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1791 | if (pty_flag) | 1787 | if (pty_flag) |
| 1792 | { | 1788 | { |
| 1793 | 1789 | ||
| 1794 | /* I wonder if emacs_close (emacs_open (pty_name, ...)) | 1790 | /* I wonder if emacs_close (emacs_open (SSDATA (lisp_pty_name), ...)) |
| 1795 | would work? */ | 1791 | would work? */ |
| 1796 | if (xforkin >= 0) | 1792 | if (xforkin >= 0) |
| 1797 | emacs_close (xforkin); | 1793 | emacs_close (xforkin); |
| 1798 | xforkout = xforkin = emacs_open (pty_name, O_RDWR, 0); | 1794 | xforkout = xforkin = emacs_open (SSDATA (lisp_pty_name), O_RDWR, 0); |
| 1799 | 1795 | ||
| 1800 | if (xforkin < 0) | 1796 | if (xforkin < 0) |
| 1801 | { | 1797 | { |
| 1802 | emacs_perror (pty_name); | 1798 | emacs_perror (SSDATA (lisp_pty_name)); |
| 1803 | _exit (EXIT_CANCELED); | 1799 | _exit (EXIT_CANCELED); |
| 1804 | } | 1800 | } |
| 1805 | 1801 | ||
| @@ -1899,17 +1895,16 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1899 | } | 1895 | } |
| 1900 | } | 1896 | } |
| 1901 | 1897 | ||
| 1902 | void | 1898 | static void |
| 1903 | create_pty (Lisp_Object process) | 1899 | create_pty (Lisp_Object process) |
| 1904 | { | 1900 | { |
| 1901 | char pty_name[PTY_NAME_SIZE]; | ||
| 1905 | int inchannel, outchannel; | 1902 | int inchannel, outchannel; |
| 1906 | bool pty_flag = 0; | ||
| 1907 | 1903 | ||
| 1908 | inchannel = outchannel = -1; | 1904 | inchannel = outchannel = -1; |
| 1909 | 1905 | ||
| 1910 | #ifdef HAVE_PTYS | ||
| 1911 | if (!NILP (Vprocess_connection_type)) | 1906 | if (!NILP (Vprocess_connection_type)) |
| 1912 | outchannel = inchannel = allocate_pty (); | 1907 | outchannel = inchannel = allocate_pty (pty_name); |
| 1913 | 1908 | ||
| 1914 | if (inchannel >= 0) | 1909 | if (inchannel >= 0) |
| 1915 | { | 1910 | { |
| @@ -1928,40 +1923,34 @@ create_pty (Lisp_Object process) | |||
| 1928 | child_setup_tty (forkout); | 1923 | child_setup_tty (forkout); |
| 1929 | #endif /* DONT_REOPEN_PTY */ | 1924 | #endif /* DONT_REOPEN_PTY */ |
| 1930 | #endif /* not USG, or USG_SUBTTY_WORKS */ | 1925 | #endif /* not USG, or USG_SUBTTY_WORKS */ |
| 1931 | pty_flag = 1; | ||
| 1932 | } | ||
| 1933 | #endif /* HAVE_PTYS */ | ||
| 1934 | 1926 | ||
| 1935 | fcntl (inchannel, F_SETFL, O_NONBLOCK); | 1927 | fcntl (inchannel, F_SETFL, O_NONBLOCK); |
| 1936 | fcntl (outchannel, F_SETFL, O_NONBLOCK); | 1928 | fcntl (outchannel, F_SETFL, O_NONBLOCK); |
| 1937 | 1929 | ||
| 1938 | /* Record this as an active process, with its channels. | 1930 | /* Record this as an active process, with its channels. |
| 1939 | As a result, child_setup will close Emacs's side of the pipes. */ | 1931 | As a result, child_setup will close Emacs's side of the pipes. */ |
| 1940 | chan_process[inchannel] = process; | 1932 | chan_process[inchannel] = process; |
| 1941 | XPROCESS (process)->infd = inchannel; | 1933 | XPROCESS (process)->infd = inchannel; |
| 1942 | XPROCESS (process)->outfd = outchannel; | 1934 | XPROCESS (process)->outfd = outchannel; |
| 1943 | 1935 | ||
| 1944 | /* Previously we recorded the tty descriptor used in the subprocess. | 1936 | /* Previously we recorded the tty descriptor used in the subprocess. |
| 1945 | It was only used for getting the foreground tty process, so now | 1937 | It was only used for getting the foreground tty process, so now |
| 1946 | we just reopen the device (see emacs_get_tty_pgrp) as this is | 1938 | we just reopen the device (see emacs_get_tty_pgrp) as this is |
| 1947 | more portable (see USG_SUBTTY_WORKS above). */ | 1939 | more portable (see USG_SUBTTY_WORKS above). */ |
| 1948 | 1940 | ||
| 1949 | XPROCESS (process)->pty_flag = pty_flag; | 1941 | XPROCESS (process)->pty_flag = 1; |
| 1950 | pset_status (XPROCESS (process), Qrun); | 1942 | pset_status (XPROCESS (process), Qrun); |
| 1951 | setup_process_coding_systems (process); | 1943 | setup_process_coding_systems (process); |
| 1952 | 1944 | ||
| 1953 | FD_SET (inchannel, &input_wait_mask); | 1945 | FD_SET (inchannel, &input_wait_mask); |
| 1954 | FD_SET (inchannel, &non_keyboard_wait_mask); | 1946 | FD_SET (inchannel, &non_keyboard_wait_mask); |
| 1955 | if (inchannel > max_process_desc) | 1947 | if (inchannel > max_process_desc) |
| 1956 | max_process_desc = inchannel; | 1948 | max_process_desc = inchannel; |
| 1949 | |||
| 1950 | pset_tty_name (XPROCESS (process), build_string (pty_name)); | ||
| 1951 | } | ||
| 1957 | 1952 | ||
| 1958 | XPROCESS (process)->pid = -2; | 1953 | XPROCESS (process)->pid = -2; |
| 1959 | #ifdef HAVE_PTYS | ||
| 1960 | if (pty_flag) | ||
| 1961 | pset_tty_name (XPROCESS (process), build_string (pty_name)); | ||
| 1962 | else | ||
| 1963 | #endif | ||
| 1964 | pset_tty_name (XPROCESS (process), Qnil); | ||
| 1965 | } | 1954 | } |
| 1966 | 1955 | ||
| 1967 | 1956 | ||
| @@ -2589,7 +2578,7 @@ usage: (make-serial-process &rest ARGS) */) | |||
| 2589 | p->kill_without_query = 1; | 2578 | p->kill_without_query = 1; |
| 2590 | if (tem = Fplist_get (contact, QCstop), !NILP (tem)) | 2579 | if (tem = Fplist_get (contact, QCstop), !NILP (tem)) |
| 2591 | pset_command (p, Qt); | 2580 | pset_command (p, Qt); |
| 2592 | p->pty_flag = 0; | 2581 | eassert (! p->pty_flag); |
| 2593 | 2582 | ||
| 2594 | if (!EQ (p->command, Qt)) | 2583 | if (!EQ (p->command, Qt)) |
| 2595 | { | 2584 | { |