diff options
| author | Gyorgy Sarvari <skandigraun@gmail.com> | 2025-12-29 21:54:12 +0100 |
|---|---|---|
| committer | Anuj Mittal <anuj.mittal@oss.qualcomm.com> | 2025-12-30 07:08:16 +0530 |
| commit | 2b26d30fc7f478f5735d514f0c1bc28f6a4148b6 (patch) | |
| tree | b62b37d462a8b3334b9f2f76b99dc93a3cac908f | |
| parent | 02dbaa8843c04acae47e7a950c0d48871e5958e7 (diff) | |
| download | meta-openembedded-2b26d30fc7f478f5735d514f0c1bc28f6a4148b6.tar.gz | |
atop: patch CVE-2025-31160
Details: https://nvd.nist.gov/vuln/detail/CVE-2025-31160
Backport the patch that's subject references the CVE id explicitly.
I was able to verify the patch with a reproducer[1] (which is mentioned
in a reference[2] in the nvd report). Without the patch atop crashed,
with the patch it worked fine (both with and without -k/-K flags).
[1]: https://blog.bismuth.sh/blog/bismuth-found-the-atop-bug
[2]: https://gist.github.com/kallsyms/3acdf857ccc5c9fbaae7ed823be0365e
Signed-off-by: Gyorgy Sarvari <skandigraun@gmail.com>
Signed-off-by: Anuj Mittal <anuj.mittal@oss.qualcomm.com>
| -rw-r--r-- | meta-oe/recipes-support/atop/atop/CVE-2025-31160.patch | 607 | ||||
| -rw-r--r-- | meta-oe/recipes-support/atop/atop_2.4.0.bb | 1 |
2 files changed, 608 insertions, 0 deletions
diff --git a/meta-oe/recipes-support/atop/atop/CVE-2025-31160.patch b/meta-oe/recipes-support/atop/atop/CVE-2025-31160.patch new file mode 100644 index 0000000000..d83eca13ef --- /dev/null +++ b/meta-oe/recipes-support/atop/atop/CVE-2025-31160.patch | |||
| @@ -0,0 +1,607 @@ | |||
| 1 | From 6427a26127cfec800b7064fd8700837c9f0c3548 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Gerlof Langeveld <gerlof.langeveld@atoptool.nl> | ||
| 3 | Date: Sat, 29 Mar 2025 18:56:44 +0100 | ||
| 4 | Subject: [PATCH] Fix security vulnerability CVE-2025-31160 (#334) | ||
| 5 | |||
| 6 | Atop will not connect to the TCP port of 'atopgpud' daemon any more | ||
| 7 | by default. The flag -k can be used explicitly when 'atopgpud' is | ||
| 8 | active. Also the code to parse the received strings is improved to | ||
| 9 | avoid future issues with heap corruption. | ||
| 10 | |||
| 11 | The flag -K has been implemented to connect to netatop/netatop-bpf. | ||
| 12 | CVE: CVE-2025-31160 | ||
| 13 | Upstream-Status: Backport [https://github.com/Atoptool/atop/commit/ec8f3038497fcf493c6ff9c9f98f7a7c6216a1cb] | ||
| 14 | Signed-off-by: Gyorgy Sarvari <skandigraun@gmail.com> | ||
| 15 | --- | ||
| 16 | atop.c | 59 +++++++-------- | ||
| 17 | atop.h | 1 + | ||
| 18 | gpucom.c | 210 +++++++++++++++++++++++++++++++++++++--------------- | ||
| 19 | photoproc.c | 3 +- | ||
| 20 | 4 files changed, 182 insertions(+), 91 deletions(-) | ||
| 21 | |||
| 22 | diff --git a/atop.c b/atop.c | ||
| 23 | index 7ea9cc8..967df46 100644 | ||
| 24 | --- a/atop.c | ||
| 25 | +++ b/atop.c | ||
| 26 | @@ -333,6 +333,8 @@ int ossub; | ||
| 27 | int supportflags; /* supported features */ | ||
| 28 | char **argvp; | ||
| 29 | |||
| 30 | +char connectgpud = 0; /* boolean: connect to atopgpud */ | ||
| 31 | +char connectnetatop = 0; /* boolean: connect to netatop(bpf) */ | ||
| 32 | |||
| 33 | struct visualize vis = {generic_samp, generic_error, | ||
| 34 | generic_end, generic_usage}; | ||
| 35 | @@ -573,7 +575,12 @@ main(int argc, char *argv[]) | ||
| 36 | |||
| 37 | linelen = atoi(optarg); | ||
| 38 | break; | ||
| 39 | - | ||
| 40 | + case 'k': /* try to open TCP connection to atopgpud */ | ||
| 41 | + connectgpud = 1; | ||
| 42 | + break; | ||
| 43 | + case 'K': /* try to open connection to netatop/netatop-bpf */ | ||
| 44 | + connectnetatop = 1; | ||
| 45 | + break; | ||
| 46 | default: /* gather other flags */ | ||
| 47 | flaglist[i++] = c; | ||
| 48 | } | ||
| 49 | @@ -688,7 +695,8 @@ main(int argc, char *argv[]) | ||
| 50 | /* | ||
| 51 | ** open socket to the IP layer to issue getsockopt() calls later on | ||
| 52 | */ | ||
| 53 | - netatop_ipopen(); | ||
| 54 | + if (connectnetatop) | ||
| 55 | + netatop_ipopen(); | ||
| 56 | |||
| 57 | /* | ||
| 58 | ** since privileged activities are finished now, there is no | ||
| 59 | @@ -791,11 +799,15 @@ engine(void) | ||
| 60 | |||
| 61 | /* | ||
| 62 | ** open socket to the atopgpud daemon for GPU statistics | ||
| 63 | + ** if explicitly required | ||
| 64 | */ | ||
| 65 | - nrgpus = gpud_init(); | ||
| 66 | + if (connectgpud) | ||
| 67 | + { | ||
| 68 | + nrgpus = gpud_init(); | ||
| 69 | |||
| 70 | - if (nrgpus) | ||
| 71 | - supportflags |= GPUSTAT; | ||
| 72 | + if (nrgpus) | ||
| 73 | + supportflags |= GPUSTAT; | ||
| 74 | + } | ||
| 75 | |||
| 76 | /* | ||
| 77 | ** MAIN-LOOP: | ||
| 78 | @@ -842,7 +854,10 @@ engine(void) | ||
| 79 | ** send request for statistics to atopgpud | ||
| 80 | */ | ||
| 81 | if (nrgpus) | ||
| 82 | - gpupending = gpud_statrequest(); | ||
| 83 | + { | ||
| 84 | + if ((gpupending = gpud_statrequest()) == 0) | ||
| 85 | + nrgpus = 0; | ||
| 86 | + } | ||
| 87 | |||
| 88 | /* | ||
| 89 | ** take a snapshot of the current system-level statistics | ||
| 90 | @@ -867,28 +882,8 @@ engine(void) | ||
| 91 | // connection lost or timeout on receive? | ||
| 92 | if (nrgpuproc == -1) | ||
| 93 | { | ||
| 94 | - int ng; | ||
| 95 | - | ||
| 96 | - // try to reconnect | ||
| 97 | - ng = gpud_init(); | ||
| 98 | - | ||
| 99 | - if (ng != nrgpus) // no success | ||
| 100 | - nrgpus = 0; | ||
| 101 | - | ||
| 102 | - if (nrgpus) | ||
| 103 | - { | ||
| 104 | - // request for stats again | ||
| 105 | - if (gpud_statrequest()) | ||
| 106 | - { | ||
| 107 | - // receive stats response | ||
| 108 | - nrgpuproc = gpud_statresponse(nrgpus, | ||
| 109 | - cursstat->gpu.gpu, &gp); | ||
| 110 | - | ||
| 111 | - // persistent failure? | ||
| 112 | - if (nrgpuproc == -1) | ||
| 113 | - nrgpus = 0; | ||
| 114 | - } | ||
| 115 | - } | ||
| 116 | + nrgpus = 0; | ||
| 117 | + supportflags &= ~GPUSTAT; | ||
| 118 | } | ||
| 119 | |||
| 120 | cursstat->gpu.nrgpus = nrgpus; | ||
| 121 | @@ -977,7 +972,7 @@ engine(void) | ||
| 122 | /* | ||
| 123 | ** merge GPU per-process stats with other per-process stats | ||
| 124 | */ | ||
| 125 | - if (nrgpus && nrgpuproc) | ||
| 126 | + if (nrgpus && nrgpuproc > 0) | ||
| 127 | gpumergeproc(curtpres, ntaskpres, | ||
| 128 | curpexit, nprocexit, | ||
| 129 | gp, nrgpuproc); | ||
| 130 | @@ -1008,8 +1003,8 @@ engine(void) | ||
| 131 | if (nprocexitnet > 0) | ||
| 132 | netatop_exiterase(); | ||
| 133 | |||
| 134 | - if (gp) | ||
| 135 | - free(gp); | ||
| 136 | + free(gp); | ||
| 137 | + gp = NULL; // avoid double free | ||
| 138 | |||
| 139 | if (lastcmd == 'r') /* reset requested ? */ | ||
| 140 | { | ||
| 141 | @@ -1050,6 +1045,8 @@ prusage(char *myname) | ||
| 142 | printf("\t -P generate parseable output for specified label(s)\n"); | ||
| 143 | printf("\t -L alternate line length (default 80) in case of " | ||
| 144 | "non-screen output\n"); | ||
| 145 | + printf("\t -k try to connect to external atopgpud daemon (default: do not connect)\n"); | ||
| 146 | + printf("\t -K try to connect to netatop/netatop-bpf interface (default: do not connect)\n"); | ||
| 147 | |||
| 148 | (*vis.show_usage)(); | ||
| 149 | |||
| 150 | diff --git a/atop.h b/atop.h | ||
| 151 | index 791c450..cbf4225 100644 | ||
| 152 | --- a/atop.h | ||
| 153 | +++ b/atop.h | ||
| 154 | @@ -82,6 +82,7 @@ extern char threadview; | ||
| 155 | extern char calcpss; | ||
| 156 | extern char rawname[]; | ||
| 157 | extern char rawreadflag; | ||
| 158 | +extern char connectnetatop; | ||
| 159 | extern unsigned int begintime, endtime; | ||
| 160 | extern char flaglist[]; | ||
| 161 | extern struct visualize vis; | ||
| 162 | diff --git a/gpucom.c b/gpucom.c | ||
| 163 | index 4834851..690937e 100644 | ||
| 164 | --- a/gpucom.c | ||
| 165 | +++ b/gpucom.c | ||
| 166 | @@ -43,12 +43,12 @@ | ||
| 167 | |||
| 168 | #define GPUDPORT 59123 | ||
| 169 | |||
| 170 | -static void gputype_parse(char *); | ||
| 171 | +static int gputype_parse(char *); | ||
| 172 | |||
| 173 | -static void gpustat_parse(int, char *, int, | ||
| 174 | +static int gpustat_parse(int, char *, int, | ||
| 175 | struct pergpu *, struct gpupidstat *); | ||
| 176 | -static void gpuparse(int, char *, struct pergpu *); | ||
| 177 | -static void pidparse(int, char *, struct gpupidstat *); | ||
| 178 | +static int gpuparse(int, char *, struct pergpu *); | ||
| 179 | +static int pidparse(int, char *, struct gpupidstat *); | ||
| 180 | static int rcvuntil(int, char *, int); | ||
| 181 | |||
| 182 | static int actsock = -1; | ||
| 183 | @@ -150,20 +150,24 @@ gpud_init(void) | ||
| 184 | if ( rcvuntil(actsock, buf, length) == -1) | ||
| 185 | { | ||
| 186 | perror("receive type request from atopgpud"); | ||
| 187 | + free(buf); | ||
| 188 | goto close_and_return; | ||
| 189 | } | ||
| 190 | |||
| 191 | buf[length] = '\0'; | ||
| 192 | |||
| 193 | - gputype_parse(buf); | ||
| 194 | - | ||
| 195 | - numgpus = numgpus <= MAXGPU ? numgpus : MAXGPU; | ||
| 196 | + if (! gputype_parse(buf)) | ||
| 197 | + { | ||
| 198 | + free(buf); | ||
| 199 | + goto close_and_return; | ||
| 200 | + } | ||
| 201 | |||
| 202 | return numgpus; | ||
| 203 | |||
| 204 | close_and_return: | ||
| 205 | close(actsock); | ||
| 206 | actsock = -1; | ||
| 207 | + numgpus = 0; | ||
| 208 | return 0; | ||
| 209 | } | ||
| 210 | |||
| 211 | @@ -176,7 +180,7 @@ gpud_init(void) | ||
| 212 | ** | ||
| 213 | ** Return value: | ||
| 214 | ** 0 in case of failure | ||
| 215 | -** 1 in case of success | ||
| 216 | +** 1 in case of success (request pending) | ||
| 217 | */ | ||
| 218 | int | ||
| 219 | gpud_statrequest(void) | ||
| 220 | @@ -190,6 +194,7 @@ gpud_statrequest(void) | ||
| 221 | { | ||
| 222 | close(actsock); | ||
| 223 | actsock = -1; | ||
| 224 | + numgpus = 0; | ||
| 225 | return 0; | ||
| 226 | } | ||
| 227 | |||
| 228 | @@ -216,7 +221,7 @@ gpud_statresponse(int maxgpu, struct pergpu *ggs, struct gpupidstat **gps) | ||
| 229 | uint32_t prelude; | ||
| 230 | char *buf = NULL, *p; | ||
| 231 | int version, length; | ||
| 232 | - int pids = 0; | ||
| 233 | + int maxprocs = 0, nrprocs; | ||
| 234 | |||
| 235 | if (actsock == -1) | ||
| 236 | return -1; | ||
| 237 | @@ -269,22 +274,22 @@ gpud_statresponse(int maxgpu, struct pergpu *ggs, struct gpupidstat **gps) | ||
| 238 | *(buf+length) = '\0'; | ||
| 239 | |||
| 240 | /* | ||
| 241 | - ** determine number of per-process stats | ||
| 242 | - ** and malloc space to parse these stats | ||
| 243 | + ** determine number of per-process stats in string | ||
| 244 | + ** and malloc space to store these stats | ||
| 245 | */ | ||
| 246 | for (p=buf; *p; p++) | ||
| 247 | { | ||
| 248 | if (*p == PIDDELIM) | ||
| 249 | - pids++; | ||
| 250 | + maxprocs++; | ||
| 251 | } | ||
| 252 | |||
| 253 | if (gps) | ||
| 254 | { | ||
| 255 | - if (pids) | ||
| 256 | + if (maxprocs) | ||
| 257 | { | ||
| 258 | - *gps = malloc(pids * sizeof(struct gpupidstat)); | ||
| 259 | - ptrverify(gps, "Malloc failed for gpu pidstats\n"); | ||
| 260 | - memset(*gps, 0, pids * sizeof(struct gpupidstat)); | ||
| 261 | + *gps = malloc(maxprocs * sizeof(struct gpupidstat)); | ||
| 262 | + ptrverify(*gps, "Malloc failed for gpu pidstats\n"); | ||
| 263 | + memset(*gps, 0, maxprocs * sizeof(struct gpupidstat)); | ||
| 264 | } | ||
| 265 | else | ||
| 266 | { | ||
| 267 | @@ -295,18 +300,27 @@ gpud_statresponse(int maxgpu, struct pergpu *ggs, struct gpupidstat **gps) | ||
| 268 | /* | ||
| 269 | ** parse stats string for per-gpu stats | ||
| 270 | */ | ||
| 271 | - gpustat_parse(version, buf, maxgpu, ggs, gps ? *gps : NULL); | ||
| 272 | + if ( (nrprocs = gpustat_parse(version, buf, maxgpu, ggs, gps ? *gps : NULL)) == -1) | ||
| 273 | + { | ||
| 274 | + if (gps) | ||
| 275 | + { | ||
| 276 | + free(*gps); | ||
| 277 | + *gps = NULL; // avoid double free later on | ||
| 278 | + } | ||
| 279 | + | ||
| 280 | + goto close_and_return; // inconsistent data received from atopgpud | ||
| 281 | + } | ||
| 282 | |||
| 283 | free(buf); | ||
| 284 | |||
| 285 | - return pids; | ||
| 286 | + return nrprocs; | ||
| 287 | |||
| 288 | close_and_return: | ||
| 289 | - if (buf) | ||
| 290 | - free(buf); | ||
| 291 | + free(buf); | ||
| 292 | |||
| 293 | close(actsock); | ||
| 294 | actsock = -1; | ||
| 295 | + numgpus = 0; | ||
| 296 | return -1; | ||
| 297 | } | ||
| 298 | |||
| 299 | @@ -314,6 +328,8 @@ gpud_statresponse(int maxgpu, struct pergpu *ggs, struct gpupidstat **gps) | ||
| 300 | /* | ||
| 301 | ** Receive given number of bytes from given socket | ||
| 302 | ** into given buffer address | ||
| 303 | +** Return value: number of bytes received | ||
| 304 | +** -1 - failed (including end-of-connection) | ||
| 305 | */ | ||
| 306 | static int | ||
| 307 | rcvuntil(int sock, char *buf, int size) | ||
| 308 | @@ -339,21 +355,22 @@ rcvuntil(int sock, char *buf, int size) | ||
| 309 | ** | ||
| 310 | ** Store the type, busid and tasksupport of every GPU in | ||
| 311 | ** static pointer tables | ||
| 312 | +** | ||
| 313 | +** Return value: 1 - success | ||
| 314 | +** 0 - failed | ||
| 315 | */ | ||
| 316 | -static void | ||
| 317 | +static int | ||
| 318 | gputype_parse(char *buf) | ||
| 319 | { | ||
| 320 | - char *p, *start, **bp, **tp, *cp; | ||
| 321 | + char *p, *start, **bp, **tp, *cp, fails=0; | ||
| 322 | |||
| 323 | /* | ||
| 324 | ** determine number of GPUs | ||
| 325 | */ | ||
| 326 | if ( sscanf(buf, "%d@", &numgpus) != 1) | ||
| 327 | - { | ||
| 328 | - close(actsock); | ||
| 329 | - actsock = -1; | ||
| 330 | return; | ||
| 331 | - } | ||
| 332 | + | ||
| 333 | + numgpus = numgpus <= MAXGPU ? numgpus : MAXGPU; | ||
| 334 | |||
| 335 | for (p=buf; *p; p++) // search for first delimiter | ||
| 336 | { | ||
| 337 | @@ -364,6 +381,9 @@ gputype_parse(char *buf) | ||
| 338 | } | ||
| 339 | } | ||
| 340 | |||
| 341 | + if (*p == 0) // no delimiter or no data behind delimeter? | ||
| 342 | + return 0; | ||
| 343 | + | ||
| 344 | /* | ||
| 345 | ** parse GPU info and build arrays of pointers to the | ||
| 346 | ** busid strings, type strings and tasksupport strings. | ||
| 347 | @@ -380,27 +400,47 @@ gputype_parse(char *buf) | ||
| 348 | ptrverify(gputypes, "Malloc failed for gpu types\n"); | ||
| 349 | ptrverify(gputasks, "Malloc failed for gpu tasksup\n"); | ||
| 350 | |||
| 351 | - for (field=0, start=p; ; p++) | ||
| 352 | + for (field=0, start=p; fails == 0; p++) | ||
| 353 | { | ||
| 354 | if (*p == ' ' || *p == '\0' || *p == GPUDELIM) | ||
| 355 | { | ||
| 356 | switch(field) | ||
| 357 | { | ||
| 358 | case 0: | ||
| 359 | + if (bp - gpubusid >= numgpus) | ||
| 360 | + { | ||
| 361 | + fails++; | ||
| 362 | + break; // inconsistent with number of GPUs | ||
| 363 | + } | ||
| 364 | + | ||
| 365 | if (p-start <= MAXGPUBUS) | ||
| 366 | *bp++ = start; | ||
| 367 | else | ||
| 368 | *bp++ = p - MAXGPUBUS; | ||
| 369 | break; | ||
| 370 | case 1: | ||
| 371 | + if (tp - gputypes >= numgpus) | ||
| 372 | + { | ||
| 373 | + fails++; | ||
| 374 | + break; // inconsistent with number of GPUs | ||
| 375 | + } | ||
| 376 | + | ||
| 377 | if (p-start <= MAXGPUTYPE) | ||
| 378 | *tp++ = start; | ||
| 379 | else | ||
| 380 | *tp++ = p - MAXGPUTYPE; | ||
| 381 | break; | ||
| 382 | case 2: | ||
| 383 | + if (cp - gputasks >= numgpus) | ||
| 384 | + { | ||
| 385 | + fails++; | ||
| 386 | + break; // inconsistent with number of GPUs | ||
| 387 | + } | ||
| 388 | + | ||
| 389 | *cp++ = *start; | ||
| 390 | break; | ||
| 391 | + default: | ||
| 392 | + fails++; | ||
| 393 | } | ||
| 394 | |||
| 395 | field++; | ||
| 396 | @@ -418,7 +458,24 @@ gputype_parse(char *buf) | ||
| 397 | |||
| 398 | *bp = NULL; | ||
| 399 | *tp = NULL; | ||
| 400 | + /* | ||
| 401 | + ** verify if number of GPUs and supplied per-GPU information | ||
| 402 | + ** appears to be inconsistent | ||
| 403 | + */ | ||
| 404 | + if (fails || bp - gpubusid != numgpus || tp - gputypes != numgpus || cp - gputasks != numgpus) | ||
| 405 | + { | ||
| 406 | + free(gpubusid); | ||
| 407 | + free(gputypes); | ||
| 408 | + free(gputasks); | ||
| 409 | + return 0; | ||
| 410 | + } | ||
| 411 | + } | ||
| 412 | + else | ||
| 413 | + { | ||
| 414 | + return 0; | ||
| 415 | } | ||
| 416 | + | ||
| 417 | + return 1; | ||
| 418 | } | ||
| 419 | |||
| 420 | |||
| 421 | @@ -430,105 +487,140 @@ gputype_parse(char *buf) | ||
| 422 | ** Every series with counters on process level is introduced | ||
| 423 | ** with a '#' delimiter (last part of the GPU level data). | ||
| 424 | */ | ||
| 425 | -static void | ||
| 426 | +static int | ||
| 427 | gpustat_parse(int version, char *buf, int maxgpu, | ||
| 428 | struct pergpu *gg, struct gpupidstat *gp) | ||
| 429 | { | ||
| 430 | - char *p, *start, delimlast; | ||
| 431 | - int gpunum = 0; | ||
| 432 | + char *p, *pp, *start; | ||
| 433 | + int gpunum, nrprocs = 0; | ||
| 434 | |||
| 435 | /* | ||
| 436 | ** parse stats string | ||
| 437 | */ | ||
| 438 | - for (p=start=buf, delimlast=DUMMY; gpunum <= maxgpu; p++) | ||
| 439 | + for (p=buf; *p && *p != GPUDELIM; p++) // find first GPU deimiter | ||
| 440 | + ; | ||
| 441 | + | ||
| 442 | + if (*p == 0) // string without GPU delimiter | ||
| 443 | + return -1; | ||
| 444 | + | ||
| 445 | + for (p++, start=p, gpunum=0; gpunum < maxgpu; p++) | ||
| 446 | { | ||
| 447 | - char delimnow; | ||
| 448 | + char delimnext; | ||
| 449 | |||
| 450 | - if (*p != '\0' && *p != GPUDELIM && *p != PIDDELIM) | ||
| 451 | + // search next GPU delimiter | ||
| 452 | + // | ||
| 453 | + if (*p && *p != GPUDELIM) | ||
| 454 | continue; | ||
| 455 | |||
| 456 | /* | ||
| 457 | - ** next delimiter or end-of-string found | ||
| 458 | + ** next GPU delimiter or end-of-string found | ||
| 459 | */ | ||
| 460 | - delimnow = *p; | ||
| 461 | + delimnext = *p; | ||
| 462 | *p = 0; | ||
| 463 | |||
| 464 | - switch (delimlast) | ||
| 465 | - { | ||
| 466 | - case DUMMY: | ||
| 467 | - break; | ||
| 468 | - | ||
| 469 | - case GPUDELIM: | ||
| 470 | - gpuparse(version, start, gg); | ||
| 471 | - | ||
| 472 | - strcpy(gg->type, gputypes[gpunum]); | ||
| 473 | - strcpy(gg->busid, gpubusid[gpunum]); | ||
| 474 | + /* | ||
| 475 | + ** parse GPU itself | ||
| 476 | + */ | ||
| 477 | + if (! gpuparse(version, start, gg)) | ||
| 478 | + return -1; | ||
| 479 | |||
| 480 | - gpunum++; | ||
| 481 | - gg++; | ||
| 482 | - break; | ||
| 483 | + strncpy(gg->type, gputypes[gpunum], MAXGPUTYPE); | ||
| 484 | + strncpy(gg->busid, gpubusid[gpunum], MAXGPUBUS); | ||
| 485 | |||
| 486 | - case PIDDELIM: | ||
| 487 | - if (gp) | ||
| 488 | + /* | ||
| 489 | + ** continue searching for per-process stats for this GPU | ||
| 490 | + */ | ||
| 491 | + if (gp) | ||
| 492 | + { | ||
| 493 | + for (pp = start; pp < p; pp++) | ||
| 494 | { | ||
| 495 | - pidparse(version, start, gp); | ||
| 496 | + if (*pp != PIDDELIM) | ||
| 497 | + continue; | ||
| 498 | + | ||
| 499 | + // new PID delimiter (#) found | ||
| 500 | + // | ||
| 501 | + if (! pidparse(version, pp+1, gp)) | ||
| 502 | + return -1; | ||
| 503 | |||
| 504 | gp->gpu.nrgpus++; | ||
| 505 | - gp->gpu.gpulist = 1<<(gpunum-1); | ||
| 506 | + gp->gpu.gpulist = 1<<gpunum; | ||
| 507 | gp++; | ||
| 508 | |||
| 509 | - (gg-1)->nrprocs++; | ||
| 510 | + gg->nrprocs++; // per GPU | ||
| 511 | + nrprocs++; // total | ||
| 512 | } | ||
| 513 | } | ||
| 514 | |||
| 515 | - if (delimnow == 0 || *(p+1) == 0) | ||
| 516 | + gpunum++; | ||
| 517 | + gg++; | ||
| 518 | + | ||
| 519 | + if (delimnext == 0 || *(p+1) == 0) | ||
| 520 | break; | ||
| 521 | |||
| 522 | start = p+1; | ||
| 523 | - delimlast = delimnow; | ||
| 524 | } | ||
| 525 | + return nrprocs; | ||
| 526 | } | ||
| 527 | |||
| 528 | |||
| 529 | /* | ||
| 530 | ** Parse GPU statistics string | ||
| 531 | +** Return value: 1 - success | ||
| 532 | +** 0 - failed | ||
| 533 | */ | ||
| 534 | -static void | ||
| 535 | +static int | ||
| 536 | gpuparse(int version, char *p, struct pergpu *gg) | ||
| 537 | { | ||
| 538 | + int nr; | ||
| 539 | + | ||
| 540 | switch (version) | ||
| 541 | { | ||
| 542 | case 1: | ||
| 543 | - (void) sscanf(p, "%d %d %lld %lld %lld %lld %lld %lld", | ||
| 544 | + nr = sscanf(p, "%d %d %lld %lld %lld %lld %lld %lld", | ||
| 545 | &(gg->gpupercnow), &(gg->mempercnow), | ||
| 546 | &(gg->memtotnow), &(gg->memusenow), | ||
| 547 | &(gg->samples), &(gg->gpuperccum), | ||
| 548 | &(gg->memperccum), &(gg->memusecum)); | ||
| 549 | |||
| 550 | + if (nr < 8) // parse error: unexpected data | ||
| 551 | + return 0; | ||
| 552 | + | ||
| 553 | gg->nrprocs = 0; | ||
| 554 | |||
| 555 | break; | ||
| 556 | } | ||
| 557 | + | ||
| 558 | + return 1; | ||
| 559 | } | ||
| 560 | |||
| 561 | |||
| 562 | /* | ||
| 563 | ** Parse PID statistics string | ||
| 564 | +** Return value: 1 - success | ||
| 565 | +** 0 - failed | ||
| 566 | */ | ||
| 567 | -static void | ||
| 568 | +static int | ||
| 569 | pidparse(int version, char *p, struct gpupidstat *gp) | ||
| 570 | { | ||
| 571 | + int nr; | ||
| 572 | + | ||
| 573 | switch (version) | ||
| 574 | { | ||
| 575 | case 1: | ||
| 576 | - (void) sscanf(p, "%c %ld %d %d %lld %lld %lld %lld", | ||
| 577 | + nr = sscanf(p, "%c %ld %d %d %lld %lld %lld %lld", | ||
| 578 | &(gp->gpu.state), &(gp->pid), | ||
| 579 | &(gp->gpu.gpubusy), &(gp->gpu.membusy), | ||
| 580 | &(gp->gpu.timems), | ||
| 581 | &(gp->gpu.memnow), &(gp->gpu.memcum), | ||
| 582 | &(gp->gpu.sample)); | ||
| 583 | + | ||
| 584 | + if (nr < 8) // parse error: unexpected data | ||
| 585 | + return 0; | ||
| 586 | + | ||
| 587 | break; | ||
| 588 | } | ||
| 589 | + | ||
| 590 | + return 1; | ||
| 591 | } | ||
| 592 | |||
| 593 | |||
| 594 | diff --git a/photoproc.c b/photoproc.c | ||
| 595 | index e5cd88b..5df04e3 100644 | ||
| 596 | --- a/photoproc.c | ||
| 597 | +++ b/photoproc.c | ||
| 598 | @@ -216,7 +216,8 @@ photoproc(struct tstat *tasklist, int maxtask) | ||
| 599 | */ | ||
| 600 | regainrootprivs(); | ||
| 601 | |||
| 602 | - netatop_probe(); | ||
| 603 | + if (connectnetatop) | ||
| 604 | + netatop_probe(); | ||
| 605 | |||
| 606 | if (! droprootprivs()) | ||
| 607 | cleanstop(42); | ||
diff --git a/meta-oe/recipes-support/atop/atop_2.4.0.bb b/meta-oe/recipes-support/atop/atop_2.4.0.bb index bb1f53624a..f6db0508f6 100644 --- a/meta-oe/recipes-support/atop/atop_2.4.0.bb +++ b/meta-oe/recipes-support/atop/atop_2.4.0.bb | |||
| @@ -20,6 +20,7 @@ SRC_URI = "http://www.atoptool.nl/download/${BP}.tar.gz \ | |||
| 20 | file://fix-permissions.patch \ | 20 | file://fix-permissions.patch \ |
| 21 | file://sysvinit-implement-status.patch \ | 21 | file://sysvinit-implement-status.patch \ |
| 22 | file://0001-atop.daily-atop.init-atop-pm.sh-Avoid-using-bash.patch \ | 22 | file://0001-atop.daily-atop.init-atop-pm.sh-Avoid-using-bash.patch \ |
| 23 | file://CVE-2025-31160.patch \ | ||
| 23 | " | 24 | " |
| 24 | SRC_URI[md5sum] = "1077da884ed94f2bc3c81ac3ab970436" | 25 | SRC_URI[md5sum] = "1077da884ed94f2bc3c81ac3ab970436" |
| 25 | SRC_URI[sha256sum] = "be1c010a77086b7d98376fce96514afcd73c3f20a8d1fe01520899ff69a73d69" | 26 | SRC_URI[sha256sum] = "be1c010a77086b7d98376fce96514afcd73c3f20a8d1fe01520899ff69a73d69" |
