@@ -62,6 +62,7 @@ netlink_kernel_create(struct net *net, int unit, struct netlink_kernel_cfg *cfg)
/* this can be increased when necessary - don't expose to userland */
#define NETLINK_MAX_COOKIE_LEN 20
+#define NL_EXTACK_MAX_MSG_SZ 128
/**
* struct netlink_ext_ack - netlink extended ACK report struct
@@ -72,40 +73,36 @@ netlink_kernel_create(struct net *net, int unit, struct netlink_kernel_cfg *cfg)
* @cookie_len: actual cookie data length
*/
struct netlink_ext_ack {
- const char *_msg;
+ char _msg[NL_EXTACK_MAX_MSG_SZ];
const struct nlattr *bad_attr;
u8 cookie[NETLINK_MAX_COOKIE_LEN];
u8 cookie_len;
};
-/* Always use this macro, this allows later putting the
- * message into a separate section or such for things
- * like translation or listing all possible messages.
- * Currently string formatting is not supported (due
- * to the lack of an output buffer.)
- */
-#define NL_SET_ERR_MSG(extack, msg) do { \
- static const char __msg[] = msg; \
+#define NL_MSG_FMT(extack, fmt, ...) \
+ WARN_ON(snprintf(extack->_msg, NL_EXTACK_MAX_MSG_SZ, fmt, ## __VA_ARGS__) \
+ >= NL_EXTACK_MAX_MSG_SZ)
+
+#define NL_SET_ERR_MSG(extack, fmt, ...) do { \
struct netlink_ext_ack *__extack = (extack); \
\
if (__extack) \
- __extack->_msg = __msg; \
+ NL_MSG_FMT(__extack, fmt, ## __VA_ARGS__); \
} while (0)
-#define NL_SET_ERR_MSG_MOD(extack, msg) \
- NL_SET_ERR_MSG((extack), KBUILD_MODNAME ": " msg)
+#define NL_SET_ERR_MSG_MOD(extack, fmt, ...) \
+ NL_SET_ERR_MSG((extack), KBUILD_MODNAME ": " fmt, ## __VA_ARGS__)
#define NL_SET_BAD_ATTR(extack, attr) do { \
if ((extack)) \
(extack)->bad_attr = (attr); \
} while (0)
-#define NL_SET_ERR_MSG_ATTR(extack, attr, msg) do { \
- static const char __msg[] = msg; \
+#define NL_SET_ERR_MSG_ATTR(extack, attr, fmt, ...) do { \
struct netlink_ext_ack *__extack = (extack); \
\
if (__extack) { \
- __extack->_msg = __msg; \
+ NL_MSG_FMT(__extack, fmt, ## __VA_ARGS__); \
__extack->bad_attr = (attr); \
} \
} while (0)
@@ -208,7 +208,7 @@ static int validate_nla(const struct nlattr *nla, int maxtype,
case NLA_REJECT:
if (extack && pt->validation_data) {
NL_SET_BAD_ATTR(extack, nla);
- extack->_msg = pt->validation_data;
+ NL_MSG_FMT(extack, pt->validation_data);
return -EINVAL;
}
err = -EINVAL;