aboutsummaryrefslogtreecommitdiffstats
path: root/src/process.c
diff options
context:
space:
mode:
authorPhilipp Stephani2020-12-30 23:43:07 +0100
committerPhilipp Stephani2020-12-31 00:18:02 +0100
commit8bc85d46cc9214a531f2d2ecb3f5fb48af8105a6 (patch)
tree346a7c64ac0b6a78eacdeb69b73a446d33d87266 /src/process.c
parentf43f1e32e92ef341077b4ffdfdd743b1a6d9d284 (diff)
downloademacs-8bc85d46cc9214a531f2d2ecb3f5fb48af8105a6.tar.gz
emacs-8bc85d46cc9214a531f2d2ecb3f5fb48af8105a6.zip
Manually limit file descriptors that we select on to FD_SETSIZE.
This works even if another thread or process resets the resource limit for open file descriptors, e.g., using 'prlimit' on GNU/Linux. * src/process.c (create_process, create_pty, Fmake_pipe_process) (Fmake_serial_process, connect_network_socket) (server_accept_connection): Limit file descriptors to FD_SETSIZE. * test/src/process-tests.el (process-tests--with-raised-rlimit): New helper macro. (process-tests--fd-setsize-test): Rename from 'process-tests--with-many-pipes'. Increase resource limit during test if possible. (process-tests/fd-setsize-no-crash/make-process) (process-tests/fd-setsize-no-crash/make-pipe-process) (process-tests/fd-setsize-no-crash/make-network-process) (process-tests--new-pty): Rename callers.
Diffstat (limited to 'src/process.c')
-rw-r--r--src/process.c25
1 files changed, 25 insertions, 0 deletions
diff --git a/src/process.c b/src/process.c
index 7c56366d8e1..ba2bb3c9e46 100644
--- a/src/process.c
+++ b/src/process.c
@@ -2114,6 +2114,9 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
2114 } 2114 }
2115 } 2115 }
2116 2116
2117 if (FD_SETSIZE <= inchannel || FD_SETSIZE <= outchannel)
2118 report_file_errno ("Creating pipe", Qnil, EMFILE);
2119
2117#ifndef WINDOWSNT 2120#ifndef WINDOWSNT
2118 if (emacs_pipe (p->open_fd + READ_FROM_EXEC_MONITOR) != 0) 2121 if (emacs_pipe (p->open_fd + READ_FROM_EXEC_MONITOR) != 0)
2119 report_file_error ("Creating pipe", Qnil); 2122 report_file_error ("Creating pipe", Qnil);
@@ -2210,6 +2213,8 @@ create_pty (Lisp_Object process)
2210 if (pty_fd >= 0) 2213 if (pty_fd >= 0)
2211 { 2214 {
2212 p->open_fd[SUBPROCESS_STDIN] = pty_fd; 2215 p->open_fd[SUBPROCESS_STDIN] = pty_fd;
2216 if (FD_SETSIZE <= pty_fd)
2217 report_file_errno ("Opening pty", Qnil, EMFILE);
2213#if ! defined (USG) || defined (USG_SUBTTY_WORKS) 2218#if ! defined (USG) || defined (USG_SUBTTY_WORKS)
2214 /* On most USG systems it does not work to open the pty's tty here, 2219 /* On most USG systems it does not work to open the pty's tty here,
2215 then close it and reopen it in the child. */ 2220 then close it and reopen it in the child. */
@@ -2317,6 +2322,9 @@ usage: (make-pipe-process &rest ARGS) */)
2317 outchannel = p->open_fd[WRITE_TO_SUBPROCESS]; 2322 outchannel = p->open_fd[WRITE_TO_SUBPROCESS];
2318 inchannel = p->open_fd[READ_FROM_SUBPROCESS]; 2323 inchannel = p->open_fd[READ_FROM_SUBPROCESS];
2319 2324
2325 if (FD_SETSIZE <= inchannel || FD_SETSIZE <= outchannel)
2326 report_file_errno ("Creating pipe", Qnil, EMFILE);
2327
2320 fcntl (inchannel, F_SETFL, O_NONBLOCK); 2328 fcntl (inchannel, F_SETFL, O_NONBLOCK);
2321 fcntl (outchannel, F_SETFL, O_NONBLOCK); 2329 fcntl (outchannel, F_SETFL, O_NONBLOCK);
2322 2330
@@ -3059,6 +3067,8 @@ usage: (make-serial-process &rest ARGS) */)
3059 3067
3060 fd = serial_open (port); 3068 fd = serial_open (port);
3061 p->open_fd[SUBPROCESS_STDIN] = fd; 3069 p->open_fd[SUBPROCESS_STDIN] = fd;
3070 if (FD_SETSIZE <= fd)
3071 report_file_errno ("Opening serial port", Qnil, EMFILE);
3062 p->infd = fd; 3072 p->infd = fd;
3063 p->outfd = fd; 3073 p->outfd = fd;
3064 if (fd > max_desc) 3074 if (fd > max_desc)
@@ -3280,6 +3290,7 @@ connect_network_socket (Lisp_Object proc, Lisp_Object addrinfos,
3280 if (!NILP (use_external_socket_p)) 3290 if (!NILP (use_external_socket_p))
3281 { 3291 {
3282 socket_to_use = external_sock_fd; 3292 socket_to_use = external_sock_fd;
3293 eassert (socket_to_use < FD_SETSIZE);
3283 3294
3284 /* Ensure we don't consume the external socket twice. */ 3295 /* Ensure we don't consume the external socket twice. */
3285 external_sock_fd = -1; 3296 external_sock_fd = -1;
@@ -3321,6 +3332,13 @@ connect_network_socket (Lisp_Object proc, Lisp_Object addrinfos,
3321 xerrno = errno; 3332 xerrno = errno;
3322 continue; 3333 continue;
3323 } 3334 }
3335 if (FD_SETSIZE <= s)
3336 {
3337 emacs_close (s);
3338 s = -1;
3339 xerrno = EMFILE;
3340 continue;
3341 }
3324 } 3342 }
3325 3343
3326 if (p->is_non_blocking_client && ! (SOCK_NONBLOCK && socket_to_use < 0)) 3344 if (p->is_non_blocking_client && ! (SOCK_NONBLOCK && socket_to_use < 0))
@@ -4782,6 +4800,13 @@ server_accept_connection (Lisp_Object server, int channel)
4782 4800
4783 s = accept4 (channel, &saddr.sa, &len, SOCK_CLOEXEC); 4801 s = accept4 (channel, &saddr.sa, &len, SOCK_CLOEXEC);
4784 4802
4803 if (FD_SETSIZE <= s)
4804 {
4805 emacs_close (s);
4806 s = -1;
4807 errno = EMFILE;
4808 }
4809
4785 if (s < 0) 4810 if (s < 0)
4786 { 4811 {
4787 int code = errno; 4812 int code = errno;