2016-08-19 16:48 GMT-07:00 Aaron Conole <[email protected]>:
> 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 <[email protected]>
> ---
> 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
[email protected]
http://openvswitch.org/mailman/listinfo/dev