-
Notifications
You must be signed in to change notification settings - Fork 1.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
GCC 7.1 fixes #6253
GCC 7.1 fixes #6253
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This may be an oversimplification, but couldn't you provide a #define TRUNC(func) if (func) {; }
then all your snprintf
calls can become something like TRUNC(snprintf(....));
. Thoughts?
GCC 7.1 with will warn when we're not checking the snprintf() return code in cases where the buffer could be truncated. This patch either checks the snprintf return code (where applicable), or simply disables the warnings (ztest.c). Signed-off-by: Tony Hutter <hutter2@llnl.gov>
@dinatale2 unfortunately I get the same build errors with that since the gcc still knows the size at compile time. This hack seems to work though:
I've updated the code with this in my latest push. |
Looks like I don't need the |
lib/libspl/include/assert.h
Outdated
char *__buf = alloca(256); \ | ||
(void) snprintf(__buf, 256, \ | ||
char *__buf = NULL; \ | ||
int rc = asprintf(&__buf, \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
asprintf will require a free. But I don't see why we need to do this. Why not pass the format strings and variable all the way, or pass va_list?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The other four callers of libspl_assert()
just pass it a const string, so it makes sense to have VERIFY3_IMPL
pass in a string as well (rather than a format string + vars).
I'll get rid of the asprintf
and use a "snprintf to get size + alloca(size)" to allocate __buf
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Then how about adding a libspl_assertf
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Works for me
include/zfs_comutil.h
Outdated
*/ | ||
#define SNPRINTF_TRUNC(str, size, ...) { \ | ||
volatile int s = size; \ | ||
snprintf(str, s, __VA_ARGS__); \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it should be ##__VA_ARGS__
to allow zero arguments.
Also, wrap this in do { } while (0)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch, will fix
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the purpose for the volatile?
Shouldn't it be fine if you pass in size directly, as it's only used once?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
volatile
fools gcc into not computing the buffer size at compile time, and thus prevents the compiler warning about snprintf truncation.
lib/libspl/include/assert.h
Outdated
va_list args; | ||
va_start(args, format); | ||
size = vsnprintf(NULL, 0, format, args); | ||
buf = alloca(size + 1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What I meant was feed the format string directly to fprintf, so we don't need to allocate any thing.
Edit, or I should say vfprintf.
include/zfs_comutil.h
Outdated
* able to compute the truncation at compile time, and thus no error. | ||
*/ | ||
#define SNPRINTF_TRUNC(str, size, ...) do { \ | ||
volatile int s = size; \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this is required then you should change it to __s
to prevent name collision.
@tuxoko my latest push should have all the fixes you were looking for |
include/zfs_comutil.h
Outdated
#define SNPRINTF_TRUNC(str, size, ...) do { \ | ||
volatile int __s = size; \ | ||
snprintf(str, __s, ##__VA_ARGS__); \ | ||
} while (0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With the single exception in zvol.c
it looks like SNPRINTF_TRUNC
is only needed by ztest.c
. In order to avoid tempting developers to use the wrapper in the core ZFS code, where there needs to be proper error handling and we want gcc to warn us, let's move this macro in to ztest.c
. The usage in zvol_rename_minors_impl()
can be fixed by using kmem_asprintf()
to always dynamically allocate a long enough buffer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And with the only semi-legitimate usage of this now occurring in ztest.c
we should be able to eliminate the need for this macro entirely by building ztest
with -Wnoformat-truncation
. Here's an untested patch, you may need to structure this like the ZFS_AC_CONFIG_USER_FRAME_LARGER_THAN
to ensure the version of gcc being used supports the option. Alternately a pragma could be used for this.
diff --git a/cmd/ztest/Makefile.am b/cmd/ztest/Makefile.am
index a2f3b5a..c7ac681 100644
--- a/cmd/ztest/Makefile.am
+++ b/cmd/ztest/Makefile.am
@@ -1,6 +1,6 @@
include $(top_srcdir)/config/Rules.am
-AM_CFLAGS += $(DEBUG_STACKFLAGS) $(FRAME_LARGER_THAN)
+AM_CFLAGS += $(DEBUG_STACKFLAGS) $(FRAME_LARGER_THAN) -Wnoformat-truncation
AM_CPPFLAGS += -DDEBUG
DEFAULT_INCLUDES += \
@behlendorf all comments fixed in latest push |
Updated commit message to remove the mention of snprintf_trunc |
config/no-format-truncation.m4
Outdated
]) | ||
|
||
CFLAGS="$saved_flags" | ||
AC_SUBST([NO_FORMAT_TRUNCATION]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ctyle: spaces instead of tabs
module/zfs/zvol.c
Outdated
@@ -2086,16 +2085,18 @@ zvol_rename_minors_impl(const char *oldname, const char *newname) | |||
} else if (strncmp(zv->zv_name, oldname, oldnamelen) == 0 && | |||
(zv->zv_name[oldnamelen] == '/' || | |||
zv->zv_name[oldnamelen] == '@')) { | |||
snprintf(name, MAXNAMELEN, "%s%c%s", newname, | |||
name = kmem_asprintf("%s%c%s", newname, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: kmem_asprintf()
using KM_SLEEP
internally and cannot fail so we can drop the if (name != NULL)
checks. What do you think about the following to simplify this.
diff --git a/module/zfs/zvol.c b/module/zfs/zvol.c
index 8890aaa..21d4467 100644
--- a/module/zfs/zvol.c
+++ b/module/zfs/zvol.c
@@ -2063,14 +2063,12 @@ zvol_rename_minors_impl(const char *oldname, const char
{
zvol_state_t *zv, *zv_next;
int oldnamelen, newnamelen;
- char *name;
if (zvol_inhibit_dev)
return;
oldnamelen = strlen(oldname);
newnamelen = strlen(newname);
- name = kmem_alloc(MAXNAMELEN, KM_SLEEP);
mutex_enter(&zvol_state_lock);
@@ -2086,16 +2084,15 @@ zvol_rename_minors_impl(const char *oldname, const char
} else if (strncmp(zv->zv_name, oldname, oldnamelen) == 0 &&
(zv->zv_name[oldnamelen] == '/' ||
zv->zv_name[oldnamelen] == '@')) {
- snprintf(name, MAXNAMELEN, "%s%c%s", newname,
+ char *name = kmem_asprintf("%s%c%s", newname,
zv->zv_name[oldnamelen],
zv->zv_name + oldnamelen + 1);
zvol_rename_minor(zv, name);
+ kmem_free(name, strlen(name + 1));
}
}
mutex_exit(&zvol_state_lock);
-
- kmem_free(name, MAXNAMELEN);
}
typedef struct zvol_snapdev_cb_arg {
module/zfs/zfs_ioctl.c
Outdated
if (snprintf(namebuf, sizeof (namebuf), "%s/%s", | ||
zc->zc_name, recv_clone_name) >= | ||
sizeof (namebuf)) | ||
return (EINVAL); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: return (SET_ERROR(EINVAL));
.
1425695
to
0f8523d
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One last thing!
config/no-format-truncation.m4
Outdated
@@ -0,0 +1,22 @@ | |||
dnl # |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This file should be renamed user-no-format-truncation.m4
since the configure check is only run as part of the user space build.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah yes, will rename
@behlendorf file renamed in latest push |
GCC 7.1 with will warn when we're not checking the snprintf() return code in cases where the buffer could be truncated. This patch either checks the snprintf return code (where applicable), or simply disables the warnings (ztest.c). Reviewed-by: Chunwei Chen <david.chen@osnexus.com> Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: Tony Hutter <hutter2@llnl.gov> Closes openzfs#6253
GCC 7.1 with will warn when we're not checking the snprintf() return code in cases where the buffer could be truncated. This patch either checks the snprintf return code (where applicable), or simply disables the warnings (ztest.c). Reviewed-by: Chunwei Chen <david.chen@osnexus.com> Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: Tony Hutter <hutter2@llnl.gov> Closes #6253
GCC 7.1 with will warn when we're not checking the snprintf()
return code in cases where the buffer could be truncated. This
patch either checks the snprintf return code (where applicable),
or simply disables the warnings (ztest.c).
Signed-off-by: Tony Hutter hutter2@llnl.gov
Motivation and Context
Fixes #6221
How Has This Been Tested?
Built on Fedora 26 alpha with gcc 7.1.1
Types of changes
Checklist:
Signed-off-by
.