diff options
author | Hitendra Prajapati <hprajapati@mvista.com> | 2022-07-28 09:17:16 +0530 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2022-08-04 16:29:15 +0100 |
commit | d9fc6566783407a960e9526e0020522f3d1d7738 (patch) | |
tree | acc68dd594c188a13fdcb3f2f61f3148cd5dd704 | |
parent | caae799d638b70b4f3a3ff199f6c9ee8a3984526 (diff) | |
download | poky-d9fc6566783407a960e9526e0020522f3d1d7738.tar.gz |
libtirpc: CVE-2021-46828 DoS vulnerability with lots of connections
Source: http://git.linux-nfs.org/?p=steved/libtirpc.git;
MR: 120225
Type: Security Fix
Disposition: Backport from http://git.linux-nfs.org/?p=steved/libtirpc.git;a=commit;h=86529758570cef4c73fb9b9c4104fdc510f701ed
ChangeID: 29c32ee171a6a47e06c788e5c608fac9bb3a64b2
Description:
CVE-2021-46828 libtirpc: DoS vulnerability with lots of connections.
(From OE-Core rev: 7eeaf4e400bf57fc9d0a376085d1788bc5c146b3)
Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com>
Signed-off-by: Steve Sakoman <steve@sakoman.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-rw-r--r-- | meta/recipes-extended/libtirpc/libtirpc/CVE-2021-46828.patch | 155 | ||||
-rw-r--r-- | meta/recipes-extended/libtirpc/libtirpc_1.3.2.bb | 4 |
2 files changed, 158 insertions, 1 deletions
diff --git a/meta/recipes-extended/libtirpc/libtirpc/CVE-2021-46828.patch b/meta/recipes-extended/libtirpc/libtirpc/CVE-2021-46828.patch new file mode 100644 index 0000000000..3d5e5b8db9 --- /dev/null +++ b/meta/recipes-extended/libtirpc/libtirpc/CVE-2021-46828.patch | |||
@@ -0,0 +1,155 @@ | |||
1 | From 3ee23a0a5a8c2261e788acbee67722fcbecbea28 Mon Sep 17 00:00:00 2001 | ||
2 | From: Hitendra Prajapati <hprajapati@mvista.com> | ||
3 | Date: Wed, 27 Jul 2022 17:34:21 +0530 | ||
4 | Subject: [PATCH] CVE-2021-46828 | ||
5 | |||
6 | Upstream-Status: Backport [http://git.linux-nfs.org/?p=steved/libtirpc.git;a=commit;h=86529758570cef4c73fb9b9c4104fdc510f701ed} | ||
7 | CVE: CVE-2021-46828 | ||
8 | Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com> | ||
9 | --- | ||
10 | src/svc.c | 17 +++++++++++++- | ||
11 | src/svc_vc.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++- | ||
12 | 2 files changed, 77 insertions(+), 2 deletions(-) | ||
13 | |||
14 | diff --git a/src/svc.c b/src/svc.c | ||
15 | index 6db164b..3a8709f 100644 | ||
16 | --- a/src/svc.c | ||
17 | +++ b/src/svc.c | ||
18 | @@ -57,7 +57,7 @@ | ||
19 | |||
20 | #define max(a, b) (a > b ? a : b) | ||
21 | |||
22 | -static SVCXPRT **__svc_xports; | ||
23 | +SVCXPRT **__svc_xports; | ||
24 | int __svc_maxrec; | ||
25 | |||
26 | /* | ||
27 | @@ -194,6 +194,21 @@ __xprt_do_unregister (xprt, dolock) | ||
28 | rwlock_unlock (&svc_fd_lock); | ||
29 | } | ||
30 | |||
31 | +int | ||
32 | +svc_open_fds() | ||
33 | +{ | ||
34 | + int ix; | ||
35 | + int nfds = 0; | ||
36 | + | ||
37 | + rwlock_rdlock (&svc_fd_lock); | ||
38 | + for (ix = 0; ix < svc_max_pollfd; ++ix) { | ||
39 | + if (svc_pollfd[ix].fd != -1) | ||
40 | + nfds++; | ||
41 | + } | ||
42 | + rwlock_unlock (&svc_fd_lock); | ||
43 | + return (nfds); | ||
44 | +} | ||
45 | + | ||
46 | /* | ||
47 | * Add a service program to the callout list. | ||
48 | * The dispatch routine will be called when a rpc request for this | ||
49 | diff --git a/src/svc_vc.c b/src/svc_vc.c | ||
50 | index f1d9f00..3dc8a75 100644 | ||
51 | --- a/src/svc_vc.c | ||
52 | +++ b/src/svc_vc.c | ||
53 | @@ -64,6 +64,8 @@ | ||
54 | |||
55 | |||
56 | extern rwlock_t svc_fd_lock; | ||
57 | +extern SVCXPRT **__svc_xports; | ||
58 | +extern int svc_open_fds(); | ||
59 | |||
60 | static SVCXPRT *makefd_xprt(int, u_int, u_int); | ||
61 | static bool_t rendezvous_request(SVCXPRT *, struct rpc_msg *); | ||
62 | @@ -82,6 +84,7 @@ static void svc_vc_ops(SVCXPRT *); | ||
63 | static bool_t svc_vc_control(SVCXPRT *xprt, const u_int rq, void *in); | ||
64 | static bool_t svc_vc_rendezvous_control (SVCXPRT *xprt, const u_int rq, | ||
65 | void *in); | ||
66 | +static int __svc_destroy_idle(int timeout); | ||
67 | |||
68 | struct cf_rendezvous { /* kept in xprt->xp_p1 for rendezvouser */ | ||
69 | u_int sendsize; | ||
70 | @@ -313,13 +316,14 @@ done: | ||
71 | return (xprt); | ||
72 | } | ||
73 | |||
74 | + | ||
75 | /*ARGSUSED*/ | ||
76 | static bool_t | ||
77 | rendezvous_request(xprt, msg) | ||
78 | SVCXPRT *xprt; | ||
79 | struct rpc_msg *msg; | ||
80 | { | ||
81 | - int sock, flags; | ||
82 | + int sock, flags, nfds, cnt; | ||
83 | struct cf_rendezvous *r; | ||
84 | struct cf_conn *cd; | ||
85 | struct sockaddr_storage addr; | ||
86 | @@ -379,6 +383,16 @@ again: | ||
87 | |||
88 | gettimeofday(&cd->last_recv_time, NULL); | ||
89 | |||
90 | + nfds = svc_open_fds(); | ||
91 | + if (nfds >= (_rpc_dtablesize() / 5) * 4) { | ||
92 | + /* destroy idle connections */ | ||
93 | + cnt = __svc_destroy_idle(15); | ||
94 | + if (cnt == 0) { | ||
95 | + /* destroy least active */ | ||
96 | + __svc_destroy_idle(0); | ||
97 | + } | ||
98 | + } | ||
99 | + | ||
100 | return (FALSE); /* there is never an rpc msg to be processed */ | ||
101 | } | ||
102 | |||
103 | @@ -820,3 +834,49 @@ __svc_clean_idle(fd_set *fds, int timeout, bool_t cleanblock) | ||
104 | { | ||
105 | return FALSE; | ||
106 | } | ||
107 | + | ||
108 | +static int | ||
109 | +__svc_destroy_idle(int timeout) | ||
110 | +{ | ||
111 | + int i, ncleaned = 0; | ||
112 | + SVCXPRT *xprt, *least_active; | ||
113 | + struct timeval tv, tdiff, tmax; | ||
114 | + struct cf_conn *cd; | ||
115 | + | ||
116 | + gettimeofday(&tv, NULL); | ||
117 | + tmax.tv_sec = tmax.tv_usec = 0; | ||
118 | + least_active = NULL; | ||
119 | + rwlock_wrlock(&svc_fd_lock); | ||
120 | + | ||
121 | + for (i = 0; i <= svc_max_pollfd; i++) { | ||
122 | + if (svc_pollfd[i].fd == -1) | ||
123 | + continue; | ||
124 | + xprt = __svc_xports[i]; | ||
125 | + if (xprt == NULL || xprt->xp_ops == NULL || | ||
126 | + xprt->xp_ops->xp_recv != svc_vc_recv) | ||
127 | + continue; | ||
128 | + cd = (struct cf_conn *)xprt->xp_p1; | ||
129 | + if (!cd->nonblock) | ||
130 | + continue; | ||
131 | + if (timeout == 0) { | ||
132 | + timersub(&tv, &cd->last_recv_time, &tdiff); | ||
133 | + if (timercmp(&tdiff, &tmax, >)) { | ||
134 | + tmax = tdiff; | ||
135 | + least_active = xprt; | ||
136 | + } | ||
137 | + continue; | ||
138 | + } | ||
139 | + if (tv.tv_sec - cd->last_recv_time.tv_sec > timeout) { | ||
140 | + __xprt_unregister_unlocked(xprt); | ||
141 | + __svc_vc_dodestroy(xprt); | ||
142 | + ncleaned++; | ||
143 | + } | ||
144 | + } | ||
145 | + if (timeout == 0 && least_active != NULL) { | ||
146 | + __xprt_unregister_unlocked(least_active); | ||
147 | + __svc_vc_dodestroy(least_active); | ||
148 | + ncleaned++; | ||
149 | + } | ||
150 | + rwlock_unlock(&svc_fd_lock); | ||
151 | + return (ncleaned); | ||
152 | +} | ||
153 | -- | ||
154 | 2.25.1 | ||
155 | |||
diff --git a/meta/recipes-extended/libtirpc/libtirpc_1.3.2.bb b/meta/recipes-extended/libtirpc/libtirpc_1.3.2.bb index 45b3d2befc..66bc4ecdd1 100644 --- a/meta/recipes-extended/libtirpc/libtirpc_1.3.2.bb +++ b/meta/recipes-extended/libtirpc/libtirpc_1.3.2.bb | |||
@@ -9,7 +9,9 @@ LIC_FILES_CHKSUM = "file://COPYING;md5=f835cce8852481e4b2bbbdd23b5e47f3 \ | |||
9 | 9 | ||
10 | PROVIDES = "virtual/librpc" | 10 | PROVIDES = "virtual/librpc" |
11 | 11 | ||
12 | SRC_URI = "${SOURCEFORGE_MIRROR}/${BPN}/${BP}.tar.bz2" | 12 | SRC_URI = "${SOURCEFORGE_MIRROR}/${BPN}/${BP}.tar.bz2 \ |
13 | file://CVE-2021-46828.patch \ | ||
14 | " | ||
13 | UPSTREAM_CHECK_URI = "https://sourceforge.net/projects/libtirpc/files/libtirpc/" | 15 | UPSTREAM_CHECK_URI = "https://sourceforge.net/projects/libtirpc/files/libtirpc/" |
14 | UPSTREAM_CHECK_REGEX = "(?P<pver>\d+(\.\d+)+)/" | 16 | UPSTREAM_CHECK_REGEX = "(?P<pver>\d+(\.\d+)+)/" |
15 | SRC_URI[sha256sum] = "e24eb88b8ce7db3b7ca6eb80115dd1284abc5ec32a8deccfed2224fc2532b9fd" | 17 | SRC_URI[sha256sum] = "e24eb88b8ce7db3b7ca6eb80115dd1284abc5ec32a8deccfed2224fc2532b9fd" |