背景:在ima-evm-utils中我发现lgetxattr()无法返回预期值。我编写了一个简单的c程序来验证它。
#include <sys/types.h>
#include <sys/xattr.h>
#include <stdio.h>
int main(){
char xattr_value[1024];
int size;
size=lgetxattr("/bin/tcpm", "security.capability", xattr_value, sizeof(xattr_value));
printf("caps: %s\n", &xattr_value);
printf("%d\n",size);
size=lgetxattr("/bin/tcpm", "security.selinux", xattr_value, sizeof(xattr_value));
printf("selinux: %s\n", &xattr_value);
printf("%d\n",size);
return 0;
}
[root@localhost ~]# ./a.out
caps:
20
selinux: system_u:object_r:bin_t:s0
27
[root@localhost ~]# getcap /bin/tcpm
/bin/tcpm cap_net_bind_service,cap_net_admin=ep
[root@localhost ~]# getfattr -m - -d /bin/tcpm
getfattr: Removing leading '/' from absolute path names
# file: bin/tcpm
security.capability=0sAQAAAgAUAAAAAAAAAAAAAAAAAAA=
security.selinux="system_u:object_r:bin_t:s0"
size 不是 -1 意味着 lgetxattr() 成功,但 xattr_value 不是预期值
尝试 gdb ima-evm-utils: #err = return of lgetxattr()
(gdb) p err
$6 = 20
(gdb) p xattr_value
$7 = "\000\000\000\002\000 ", '\000' <repeats 14 times>, "P\261\037&@&^\a\022\274fOT\031", '\000' <repeats 294 times>...
(gdb) p err
$8 = 27
(gdb) p xattr_value
$9 = "system_u:object_r:bin_t:s0", '\000' <repeats 302 times>...
该问题的源代码:
for (xattrname = evm_config_xattrnames; *xattrname != NULL; xattrname++) {
err = lgetxattr(file, *xattrname, xattr_value, sizeof(xattr_value));
if (err < 0) {
log_info("no xattr: %s\n", *xattrname);
continue;
}
if (!find_xattr(list, list_size, *xattrname)) {
log_info("skipping xattr: %s\n", *xattrname);
continue;
}
log_info("name: %s, size: %d\n", *xattrname, err);
log_debug_dump(xattr_value, err);
err = !HMAC_Update(pctx, xattr_value, err);
if (err) {
log_err("HMAC_Update() failed\n");
goto out_ctx_cleanup;
}
}
答案1
getxattr 或 lgetxattr 实际上获取的是二进制能力值。
[root@localhost ~]# strace -e getxattr getfattr -d -m - /bin/tcpm
getxattr("/bin/tcpm", "security.capability", NULL, 0) = 20
getxattr("/bin/tcpm", "security.capability", "\0\0\0\2\0 \0\0\0\0\0\0\0\0\0\0\0\0\0", 256) = 20