implement a union to pad out file_handle

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.
This commit is contained in:
Dave Reisner 2014-04-19 13:22:35 -04:00
parent dbb9401dba
commit 370c860f74
4 changed files with 14 additions and 15 deletions

View file

@ -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;

View file

@ -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;

View file

@ -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];
};

View file

@ -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;