一个内核slub内存泄漏问题分析

操作系统版本:centos7.3

内核版本:3.10.0-693

利用slabtop命令,发现有大量的kmalloc-64占用,且一直未释放,初步怀疑是内存泄漏,但不知道谁泄漏的。

通过打开kmemleak,发现有install进程大量__kmalloc且size大小刚好也为64k

(线上机器会定期调用/usr/bin/install命令,至于为何调用,那是业务的需求了。。。。。。写个死循环疯狂调用install确实能复现,该命令实际是调用了setxattr函数,你可以写个c函数疯狂调用之复现)

函数栈如下:

unreferenced object 0xffff8801c5a40000 (size 64):
comm "install", pid 15131, jiffies 4300179882 (age 217981.193s)
hex dump (first 32 bytes):
01 00 00 00 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b ....kkkkkkkkkkkk
03 00 00 00 01 00 06 00 6b 6b 6b 6b 04 00 00 00 ........kkkk....
backtrace:
[<ffffffff816a2a1e>] kmemleak_alloc+0x4e/0xb0
[<ffffffff811e313d>] __kmalloc+0xdd/0x1b0
[<ffffffff812692dc>] posix_acl_alloc+0x1c/0x30
[<ffffffff81269c02>] posix_acl_from_xattr+0x82/0x190
[<ffffffffc0248eb2>] ext4_xattr_set_acl+0x92/0x2d0 [ext4]
[<ffffffff8122d518>] generic_setxattr+0x68/0x80
[<ffffffff8122dd85>] __vfs_setxattr_noperm+0x65/0x1b0
[<ffffffff8122df85>] vfs_setxattr+0xb5/0xc0
[<ffffffff8122e0be>] setxattr+0x12e/0x1c0
[<ffffffff8122e5be>] SyS_fsetxattr+0xce/0x110
[<ffffffff816c2695>] system_call_fastpath+0x1c/0x21
[<ffffffffffffffff>] 0xffffffffffffffff

但是还是不明白为何会泄漏,没办法,只能上gdb大法。。。

用gdb跟踪内核,成功发现泄露点位于函数:ext4_xattr_set_acl
该函数中其中一行: error = posix_acl_update_mode(inode, &mode, &acl);
继续跟进 posix_acl_update_mode函数,其中有一行:*acl = NULL,该操作会将ext4_xattr_set_acl中的acl置空;ext4_xattr_set_acl中最后部分有一行: posix_acl_release(acl); 该函数由于判断acl为NULL,导致无法执行到kfree,最终引起不断创建的acl大量堆积,内存泄露。

附上本人的patch修复:

— a/fs/ext4/acl.c 2018-04-29 01:23:50.000000000 +0800
+++ b/fs/ext4/acl.c 2019-09-17 17:48:03.094206145 +0800
@@ -404,6 +404,7 @@ ext4_xattr_set_acl(struct dentry *dentry
struct inode *inode = dentry->d_inode;
handle_t *handle;
struct posix_acl *acl;
+ struct posix_acl *p = NULL;
int error, retries = 0;
int update_mode = 0;
umode_t mode = inode->i_mode;
@@ -426,6 +427,7 @@ ext4_xattr_set_acl(struct dentry *dentry
}
} else
acl = NULL;
+ p = acl;

retry:
handle = ext4_journal_start(inode, EXT4_HT_XATTR,
@@ -452,7 +454,7 @@ out_stop:
goto retry;

release_and_out:

  • posix_acl_release(acl);
    + posix_acl_release(p);
    return error;
    }

打上补丁,问题成功解决。

 

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值