[systemd-devel] [PATCH 2/2] implement a union to pad out file_handle

Zbigniew Jędrzejewski-Szmek zbyszek at in.waw.pl
Sun Apr 20 20:00:02 PDT 2014


On Sat, Apr 19, 2014 at 01:33:29PM -0400, Dave Reisner wrote:
> Cases where name_to_handle_at is used allocated the full struct to be
> MAX_HANDLE_SZ, and assigned this size to handle_bytes. This is wrong
> since handle_bytes should describe the length of the flexible array
> member and not the whole struct.
> 
> Define a union type which includes sufficient padding to allow
> assignment of MAX_HANDLE_SZ to be correct.
Yikes. Patch looks good.

Zbyszek

> ---
>  src/libudev/libudev-monitor.c    |  6 ++----
>  src/readahead/readahead-common.c |  6 ++----
>  src/shared/util.h                |  6 ++++++
>  src/tmpfiles/tmpfiles.c          | 11 ++++-------
>  4 files changed, 14 insertions(+), 15 deletions(-)
> 
> diff --git a/src/libudev/libudev-monitor.c b/src/libudev/libudev-monitor.c
> index 3f7436b..0a2ab82 100644
> --- a/src/libudev/libudev-monitor.c
> +++ b/src/libudev/libudev-monitor.c
> @@ -108,15 +108,13 @@ static struct udev_monitor *udev_monitor_new(struct udev *udev)
>  
>  /* we consider udev running when /dev is on devtmpfs */
>  static bool udev_has_devtmpfs(struct udev *udev) {
> -        struct file_handle *h;
> +        union file_handle_union h = { .handle.handle_bytes = MAX_HANDLE_SZ, };
>          int mount_id;
>          _cleanup_fclose_ FILE *f = NULL;
>          char line[LINE_MAX], *e;
>          int r;
>  
> -        h = alloca(MAX_HANDLE_SZ);
> -        h->handle_bytes = MAX_HANDLE_SZ;
> -        r = name_to_handle_at(AT_FDCWD, "/dev", h, &mount_id, 0);
> +        r = name_to_handle_at(AT_FDCWD, "/dev", &h.handle, &mount_id, 0);
>          if (r < 0)
>                  return false;
>  
> diff --git a/src/readahead/readahead-common.c b/src/readahead/readahead-common.c
> index 5ffa88b..49679fc 100644
> --- a/src/readahead/readahead-common.c
> +++ b/src/readahead/readahead-common.c
> @@ -75,7 +75,7 @@ int fs_on_ssd(const char *p) {
>          if (major(st.st_dev) == 0) {
>                  _cleanup_fclose_ FILE *f = NULL;
>                  int mount_id;
> -                struct file_handle *h;
> +                union file_handle_union h = { .handle.handle_bytes = MAX_HANDLE_SZ, };
>  
>                  /* Might be btrfs, which exposes "ssd" as mount flag if it is on ssd.
>                   *
> @@ -83,9 +83,7 @@ int fs_on_ssd(const char *p) {
>                   * and then lookup the mount ID in mountinfo to find
>                   * the mount options. */
>  
> -                h = alloca(MAX_HANDLE_SZ);
> -                h->handle_bytes = MAX_HANDLE_SZ;
> -                r = name_to_handle_at(AT_FDCWD, p, h, &mount_id, AT_SYMLINK_FOLLOW);
> +                r = name_to_handle_at(AT_FDCWD, p, &h.handle, &mount_id, AT_SYMLINK_FOLLOW);
>                  if (r < 0)
>                          return false;
>  
> diff --git a/src/shared/util.h b/src/shared/util.h
> index 900f1cf..891848a 100644
> --- a/src/shared/util.h
> +++ b/src/shared/util.h
> @@ -22,6 +22,7 @@
>  ***/
>  
>  #include <alloca.h>
> +#include <fcntl.h>
>  #include <inttypes.h>
>  #include <time.h>
>  #include <sys/time.h>
> @@ -914,3 +915,8 @@ uint64_t physical_memory(void);
>  char* mount_test_option(const char *haystack, const char *needle);
>  
>  void hexdump(FILE *f, const void *p, size_t s);
> +
> +union file_handle_union {
> +  struct file_handle handle;
> +  char padding[sizeof(struct file_handle) + MAX_HANDLE_SZ];
> +};
> diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c
> index 33e7cbc..04b472d 100644
> --- a/src/tmpfiles/tmpfiles.c
> +++ b/src/tmpfiles/tmpfiles.c
> @@ -217,19 +217,16 @@ static bool unix_socket_alive(const char *fn) {
>  }
>  
>  static int dir_is_mount_point(DIR *d, const char *subdir) {
> -        struct file_handle *h;
> +        union file_handle_union h = { .handle.handle_bytes = MAX_HANDLE_SZ };
>          int mount_id_parent, mount_id;
>          int r_p, r;
>  
> -        h = alloca(MAX_HANDLE_SZ);
> -
> -        h->handle_bytes = MAX_HANDLE_SZ;
> -        r_p = name_to_handle_at(dirfd(d), ".", h, &mount_id_parent, 0);
> +        r_p = name_to_handle_at(dirfd(d), ".", &h.handle, &mount_id_parent, 0);
>          if (r_p < 0)
>                  r_p = -errno;
>  
> -        h->handle_bytes = MAX_HANDLE_SZ;
> -        r = name_to_handle_at(dirfd(d), subdir, h, &mount_id, 0);
> +        h.handle.handle_bytes = MAX_HANDLE_SZ;
> +        r = name_to_handle_at(dirfd(d), subdir, &h.handle, &mount_id, 0);
>          if (r < 0)
>                  r = -errno;
>  
> -- 
> 1.9.2
> 
> _______________________________________________
> systemd-devel mailing list
> systemd-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/systemd-devel
> 


More information about the systemd-devel mailing list