(/home/sate/Testcases/c/cve/dovecot-1.2.0/src/plugins/acl/acl-backend-vfile-acllist.c) |
| |
| 41 | | | static int acl_backend_vfile_acllist_read(struct acl_backend_vfile *backend) |
| 42 | | | { |
| 43 | | | struct acl_backend_vfile_acllist acllist; |
| 44 | | | struct istream *input; |
| 45 | | | struct stat st; |
| 46 | | | const char *rootdir, *path, *line, *p; |
| 47 | | | int fd, ret = 0; |
| 48 | | | |
| 49 | | | backend->acllist_last_check = ioloop_time; |
| 50 | | | |
| 51 | | | rootdir = mailbox_list_get_path(backend->backend.list, NULL, |
| 52 | [+] | | MAILBOX_LIST_PATH_TYPE_DIR); |
 |
| 53 | | | if (rootdir == NULL) { |
Event 1:
Skipping " if". rootdir == (void *)0 evaluates to false.
hide
|
|
| 54 | | | |
| 55 | | | i_array_init(&backend->acllist, 1);
x /home/sate/Testcases/c/cve/dovecot-1.2.0/src/lib/array.h |
| |
37 | #define i_array_init(array, init_count) \ |
38 | p_array_init(array, default_pool, init_count) |
| |
x /home/sate/Testcases/c/cve/dovecot-1.2.0/src/lib/array.h |
| |
35 | #define p_array_init(array, pool, init_count) \ |
36 | array_create(array, pool, sizeof(**(array)->v), init_count) |
| |
x /home/sate/Testcases/c/cve/dovecot-1.2.0/src/lib/array.h |
| |
75 | #define array_create(array, pool, element_size, init_count) \ |
76 | array_create_i(&(array)->arr, pool, element_size, init_count) |
| |
|
| 56 | | | return 0; |
| 57 | | | } |
| 58 | [+] | | path = t_strdup_printf("%s/"ACLLIST_FILENAME, rootdir); |
 |
| 59 | | | |
| 60 | | | if (backend->acllist_mtime != 0) { |
Event 33:
Taking true branch. backend->acllist_mtime != 0 evaluates to true.
hide
|
|
| 61 | | | |
| 62 | | | if (stat(path, &st) < 0) { |
Event 34:
path, which evaluates to the value assigned to ret at data-stack.c:335, is passed to stat64() as the first argument. See related event 32.
hide
Event 35:
stat64() accesses the file named path, where path is the value assigned to ret at data-stack.c:335. - The same name is used to access a file later, but it is not safe to assume that it will be the same underlying file.
See related event 34.
hide
Event 36:
Skipping " if". stat(path, &st) < 0 evaluates to false.
hide
|
|
| 63 | | | if (errno == ENOENT)
x /usr/include/asm-generic/errno-base.h |
| |
5 | #define ENOENT 2 /* No such file or directory */ |
| |
|
| 64 | | | backend->acllist_mtime = 0; |
| 65 | | | else |
| 66 | | | i_error("stat(%s) failed: %m", path); |
| 67 | | | return -1; |
| 68 | | | } |
| 69 | | | if (st.st_mtime == backend->acllist_mtime)
x /usr/include/bits/stat.h |
| |
95 | # define st_mtime st_mtim.tv_sec |
| |
|
Event 37:
Skipping " if". st.st_mtim.tv_sec == backend->acllist_mtime evaluates to false.
hide
|
|
| 70 | | | return 0; |
| 71 | | | } |
| 72 | | | |
| 73 | | | fd = open(path, O_RDONLY); |
| 74 | | | if (fd == -1) { |
Event 39:
Skipping " if". fd == -1 evaluates to false.
hide
|
|
| 75 | | | if (errno == ENOENT) {
x /usr/include/asm-generic/errno-base.h |
| |
5 | #define ENOENT 2 /* No such file or directory */ |
| |
|
| 76 | | | backend->acllist_mtime = 0; |
| 77 | | | return -1; |
| 78 | | | } |
| 79 | | | i_error("open(%s) failed: %m", path); |
| 80 | | | return -1; |
| 81 | | | } |
| 82 | | | if (fstat(fd, &st) < 0) { |
Event 40:
Skipping " if". fstat(fd, &st) < 0 evaluates to false.
hide
|
|
| 83 | | | i_error("fstat(%s) failed: %m", path); |
| 84 | | | (void)close(fd); |
| 85 | | | return -1; |
| 86 | | | } |
| 87 | | | backend->acllist_mtime = st.st_mtime;
x /usr/include/bits/stat.h |
| |
95 | # define st_mtime st_mtim.tv_sec |
| |
|
| 88 | | | acllist_clear(backend, st.st_size); |
| 89 | | | |
| 90 | | | input = i_stream_create_fd(fd, (size_t)-1, FALSE); |
| 91 | [+] | | while ((line = i_stream_read_next_line(input)) != NULL) { |
 |
| 92 | | | acllist.mtime = 0; |
| 93 | | | for (p = line; *p >= '0' && *p <= '9'; p++) |
| 94 | | | acllist.mtime = acllist.mtime * 10 + (*p - '0'); |
| 95 | | | |
| 96 | | | if (p == line || *p != ' ' || p[1] == '\0') { |
| 97 | | | i_error("Broken acllist file: %s", path); |
| 98 | | | if (unlink(path) < 0 && errno != ENOENT)
x /usr/include/asm-generic/errno-base.h |
| |
5 | #define ENOENT 2 /* No such file or directory */ |
| |
|
Event 56:
path, which evaluates to the value assigned to ret at data-stack.c:335, is passed to unlink(). See related event 32.
hide
File System Race Condition
The file named path is accessed again. Another process may have changed the file since the access at acl-backend-vfile-acllist.c:62. For example, an attacker could replace the original file with a link to a file containing important or confidential data. The issue can occur if the highlighted code executes. See related events 35 and 56. Show: All events | Only primary events |
|
| 99 | | | i_error("unlink(%s) failed: %m", path); |
| 100 | | | return -1; |
| 101 | | | } |
| 102 | | | acllist.name = p_strdup(backend->acllist_pool, p + 1); |
| 103 | | | array_append(&backend->acllist, &acllist, 1);
x /home/sate/Testcases/c/cve/dovecot-1.2.0/src/lib/array.h |
| |
116 | #define array_append(array, data, count) \ |
117 | array_append_i(&(array)->arr + ARRAY_TYPE_CHECK(array, data), \ |
118 | data, count) |
| |
x /home/sate/Testcases/c/cve/dovecot-1.2.0/src/lib/array.h |
| |
47 | # define ARRAY_TYPE_CHECK(array, data) \ |
48 | COMPILE_ERROR_IF_TYPES_NOT_COMPATIBLE( \ |
49 | **(array)->v_modifiable, *data) |
| |
x /home/sate/Testcases/c/cve/dovecot-1.2.0/src/lib/macros.h |
| |
158 | # define COMPILE_ERROR_IF_TYPES_NOT_COMPATIBLE(_a, _b) \ |
159 | COMPILE_ERROR_IF_TRUE( \ |
160 | !__builtin_types_compatible_p(typeof(_a), typeof(_b))) |
| |
x /home/sate/Testcases/c/cve/dovecot-1.2.0/src/lib/macros.h |
| |
156 | # define COMPILE_ERROR_IF_TRUE(condition) \ |
157 | (sizeof(char[1 - 2 * !!(condition)]) - 1) |
| |
|
| |