Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

gen_stats.c: Duplicate xstats buffer for later use

The gnet_stats_copy_app() function gets called, more often than not, with its
second argument a pointer to an automatic variable in the caller's stack.
Therefore, to avoid copying garbage afterwards when calling
gnet_stats_finish_copy(), this data is better copied to a dynamically allocated
memory that gets freed after use.

[xiyou.wangcong@gmail.com: remove a useless kfree()]

Signed-off-by: Ignacy Gawędzki <ignacy.gawedzki@green-communications.fr>
Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Ignacy Gawędzki and committed by
David S. Miller
1c4cff0c 5c277007

+14 -1
+14 -1
net/core/gen_stats.c
··· 32 32 return 0; 33 33 34 34 nla_put_failure: 35 + kfree(d->xstats); 36 + d->xstats = NULL; 37 + d->xstats_len = 0; 35 38 spin_unlock_bh(d->lock); 36 39 return -1; 37 40 } ··· 308 305 gnet_stats_copy_app(struct gnet_dump *d, void *st, int len) 309 306 { 310 307 if (d->compat_xstats) { 311 - d->xstats = st; 308 + d->xstats = kmemdup(st, len, GFP_ATOMIC); 309 + if (!d->xstats) 310 + goto err_out; 312 311 d->xstats_len = len; 313 312 } 314 313 ··· 318 313 return gnet_stats_copy(d, TCA_STATS_APP, st, len); 319 314 320 315 return 0; 316 + 317 + err_out: 318 + d->xstats_len = 0; 319 + spin_unlock_bh(d->lock); 320 + return -1; 321 321 } 322 322 EXPORT_SYMBOL(gnet_stats_copy_app); 323 323 ··· 355 345 return -1; 356 346 } 357 347 348 + kfree(d->xstats); 349 + d->xstats = NULL; 350 + d->xstats_len = 0; 358 351 spin_unlock_bh(d->lock); 359 352 return 0; 360 353 }