Fix misaligned access inside taskstats structure

Reported by UB sanitizer (alongside several other messages):
linux/LinuxProcessList.c:782:25: runtime error: member access within misaligned address 0x614000000264 for type 'struct taskstats', which requires 8 byte alignment
0x614000000264: note: pointer points here
  64 01 03 00 0a 00 00 00  00 00 00 00 02 00 00 00  00 00 00 00 4b c8 2e 00  00 00 00 00 3e 45 3c fd
              ^

The issue doesn't cause trouble on x86, but any architecture with stricter memory alignment requirements may inadvertedly break.
This commit is contained in:
Benny Baumann 2020-10-17 23:28:26 +02:00
parent c138d14897
commit 81543253cf
1 changed files with 12 additions and 11 deletions

View File

@ -766,7 +766,7 @@ static int handleNetlinkMsg(struct nl_msg *nlmsg, void *linuxProcess) {
struct nlmsghdr *nlhdr; struct nlmsghdr *nlhdr;
struct nlattr *nlattrs[TASKSTATS_TYPE_MAX + 1]; struct nlattr *nlattrs[TASKSTATS_TYPE_MAX + 1];
struct nlattr *nlattr; struct nlattr *nlattr;
struct taskstats *stats; struct taskstats stats;
int rem; int rem;
unsigned long long int timeDelta; unsigned long long int timeDelta;
LinuxProcess* lp = (LinuxProcess*) linuxProcess; LinuxProcess* lp = (LinuxProcess*) linuxProcess;
@ -778,20 +778,21 @@ static int handleNetlinkMsg(struct nl_msg *nlmsg, void *linuxProcess) {
} }
if ((nlattr = nlattrs[TASKSTATS_TYPE_AGGR_PID]) || (nlattr = nlattrs[TASKSTATS_TYPE_NULL])) { if ((nlattr = nlattrs[TASKSTATS_TYPE_AGGR_PID]) || (nlattr = nlattrs[TASKSTATS_TYPE_NULL])) {
stats = nla_data(nla_next(nla_data(nlattr), &rem)); memcpy(&stats, nla_data(nla_next(nla_data(nlattr), &rem)), sizeof(stats));
assert(lp->super.pid == (pid_t)stats->ac_pid); assert(lp->super.pid == (pid_t)stats.ac_pid);
timeDelta = (stats->ac_etime*1000 - lp->delay_read_time);
timeDelta = (stats.ac_etime*1000 - lp->delay_read_time);
#define BOUNDS(x) isnan(x) ? 0.0 : (x > 100) ? 100.0 : x; #define BOUNDS(x) isnan(x) ? 0.0 : (x > 100) ? 100.0 : x;
#define DELTAPERC(x,y) BOUNDS((float) (x - y) / timeDelta * 100); #define DELTAPERC(x,y) BOUNDS((float) (x - y) / timeDelta * 100);
lp->cpu_delay_percent = DELTAPERC(stats->cpu_delay_total, lp->cpu_delay_total); lp->cpu_delay_percent = DELTAPERC(stats.cpu_delay_total, lp->cpu_delay_total);
lp->blkio_delay_percent = DELTAPERC(stats->blkio_delay_total, lp->blkio_delay_total); lp->blkio_delay_percent = DELTAPERC(stats.blkio_delay_total, lp->blkio_delay_total);
lp->swapin_delay_percent = DELTAPERC(stats->swapin_delay_total, lp->swapin_delay_total); lp->swapin_delay_percent = DELTAPERC(stats.swapin_delay_total, lp->swapin_delay_total);
#undef DELTAPERC #undef DELTAPERC
#undef BOUNDS #undef BOUNDS
lp->swapin_delay_total = stats->swapin_delay_total; lp->swapin_delay_total = stats.swapin_delay_total;
lp->blkio_delay_total = stats->blkio_delay_total; lp->blkio_delay_total = stats.blkio_delay_total;
lp->cpu_delay_total = stats->cpu_delay_total; lp->cpu_delay_total = stats.cpu_delay_total;
lp->delay_read_time = stats->ac_etime*1000; lp->delay_read_time = stats.ac_etime*1000;
} }
return NL_OK; return NL_OK;
} }