From fc010b01e7a2d02130269add7c0a0ebbc7171d30 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 23 Nov 2017 12:42:24 +0100 Subject: [PATCH] mount-util: drop exponential buffer growing in name_to_handle_at_loop() So, it appears name_to_handle_at() always returns the right buffer size on EOVERFLOW, when it's returned due to a too small buffer. Let's rely on that exclusively for sizing the buffer, and let's drop the exponential buffer growing. The new logic is now: if we see EOVERFLOW and the returned size has increased, resize our buffer and try again. But if it didn't increase, then propagate the EOVERFLOW as it likely has other causes. --- src/basic/mount-util.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/basic/mount-util.c b/src/basic/mount-util.c index 5f22bd68cec..fc7b0b599e5 100644 --- a/src/basic/mount-util.c +++ b/src/basic/mount-util.c @@ -65,7 +65,6 @@ int name_to_handle_at_loop( for (;;) { int mnt_id = -1; - size_t m; if (name_to_handle_at(fd, path, h, &mnt_id, flags) >= 0) { @@ -84,22 +83,24 @@ int name_to_handle_at_loop( if (!ret_handle && ret_mnt_id && mnt_id >= 0) { - /* As it appears, name_to_handle_at() fills in mnt_id even when it returns EOVERFLOW, but - * that's undocumented. Hence, let's make use of this if it appears to be filled in, and the - * caller was interested in only the mount ID an nothing else. */ + /* As it appears, name_to_handle_at() fills in mnt_id even when it returns EOVERFLOW when the + * buffer is too small, but that's undocumented. Hence, let's make use of this if it appears to + * be filled in, and the caller was interested in only the mount ID an nothing else. */ *ret_mnt_id = mnt_id; return 0; } - /* The buffer was too small. Size the new buffer by what name_to_handle_at() returned, but make sure it - * is always larger than what we passed in before */ - m = h->handle_bytes > n ? h->handle_bytes : n * 2; - if (m < n) /* Check for multiplication overflow */ + /* If name_to_handle_at() didn't increase the byte size, then this EOVERFLOW is caused by something + * else (apparently EOVERFLOW is returned for untriggered nfs4 mounts sometimes), not by the too small + * buffer. In that case propagate EOVERFLOW */ + if (h->handle_bytes <= n) return -EOVERFLOW; - if (offsetof(struct file_handle, f_handle) + m < m) /* check for addition overflow */ + + /* The buffer was too small. Size the new buffer by what name_to_handle_at() returned. */ + n = h->handle_bytes; + if (offsetof(struct file_handle, f_handle) + n < n) /* check for addition overflow */ return -EOVERFLOW; - n = m; free(h); h = malloc0(offsetof(struct file_handle, f_handle) + n); -- 2.39.5