| File src/ipc.c changed (mode: 100644) (index 5d65686c5..f10251fee) |
| 40 |
40 |
# endif |
# endif |
| 41 |
41 |
#endif |
#endif |
| 42 |
42 |
|
|
| 43 |
|
#include <sys/stat.h> /* mkfifo() stat() */ |
|
|
43 |
|
#include <sys/stat.h> /* fstat() mkfifo() stat() */ |
| 44 |
44 |
#include <dirent.h> /* DIR closedir() opendir() readdir() */ |
#include <dirent.h> /* DIR closedir() opendir() readdir() */ |
| 45 |
45 |
#include <fcntl.h> |
#include <fcntl.h> |
| 46 |
|
#include <unistd.h> /* close() open() select() unlink() usleep() */ |
|
|
46 |
|
#include <unistd.h> /* close() getgid() getuid() open() select() unlink() |
|
47 |
|
usleep() */ |
| 47 |
48 |
|
|
| 48 |
49 |
#include <errno.h> /* EACCES EEXIST EDQUOT ENOSPC ENXIO errno */ |
#include <errno.h> /* EACCES EEXIST EDQUOT ENOSPC ENXIO errno */ |
| 49 |
50 |
#include <stddef.h> /* NULL size_t ssize_t */ |
#include <stddef.h> /* NULL size_t ssize_t */ |
| |
| ... |
... |
static read_pipe_t |
| 394 |
395 |
try_use_pipe(const char path[], int *fatal) |
try_use_pipe(const char path[], int *fatal) |
| 395 |
396 |
{ |
{ |
| 396 |
397 |
#ifndef WIN32_PIPE_READ |
#ifndef WIN32_PIPE_READ |
|
398 |
|
enum { IPC_PIPE_PERMS = 0600 }; |
|
399 |
|
|
| 397 |
400 |
FILE *f; |
FILE *f; |
| 398 |
401 |
int fd; |
int fd; |
| 399 |
402 |
|
|
| 400 |
403 |
*fatal = 0; |
*fatal = 0; |
| 401 |
404 |
|
|
| 402 |
405 |
/* Try to create a pipe. */ |
/* Try to create a pipe. */ |
| 403 |
|
if(mkfifo(path, 0600) == 0) |
|
|
406 |
|
if(mkfifo(path, IPC_PIPE_PERMS) == 0) |
| 404 |
407 |
{ |
{ |
| 405 |
408 |
/* Open if created. */ |
/* Open if created. */ |
| 406 |
409 |
const int fd = open(path, O_RDONLY | O_NONBLOCK); |
const int fd = open(path, O_RDONLY | O_NONBLOCK); |
| |
| ... |
... |
try_use_pipe(const char path[], int *fatal) |
| 429 |
432 |
|
|
| 430 |
433 |
/* Use this file if we're the only one willing to read from it. */ |
/* Use this file if we're the only one willing to read from it. */ |
| 431 |
434 |
fd = open(path, O_RDONLY | O_NONBLOCK); |
fd = open(path, O_RDONLY | O_NONBLOCK); |
| 432 |
|
|
|
| 433 |
435 |
if(fd == -1) |
if(fd == -1) |
| 434 |
436 |
{ |
{ |
| 435 |
437 |
return NULL_READ_PIPE; |
return NULL_READ_PIPE; |
| 436 |
438 |
} |
} |
| 437 |
439 |
|
|
|
440 |
|
struct stat statbuf; |
|
441 |
|
if(fstat(fd, &statbuf) != 0 || statbuf.st_uid != getuid() || |
|
442 |
|
statbuf.st_gid != getgid() || !S_ISFIFO(statbuf.st_mode) || |
|
443 |
|
(statbuf.st_mode & 07777) != IPC_PIPE_PERMS) |
|
444 |
|
{ |
|
445 |
|
(void)close(fd); |
|
446 |
|
/* Either can't query file's metadata or its type, ownership or permissions |
|
447 |
|
* are incorrect. Using such a pipe may be unsafe, so skip it. */ |
|
448 |
|
return NULL_READ_PIPE; |
|
449 |
|
} |
|
450 |
|
|
| 438 |
451 |
f = fdopen(fd, "r"); |
f = fdopen(fd, "r"); |
| 439 |
452 |
if(f == NULL_READ_PIPE) |
if(f == NULL_READ_PIPE) |
| 440 |
453 |
{ |
{ |
| File tests/misc/ipc.c changed (mode: 100644) (index 0211cac32..42b3aa618) |
| 1 |
1 |
#include <stic.h> |
#include <stic.h> |
| 2 |
2 |
|
|
|
3 |
|
#include <unistd.h> /* chown() getgid() getuid() */ |
|
4 |
|
|
| 3 |
5 |
#include <stddef.h> /* NULL */ |
#include <stddef.h> /* NULL */ |
| 4 |
6 |
#include <stdlib.h> /* free() malloc() */ |
#include <stdlib.h> /* free() malloc() */ |
| 5 |
7 |
#include <string.h> /* memset() strcmp() strdup() */ |
#include <string.h> /* memset() strcmp() strdup() */ |
| 6 |
8 |
|
|
| 7 |
9 |
#include <test-utils.h> |
#include <test-utils.h> |
| 8 |
10 |
|
|
|
11 |
|
#include "../../src/compat/fs_limits.h" |
|
12 |
|
#include "../../src/utils/env.h" |
| 9 |
13 |
#include "../../src/utils/str.h" |
#include "../../src/utils/str.h" |
| 10 |
14 |
#include "../../src/utils/string_array.h" |
#include "../../src/utils/string_array.h" |
| 11 |
15 |
#include "../../src/background.h" |
#include "../../src/background.h" |
| |
| ... |
... |
static void other_instance(bg_op_t *bg_op, void *arg); |
| 20 |
24 |
static int enabled_and_not_in_wine(void); |
static int enabled_and_not_in_wine(void); |
| 21 |
25 |
static int enabled_and_not_windows(void); |
static int enabled_and_not_windows(void); |
| 22 |
26 |
|
|
| 23 |
|
static const char NAME[] = "vifm-test"; |
|
|
27 |
|
#define NAME "vifm-test" |
|
28 |
|
|
| 24 |
29 |
static int nmessages; |
static int nmessages; |
| 25 |
30 |
static char *message; |
static char *message; |
| 26 |
31 |
static int nmessages2; |
static int nmessages2; |
| |
| ... |
... |
TEST(no_eval_to_self, IF(enabled_and_not_in_wine)) |
| 251 |
256 |
assert_string_equal(NULL, message); |
assert_string_equal(NULL, message); |
| 252 |
257 |
} |
} |
| 253 |
258 |
|
|
|
259 |
|
TEST(pipe_is_reused_safely, IF(enabled_and_not_windows)) |
|
260 |
|
{ |
|
261 |
|
char ipc_dir[PATH_MAX + 1]; |
|
262 |
|
make_abs_path(ipc_dir, sizeof(ipc_dir), SANDBOX_PATH, "", /*cwd=*/NULL); |
|
263 |
|
|
|
264 |
|
/* $TMPDIR because of how get_tmpdir() is implemented. */ |
|
265 |
|
env_set("TMPDIR", ipc_dir); |
|
266 |
|
|
|
267 |
|
ipc_t *ipc; |
|
268 |
|
|
|
269 |
|
/* There are no other pipes. */ |
|
270 |
|
ipc = ipc_init(NAME, &test_ipc_args, &test_ipc_eval); |
|
271 |
|
assert_string_equal(NAME, ipc_get_name(ipc)); |
|
272 |
|
ipc_free(ipc); |
|
273 |
|
|
|
274 |
|
/* The default pipe name is in use by a regular file. */ |
|
275 |
|
create_file(SANDBOX_PATH "/vifm-ipc-" NAME); |
|
276 |
|
ipc = ipc_init(NAME, &test_ipc_args, &test_ipc_eval); |
|
277 |
|
assert_string_equal(NAME "1", ipc_get_name(ipc)); |
|
278 |
|
ipc_free(ipc); |
|
279 |
|
remove_file(SANDBOX_PATH "/vifm-ipc-" NAME); |
|
280 |
|
|
|
281 |
|
/* The default pipe name is in use by a pipe with bad permissions. */ |
|
282 |
|
assert_success(make_fifo(SANDBOX_PATH "/vifm-ipc-" NAME, 0660)); |
|
283 |
|
ipc = ipc_init(NAME, &test_ipc_args, &test_ipc_eval); |
|
284 |
|
assert_string_equal(NAME "1", ipc_get_name(ipc)); |
|
285 |
|
ipc_free(ipc); |
|
286 |
|
remove_file(SANDBOX_PATH "/vifm-ipc-" NAME); |
|
287 |
|
|
|
288 |
|
#ifndef _WIN32 |
|
289 |
|
if(!regular_unix_user()) |
|
290 |
|
{ |
|
291 |
|
/* The default pipe name is in use by a pipe with a bad owner. */ |
|
292 |
|
assert_success(make_fifo(SANDBOX_PATH "/vifm-ipc-" NAME, 0600)); |
|
293 |
|
assert_success(chown(SANDBOX_PATH "/vifm-ipc-" NAME, 1234, getgid())); |
|
294 |
|
ipc = ipc_init(NAME, &test_ipc_args, &test_ipc_eval); |
|
295 |
|
assert_string_equal(NAME "1", ipc_get_name(ipc)); |
|
296 |
|
ipc_free(ipc); |
|
297 |
|
remove_file(SANDBOX_PATH "/vifm-ipc-" NAME); |
|
298 |
|
|
|
299 |
|
/* The default pipe name is in use by a pipe with a bad group. */ |
|
300 |
|
assert_success(make_fifo(SANDBOX_PATH "/vifm-ipc-" NAME, 0600)); |
|
301 |
|
assert_success(chown(SANDBOX_PATH "/vifm-ipc-" NAME, getuid(), 1234)); |
|
302 |
|
ipc = ipc_init(NAME, &test_ipc_args, &test_ipc_eval); |
|
303 |
|
assert_string_equal(NAME "1", ipc_get_name(ipc)); |
|
304 |
|
ipc_free(ipc); |
|
305 |
|
remove_file(SANDBOX_PATH "/vifm-ipc-" NAME); |
|
306 |
|
} |
|
307 |
|
#endif |
|
308 |
|
|
|
309 |
|
/* The default pipe name is in use by an abandoned pipe. */ |
|
310 |
|
assert_success(make_fifo(SANDBOX_PATH "/vifm-ipc-" NAME, 0600)); |
|
311 |
|
ipc = ipc_init(NAME, &test_ipc_args, &test_ipc_eval); |
|
312 |
|
assert_string_equal(NAME, ipc_get_name(ipc)); |
|
313 |
|
ipc_free(ipc); |
|
314 |
|
no_remove_file(SANDBOX_PATH "/vifm-ipc-" NAME); |
|
315 |
|
|
|
316 |
|
env_remove("TMPDIR"); |
|
317 |
|
} |
|
318 |
|
|
| 254 |
319 |
static void |
static void |
| 255 |
320 |
test_ipc_args(char *args[]) |
test_ipc_args(char *args[]) |
| 256 |
321 |
{ |
{ |