2016-08-19 16:48 GMT-07:00 Aaron Conole <acon...@redhat.com>: > For certain types of files (in particular Unix Domain Sockets), the > standard > fchmod/fchown calls have strange side effects. While Unix Domain Sockets > have their own particular quirks depending on the system, there may be > other > files where Open vSwitch would operate on the file without a concrete file > handle. To detect, and possibly prevent, file system races when operating > on > these files, two new functions are added (ovs_kchmod and ovs_kchown), which > perform hardness amplification and column-wise traversal as described in > https://www.usenix.org/legacy/event/fast08/tech/full_papers/ > tsafrir/tsafrir_html/index.html > > Fallbacks are provided which return ENOTSUP on systems where the > POSIX1.2008 > function calls for {fchmod,fchown,fstat,readlink,open}at are not > available. > > Signed-off-by: Aaron Conole <acon...@redhat.com> > --- > v3->v4: > * Complete rewrite using both directory traversal and hardness > amplification. > The check for the *at were added for the travis build - AIUI FreeBSD does > provide those functions, but I did not test there. > > configure.ac | 2 +- > lib/chutil-unix.c | 304 ++++++++++++++++++++++++++++++ > ++++++++++++++++++++++ > lib/chutil.h | 4 + > tests/test-chutil.c | 92 ++++++++++++---- > 4 files changed, 382 insertions(+), 20 deletions(-) > > +/* Checks whether the relative path element is a symlink. If an error > + * occurs, returns -1. If the path is a symlink, returns 1. Otherwise, > + * returns 0. The stat struct, and target, are output variables and are > + * considered valid unless the return value is -1. In the case that the > + * hardness Amplification fails, errno will be set to EBADFD. */ > +static int is_symlink(int dirfd, const char *path_elem, char target[], > + size_t target_len, struct stat *s) > +{ > + struct stat s_cmp; > + int result; > + for (int k = 0; k < K_ROUNDS; ++k) { > + result = fstatat(dirfd, path_elem, s, 0); > + if (!k) { > + s_cmp = *s; > + } else if (!cmp_stat(&s_cmp, s)){ >
It looks like a false positive, but gcc 4.8 complains that 's_cmp' may be uninitialized here. > + return -1; > + } > + } > + > + if (!result && S_ISLNK(s->st_mode)) { > + result = readlinkat(dirfd, path_elem, target, target_len); > + if (result != -1) { > + target[result] = '\0'; > + result = 1; > + } > + } > + return result; > +} > + > [...] _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev