From nobody Fri Mar 29 20:36:13 2024 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4V5sct3Wvyz5Fgrb; Fri, 29 Mar 2024 20:36:14 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4V5sct0H7zz4DPK; Fri, 29 Mar 2024 20:36:14 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1711744574; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=WCMJlGBhv8jRXvgz2bvSM/0oGXkmgzl8FiJ7fha6HBY=; b=drGk8wn8LqHv2iy41M5M0RPPVbABOL/SgrEy6p0JSUhSOc8/OniLF+Z/70Z3+J/6ZpBfz8 gl5mM3T5Q+OIUjkL/zJGxUiDHYoc5mQyNmohc/i6TrKoy0B4c5tbrjwisDvQFJ5CkJuvqr kIQjdTrIHIOPsx/+7S/7qqyMQsIR/iDXGMtEdpIA/6ACwIBYEvnUkUXV915blwwe9+ZEzK WFBUG3NRkmn3aOXImn6UTU5s8JscYdVivUzeDTWBa5AlM90WgQTfSxEB85TMtQ9mhZWt17 Yw9hgSEWkCCKG1EKd583aukueKfy0VxC53r7nO5wKJvcPVanBw0zz8pP9Hxw1A== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1711744574; a=rsa-sha256; cv=none; b=Q5I1DI2ori7wU03ei0kwyJRqa0tQGcb3lf+24QBEBYlxiXx9Z7rpGVVtxLGUPaWtY/qhg/ AFJ7weY5dcywg49saa3Fbx8z7UutOtRBv/epSG6JTbp98hzYUFD70lZOyZTX40k8IlLmK/ jEjRxP9d4LQTw1fuVwet/amLzdyt/fp9lELkoE4pKI8CZ6JbsX0tBIIu60O69cJ16dtLae caNyDq8P7fH7X3j1J6FV2U5h2bQfzUubhF8pgMugCd3S8PxfTXMgzI1+D5N0Jy5h/M/Unz r5DCfXziLhYOpzdta0qX1Ef8yQWjZhaOM/9BWkdSn5Op4c3wHNYazkDq1NBz2g== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1711744574; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=WCMJlGBhv8jRXvgz2bvSM/0oGXkmgzl8FiJ7fha6HBY=; b=aa/Wq3AmtyeM6CustLNnl2CRFpfWlidT81MC8JPQJwGaCXglPPsQTK0/Ujsyfy9ma44vv9 slzxKyiTtyb1YLwU3XnlL6QuYTxF0PTGjWWrKT8JbF+lAFiWCkrwr0BnkTgs1czdgKyLAf Q3AX/hexKCstFEgOZd8LRxw3qeohFKz13oA4aynTlpE1C3E2Oa8yFK/MXvmRdNDsu4xGXF Y7f454D2ig1EJO44tCD44KGHFx/vj6wdeFKVlBmacd8VfP7RYZ4A+4YBYJvZQiXNyIU1V4 lVQlaPzpMrTf/hYC+I89l12/SKz2KIr602mMSdbujsS48tTkPwIOBhdHlFqyVA== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4V5scs714dzQ99; Fri, 29 Mar 2024 20:36:13 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.17.1/8.17.1) with ESMTP id 42TKaDDE023294; Fri, 29 Mar 2024 20:36:13 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.17.1/8.17.1/Submit) id 42TKaDlZ023291; Fri, 29 Mar 2024 20:36:13 GMT (envelope-from git) Date: Fri, 29 Mar 2024 20:36:13 GMT Message-Id: <202403292036.42TKaDlZ023291@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Gleb Smirnoff Subject: git: b977dd1ea5fb - main - linux: make linux_netlink_p->msg_from_linux be able to fail List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-all@freebsd.org X-BeenThere: dev-commits-src-all@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: glebius X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: b977dd1ea5fbc2df3f1279330be4d089322eb2cf Auto-Submitted: auto-generated The branch main has been updated by glebius: URL: https://cgit.FreeBSD.org/src/commit/?id=b977dd1ea5fbc2df3f1279330be4d089322eb2cf commit b977dd1ea5fbc2df3f1279330be4d089322eb2cf Author: Gleb Smirnoff AuthorDate: 2024-03-29 20:35:51 +0000 Commit: Gleb Smirnoff CommitDate: 2024-03-29 20:35:51 +0000 linux: make linux_netlink_p->msg_from_linux be able to fail The KPI for this function was misleading. From the NetLink perspective it looked like a function that: a) allocates new hdr, b) can fail. Neither was true. Let the function return a error code instead of returning the same hdr it was passed to. In case if future Linux NetLink compatibility support calls for reallocating header, pass hdr as pointer to pointer. With KPI that returns a error, propagate domain conversion errors all the way up to NetLink module. This fixes panic when unknown domain is converted to 0xff and this invalid value is passed into NetLink processing. PR: 274536 Reviewed by: melifaro Differential Revision: https://reviews.freebsd.org/D44392 --- sys/compat/linux/linux_netlink.c | 58 ++++++++++++++++++++++++++-------------- sys/netlink/netlink_io.c | 22 +++++++-------- sys/netlink/netlink_linux.h | 2 +- 3 files changed, 48 insertions(+), 34 deletions(-) diff --git a/sys/compat/linux/linux_netlink.c b/sys/compat/linux/linux_netlink.c index d2afec24fe71..8675f830b4ef 100644 --- a/sys/compat/linux/linux_netlink.c +++ b/sys/compat/linux/linux_netlink.c @@ -31,7 +31,6 @@ #include #include #include -#include #include #include @@ -73,37 +72,55 @@ _rta_get_uint32(const struct rtattr *rta) return (*((const uint32_t *)NL_RTA_DATA_CONST(rta))); } -static struct nlmsghdr * +static int rtnl_neigh_from_linux(struct nlmsghdr *hdr, struct nl_pstate *npt) { struct ndmsg *ndm = (struct ndmsg *)(hdr + 1); + sa_family_t f; + + if (hdr->nlmsg_len < sizeof(struct nlmsghdr) + sizeof(struct ndmsg)) + return (EBADMSG); + if ((f = linux_to_bsd_domain(ndm->ndm_family)) == AF_UNKNOWN) + return (EPFNOSUPPORT); - if (hdr->nlmsg_len >= sizeof(struct nlmsghdr) + sizeof(struct ndmsg)) - ndm->ndm_family = linux_to_bsd_domain(ndm->ndm_family); + ndm->ndm_family = f; - return (hdr); + return (0); } -static struct nlmsghdr * +static int rtnl_ifaddr_from_linux(struct nlmsghdr *hdr, struct nl_pstate *npt) { struct ifaddrmsg *ifam = (struct ifaddrmsg *)(hdr + 1); + sa_family_t f; - if (hdr->nlmsg_len >= sizeof(struct nlmsghdr) + sizeof(struct ifaddrmsg)) - ifam->ifa_family = linux_to_bsd_domain(ifam->ifa_family); + if (hdr->nlmsg_len < sizeof(struct nlmsghdr) + sizeof(struct ifaddrmsg)) + return (EBADMSG); + if ((f = linux_to_bsd_domain(ifam->ifa_family)) == AF_UNKNOWN) + return (EPFNOSUPPORT); - return (hdr); + ifam->ifa_family = f; + + return (0); } -static struct nlmsghdr * +/* + * XXX: in case of error state of hdr is inconsistent. + */ +static int rtnl_route_from_linux(struct nlmsghdr *hdr, struct nl_pstate *npt) { /* Tweak address families and default fib only */ struct rtmsg *rtm = (struct rtmsg *)(hdr + 1); struct nlattr *nla, *nla_head; int attrs_len; + sa_family_t f; - rtm->rtm_family = linux_to_bsd_domain(rtm->rtm_family); + if (hdr->nlmsg_len < sizeof(struct nlmsghdr) + sizeof(struct rtmsg)) + return (EBADMSG); + if ((f = linux_to_bsd_domain(rtm->rtm_family)) == AF_UNKNOWN) + return (EPFNOSUPPORT); + rtm->rtm_family = f; if (rtm->rtm_table == 254) rtm->rtm_table = 0; @@ -122,7 +139,7 @@ rtnl_route_from_linux(struct nlmsghdr *hdr, struct nl_pstate *npt) switch (rta->rta_type) { case NL_RTA_TABLE: if (!valid_rta_u32(rta)) - goto done; + return (EBADMSG); rtm->rtm_table = 0; uint32_t fibnum = _rta_get_uint32(rta); RT_LOG(LOG_DEBUG3, "GET RTABLE: %u", fibnum); @@ -133,13 +150,13 @@ rtnl_route_from_linux(struct nlmsghdr *hdr, struct nl_pstate *npt) } } -done: - return (hdr); + return (0); } -static struct nlmsghdr * +static int rtnl_from_linux(struct nlmsghdr *hdr, struct nl_pstate *npt) { + switch (hdr->nlmsg_type) { case NL_RTM_GETROUTE: case NL_RTM_NEWROUTE: @@ -157,21 +174,22 @@ rtnl_from_linux(struct nlmsghdr *hdr, struct nl_pstate *npt) default: RT_LOG(LOG_DEBUG, "Passing message type %d untranslated", hdr->nlmsg_type); + /* XXXGL: maybe return error? */ } - return (hdr); + return (0); } -static struct nlmsghdr * -nlmsg_from_linux(int netlink_family, struct nlmsghdr *hdr, +static int +nlmsg_from_linux(int netlink_family, struct nlmsghdr **hdr, struct nl_pstate *npt) { switch (netlink_family) { case NETLINK_ROUTE: - return (rtnl_from_linux(hdr, npt)); + return (rtnl_from_linux(*hdr, npt)); } - return (hdr); + return (0); } diff --git a/sys/netlink/netlink_io.c b/sys/netlink/netlink_io.c index 61d9d657556a..2dd49d5e8eb5 100644 --- a/sys/netlink/netlink_io.c +++ b/sys/netlink/netlink_io.c @@ -275,25 +275,21 @@ nl_receive_message(struct nlmsghdr *hdr, int remaining_length, npt->hdr = hdr; - if (hdr->nlmsg_flags & NLM_F_REQUEST && hdr->nlmsg_type >= NLMSG_MIN_TYPE) { + if (hdr->nlmsg_flags & NLM_F_REQUEST && + hdr->nlmsg_type >= NLMSG_MIN_TYPE) { NL_LOG(LOG_DEBUG2, "handling message with msg type: %d", hdr->nlmsg_type); - - if (nlp->nl_linux && linux_netlink_p != NULL) { - struct nlmsghdr *hdr_orig = hdr; - hdr = linux_netlink_p->msg_from_linux(nlp->nl_proto, hdr, npt); - if (hdr == NULL) { - /* Failed to translate to kernel format. Report an error back */ - hdr = hdr_orig; - npt->hdr = hdr; - if (hdr->nlmsg_flags & NLM_F_ACK) - nlmsg_ack(nlp, EOPNOTSUPP, hdr, npt); - return (0); - } + if (nlp->nl_linux) { + MPASS(linux_netlink_p != NULL); + error = linux_netlink_p->msg_from_linux(nlp->nl_proto, + &hdr, npt); + if (error) + goto ack; } error = handler(hdr, npt); NL_LOG(LOG_DEBUG2, "retcode: %d", error); } +ack: if ((hdr->nlmsg_flags & NLM_F_ACK) || (error != 0 && error != EINTR)) { if (!npt->nw->suppress_ack) { NL_LOG(LOG_DEBUG3, "ack"); diff --git a/sys/netlink/netlink_linux.h b/sys/netlink/netlink_linux.h index 2d9f8d1b7bd6..d4c451d470b2 100644 --- a/sys/netlink/netlink_linux.h +++ b/sys/netlink/netlink_linux.h @@ -38,7 +38,7 @@ struct nl_pstate; struct nl_writer; typedef bool msgs_to_linux_cb_t(struct nl_writer *nw, struct nlpcb *nlp); -typedef struct nlmsghdr *msg_from_linux_cb_t(int netlink_family, struct nlmsghdr *hdr, +typedef int msg_from_linux_cb_t(int netlink_family, struct nlmsghdr **hdr, struct nl_pstate *npt); struct linux_netlink_provider {