From 561746080b0b7154bfb3bdee20d426cf2ef7db17 Mon Sep 17 00:00:00 2001 From: "Kaleb S. KEITHLEY" Date: Thu, 7 Jul 2016 08:51:08 -0400 Subject: core: use readdir(3) with glibc, and associated cleanup Starting with glibc-2.23 (i.e. what's in Fedora 25), readdir_r(3) is marked as deprecated. Specifically the function decl in has the deprecated attribute, and now warnings are thrown during the compile on Fedora 25 builds. The readdir(_r)(3) man page (on Fedora 25 at least) and World+Dog say that glibc's readdir(3) is, and always has been, MT-SAFE as long as only one thread is accessing the directory object returned by opendir(). World+Dog also says there is a potential buffer overflow in readdir_r(). World+Dog suggests that it is preferable to simply use readdir(). There's an implication that eventually readdir_r(3) will be removed from glibc. POSIX has, apparently deprecated it in the standard, or even removed it entirely. Over and above that, our source near the various uses of readdir(_r)(3) has a few unsafe uses of strcpy()+strcat(). (AFAIK nobody has looked at the readdir(3) implemenation in *BSD to see if the same is true on those platforms, and we can't be sure of MacOS even though we know it's based on *BSD.) Change-Id: I5481f18ba1eebe7ee177895eecc9a80a71b60568 BUG: 1356998 Signed-off-by: Kaleb S. KEITHLEY Reviewed-on: http://review.gluster.org/14838 Smoke: Gluster Build System Reviewed-by: Niels de Vos CentOS-regression: Gluster Build System NetBSD-regression: NetBSD Build System Reviewed-by: Kotresh HR Reviewed-by: Jeff Darcy --- geo-replication/src/procdiggy.c | 9 +- libglusterfs/src/common-utils.c | 5 +- libglusterfs/src/common-utils.h | 6 +- libglusterfs/src/inode.c | 5 +- libglusterfs/src/run.c | 7 +- libglusterfs/src/syscall.c | 19 +- libglusterfs/src/syscall.h | 2 +- tools/gfind_missing_files/gcrawler.c | 41 ++-- xlators/experimental/jbr-server/src/jbr.c | 53 +++-- .../bit-rot/src/stub/bit-rot-stub-helpers.c | 26 +-- .../features/changelog/lib/src/gf-changelog-api.c | 42 ++-- .../changelog/lib/src/gf-history-changelog.c | 59 ++--- .../features/changelog/src/changelog-mem-types.h | 11 +- xlators/features/index/src/index.c | 129 ++++++----- xlators/mgmt/glusterd/src/glusterd-hooks.c | 19 +- xlators/mgmt/glusterd/src/glusterd-quota.c | 11 +- .../mgmt/glusterd/src/glusterd-snapshot-utils.c | 30 ++- xlators/mgmt/glusterd/src/glusterd-store.c | 41 ++-- xlators/mgmt/glusterd/src/glusterd-volgen.c | 66 +++--- xlators/storage/posix/src/posix.c | 244 ++++++++++----------- 20 files changed, 432 insertions(+), 393 deletions(-) diff --git a/geo-replication/src/procdiggy.c b/geo-replication/src/procdiggy.c index 1ea52c1a6a1..35125d20ba8 100644 --- a/geo-replication/src/procdiggy.c +++ b/geo-replication/src/procdiggy.c @@ -86,6 +86,7 @@ prociter (int (*proch) (pid_t pid, pid_t ppid, char *tmpname, void *data), char *name = NULL; DIR *d = NULL; struct dirent *de = NULL; + struct dirent scratch[2] = {{0,},}; pid_t pid = -1; pid_t ppid = -1; int ret = 0; @@ -93,7 +94,13 @@ prociter (int (*proch) (pid_t pid, pid_t ppid, char *tmpname, void *data), d = sys_opendir (PROC); if (!d) return -1; - while (errno = 0, de = sys_readdir (d)) { + + for (;;) { + errno = 0; + de = sys_readdir (d, scratch); + if (!de || errno != 0) + break; + if (gf_string2int (de->d_name, &pid) != -1 && pid >= 0) { ppid = pidinfo (pid, &name); switch (ppid) { diff --git a/libglusterfs/src/common-utils.c b/libglusterfs/src/common-utils.c index b2d5a279dc8..3529ad7f897 100644 --- a/libglusterfs/src/common-utils.c +++ b/libglusterfs/src/common-utils.c @@ -4084,6 +4084,7 @@ recursive_rmdir (const char *delete_path) struct stat st = {0,}; DIR *dir = NULL; struct dirent *entry = NULL; + struct dirent scratch[2] = {{0,},}; xlator_t *this = NULL; this = THIS; @@ -4098,7 +4099,7 @@ recursive_rmdir (const char *delete_path) goto out; } - GF_FOR_EACH_ENTRY_IN_DIR (entry, dir); + GF_FOR_EACH_ENTRY_IN_DIR (entry, dir, scratch); while (entry) { snprintf (path, PATH_MAX, "%s/%s", delete_path, entry->d_name); ret = sys_lstat (path, &st); @@ -4121,7 +4122,7 @@ recursive_rmdir (const char *delete_path) gf_msg_debug (this->name, 0, "%s %s", ret ? "Failed to remove" : "Removed", entry->d_name); - GF_FOR_EACH_ENTRY_IN_DIR (entry, dir); + GF_FOR_EACH_ENTRY_IN_DIR (entry, dir, scratch); } ret = sys_closedir (dir); diff --git a/libglusterfs/src/common-utils.h b/libglusterfs/src/common-utils.h index d7277e6e834..aacf2c5a32c 100644 --- a/libglusterfs/src/common-utils.h +++ b/libglusterfs/src/common-utils.h @@ -396,15 +396,15 @@ union gf_sock_union { #define IOV_MIN(n) min(IOV_MAX,n) -#define GF_FOR_EACH_ENTRY_IN_DIR(entry, dir) \ +#define GF_FOR_EACH_ENTRY_IN_DIR(entry, dir, scr) \ do {\ entry = NULL;\ if (dir) { \ - entry = sys_readdir (dir); \ + entry = sys_readdir (dir, scr); \ while (entry && (!strcmp (entry->d_name, ".") || \ !fnmatch ("*.tmp", entry->d_name, 0) || \ !strcmp (entry->d_name, ".."))) { \ - entry = sys_readdir (dir); \ + entry = sys_readdir (dir, scr); \ } \ } \ } while (0) diff --git a/libglusterfs/src/inode.c b/libglusterfs/src/inode.c index 6d79ac2d3f9..6e1234e9ce2 100644 --- a/libglusterfs/src/inode.c +++ b/libglusterfs/src/inode.c @@ -852,10 +852,7 @@ inode_grep_for_gfid (inode_table_t *table, inode_t *parent, const char *name, gf_boolean_t __is_root_gfid (uuid_t gfid) { - uuid_t root; - - memset (root, 0, 16); - root[15] = 1; + static uuid_t root = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}; if (gf_uuid_compare (gfid, root) == 0) return _gf_true; diff --git a/libglusterfs/src/run.c b/libglusterfs/src/run.c index c625a5b99de..ff587f7e4de 100644 --- a/libglusterfs/src/run.c +++ b/libglusterfs/src/run.c @@ -277,11 +277,16 @@ runner_start (runner_t *runner) #ifdef GF_LINUX_HOST_OS DIR *d = NULL; struct dirent *de = NULL; + struct dirent scratch[2] = {{0,},}; char *e = NULL; d = sys_opendir ("/proc/self/fd"); if (d) { - while ((de = sys_readdir (d))) { + for (;;) { + errno = 0; + de = sys_readdir (d, scratch); + if (!de || errno != 0) + break; i = strtoul (de->d_name, &e, 10); if (*e == '\0' && i > 2 && i != dirfd (d) && i != xpi[1]) diff --git a/libglusterfs/src/syscall.c b/libglusterfs/src/syscall.c index 316d80452fb..93838e285a4 100644 --- a/libglusterfs/src/syscall.c +++ b/libglusterfs/src/syscall.c @@ -94,9 +94,26 @@ int sys_mkdirat(int dirfd, const char *pathname, mode_t mode) } struct dirent * -sys_readdir (DIR *dir) +sys_readdir (DIR *dir, struct dirent *de) { +#if !defined(__GLIBC__) + /* + * World+Dog says glibc's readdir(3) is MT-SAFE as long as + * two threads are not accessing the same DIR; there's a + * potential buffer overflow in glibc's readdir_r(3); and + * glibc's readdir_r(3) is deprecated after version 2.22 + * with presumed eventual removal. + * Given all that, World+Dog says everyone should just use + * readdir(3). But it's unknown, unclear whether the same + * is also true for *BSD, MacOS, and, etc. + */ + struct dirent *entry = NULL; + + (void) readdir_r (dir, de, &entry); + return entry; +#else return readdir (dir); +#endif } diff --git a/libglusterfs/src/syscall.h b/libglusterfs/src/syscall.h index b549f6a1b3c..6fee9bd5c5c 100644 --- a/libglusterfs/src/syscall.h +++ b/libglusterfs/src/syscall.h @@ -69,7 +69,7 @@ sys_openat (int dirfd, const char *pathname, int flags, ...); DIR *sys_opendir (const char *name); struct dirent * -sys_readdir (DIR *dir); +sys_readdir (DIR *dir, struct dirent *de); ssize_t sys_readlink (const char *path, char *buf, size_t bufsiz); diff --git a/tools/gfind_missing_files/gcrawler.c b/tools/gfind_missing_files/gcrawler.c index 35772b51582..02b644a1a77 100644 --- a/tools/gfind_missing_files/gcrawler.c +++ b/tools/gfind_missing_files/gcrawler.c @@ -306,12 +306,12 @@ xworker_do_crawl (struct xwork *xwork, struct dirjob *job) int ret = -1; int boff; int plen; - struct dirent *result; - char dbuf[512]; char *path = NULL; struct dirjob *cjob = NULL; struct stat statbuf = {0,}; - char gfid_path[4096] = {0,}; + struct dirent *entry; + struct dirent scratch[2] = {{0,},}; + char gfid_path[PATH_MAX] = {0,}; plen = strlen (job->dirname) + 256 + 2; @@ -329,27 +329,29 @@ xworker_do_crawl (struct xwork *xwork, struct dirjob *job) boff = sprintf (path, "%s/", job->dirname); for (;;) { - ret = readdir_r (dirp, (struct dirent *)dbuf, &result); - if (ret) { - err ("readdir_r(%s): %s\n", job->dirname, - strerror (errno)); - goto out; - } - - if (!result) /* EOF */ + errno = 0; + entry = sys_readdir (dirp, scratch); + if (!entry || errno != 0) { + if (errno != 0) { + err ("readdir(%s): %s\n", job->dirname, + strerror (errno)); + ret = errno; + goto out; + } break; + } - if (result->d_ino == 0) + if (entry->d_ino == 0) continue; - if (skip_name (job->dirname, result->d_name)) + if (skip_name (job->dirname, entry->d_name)) continue; /* It is sure that, children and grandchildren of .glusterfs * are directories, just add them to global queue. */ - if (skip_stat (job, result->d_name)) { - strncpy (path + boff, result->d_name, (plen-boff)); + if (skip_stat (job, entry->d_name)) { + strncpy (path + boff, entry->d_name, (plen-boff)); cjob = dirjob_new (path, job); if (!cjob) { err ("dirjob_new(%s): %s\n", @@ -361,13 +363,12 @@ xworker_do_crawl (struct xwork *xwork, struct dirjob *job) continue; } - strcpy (gfid_path, slavemnt); - strcat (gfid_path, "/.gfid/"); - strcat (gfid_path, result->d_name); + (void) snprintf (gfid_path, sizeof(gfid_path), "%s/.gfid/%s", + slavemnt, entry->d_name); ret = sys_lstat (gfid_path, &statbuf); if (ret && errno == ENOENT) { - out ("%s\n", result->d_name); + out ("%s\n", entry->d_name); BUMP (skipped_gfids); } @@ -381,7 +382,7 @@ xworker_do_crawl (struct xwork *xwork, struct dirjob *job) ret = 0; out: if (dirp) - sys_closedir (dirp); + (void) sys_closedir (dirp); return ret; } diff --git a/xlators/experimental/jbr-server/src/jbr.c b/xlators/experimental/jbr-server/src/jbr.c index e07c511f4a9..68badb85079 100644 --- a/xlators/experimental/jbr-server/src/jbr.c +++ b/xlators/experimental/jbr-server/src/jbr.c @@ -989,17 +989,17 @@ jbr_get_changelog_dir (xlator_t *this, char **cl_dir_p) void jbr_get_terms (call_frame_t *frame, xlator_t *this) { - int32_t op_errno; - char *cl_dir; - DIR *fp = NULL; - struct dirent *rd_entry; - struct dirent *rd_result; - int32_t term_first = -1; - int32_t term_contig = -1; - int32_t term_last = -1; - int term_num; - char *probe_str; - dict_t *my_xdata = NULL; + int32_t op_errno = 0; + char *cl_dir = NULL; + int32_t term_first = -1; + int32_t term_contig = -1; + int32_t term_last = -1; + int term_num = 0; + char *probe_str = NULL; + dict_t *my_xdata = NULL; + DIR *fp = NULL; + struct dirent *entry = NULL; + struct dirent scratch[2] = {{0,},}; op_errno = jbr_get_changelog_dir(this, &cl_dir); if (op_errno) { @@ -1007,12 +1007,6 @@ jbr_get_terms (call_frame_t *frame, xlator_t *this) } op_errno = ENODATA; /* Most common error after this. */ - rd_entry = alloca (offsetof(struct dirent, d_name) + - pathconf(cl_dir, _PC_NAME_MAX) + 1); - if (!rd_entry) { - goto err; - } - fp = sys_opendir (cl_dir); if (!fp) { op_errno = errno; @@ -1021,25 +1015,28 @@ jbr_get_terms (call_frame_t *frame, xlator_t *this) /* Find first and last terms. */ for (;;) { - if (readdir_r(fp, rd_entry, &rd_result) != 0) { - op_errno = errno; - goto err; - } - if (!rd_result) { + errno = 0; + entry = sys_readdir (fp, scratch); + if (!entry || errno != 0) { + if (errno != 0) { + op_errno = errno; + goto err; + } break; } - if (fnmatch("TERM.*", rd_entry->d_name, FNM_PATHNAME) != 0) { + + if (fnmatch("TERM.*", entry->d_name, FNM_PATHNAME) != 0) { continue; } /* +5 points to the character after the period */ - term_num = atoi(rd_entry->d_name+5); + term_num = atoi(entry->d_name+5); gf_msg (this->name, GF_LOG_INFO, 0, J_MSG_GENERIC, - "%s => %d", rd_entry->d_name, term_num); + "%s => %d", entry->d_name, term_num); if (term_num < 0) { gf_msg (this->name, GF_LOG_ERROR, 0, J_MSG_INVALID, - "invalid term file name %s", rd_entry->d_name); + "invalid term file name %s", entry->d_name); op_errno = EINVAL; goto err; } @@ -1058,7 +1055,7 @@ jbr_get_terms (call_frame_t *frame, xlator_t *this) goto err; } - sys_closedir (fp); + (void) sys_closedir (fp); fp = NULL; /* @@ -1119,7 +1116,7 @@ jbr_get_terms (call_frame_t *frame, xlator_t *this) err: if (fp) { - sys_closedir (fp); + (void) sys_closedir (fp); } if (my_xdata) { dict_unref(my_xdata); diff --git a/xlators/features/bit-rot/src/stub/bit-rot-stub-helpers.c b/xlators/features/bit-rot/src/stub/bit-rot-stub-helpers.c index 7bd270d1513..09f556db10b 100644 --- a/xlators/features/bit-rot/src/stub/bit-rot-stub-helpers.c +++ b/xlators/features/bit-rot/src/stub/bit-rot-stub-helpers.c @@ -465,15 +465,15 @@ static int br_stub_fill_readdir (fd_t *fd, br_stub_fd_t *fctx, DIR *dir, off_t off, size_t size, gf_dirent_t *entries) { - off_t in_case = -1; - off_t last_off = 0; - size_t filled = 0; - int count = 0; - char entrybuf[sizeof(struct dirent) + 256 + 8]; - struct dirent *entry = NULL; - int32_t this_size = -1; - gf_dirent_t *this_entry = NULL; - xlator_t *this = NULL; + off_t in_case = -1; + off_t last_off = 0; + size_t filled = 0; + int count = 0; + int32_t this_size = -1; + gf_dirent_t *this_entry = NULL; + xlator_t *this = NULL; + struct dirent *entry = NULL; + struct dirent scratch[2] = {{0,},}; this = THIS; if (!off) { @@ -507,10 +507,8 @@ br_stub_fill_readdir (fd_t *fd, br_stub_fd_t *fctx, DIR *dir, off_t off, } errno = 0; - entry = NULL; - readdir_r (dir, (struct dirent *)entrybuf, &entry); - - if (!entry) { + entry = sys_readdir (dir, scratch); + if (!entry || errno != 0) { if (errno == EBADF) { gf_msg (THIS->name, GF_LOG_WARNING, 0, BRS_MSG_BAD_OBJECT_DIR_READ_FAIL, @@ -579,7 +577,7 @@ br_stub_fill_readdir (fd_t *fd, br_stub_fd_t *fctx, DIR *dir, off_t off, count++; } - if ((!sys_readdir (dir) && (errno == 0))) { + if ((!sys_readdir (dir, scratch) && (errno == 0))) { /* Indicate EOF */ errno = ENOENT; /* Remember EOF offset for later detection */ diff --git a/xlators/features/changelog/lib/src/gf-changelog-api.c b/xlators/features/changelog/lib/src/gf-changelog-api.c index f41b505a749..d2a28bc6d52 100644 --- a/xlators/features/changelog/lib/src/gf-changelog-api.c +++ b/xlators/features/changelog/lib/src/gf-changelog-api.c @@ -152,16 +152,16 @@ out: ssize_t gf_changelog_scan () { - int ret = 0; - int tracker_fd = 0; - size_t len = 0; - size_t off = 0; - xlator_t *this = NULL; - size_t nr_entries = 0; + int ret = 0; + int tracker_fd = 0; + size_t len = 0; + size_t off = 0; + xlator_t *this = NULL; + size_t nr_entries = 0; gf_changelog_journal_t *jnl = NULL; - struct dirent *entryp = NULL; - struct dirent *result = NULL; - char buffer[PATH_MAX] = {0,}; + struct dirent *entry = NULL; + struct dirent scratch[2] = {{0,},}; + char buffer[PATH_MAX] = {0,}; this = THIS; if (!this) @@ -183,19 +183,17 @@ gf_changelog_scan () len = offsetof(struct dirent, d_name) + pathconf(jnl->jnl_processing_dir, _PC_NAME_MAX) + 1; - entryp = GF_CALLOC (1, len, - gf_changelog_mt_libgfchangelog_dirent_t); - if (!entryp) - goto out; rewinddir (jnl->jnl_dir); - while (1) { - ret = readdir_r (jnl->jnl_dir, entryp, &result); - if (ret || !result) + + for (;;) { + errno = 0; + entry = sys_readdir (jnl->jnl_dir, scratch); + if (!entry || errno != 0) break; - if (!strcmp (basename (entryp->d_name), ".") - || !strcmp (basename (entryp->d_name), "..")) + if (!strcmp (basename (entry->d_name), ".") + || !strcmp (basename (entry->d_name), "..")) continue; nr_entries++; @@ -203,8 +201,8 @@ gf_changelog_scan () GF_CHANGELOG_FILL_BUFFER (jnl->jnl_processing_dir, buffer, off, strlen (jnl->jnl_processing_dir)); - GF_CHANGELOG_FILL_BUFFER (entryp->d_name, buffer, - off, strlen (entryp->d_name)); + GF_CHANGELOG_FILL_BUFFER (entry->d_name, buffer, + off, strlen (entry->d_name)); GF_CHANGELOG_FILL_BUFFER ("\n", buffer, off, 1); if (gf_changelog_write (tracker_fd, buffer, off) != off) { @@ -217,9 +215,7 @@ gf_changelog_scan () off = 0; } - GF_FREE (entryp); - - if (!result) { + if (!entry) { if (gf_lseek (tracker_fd, 0, SEEK_SET) != -1) return nr_entries; } diff --git a/xlators/features/changelog/lib/src/gf-history-changelog.c b/xlators/features/changelog/lib/src/gf-history-changelog.c index 389b65f3b16..5ed50390a7c 100644 --- a/xlators/features/changelog/lib/src/gf-history-changelog.c +++ b/xlators/features/changelog/lib/src/gf-history-changelog.c @@ -222,8 +222,8 @@ gf_history_changelog_scan () size_t nr_entries = 0; gf_changelog_journal_t *jnl = NULL; gf_changelog_journal_t *hist_jnl = NULL; - struct dirent *entryp = NULL; - struct dirent *result = NULL; + struct dirent *entry = NULL; + struct dirent scratch[2] = {{0,},}; char buffer[PATH_MAX] = {0,}; static int is_last_scan; @@ -260,19 +260,17 @@ gf_history_changelog_scan () len = offsetof (struct dirent, d_name) + pathconf (hist_jnl->jnl_processing_dir, _PC_NAME_MAX) + 1; - entryp = GF_CALLOC (1, len, - gf_changelog_mt_libgfchangelog_dirent_t); - if (!entryp) - goto out; rewinddir (hist_jnl->jnl_dir); - while (1) { - ret = readdir_r (hist_jnl->jnl_dir, entryp, &result); - if (ret || !result) + + for (;;) { + errno = 0; + entry = sys_readdir (hist_jnl->jnl_dir, scratch); + if (!entry || errno != 0) break; - if ( !strcmp (basename (entryp->d_name), ".") - || !strcmp (basename (entryp->d_name), "..") ) + if (strcmp (basename (entry->d_name), ".") == 0 || + strcmp (basename (entry->d_name), "..") == 0) continue; nr_entries++; @@ -280,8 +278,8 @@ gf_history_changelog_scan () GF_CHANGELOG_FILL_BUFFER (hist_jnl->jnl_processing_dir, buffer, off, strlen (hist_jnl->jnl_processing_dir)); - GF_CHANGELOG_FILL_BUFFER (entryp->d_name, buffer, - off, strlen (entryp->d_name)); + GF_CHANGELOG_FILL_BUFFER (entry->d_name, buffer, + off, strlen (entry->d_name)); GF_CHANGELOG_FILL_BUFFER ("\n", buffer, off, 1); if (gf_changelog_write (tracker_fd, buffer, off) != off) { @@ -294,13 +292,11 @@ gf_history_changelog_scan () off = 0; } - GF_FREE (entryp); - gf_msg_debug (this->name, 0, "hist_done %d, is_last_scan: %d", hist_jnl->hist_done, is_last_scan); - if (!result) { + if (!entry) { if (gf_lseek (tracker_fd, 0, SEEK_SET) != -1) { if (nr_entries > 0) return nr_entries; @@ -678,7 +674,7 @@ gf_history_consume (void * data) out: if (fd != -1) - sys_close (fd); + (void) sys_close (fd); GF_FREE (hist_data); return NULL; } @@ -794,12 +790,13 @@ gf_history_changelog (char* changelog_dir, unsigned long start, unsigned long to = 0; unsigned long from = 0; unsigned long total_changelog = 0; - xlator_t *this = NULL; - gf_changelog_journal_t *jnl = NULL; - gf_changelog_journal_t *hist_jnl = NULL; - gf_changelog_history_data_t *hist_data = NULL; - DIR *dirp = NULL; - struct dirent *dp = NULL; + xlator_t *this = NULL; + gf_changelog_journal_t *jnl = NULL; + gf_changelog_journal_t *hist_jnl = NULL; + gf_changelog_history_data_t *hist_data = NULL; + DIR *dirp = NULL; + struct dirent *entry = NULL; + struct dirent scratch[2] = {{0,},}; pthread_t consume_th = 0; char htime_dir[PATH_MAX] = {0,}; char buffer[PATH_MAX] = {0,}; @@ -851,8 +848,16 @@ gf_history_changelog (char* changelog_dir, unsigned long start, goto out; } - while ((dp = sys_readdir (dirp)) != NULL) { - ret = gf_changelog_extract_min_max (dp->d_name, htime_dir, + for (;;) { + + errno = 0; + + entry = sys_readdir (dirp, scratch); + + if (!entry || errno != 0) + break; + + ret = gf_changelog_extract_min_max (entry->d_name, htime_dir, &fd, &total_changelog, &min_ts, &max_ts); if (ret) { @@ -968,11 +973,11 @@ gf_history_changelog (char* changelog_dir, unsigned long start, out: if (dirp != NULL) - sys_closedir (dirp); + (void) sys_closedir (dirp); if (ret < 0) { if (fd != -1) - sys_close (fd); + (void) sys_close (fd); GF_FREE (hist_data); (void) pthread_attr_destroy (&attr); diff --git a/xlators/features/changelog/src/changelog-mem-types.h b/xlators/features/changelog/src/changelog-mem-types.h index 1618f722f6c..33fea31b979 100644 --- a/xlators/features/changelog/src/changelog-mem-types.h +++ b/xlators/features/changelog/src/changelog-mem-types.h @@ -23,12 +23,11 @@ enum gf_changelog_mem_types { gf_changelog_mt_libgfchangelog_t = gf_common_mt_end + 7, gf_changelog_mt_libgfchangelog_entry_t = gf_common_mt_end + 8, gf_changelog_mt_libgfchangelog_rl_t = gf_common_mt_end + 9, - gf_changelog_mt_libgfchangelog_dirent_t = gf_common_mt_end + 10, - gf_changelog_mt_changelog_buffer_t = gf_common_mt_end + 11, - gf_changelog_mt_history_data_t = gf_common_mt_end + 12, - gf_changelog_mt_libgfchangelog_call_pool_t = gf_common_mt_end + 13, - gf_changelog_mt_libgfchangelog_event_t = gf_common_mt_end + 14, - gf_changelog_mt_ev_dispatcher_t = gf_common_mt_end + 15, + gf_changelog_mt_changelog_buffer_t = gf_common_mt_end + 10, + gf_changelog_mt_history_data_t = gf_common_mt_end + 11, + gf_changelog_mt_libgfchangelog_call_pool_t = gf_common_mt_end + 12, + gf_changelog_mt_libgfchangelog_event_t = gf_common_mt_end + 13, + gf_changelog_mt_ev_dispatcher_t = gf_common_mt_end + 14, gf_changelog_mt_end }; diff --git a/xlators/features/index/src/index.c b/xlators/features/index/src/index.c index f25697ebebd..75809e36e4c 100644 --- a/xlators/features/index/src/index.c +++ b/xlators/features/index/src/index.c @@ -437,15 +437,15 @@ static int index_fill_readdir (fd_t *fd, index_fd_ctx_t *fctx, DIR *dir, off_t off, size_t size, gf_dirent_t *entries) { - off_t in_case = -1; - off_t last_off = 0; - size_t filled = 0; - int count = 0; - char entrybuf[sizeof(struct dirent) + 256 + 8]; - struct dirent *entry = NULL; - int32_t this_size = -1; - gf_dirent_t *this_entry = NULL; - xlator_t *this = NULL; + off_t in_case = -1; + off_t last_off = 0; + size_t filled = 0; + int count = 0; + struct dirent *entry = NULL; + struct dirent scratch[2] = {{0,},}; + int32_t this_size = -1; + gf_dirent_t *this_entry = NULL; + xlator_t *this = NULL; this = THIS; if (!off) { @@ -477,10 +477,8 @@ index_fill_readdir (fd_t *fd, index_fd_ctx_t *fctx, DIR *dir, off_t off, } errno = 0; - entry = NULL; - readdir_r (dir, (struct dirent *)entrybuf, &entry); - - if (!entry) { + entry = sys_readdir (dir, scratch); + if (!entry || errno != 0) { if (errno == EBADF) { gf_msg (THIS->name, GF_LOG_WARNING, errno, INDEX_MSG_INDEX_READDIR_FAILED, @@ -550,7 +548,9 @@ index_fill_readdir (fd_t *fd, index_fd_ctx_t *fctx, DIR *dir, off_t off, count ++; } - if ((!sys_readdir (dir) && (errno == 0))) { + errno = 0; + + if ((!sys_readdir (dir, scratch) && (errno == 0))) { /* Indicate EOF */ errno = ENOENT; /* Remember EOF offset for later detection */ @@ -1107,7 +1107,7 @@ __index_fd_ctx_get (fd_t *fd, xlator_t *this, index_fd_ctx_t **ctx) ret = __fd_ctx_set (fd, this, (uint64_t)(long)fctx); if (ret) { - sys_closedir (fctx->dir); + (void) sys_closedir (fctx->dir); GF_FREE (fctx); fctx = NULL; ret = -EINVAL; @@ -1374,12 +1374,12 @@ out: uint64_t index_entry_count (xlator_t *this, char *subdir) { - index_priv_t *priv = NULL; - char index_dir[PATH_MAX]; - DIR *dirp = NULL; - uint64_t count = 0; - struct dirent buf; - struct dirent *entry = NULL; + uint64_t count = 0; + index_priv_t *priv = NULL; + DIR *dirp = NULL; + struct dirent *entry = NULL; + struct dirent scratch[2] = {{0,},}; + char index_dir[PATH_MAX] = {0,}; priv = this->private; @@ -1390,17 +1390,23 @@ index_entry_count (xlator_t *this, char *subdir) if (!dirp) return 0; - while (readdir_r (dirp, &buf, &entry) == 0) { - if (!entry) + for (;;) { + errno = 0; + entry = sys_readdir (dirp, scratch); + if (!entry || errno != 0) break; - if (!strcmp (entry->d_name, ".") || - !strcmp (entry->d_name, "..")) + + if (strcmp (entry->d_name, ".") == 0 || + strcmp (entry->d_name, "..") == 0) continue; + if (!strncmp (entry->d_name, subdir, strlen (subdir))) continue; + count++; } - sys_closedir (dirp); + + (void) sys_closedir (dirp); return count; } @@ -1909,53 +1915,56 @@ out: int64_t index_fetch_link_count (xlator_t *this, index_xattrop_type_t type) { - char index_dir[PATH_MAX] = {0}; - char index_path[PATH_MAX] = {0}; - index_priv_t *priv = this->private; - char *subdir = NULL; - DIR *dirp = NULL; - struct dirent *entry = NULL; - struct stat lstatbuf = {0}; - int ret = -1; - int64_t count = -1; - struct dirent buf; + index_priv_t *priv = this->private; + char *subdir = NULL; + struct stat lstatbuf = {0,}; + int ret = -1; + int64_t count = -1; + DIR *dirp = NULL; + struct dirent *entry = NULL; + struct dirent scratch[2] = {{0,},}; + char index_dir[PATH_MAX] = {0,}; + char index_path[PATH_MAX] = {0,}; subdir = index_get_subdir_from_type (type); - make_index_dir_path (priv->index_basepath, subdir, - index_dir, sizeof (index_dir)); + make_index_dir_path (priv->index_basepath, subdir, + index_dir, sizeof (index_dir)); - dirp = sys_opendir (index_dir); - if (!dirp) + dirp = sys_opendir (index_dir); + if (!dirp) goto out; - while (readdir_r (dirp, &buf, &entry) == 0) { - if (!entry) { + for (;;) { + errno = 0; + entry = sys_readdir (dirp, scratch); + if (!entry || errno != 0) { if (count == -1) count = 0; goto out; - } else if (!strcmp (entry->d_name, ".") || - !strcmp (entry->d_name, "..")) { - continue; + } + + if (strcmp (entry->d_name, ".") == 0 || + strcmp (entry->d_name, "..") == 0) + continue; + + make_file_path (priv->index_basepath, subdir, + entry->d_name, index_path, sizeof(index_path)); + + ret = sys_lstat (index_path, &lstatbuf); + if (ret < 0) { + count = -2; + continue; } else { - make_file_path (priv->index_basepath, subdir, - entry->d_name, index_path, - sizeof (index_path)); - ret = sys_lstat (index_path, &lstatbuf); - if (ret < 0) { - count = -2; + count = lstatbuf.st_nlink - 1; + if (count == 0) continue; - } else { - count = lstatbuf.st_nlink - 1; - if (count == 0) - continue; - else - break; - } + else + break; } - } + } out: if (dirp) - sys_closedir (dirp); + (void) sys_closedir (dirp); return count; } diff --git a/xlators/mgmt/glusterd/src/glusterd-hooks.c b/xlators/mgmt/glusterd/src/glusterd-hooks.c index 45a5912a1eb..cb3d38d2358 100644 --- a/xlators/mgmt/glusterd/src/glusterd-hooks.c +++ b/xlators/mgmt/glusterd/src/glusterd-hooks.c @@ -323,15 +323,16 @@ glusterd_hooks_run_hooks (char *hooks_path, glusterd_op_t op, dict_t *op_ctx, { xlator_t *this = NULL; glusterd_conf_t *priv = NULL; - runner_t runner = {0, }; - struct dirent *entry = NULL; + runner_t runner = {0,}; DIR *hookdir = NULL; + struct dirent *entry = NULL; + struct dirent scratch[2] = {{0,},}; char *volname = NULL; - char **lines = NULL; - int N = 8; /*arbitrary*/ - int lineno = 0; - int line_count = 0; - int ret = -1; + char **lines = NULL; + int N = 8; /*arbitrary*/ + int lineno = 0; + int line_count = 0; + int ret = -1; this = THIS; priv = this->private; @@ -362,7 +363,7 @@ glusterd_hooks_run_hooks (char *hooks_path, glusterd_op_t op, dict_t *op_ctx, ret = -1; line_count = 0; - GF_FOR_EACH_ENTRY_IN_DIR (entry, hookdir); + GF_FOR_EACH_ENTRY_IN_DIR (entry, hookdir, scratch); while (entry) { if (line_count == N-1) { N *= 2; @@ -376,7 +377,7 @@ glusterd_hooks_run_hooks (char *hooks_path, glusterd_op_t op, dict_t *op_ctx, line_count++; } - GF_FOR_EACH_ENTRY_IN_DIR (entry, hookdir); + GF_FOR_EACH_ENTRY_IN_DIR (entry, hookdir, scratch); } lines[line_count] = NULL; diff --git a/xlators/mgmt/glusterd/src/glusterd-quota.c b/xlators/mgmt/glusterd/src/glusterd-quota.c index 55699cc57a9..0d7113bc1a0 100644 --- a/xlators/mgmt/glusterd/src/glusterd-quota.c +++ b/xlators/mgmt/glusterd/src/glusterd-quota.c @@ -392,10 +392,11 @@ void glusterd_stop_all_quota_crawl_service (glusterd_conf_t *priv, glusterd_volinfo_t *volinfo, int type) { - char pid_dir[PATH_MAX] = {0, }; - char pidfile[PATH_MAX] = {0,}; - struct dirent *entry = NULL; DIR *dir = NULL; + struct dirent *entry = NULL; + struct dirent scratch[2] = {{0,},}; + char pid_dir[PATH_MAX] = {0,}; + char pidfile[PATH_MAX] = {0,}; GLUSTERD_GET_QUOTA_CRAWL_PIDDIR (pid_dir, volinfo, type); @@ -403,7 +404,7 @@ glusterd_stop_all_quota_crawl_service (glusterd_conf_t *priv, if (dir == NULL) return; - GF_FOR_EACH_ENTRY_IN_DIR (entry, dir); + GF_FOR_EACH_ENTRY_IN_DIR (entry, dir, scratch); while (entry) { snprintf (pidfile, sizeof (pidfile), "%s/%s", pid_dir, entry->d_name); @@ -412,7 +413,7 @@ glusterd_stop_all_quota_crawl_service (glusterd_conf_t *priv, _gf_true); sys_unlink (pidfile); - GF_FOR_EACH_ENTRY_IN_DIR (entry, dir); + GF_FOR_EACH_ENTRY_IN_DIR (entry, dir, scratch); } sys_closedir (dir); } diff --git a/xlators/mgmt/glusterd/src/glusterd-snapshot-utils.c b/xlators/mgmt/glusterd/src/glusterd-snapshot-utils.c index 46c8bad1aa9..1765df3d0ef 100644 --- a/xlators/mgmt/glusterd/src/glusterd-snapshot-utils.c +++ b/xlators/mgmt/glusterd/src/glusterd-snapshot-utils.c @@ -3443,12 +3443,13 @@ out: int32_t glusterd_copy_folder (const char *source, const char *destination) { - DIR *dir_ptr = NULL; - struct dirent *direntp = NULL; - int32_t ret = -1; - char src_path[PATH_MAX] = ""; - char dest_path[PATH_MAX] = ""; - xlator_t *this = NULL; + int32_t ret = -1; + xlator_t *this = NULL; + DIR *dir_ptr = NULL; + struct dirent *entry = NULL; + struct dirent scratch[2] = {{0,},}; + char src_path[PATH_MAX] = {0,}; + char dest_path[PATH_MAX] = {0,}; this = THIS; GF_ASSERT (this); @@ -3463,17 +3464,22 @@ glusterd_copy_folder (const char *source, const char *destination) goto out; } - while ((direntp = sys_readdir (dir_ptr)) != NULL) { - if (strcmp (direntp->d_name, ".") == 0 || - strcmp (direntp->d_name, "..") == 0) + for (;;) { + errno = 0; + entry = sys_readdir (dir_ptr, scratch); + if (!entry || errno != 0) + break; + + if (strcmp (entry->d_name, ".") == 0 || + strcmp (entry->d_name, "..") == 0) continue; ret = snprintf (src_path, sizeof (src_path), "%s/%s", - source, direntp->d_name); + source, entry->d_name); if (ret < 0) goto out; ret = snprintf (dest_path, sizeof (dest_path), "%s/%s", - destination, direntp->d_name); + destination, entry->d_name); if (ret < 0) goto out; @@ -3487,7 +3493,7 @@ glusterd_copy_folder (const char *source, const char *destination) } out: if (dir_ptr) - sys_closedir (dir_ptr); + (void) sys_closedir (dir_ptr); return ret; } diff --git a/xlators/mgmt/glusterd/src/glusterd-store.c b/xlators/mgmt/glusterd/src/glusterd-store.c index 8b903ba1e48..deaa0892afe 100644 --- a/xlators/mgmt/glusterd/src/glusterd-store.c +++ b/xlators/mgmt/glusterd/src/glusterd-store.c @@ -626,14 +626,15 @@ out: int32_t glusterd_store_remove_bricks (glusterd_volinfo_t *volinfo, char *delete_path) { - int32_t ret = 0; - glusterd_brickinfo_t *tmp = NULL; - glusterd_conf_t *priv = NULL; - char brickdir [PATH_MAX] = {0,}; - DIR *dir = NULL; - struct dirent *entry = NULL; - char path[PATH_MAX] = {0,}; - xlator_t *this = NULL; + int32_t ret = 0; + glusterd_brickinfo_t *tmp = NULL; + glusterd_conf_t *priv = NULL; + xlator_t *this = NULL; + DIR *dir = NULL; + struct dirent *entry = NULL; + struct dirent scratch[2] = {{0,},}; + char path[PATH_MAX] = {0,}; + char brickdir[PATH_MAX] = {0,}; this = THIS; GF_ASSERT (this); @@ -654,7 +655,7 @@ glusterd_store_remove_bricks (glusterd_volinfo_t *volinfo, char *delete_path) dir = sys_opendir (brickdir); - GF_FOR_EACH_ENTRY_IN_DIR (entry, dir); + GF_FOR_EACH_ENTRY_IN_DIR (entry, dir, scratch); while (entry) { snprintf (path, sizeof (path), "%s/%s", @@ -664,7 +665,7 @@ glusterd_store_remove_bricks (glusterd_volinfo_t *volinfo, char *delete_path) gf_msg_debug (this->name, 0, "Unable to unlink %s", path); } - GF_FOR_EACH_ENTRY_IN_DIR (entry, dir); + GF_FOR_EACH_ENTRY_IN_DIR (entry, dir, scratch); } sys_closedir (dir); @@ -1772,6 +1773,7 @@ glusterd_store_delete_snap (glusterd_snap_t *snap) glusterd_conf_t *priv = NULL; DIR *dir = NULL; struct dirent *entry = NULL; + struct dirent scratch[2] = {{0,},}; char path[PATH_MAX] = {0,}; char delete_path[PATH_MAX] = {0,}; char trashdir[PATH_MAX] = {0,}; @@ -1819,7 +1821,7 @@ glusterd_store_delete_snap (glusterd_snap_t *snap) goto out; } - GF_FOR_EACH_ENTRY_IN_DIR (entry, dir); + GF_FOR_EACH_ENTRY_IN_DIR (entry, dir, scratch); while (entry) { snprintf (path, PATH_MAX, "%s/%s", delete_path, entry->d_name); ret = sys_stat (path, &st); @@ -1844,7 +1846,7 @@ glusterd_store_delete_snap (glusterd_snap_t *snap) entry->d_name); stat_failed: memset (path, 0, sizeof(path)); - GF_FOR_EACH_ENTRY_IN_DIR (entry, dir); + GF_FOR_EACH_ENTRY_IN_DIR (entry, dir, scratch); } ret = sys_closedir (dir); @@ -3111,6 +3113,7 @@ glusterd_store_retrieve_volumes (xlator_t *this, glusterd_snap_t *snap) glusterd_conf_t *priv = NULL; DIR *dir = NULL; struct dirent *entry = NULL; + struct dirent scratch[2] = {{0,},}; glusterd_volinfo_t *volinfo = NULL; GF_ASSERT (this); @@ -3133,7 +3136,7 @@ glusterd_store_retrieve_volumes (xlator_t *this, glusterd_snap_t *snap) goto out; } - GF_FOR_EACH_ENTRY_IN_DIR (entry, dir); + GF_FOR_EACH_ENTRY_IN_DIR (entry, dir, scratch); while (entry) { if (snap && ((!strcmp (entry->d_name, "geo-replication")) || @@ -3161,7 +3164,7 @@ glusterd_store_retrieve_volumes (xlator_t *this, glusterd_snap_t *snap) } next: - GF_FOR_EACH_ENTRY_IN_DIR (entry, dir); + GF_FOR_EACH_ENTRY_IN_DIR (entry, dir, scratch); } ret = 0; @@ -3678,6 +3681,7 @@ glusterd_store_retrieve_snaps (xlator_t *this) glusterd_conf_t *priv = NULL; DIR *dir = NULL; struct dirent *entry = NULL; + struct dirent scratch[2] = {{0,},}; GF_ASSERT (this); priv = this->private; @@ -3700,7 +3704,7 @@ glusterd_store_retrieve_snaps (xlator_t *this) goto out; } - GF_FOR_EACH_ENTRY_IN_DIR (entry, dir); + GF_FOR_EACH_ENTRY_IN_DIR (entry, dir, scratch); while (entry) { if (strcmp (entry->d_name, GLUSTERD_MISSED_SNAPS_LIST_FILE)) { @@ -3713,7 +3717,7 @@ glusterd_store_retrieve_snaps (xlator_t *this) goto out; } } - GF_FOR_EACH_ENTRY_IN_DIR (entry, dir); + GF_FOR_EACH_ENTRY_IN_DIR (entry, dir, scratch); } /* Retrieve missed_snaps_list */ @@ -4109,6 +4113,7 @@ glusterd_store_retrieve_peers (xlator_t *this) glusterd_conf_t *priv = NULL; DIR *dir = NULL; struct dirent *entry = NULL; + struct dirent scratch[2] = {{0,},}; char path[PATH_MAX] = {0,}; glusterd_peerinfo_t *peerinfo = NULL; gf_store_handle_t *shandle = NULL; @@ -4138,7 +4143,7 @@ glusterd_store_retrieve_peers (xlator_t *this) goto out; } - GF_FOR_EACH_ENTRY_IN_DIR (entry, dir); + GF_FOR_EACH_ENTRY_IN_DIR (entry, dir, scratch); while (entry) { snprintf (filepath, PATH_MAX, "%s/%s", path, entry->d_name); @@ -4216,7 +4221,7 @@ glusterd_store_retrieve_peers (xlator_t *this) peerinfo->shandle = shandle; peerinfo = NULL; - GF_FOR_EACH_ENTRY_IN_DIR (entry, dir); + GF_FOR_EACH_ENTRY_IN_DIR (entry, dir, scratch); } args.mode = GD_MODE_ON; diff --git a/xlators/mgmt/glusterd/src/glusterd-volgen.c b/xlators/mgmt/glusterd/src/glusterd-volgen.c index b56e9f26379..6a755486d7d 100644 --- a/xlators/mgmt/glusterd/src/glusterd-volgen.c +++ b/xlators/mgmt/glusterd/src/glusterd-volgen.c @@ -913,58 +913,59 @@ out: static void volgen_apply_filters (char *orig_volfile) { - DIR *filterdir = NULL; - struct dirent entry = {0,}; - struct dirent *next = NULL; - char *filterpath = NULL; - struct stat statbuf = {0,}; + DIR *filterdir = NULL; + struct dirent *entry = NULL; + struct dirent scratch[2] = {{0,},}; + struct stat statbuf = {0,}; + char filterpath[PATH_MAX] = {0,}; filterdir = sys_opendir (FILTERDIR); - if (!filterdir) { + + if (!filterdir) return; - } - while ((readdir_r(filterdir,&entry,&next) == 0) && next) { - if (!strncmp(entry.d_name,".",sizeof(entry.d_name))) { - continue; - } - if (!strncmp(entry.d_name,"..",sizeof(entry.d_name))) { + for (;;) { + + errno = 0; + + entry = sys_readdir (filterdir, scratch); + + if (!entry || errno != 0) + break; + + if (strcmp (entry->d_name, ".") == 0 || + strcmp (entry->d_name, "..") == 0) continue; - } /* * d_type isn't guaranteed to be present/valid on all systems, * so do an explicit stat instead. */ - if (gf_asprintf(&filterpath,"%s/%.*s",FILTERDIR, - sizeof(entry.d_name), entry.d_name) == (-1)) { - continue; - } + (void) snprintf (filterpath, sizeof(filterpath), "%s/%s", + FILTERDIR, entry->d_name); + /* Deliberately use stat instead of lstat to allow symlinks. */ - if (sys_stat(filterpath, &statbuf) == (-1)) { - goto free_fp; - } - if (!S_ISREG(statbuf.st_mode)) { - goto free_fp; - } + if (sys_stat (filterpath, &statbuf) == -1) + continue; + + if (!S_ISREG (statbuf.st_mode)) + continue; /* * We could check the mode in statbuf directly, or just skip * this entirely and check for EPERM after exec fails, but this * is cleaner. */ - if (sys_access(filterpath, X_OK) != 0) { - goto free_fp; - } - if (runcmd(filterpath,orig_volfile,NULL)) { + if (sys_access (filterpath, X_OK) != 0) + continue; + + if (runcmd (filterpath, orig_volfile, NULL)) { gf_msg ("glusterd", GF_LOG_ERROR, 0, GD_MSG_FILTER_RUN_FAILED, - "failed to run filter %.*s", - (int)sizeof(entry.d_name), entry.d_name); + "failed to run filter %s", + entry->d_name); } -free_fp: - GF_FREE(filterpath); } - sys_closedir (filterdir); + (void) sys_closedir (filterdir); } static int @@ -979,7 +980,6 @@ volgen_write_volfile (volgen_graph_t *graph, char *filename) if (gf_asprintf (&ftmp, "%s.tmp", filename) == -1) { ftmp = NULL; - goto error; } diff --git a/xlators/storage/posix/src/posix.c b/xlators/storage/posix/src/posix.c index 38f49df78ac..92971551c83 100644 --- a/xlators/storage/posix/src/posix.c +++ b/xlators/storage/posix/src/posix.c @@ -1099,7 +1099,7 @@ posix_opendir (call_frame_t *frame, xlator_t *this, out: if (op_ret == -1) { if (dir) { - sys_closedir (dir); + (void) sys_closedir (dir); dir = NULL; } if (pfd) { @@ -2063,15 +2063,16 @@ int posix_rmdir (call_frame_t *frame, xlator_t *this, loc_t *loc, int flags, dict_t *xdata) { - int32_t op_ret = -1; - int32_t op_errno = 0; - char * real_path = NULL; - char * par_path = NULL; - char * gfid_str = NULL; - struct iatt preparent = {0,}; - struct iatt postparent = {0,}; - struct iatt stbuf; - struct posix_private *priv = NULL; + int32_t op_ret = -1; + int32_t op_errno = 0; + char *real_path = NULL; + char *par_path = NULL; + char *gfid_str = NULL; + struct iatt preparent = {0,}; + struct iatt postparent = {0,}; + struct iatt stbuf = {0,}; + struct posix_private *priv = NULL; + char tmp_path[PATH_MAX] = {0,}; DECLARE_OLD_FS_ID_VAR; @@ -2113,9 +2114,6 @@ posix_rmdir (call_frame_t *frame, xlator_t *this, if (flags) { gfid_str = uuid_utoa (stbuf.ia_gfid); - char *tmp_path = alloca (strlen (priv->trash_path) + - strlen ("/") + - strlen (gfid_str) + 1); op_ret = sys_mkdir (priv->trash_path, 0755); if (errno != EEXIST && op_ret == -1) { @@ -2123,7 +2121,8 @@ posix_rmdir (call_frame_t *frame, xlator_t *this, P_MSG_MKDIR_FAILED, "mkdir of %s failed", priv->trash_path); } else { - sprintf (tmp_path, "%s/%s", priv->trash_path, gfid_str); + (void) snprintf (tmp_path, sizeof(tmp_path), "%s/%s", + priv->trash_path, gfid_str); op_ret = sys_rename (real_path, tmp_path); pthread_cond_signal (&priv->janitor_cond); } @@ -3861,37 +3860,43 @@ int posix_xattr_get_real_filename (call_frame_t *frame, xlator_t *this, loc_t *loc, const char *key, dict_t *dict, dict_t *xdata) { - char *real_path = NULL; - struct dirent *dirent = NULL; - DIR *fd = NULL; - const char *fname = NULL; - char *found = NULL; - int ret = -1; - int op_ret = -1; + int ret = -1; + int op_ret = -1; + const char *fname = NULL; + char *real_path = NULL; + char *found = NULL; + DIR *fd = NULL; + struct dirent *entry = NULL; + struct dirent scratch[2] = {{0,},}; MAKE_INODE_HANDLE (real_path, this, loc, NULL); if (!real_path) { return -ESTALE; } - fd = sys_opendir (real_path); - if (!fd) - return -errno; + fd = sys_opendir (real_path); + if (!fd) + return -errno; fname = key + strlen (GF_XATTR_GET_REAL_FILENAME_KEY); - while ((dirent = sys_readdir (fd))) { - if (strcasecmp (dirent->d_name, fname) == 0) { - found = gf_strdup (dirent->d_name); + for (;;) { + errno = 0; + entry = sys_readdir (fd, scratch); + if (!entry || errno != 0) + break; + + if (strcasecmp (entry->d_name, fname) == 0) { + found = gf_strdup (entry->d_name); if (!found) { - sys_closedir (fd); + (void) sys_closedir (fd); return -ENOMEM; } break; } } - sys_closedir (fd); + (void) sys_closedir (fd); if (!found) return -ENOENT; @@ -3913,9 +3918,9 @@ posix_get_ancestry_directory (xlator_t *this, inode_t *leaf_inode, { ssize_t handle_size = 0; struct posix_private *priv = NULL; - char dirpath[PATH_MAX+1] = {0,}; inode_t *inode = NULL; int ret = -1; + char dirpath[PATH_MAX] = {0,}; priv = this->private; @@ -3951,16 +3956,17 @@ posix_links_in_same_directory (char *dirpath, int count, inode_t *leaf_inode, gf_dirent_t *head, char **path, int type, dict_t *xdata, int32_t *op_errno) { - DIR *dirp = NULL; int op_ret = -1; - struct dirent *entry = NULL; - struct dirent *result = NULL; inode_t *linked_inode = NULL; gf_dirent_t *gf_entry = NULL; - char temppath[PATH_MAX+1] = {0,}; xlator_t *this = NULL; struct posix_private *priv = NULL; char *tempv = NULL; + DIR *dirp = NULL; + struct dirent *entry = NULL; + struct dirent scratch[2] = {{0,},}; + char temppath[PATH_MAX] = {0,}; + char scr[PATH_MAX * 4] = {0,}; this = THIS; @@ -3974,13 +3980,10 @@ posix_links_in_same_directory (char *dirpath, int count, inode_t *leaf_inode, goto out; } - entry = alloca (offsetof(struct dirent, d_name) + NAME_MAX + 1); - if (entry == NULL) - goto out; - while (count > 0) { - *op_errno = readdir_r (dirp, entry, &result); - if ((result == NULL) || *op_errno) + errno = 0; + entry = sys_readdir (dirp, scratch); + if (!entry || errno != 0) break; if (entry->d_ino != stbuf->st_ino) @@ -4005,9 +4008,8 @@ posix_links_in_same_directory (char *dirpath, int count, inode_t *leaf_inode, loc.inode = inode_ref (leaf_inode); gf_uuid_copy (loc.gfid, leaf_inode->gfid); - strcpy (temppath, dirpath); - strcat (temppath, "/"); - strcat (temppath, entry->d_name); + (void) snprintf (temppath, sizeof(temppath), "%s/%s", + dirpath, entry->d_name); gf_entry = gf_dirent_for_name (entry->d_name); gf_entry->inode = inode_ref (leaf_inode); @@ -4021,29 +4023,24 @@ posix_links_in_same_directory (char *dirpath, int count, inode_t *leaf_inode, } if (type & POSIX_ANCESTRY_PATH) { - strcpy (temppath, - &dirpath[priv->base_path_length]); - strcat (temppath, "/"); - strcat (temppath, entry->d_name); + (void) snprintf (temppath, sizeof(temppath), "%s/%s", + &dirpath[priv->base_path_length], + entry->d_name); if (!*path) { *path = gf_strdup (temppath); } else { /* creating a colon separated */ /* list of hard links */ - tempv = GF_REALLOC (*path, strlen (*path) - + 1 // ':' - + strlen (temppath) + 1 ); - if (!tempv) { - GF_FREE (*path); - *path = NULL; - op_ret = -1; - *op_errno = ENOMEM; - goto out; - } + (void) snprintf (scr, sizeof(scr), "%s:%s", + *path, temppath); - *path = tempv; - strcat (*path, ":"); - strcat (*path, temppath); + GF_FREE (*path); + *path = gf_strdup (scr); + } + if (!*path) { + op_ret = -1; + *op_errno = ENOMEM; + goto out; } } @@ -4069,21 +4066,22 @@ posix_get_ancestry_non_directory (xlator_t *this, inode_t *leaf_inode, gf_dirent_t *head, char **path, int type, int32_t *op_errno, dict_t *xdata) { - size_t remaining_size = 0; - char dirpath[PATH_MAX+1] = {0,}, *leaf_path = NULL; - int op_ret = -1, pathlen = -1; - ssize_t handle_size = 0; - char pgfidstr[UUID_CANONICAL_FORM_LEN+1] = {0,}; - uuid_t pgfid = {0, }; - int nlink_samepgfid = 0; - struct stat stbuf = {0,}; - char *list = NULL; - int32_t list_offset = 0; - char key[4096] = {0,}; - struct posix_private *priv = NULL; - ssize_t size = 0; - inode_t *parent = NULL; - loc_t *loc = NULL; + size_t remaining_size = 0; + int op_ret = -1, pathlen = -1; + ssize_t handle_size = 0; + uuid_t pgfid = {0,}; + int nlink_samepgfid = 0; + struct stat stbuf = {0,}; + char *list = NULL; + int32_t list_offset = 0; + struct posix_private *priv = NULL; + ssize_t size = 0; + inode_t *parent = NULL; + loc_t *loc = NULL; + char *leaf_path = NULL; + char key[4096] = {0,}; + char dirpath[PATH_MAX] = {0,}; + char pgfidstr[UUID_CANONICAL_FORM_LEN+1] = {0,}; priv = this->private; @@ -4153,7 +4151,7 @@ posix_get_ancestry_non_directory (xlator_t *this, inode_t *leaf_inode, } while (remaining_size > 0) { - strcpy (key, list + list_offset); + strncpy (key, list + list_offset, sizeof(key)); if (strncmp (key, PGFID_XATTR_KEY_PREFIX, strlen (PGFID_XATTR_KEY_PREFIX)) != 0) goto next; @@ -4171,13 +4169,14 @@ posix_get_ancestry_non_directory (xlator_t *this, inode_t *leaf_inode, nlink_samepgfid = ntoh32 (nlink_samepgfid); - strcpy (pgfidstr, key + strlen(PGFID_XATTR_KEY_PREFIX)); + strncpy (pgfidstr, key + strlen(PGFID_XATTR_KEY_PREFIX), + sizeof(pgfidstr)); gf_uuid_parse (pgfidstr, pgfid); handle_size = POSIX_GFID_HANDLE_SIZE(priv->base_path_length); /* constructing the absolute real path of parent dir */ - strcpy (dirpath, priv->base_path); + strncpy (dirpath, priv->base_path, sizeof(dirpath)); pathlen = PATH_MAX + 1 - priv->base_path_length; op_ret = posix_make_ancestryfromgfid (this, @@ -4260,7 +4259,6 @@ posix_getxattr (call_frame_t *frame, xlator_t *this, struct posix_private *priv = NULL; int32_t op_ret = -1; int32_t op_errno = 0; - char host_buf[1024] = {0,}; char *value = NULL; char *real_path = NULL; dict_t *dict = NULL; @@ -4273,6 +4271,7 @@ posix_getxattr (call_frame_t *frame, xlator_t *this, char *list = NULL; int32_t list_offset = 0; size_t remaining_size = 0; + char host_buf[1024] = {0,}; char keybuffer[4096] = {0,}; DECLARE_OLD_FS_ID_VAR; @@ -4387,7 +4386,7 @@ posix_getxattr (call_frame_t *frame, xlator_t *this, else rpath = real_path; - (void) snprintf (host_buf, 1024, + (void) snprintf (host_buf, sizeof(host_buf), "", priv->base_path, ((priv->node_uuid_pathinfo && !gf_uuid_is_null(priv->glusterd_uuid)) @@ -4415,7 +4414,7 @@ posix_getxattr (call_frame_t *frame, xlator_t *this, if (loc->inode && name && (strcmp (name, GF_XATTR_NODE_UUID_KEY) == 0) && !gf_uuid_is_null (priv->glusterd_uuid)) { - (void) snprintf (host_buf, 1024, "%s", + (void) snprintf (host_buf, sizeof(host_buf), "%s", uuid_utoa (priv->glusterd_uuid)); dyn_rpath = gf_strdup (host_buf); @@ -4499,7 +4498,7 @@ posix_getxattr (call_frame_t *frame, xlator_t *this, } if (name) { - strcpy (keybuffer, name); + strncpy (keybuffer, name, sizeof(keybuffer)); char *key = keybuffer; #if defined(GF_DARWIN_HOST_OS_DISABLED) if (priv->xattr_user_namespace == XATTR_STRIP) { @@ -4603,7 +4602,7 @@ posix_getxattr (call_frame_t *frame, xlator_t *this, remaining_size = size; list_offset = 0; while (remaining_size > 0) { - strcpy (keybuffer, list + list_offset); + strncpy (keybuffer, list + list_offset, sizeof(keybuffer)); if (frame->root->pid != GF_CLIENT_PID_GSYNCD && fnmatch ("*.glusterfs.*.stime", keybuffer, FNM_PERIOD) == 0) goto ignore; @@ -4641,7 +4640,7 @@ posix_getxattr (call_frame_t *frame, xlator_t *this, /* The protocol expect namespace for now */ char *newkey = NULL; gf_add_prefix (XATTR_USER_PREFIX, keybuffer, &newkey); - strcpy (keybuffer, newkey); + strncpy (keybuffer, newkey, sizeof(keybuffer)); GF_FREE (newkey); #endif op_ret = dict_set_dynptr (dict, keybuffer, value, size); @@ -4693,11 +4692,11 @@ posix_fgetxattr (call_frame_t *frame, xlator_t *this, int32_t list_offset = 0; ssize_t size = 0; size_t remaining_size = 0; - char key[4096] = {0,}; char * value = NULL; char * list = NULL; dict_t * dict = NULL; int ret = -1; + char key[4096] = {0,}; DECLARE_OLD_FS_ID_VAR; @@ -4753,14 +4752,14 @@ posix_fgetxattr (call_frame_t *frame, xlator_t *this, } if (name) { - strcpy (key, name); + strncpy (key, name, sizeof(key)); #ifdef GF_DARWIN_HOST_OS struct posix_private *priv = NULL; priv = this->private; if (priv->xattr_user_namespace == XATTR_STRIP) { char *newkey = NULL; gf_add_prefix (XATTR_USER_PREFIX, key, &newkey); - strcpy (key, newkey); + strncpy (key, newkey, sizeof(key)); GF_FREE (newkey); } #endif @@ -4849,7 +4848,7 @@ posix_fgetxattr (call_frame_t *frame, xlator_t *this, if(*(list + list_offset) == '\0') break; - strcpy (key, list + list_offset); + strncpy (key, list + list_offset, sizeof(key)); size = sys_fgetxattr (_fd, key, NULL, 0); if (size == -1) { op_ret = -1; @@ -5939,21 +5938,20 @@ int posix_fill_readdir (fd_t *fd, DIR *dir, off_t off, size_t size, gf_dirent_t *entries, xlator_t *this, int32_t skip_dirs) { - off_t in_case = -1; - off_t last_off = 0; - size_t filled = 0; - int count = 0; - char entrybuf[sizeof(struct dirent) + 256 + 8]; - struct dirent *entry = NULL; - int32_t this_size = -1; - gf_dirent_t *this_entry = NULL; - struct posix_fd *pfd = NULL; - uuid_t rootgfid = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}; - struct stat stbuf = {0,}; - char *hpath = NULL; - int len = 0; - int ret = 0; - int op_errno = 0; + off_t in_case = -1; + off_t last_off = 0; + size_t filled = 0; + int count = 0; + int32_t this_size = -1; + gf_dirent_t *this_entry = NULL; + struct posix_fd *pfd = NULL; + struct stat stbuf = {0,}; + char *hpath = NULL; + int len = 0; + int ret = 0; + int op_errno = 0; + struct dirent *entry = NULL; + struct dirent scratch[2] = {{0,},}; ret = posix_fd_ctx_get (fd, this, &pfd, &op_errno); if (ret < 0) { @@ -6013,10 +6011,10 @@ posix_fill_readdir (fd_t *fd, DIR *dir, off_t off, size_t size, } errno = 0; - entry = NULL; - readdir_r (dir, (struct dirent *)entrybuf, &entry); - if (!entry) { + entry = sys_readdir (dir, scratch); + + if (!entry || errno != 0) { if (errno == EBADF) { gf_msg (THIS->name, GF_LOG_WARNING, errno, P_MSG_DIR_OPERATION_FAILED, @@ -6036,12 +6034,12 @@ posix_fill_readdir (fd_t *fd, DIR *dir, off_t off, size_t size, * when the cluster/dht xlator decides to distribute * exended attribute backing file across storage servers. */ - if ((gf_uuid_compare (fd->inode->gfid, rootgfid) == 0) + if (__is_root_gfid (fd->inode->gfid) == 0 && (!strcmp(entry->d_name, ".attribute"))) continue; #endif /* __NetBSD__ */ - if ((gf_uuid_compare (fd->inode->gfid, rootgfid) == 0) + if (__is_root_gfid (fd->inode->gfid) && (!strcmp (GF_HIDDEN_PATH, entry->d_name))) { continue; } @@ -6050,7 +6048,7 @@ posix_fill_readdir (fd_t *fd, DIR *dir, off_t off, size_t size, if (DT_ISDIR (entry->d_type)) { continue; } else if (hpath) { - strcpy (&hpath[len+1],entry->d_name); + strcpy (&hpath[len+1], entry->d_name); ret = sys_lstat (hpath, &stbuf); if (!ret && S_ISDIR (stbuf.st_mode)) continue; @@ -6106,7 +6104,7 @@ posix_fill_readdir (fd_t *fd, DIR *dir, off_t off, size_t size, count ++; } - if ((!sys_readdir (dir) && (errno == 0))) { + if ((!sys_readdir (dir, scratch) && (errno == 0))) { /* Indicate EOF */ errno = ENOENT; /* Remember EOF offset for later detection */ @@ -6161,6 +6159,7 @@ posix_readdirp_fill (xlator_t *this, fd_t *fd, gf_dirent_t *entries, dict_t *dic struct iatt stbuf = {0, }; uuid_t gfid; int ret = -1; + if (list_empty(&entries->list)) return 0; @@ -6353,8 +6352,8 @@ posix_priv (xlator_t *this) struct posix_private *priv = NULL; char key_prefix[GF_DUMP_MAX_BUF_LEN]; - snprintf(key_prefix, GF_DUMP_MAX_BUF_LEN, "%s.%s", this->type, - this->name); + (void) snprintf(key_prefix, GF_DUMP_MAX_BUF_LEN, "%s.%s", + this->type, this->name); gf_proc_dump_add_section(key_prefix); if (!this) @@ -6667,29 +6666,24 @@ out: int32_t posix_create_unlink_dir (xlator_t *this) { - char *unlink_path = NULL; - char *landfill_path = NULL; struct posix_private *priv = NULL; struct stat stbuf; - int ret = -1; + int ret = -1; uuid_t gfid = {0}; char gfid_str[64] = {0}; + char unlink_path[PATH_MAX] = {0,}; + char landfill_path[PATH_MAX] = {0,}; priv = this->private; - unlink_path = alloca (strlen (priv->base_path) + 1 + - strlen (GF_UNLINK_PATH) + 1); - sprintf (unlink_path, "%s/%s", priv->base_path, - GF_UNLINK_PATH); + (void) snprintf (unlink_path, sizeof(unlink_path), "%s/%s", + priv->base_path, GF_UNLINK_PATH); gf_uuid_generate (gfid); uuid_utoa_r (gfid, gfid_str); - landfill_path = alloca (strlen (priv->base_path) + 1 + - strlen (GF_LANDFILL_PATH) + 1 + - strlen (gfid_str) + 1); - sprintf (landfill_path, "%s/%s/%s", priv->base_path, - GF_LANDFILL_PATH, gfid_str); + (void) snprintf (landfill_path, sizeof(landfill_path), "%s/%s/%s", + priv->base_path, GF_LANDFILL_PATH, gfid_str); ret = sys_stat (unlink_path, &stbuf); switch (ret) { @@ -7240,7 +7234,7 @@ fini (xlator_t *this) this->private = NULL; /*unlock brick dir*/ if (priv->mount_lock) - sys_closedir (priv->mount_lock); + (void) sys_closedir (priv->mount_lock); GF_FREE (priv); return; } -- cgit