diff --git a/0001-patchset-for-3.2.29-2.patch b/0001-patchset-for-3.2.29-2.patch new file mode 100644 index 0000000..a0c1aa8 --- /dev/null +++ b/0001-patchset-for-3.2.29-2.patch @@ -0,0 +1,458 @@ +From e70446547eafb7966801839f3c43fa833452e637 Mon Sep 17 00:00:00 2001 +From: Tobias Klauser +Date: Fri, 13 Jan 2017 18:18:20 +0100 +Subject: [PATCH 1/8] route/tc: Remove unused function tca_set_kind() + +The public prototype and the last internal user of the function were +removed in commit 8eb5b5532e ("Unified TC API") and it was unexported in +commit 4280dfb85d ("build: don't export internal symbols"), so it is +safe to remove it. + +Signed-off-by: Tobias Klauser +Signed-off-by: Thomas Haller + +https://github.com/thom311/libnl/pull/122 +(cherry picked from commit e2d8f05bd9ffc6748d1c02482cba8c693a49557c) +--- + lib/route/tc.c | 6 ------ + 1 file changed, 6 deletions(-) + +diff --git a/lib/route/tc.c b/lib/route/tc.c +index 384e857..f5b23f0 100644 +--- a/lib/route/tc.c ++++ b/lib/route/tc.c +@@ -239,12 +239,6 @@ nla_put_failure: + return err; + } + +-void tca_set_kind(struct rtnl_tc *t, const char *kind) +-{ +- strncpy(t->tc_kind, kind, sizeof(t->tc_kind) - 1); +- t->ce_mask |= TCA_ATTR_KIND; +-} +- + + /** @endcond */ + +-- +2.9.3 + + +From f1d7373022ccdea288e19e19b566fe133a7ced3f Mon Sep 17 00:00:00 2001 +From: Laine Stump +Date: Tue, 17 Jan 2017 10:47:34 -0500 +Subject: [PATCH 2/8] sriov: fix crash in rtnl_link_sriov_parse_vflist + +vf_vlan_info was incorrectly indexed with "len" (the length in bytes +of the entire vfinfo_list rather than list_len (the index of the +current end of the vf_vlan_info array) + +https://github.com/thom311/libnl/issues/126 +http://lists.infradead.org/pipermail/libnl/2017-January/002270.html + +Fixes: 5d6e43ebef12deadf31fccfa46c0b34892675d36 + +Signed-off-by: Thomas Haller +(cherry picked from commit 2d11f40f5034eeee4c2c994aa4015aa11d7a3784) +--- + lib/route/link/sriov.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/lib/route/link/sriov.c b/lib/route/link/sriov.c +index acabf67..3721ae8 100644 +--- a/lib/route/link/sriov.c ++++ b/lib/route/link/sriov.c +@@ -568,7 +568,7 @@ int rtnl_link_sriov_parse_vflist(struct rtnl_link *link, struct nlattr **tb) { + list_len = 0; + nla_for_each_nested(nla_list, t[IFLA_VF_VLAN_LIST], + list_rem) { +- vf_vlan_info[len] = nla_data(nla_list); ++ vf_vlan_info[list_len] = nla_data(nla_list); + list_len++; + } + +-- +2.9.3 + + +From b314759618a6ce7e93023c0f32595fa2105f5541 Mon Sep 17 00:00:00 2001 +From: Thomas Haller +Date: Tue, 17 Jan 2017 18:16:11 +0100 +Subject: [PATCH 3/8] sriov: avoid buffer overrun in + rtnl_link_sriov_parse_vflist() + +Fixes: 5d6e43ebef12deadf31fccfa46c0b34892675d36 + +Signed-off-by: Thomas Haller +(cherry picked from commit 20ed636dee408d5fb288c400394342e619a55559) +--- + lib/route/link/sriov.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/lib/route/link/sriov.c b/lib/route/link/sriov.c +index 3721ae8..b4bc9a7 100644 +--- a/lib/route/link/sriov.c ++++ b/lib/route/link/sriov.c +@@ -568,6 +568,8 @@ int rtnl_link_sriov_parse_vflist(struct rtnl_link *link, struct nlattr **tb) { + list_len = 0; + nla_for_each_nested(nla_list, t[IFLA_VF_VLAN_LIST], + list_rem) { ++ if (list_len >= MAX_VLAN_LIST_LEN) ++ break; + vf_vlan_info[list_len] = nla_data(nla_list); + list_len++; + } +-- +2.9.3 + + +From a6fc07243cccd320ec9f95e49b349d9e36a6d7dd Mon Sep 17 00:00:00 2001 +From: Nick Kralevich +Date: Sat, 14 Jan 2017 11:11:34 -0800 +Subject: [PATCH 4/8] lib/utils.c: lazy initialize user_hz and psched_hz + +Rather than initializing user_hz and psched_hz when libnl is loaded, +defer initialization of these variables to the first time they are used. +This has several advantages: + +1) Avoids an unnecessary permission denied error on /proc/net/psched, +which can occur on systems where /proc/net isn't readable due to +security policy. +2) Allows program code to initialize the environment variables +PROC_NET_PSCHED and/or PROC_ROOT prior to the first libnl call, giving a +program more flexibility about where libnl should look. +3) Trivially faster startup time (although unlikely to be significant). +4) Compiler may be able to prove that the get_psched_settings() function +is unreachable and optimize appropriately, because the callers never +(directly or indirectly) use this method. This could occur, for +instance, in doing dead code elimination for programs which statically +link libnl. + +Signed-off-by: Nick Kralevich + +https://github.com/thom311/libnl/pull/123 +(cherry picked from commit 8e0ead4b5bcf22dcc210442629ebb416116ea1f0) +--- + lib/utils.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/lib/utils.c b/lib/utils.c +index 1c9e594..49e2547 100644 +--- a/lib/utils.c ++++ b/lib/utils.c +@@ -427,11 +427,15 @@ static double ticks_per_usec = 1.0f; + * Supports the environment variables: + * PROC_NET_PSCHED - may point to psched file in /proc + * PROC_ROOT - may point to /proc fs */ +-static void __init get_psched_settings(void) ++static void get_psched_settings(void) + { + char name[FILENAME_MAX]; + FILE *fd; + int got_hz = 0; ++ static int initialized = 0; ++ if (initialized == 1) { ++ return; ++ } + + if (getenv("HZ")) { + long hz = strtol(getenv("HZ"), NULL, 0); +@@ -480,6 +484,7 @@ static void __init get_psched_settings(void) + fclose(fd); + } + } ++ initialized = 1; + } + + +@@ -488,6 +493,7 @@ static void __init get_psched_settings(void) + */ + int nl_get_user_hz(void) + { ++ get_psched_settings(); + return user_hz; + } + +@@ -496,6 +502,7 @@ int nl_get_user_hz(void) + */ + int nl_get_psched_hz(void) + { ++ get_psched_settings(); + return psched_hz; + } + +-- +2.9.3 + + +From ab357122ddc3fa813dfa2e566755ebdec0f25a70 Mon Sep 17 00:00:00 2001 +From: Thomas Haller +Date: Tue, 17 Jan 2017 18:32:08 +0100 +Subject: [PATCH 5/8] lib/utils.c: ensure calling get_psched_settings() for + nl_us2ticks()/nl_ticks2us() + +(cherry picked from commit c33dec5a4a7df01730f90dd41f28a53c188aab46) +--- + lib/utils.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/lib/utils.c b/lib/utils.c +index 49e2547..7a791e1 100644 +--- a/lib/utils.c ++++ b/lib/utils.c +@@ -513,6 +513,7 @@ int nl_get_psched_hz(void) + */ + uint32_t nl_us2ticks(uint32_t us) + { ++ get_psched_settings(); + return us * ticks_per_usec; + } + +@@ -524,6 +525,7 @@ uint32_t nl_us2ticks(uint32_t us) + */ + uint32_t nl_ticks2us(uint32_t ticks) + { ++ get_psched_settings(); + return ticks / ticks_per_usec; + } + +-- +2.9.3 + + +From 8b63978d1ea9be8654af8fd790de6ae24deb84c7 Mon Sep 17 00:00:00 2001 +From: Thomas Haller +Date: Tue, 17 Jan 2017 18:49:42 +0100 +Subject: [PATCH 6/8] lib/utils.c: add mutex to get_psched_settings() + +Let's add a mutex to get_psched_settings() hoping to solve worst +case scenarios when calling get_psched_settings() from multiple +threads. + +Also, only read the environment variables once, who knows whether +they are modified concurrently. + +(cherry picked from commit 24d669a3a990d1d637fc94698cc4ae2c6e8e178e) +--- + lib/utils.c | 32 ++++++++++++++++++++------------ + 1 file changed, 20 insertions(+), 12 deletions(-) + +diff --git a/lib/utils.c b/lib/utils.c +index 7a791e1..fead196 100644 +--- a/lib/utils.c ++++ b/lib/utils.c +@@ -432,13 +432,20 @@ static void get_psched_settings(void) + char name[FILENAME_MAX]; + FILE *fd; + int got_hz = 0; +- static int initialized = 0; +- if (initialized == 1) { ++ static volatile int initialized = 0; ++ const char *ev; ++ NL_LOCK(mutex); ++ ++ if (initialized == 1) + return; +- } + +- if (getenv("HZ")) { +- long hz = strtol(getenv("HZ"), NULL, 0); ++ nl_lock(&mutex); ++ ++ if (initialized == 1) ++ return; ++ ++ if ((ev = getenv("HZ"))) { ++ long hz = strtol(ev, NULL, 0); + + if (LONG_MIN != hz && LONG_MAX != hz) { + user_hz = hz; +@@ -451,16 +458,15 @@ static void get_psched_settings(void) + + psched_hz = user_hz; + +- if (getenv("TICKS_PER_USEC")) { +- double t = strtod(getenv("TICKS_PER_USEC"), NULL); ++ if ((ev = getenv("TICKS_PER_USEC"))) { ++ double t = strtod(ev, NULL); + ticks_per_usec = t; + } + else { +- if (getenv("PROC_NET_PSCHED")) +- snprintf(name, sizeof(name), "%s", getenv("PROC_NET_PSCHED")); +- else if (getenv("PROC_ROOT")) +- snprintf(name, sizeof(name), "%s/net/psched", +- getenv("PROC_ROOT")); ++ if ((ev = getenv("PROC_NET_PSCHED"))) ++ snprintf(name, sizeof(name), "%s", ev); ++ else if ((ev = getenv("PROC_ROOT"))) ++ snprintf(name, sizeof(name), "%s/net/psched", ev); + else + strncpy(name, "/proc/net/psched", sizeof(name) - 1); + +@@ -485,6 +491,8 @@ static void get_psched_settings(void) + } + } + initialized = 1; ++ ++ nl_unlock(&mutex); + } + + +-- +2.9.3 + + +From 64d91a58f78116a769eb274e6360a63c4bbf3140 Mon Sep 17 00:00:00 2001 +From: Nick Kralevich +Date: Tue, 17 Jan 2017 10:56:52 -0800 +Subject: [PATCH 7/8] fopen: add O_CLOEXEC + +Add O_CLOEXEC to various fopen() calls. This avoids file descriptors +leaking across an exec() boundary in a multi-threaded program. Please +see "man 2 open" for additional information about O_CLOEXEC. + +Signed-off-by: Nick Kralevich + +https://github.com/thom311/libnl/pull/128 +(cherry picked from commit 64b12a065ae4fb84ae92299037c7eb8526549c85) +--- + lib/route/classid.c | 4 ++-- + lib/route/pktloc.c | 2 +- + lib/route/qdisc/netem.c | 2 +- + lib/utils.c | 4 ++-- + src/nl-list-sockets.c | 2 +- + 5 files changed, 7 insertions(+), 7 deletions(-) + +diff --git a/lib/route/classid.c b/lib/route/classid.c +index f2d3a01..0331eee 100644 +--- a/lib/route/classid.c ++++ b/lib/route/classid.c +@@ -328,7 +328,7 @@ int rtnl_tc_read_classid_file(void) + } + } + +- if (!(fd = fopen(path, "r"))) { ++ if (!(fd = fopen(path, "re"))) { + err = -nl_syserr2nlerr(errno); + goto errout; + } +@@ -402,7 +402,7 @@ int rtnl_classid_generate(const char *name, uint32_t *result, uint32_t parent) + if (build_sysconf_path(&path, "classid") < 0) + return -NLE_NOMEM; + +- if (!(fd = fopen(path, "a"))) { ++ if (!(fd = fopen(path, "ae"))) { + err = -nl_syserr2nlerr(errno); + goto errout; + } +diff --git a/lib/route/pktloc.c b/lib/route/pktloc.c +index 75d049e..6d95cc5 100644 +--- a/lib/route/pktloc.c ++++ b/lib/route/pktloc.c +@@ -109,7 +109,7 @@ static int read_pktlocs(void) + + NL_DBG(2, "Reading packet location file \"%s\"\n", path); + +- if (!(fd = fopen(path, "r"))) { ++ if (!(fd = fopen(path, "re"))) { + err = -NLE_PKTLOC_FILE; + goto errout; + } +diff --git a/lib/route/qdisc/netem.c b/lib/route/qdisc/netem.c +index 399fd2c..8ecc405 100644 +--- a/lib/route/qdisc/netem.c ++++ b/lib/route/qdisc/netem.c +@@ -901,7 +901,7 @@ int rtnl_netem_set_delay_distribution(struct rtnl_qdisc *qdisc, const char *dist + + for (i = 0; i < ARRAY_SIZE(test_path); i++) { + snprintf(name, NAME_MAX, "%s%s%s", test_path[i], dist_type, dist_suffix); +- if ((f = fopen(name, "r"))) ++ if ((f = fopen(name, "re"))) + break; + } + +diff --git a/lib/utils.c b/lib/utils.c +index fead196..64e87b6 100644 +--- a/lib/utils.c ++++ b/lib/utils.c +@@ -75,7 +75,7 @@ int __nl_read_num_str_file(const char *path, int (*cb)(long, const char *)) + FILE *fd; + char buf[128]; + +- fd = fopen(path, "r"); ++ fd = fopen(path, "re"); + if (fd == NULL) + return -nl_syserr2nlerr(errno); + +@@ -470,7 +470,7 @@ static void get_psched_settings(void) + else + strncpy(name, "/proc/net/psched", sizeof(name) - 1); + +- if ((fd = fopen(name, "r"))) { ++ if ((fd = fopen(name, "re"))) { + unsigned int ns_per_usec, ns_per_tick, nom, denom; + + if (fscanf(fd, "%08x %08x %08x %08x", +diff --git a/src/nl-list-sockets.c b/src/nl-list-sockets.c +index c2fa1cd..74957de 100644 +--- a/src/nl-list-sockets.c ++++ b/src/nl-list-sockets.c +@@ -18,7 +18,7 @@ int main(int argc, char *argv[]) + FILE *fd; + char buf[2048], p[64]; + +- fd = fopen(PROC_NETLINK, "r"); ++ fd = fopen(PROC_NETLINK, "re"); + if (fd == NULL) { + perror("fopen"); + return -1; +-- +2.9.3 + + +From f2d61fa9a602248340774fb2cc1ac452fa0b101b Mon Sep 17 00:00:00 2001 +From: Thomas Haller +Date: Wed, 18 Jan 2017 11:59:23 +0100 +Subject: [PATCH 8/8] lib/attr.c: check for valid length argument in + nla_reserve() + +https://github.com/thom311/libnl/issues/124 +(cherry picked from commit c473d59f972c35c5a7363d52ee6ee1e0792de0f8) +--- + lib/attr.c | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +diff --git a/lib/attr.c b/lib/attr.c +index a3d1b16..0dca3ec 100644 +--- a/lib/attr.c ++++ b/lib/attr.c +@@ -457,7 +457,10 @@ struct nlattr *nla_reserve(struct nl_msg *msg, int attrtype, int attrlen) + { + struct nlattr *nla; + int tlen; +- ++ ++ if (attrlen < 0) ++ return NULL; ++ + tlen = NLMSG_ALIGN(msg->nm_nlh->nlmsg_len) + nla_total_size(attrlen); + + if (tlen > msg->nm_size) +@@ -499,8 +502,12 @@ int nla_put(struct nl_msg *msg, int attrtype, int datalen, const void *data) + struct nlattr *nla; + + nla = nla_reserve(msg, attrtype, datalen); +- if (!nla) ++ if (!nla) { ++ if (datalen < 0) ++ return -NLE_INVAL; ++ + return -NLE_NOMEM; ++ } + + if (datalen > 0) { + memcpy(nla_data(nla), data, datalen); +-- +2.9.3 + diff --git a/libnl3.spec b/libnl3.spec index a9030a3..4a3aac9 100644 --- a/libnl3.spec +++ b/libnl3.spec @@ -1,6 +1,6 @@ Name: libnl3 Version: 3.2.29 -Release: 1%{?dist} +Release: 2%{?dist} Summary: Convenience library for kernel netlink sockets Group: Development/Libraries License: LGPLv2 @@ -11,6 +11,8 @@ URL: http://www.infradead.org/~tgr/libnl/ Source: http://www.infradead.org/~tgr/libnl/files/libnl-%{fullversion}.tar.gz Source1: http://www.infradead.org/~tgr/libnl/files/libnl-doc-%{fullversion}.tar.gz +Patch1: 0001-patchset-for-3.2.29-2.patch + BuildRequires: flex bison BuildRequires: python BuildRequires: libtool autoconf automake @@ -69,6 +71,8 @@ Python 3 bindings for libnl3 %prep %setup -q -n libnl-%{fullversion} +%patch1 -p1 + tar -xzf %SOURCE1 %build @@ -148,6 +152,13 @@ popd %{python3_sitearch}/netlink-*.egg-info %changelog +* Wed Jan 18 2017 Thomas Haller - 3.2.29-2 +- Update with patches from upstream +- check valid input arguments for nla_reserve() (rh#1414305, CVE-2017-0386) +- fix crash during SRIOV parsing +- lazyly read psched settings +- use O_CLOEXEC when creating file descriptors with fopen() + * Fri Dec 30 2016 Thomas Haller - 3.2.29-1 - Update to 3.2.29