SIOCGIWRATE (and others) leaking SLAB (kmalloc-2048)

From: Stefan Seyfried
Date: Sun Sep 30 2018 - 05:24:44 EST


Hi all,

I'm running the openSUSE provided latest rc kernels and found, that
after 2 weeks, about 4GB of memory had leaked into kmalloc-2048.
Investigating with trace-cmd lead me to the gkrellm-wifi plugin, which
periodically polls via wireless extension ioctls.

This is an easy to use reproducer:

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <linux/wireless.h>
int main(int argc, char **argv)
{
struct iwreq request;
int fd;
if (argc < 2) {
fprintf(stderr, "usage: %s <interface>\n", argv[0]);
return 1;
}
fd = socket (AF_INET, SOCK_DGRAM, 0);
if (fd < 0) {
fprintf(stderr, "Could not open socket: %m\n");
return 2;
}
strncpy (request.ifr_name, argv[1], IFNAMSIZ);
for (int i = 0; i < 10000; i++)
if (ioctl (fd, SIOCGIWRATE, &request) < 0)
fprintf(stderr, "ioctl: %m\n");
close (fd);
return 0;
}

http://paste.opensuse.org/75377254

# grep ^kmalloc-2048 /proc/slabinfo
kmalloc-2048 168090 168106 2048 2 1 : tunables 24 12 8 : slabdata 84053
84053 0
# ./leak air
# grep ^kmalloc-2048 /proc/slabinfo
kmalloc-2048 178086 178086 2048 2 1 : tunables 24 12 8 : slabdata 89043
89043 0

The same happens with SIOCGIWSTATS and when reading /proc/net/wireless:

#!/bin/bash
for ((i=0; i<10000; i++)); do
while read line; do :; done < /proc/net/wireless
done

Thie lets me suspect an issue with rdev_get_station, but OTOH "iw air
station dump" which I think also calls rdev_get_station via
nl80211_get_station() does not seem to leak.

I did not see this with 4.18, I have noticed this with 4.19-rc3 after 13
days and still see it with -rc5.

Best regards,

Stefan
--
Stefan Seyfried

"For a successful technology, reality must take precedence over
public relations, for nature cannot be fooled." -- Richard Feynman