tipc: compat: allow tipc commands without arguments [Linux 4.9.189]

This Linux kernel change "tipc: compat: allow tipc commands without arguments" is included in the Linux 4.9.189 release. This change is authored by Taras Kondratiuk <takondra [at] cisco.com> on Mon Jul 29 22:15:07 2019 +0000. The commit for this change in Linux stable tree is 695074c (patch) which is from upstream commit 4da5f00. The same Linux upstream change may have been applied to various maintained Linux releases and you can find all Linux releases containing changes from upstream 4da5f00.

tipc: compat: allow tipc commands without arguments

[ Upstream commit 4da5f0018eef4c0de31675b670c80e82e13e99d1 ]

Commit 2753ca5d9009 ("tipc: fix uninit-value in tipc_nl_compat_doit")
broke older tipc tools that use compat interface (e.g. tipc-config from
tipcutils package):

% tipc-config -p
operation not supported

The commit started to reject TIPC netlink compat messages that do not
have attributes. It is too restrictive because some of such messages are
valid (they don't need any arguments):

% grep 'tx none' include/uapi/linux/tipc_config.h
#define  TIPC_CMD_NOOP              0x0000    /* tx none, rx none */
#define  TIPC_CMD_GET_MEDIA_NAMES   0x0002    /* tx none, rx media_name(s) */
#define  TIPC_CMD_GET_BEARER_NAMES  0x0003    /* tx none, rx bearer_name(s) */
#define  TIPC_CMD_SHOW_PORTS        0x0006    /* tx none, rx ultra_string */
#define  TIPC_CMD_GET_REMOTE_MNG    0x4003    /* tx none, rx unsigned */
#define  TIPC_CMD_GET_MAX_PORTS     0x4004    /* tx none, rx unsigned */
#define  TIPC_CMD_GET_NETID         0x400B    /* tx none, rx unsigned */
#define  TIPC_CMD_NOT_NET_ADMIN     0xC001    /* tx none, rx none */

This patch relaxes the original fix and rejects messages without
arguments only if such arguments are expected by a command (reg_type is
non zero).

Fixes: 2753ca5d9009 ("tipc: fix uninit-value in tipc_nl_compat_doit")
Cc: stable@vger.kernel.org
Signed-off-by: Taras Kondratiuk <takondra@cisco.com>
Acked-by: Ying Xue <ying.xue@windriver.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

There are 11 lines of Linux source code added/deleted in this change. Code changes to Linux kernel are as follows.

 net/tipc/netlink_compat.c | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/net/tipc/netlink_compat.c b/net/tipc/netlink_compat.c
index b7c539a..63a913b 100644
--- a/net/tipc/netlink_compat.c
+++ b/net/tipc/netlink_compat.c
@@ -55,6 +55,7 @@ struct tipc_nl_compat_msg {
    int rep_type;
    int rep_size;
    int req_type;
+   int req_size;
    struct net *net;
    struct sk_buff *rep;
    struct tlv_desc *req;
@@ -252,7 +253,8 @@ static int tipc_nl_compat_dumpit(struct tipc_nl_compat_cmd_dump *cmd,
    int err;
    struct sk_buff *arg;

-   if (msg->req_type && !TLV_CHECK_TYPE(msg->req, msg->req_type))
+   if (msg->req_type && (!msg->req_size ||
+                 !TLV_CHECK_TYPE(msg->req, msg->req_type)))
        return -EINVAL;

    msg->rep = tipc_tlv_alloc(msg->rep_size);
@@ -345,7 +347,8 @@ static int tipc_nl_compat_doit(struct tipc_nl_compat_cmd_doit *cmd,
 {
    int err;

-   if (msg->req_type && !TLV_CHECK_TYPE(msg->req, msg->req_type))
+   if (msg->req_type && (!msg->req_size ||
+                 !TLV_CHECK_TYPE(msg->req, msg->req_type)))
        return -EINVAL;

    err = __tipc_nl_compat_doit(cmd, msg);
@@ -1267,8 +1270,8 @@ static int tipc_nl_compat_recv(struct sk_buff *skb, struct genl_info *info)
        goto send;
    }

-   len = nlmsg_attrlen(req_nlh, GENL_HDRLEN + TIPC_GENL_HDRLEN);
-   if (!len || !TLV_OK(msg.req, len)) {
+   msg.req_size = nlmsg_attrlen(req_nlh, GENL_HDRLEN + TIPC_GENL_HDRLEN);
+   if (msg.req_size && !TLV_OK(msg.req, msg.req_size)) {
        msg.rep = tipc_get_err_tlv(TIPC_CFG_NOT_SUPPORTED);
        err = -EOPNOTSUPP;
        goto send;

Leave a Reply

Your email address will not be published. Required fields are marked *