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@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/systemd-devel > _______________________________________________ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel