Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Arch Linux Ping fails (capabilities problems) #1303

Closed
fpqc opened this issue Nov 1, 2016 · 14 comments
Closed

Arch Linux Ping fails (capabilities problems) #1303

fpqc opened this issue Nov 1, 2016 · 14 comments

Comments

@fpqc
Copy link

fpqc commented Nov 1, 2016

On build 14955, installed pritunl/archlinux with @RoliSoft 's tool.

Ping works fine on the Ubuntu distros (ubuntu 16.04, 16.10, 17.06, etc), but it breaks in Arch.

It seems to be related to the failing UDP in IPV6, but I'm not sure so I'm attaching the strace -ff
strace.txt

If it's a duplicate, please close. Thanks.

@RoliSoft
Copy link

RoliSoft commented Nov 1, 2016

Have you tried running it with root permissions? Have you tried running WSL as admin and then run ping with root?

Your strace has the line getuid() = 1000 which means you are running it as your normal user. As far as I know, the ping binary should have the suid flag and run as root. However, it's possible that the suid flag might not have been set due to security concerns in the distribution.

You can add the suid flag with:

sudo chown root:root $(which ping)
sudo chmod +s $(which ping)

However, on the Anniversary Update, at least, you still need to run WSL as admin to be able to ping.

@fpqc
Copy link
Author

fpqc commented Nov 1, 2016

Yeah, in 14955 you can ping without admin, but I will try as root.

Edit: Yeah Roli, it was the root thing. Setting +s doesn't work though.

@fpqc fpqc closed this as completed Nov 1, 2016
@fpqc fpqc reopened this Nov 1, 2016
@fpqc
Copy link
Author

fpqc commented Nov 2, 2016

Final comment, restarting WSL fixed it after setting the setuid permission. Maybe it was some weird thing from caching permissions.

@fpqc fpqc closed this as completed Nov 2, 2016
@fpqc
Copy link
Author

fpqc commented Nov 2, 2016

Fwiw, on my real Arch install, I do not have to have setuid/setgid on ping. Maybe MS's implementation right now requires root for some reason. I guess I can try it out on an ubuntu VM and see if they do it there.

@RoliSoft
Copy link

RoliSoft commented Nov 2, 2016

The practice of using setuid can be pretty dangerous, and so it is mostly discouraged. Linux has a "capabilities" system, where you can add only specific capabilities, instead of full system access. Ping most likely needs raw socket usage, in which case you'd run:

setcap cap_net_raw+ep $(which ping)

However, I'm not sure if the WSL kernel wrapper supports capabilities. It most likely does not.

I had an Arch VM laying around, and I was able to confirm this, ping does come with capabilities set:

$ getcap /bin/ping
/bin/ping = cap_net_raw+ep

@fpqc
Copy link
Author

fpqc commented Nov 2, 2016

Yeah, I found out it was capabilities independently, searching why Ubuntu uses setuid (apparently for backwards compatibility or something), found a bug report about it from 2014.

@sunilmut
Copy link
Member

sunilmut commented Nov 2, 2016

However, I'm not sure if the WSL kernel wrapper supports capabilities. It most likely does not.

WSL does support capabilities and so enforces the CAP_NET_RAW capability for raw sockets.

@fpqc
Copy link
Author

fpqc commented Nov 2, 2016

@sunilmut getcap and getfattr both die silently, and setcap dies with an error message

Here is the strace of setcap cap_net_raw+ep /usr/sbin/ping:

execve("/usr/sbin/setcap", ["setcap", "cap_net_raw+ep", "/usr/sbin/ping"], [/* 17 vars */]) = 0
brk(NULL)                               = 0x2517000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=23610, ...}) = 0
mmap(NULL, 23610, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f26addc3000
close(3)                                = 0
open("/usr/lib/libcap.so.2", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0`\25\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0644, st_size=17256, ...}) = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f26addc0000
mmap(NULL, 2112504, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f26ad7f0000
mprotect(0x7f26ad7f4000, 2093056, PROT_NONE) = 0
mmap(0x7f26ad9f3000, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x3000) = 0x7f26ad9f3000
close(3)                                = 0
open("/usr/lib/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\260\3\2\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=1951744, ...}) = 0
mmap(NULL, 3791152, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f26ad450000
mprotect(0x7f26ad5e5000, 2093056, PROT_NONE) = 0
mmap(0x7f26ad7e4000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x194000) = 0x7f26ad7e4000
mmap(0x7f26ad7ea000, 14640, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f26ad7ea000
close(3)                                = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f26addb0000
arch_prctl(ARCH_SET_FS, 0x7f26addb0700) = 0
mprotect(0x7f26ad7e4000, 16384, PROT_READ) = 0
mprotect(0x7f26adc22000, 4096, PROT_READ) = 0
munmap(0x7f26addc3000, 23610)           = 0
brk(NULL)                               = 0x2517000
brk(0x2538000)                          = 0x2538000
capget({_LINUX_CAPABILITY_VERSION_3, 0}, NULL) = -1 EFAULT (Bad address)
capget({_LINUX_CAPABILITY_VERSION_3, 0}, {1<<CAP_CHOWN|1<<CAP_DAC_OVERRIDE|1<<CAP_DAC_READ_SEARCH|1<<CAP_FOWNER|1<<CAP_FSETID|1<<CAP_KILL|1<<CAP_SETGID|1<<CAP_SETUID|1<<CAP_SETPCAP|1<<CAP_LINUX_IMMUTABLE|1<<CAP_NET_BIND_SERVICE|1<<CAP_NET_BROADCAST|1<<CAP_NET_ADMIN|1<<CAP_NET_RAW|1<<CAP_IPC_LOCK|1<<CAP_IPC_OWNER|1<<CAP_SYS_MODULE|1<<CAP_SYS_RAWIO|1<<CAP_SYS_CHROOT|1<<CAP_SYS_PTRACE|1<<CAP_SYS_PACCT|1<<CAP_SYS_ADMIN|1<<CAP_SYS_BOOT|1<<CAP_SYS_NICE|1<<CAP_SYS_RESOURCE|1<<CAP_SYS_TIME|1<<CAP_SYS_TTY_CONFIG|1<<CAP_MKNOD|1<<CAP_LEASE|1<<CAP_AUDIT_WRITE|1<<CAP_AUDIT_CONTROL|1<<CAP_SETFCAP|1<<CAP_MAC_OVERRIDE|1<<CAP_MAC_ADMIN|1<<CAP_SYSLOG|1<<CAP_WAKE_ALARM|1<<CAP_BLOCK_SUSPEND, 1<<CAP_CHOWN|1<<CAP_DAC_OVERRIDE|1<<CAP_DAC_READ_SEARCH|1<<CAP_FOWNER|1<<CAP_FSETID|1<<CAP_KILL|1<<CAP_SETGID|1<<CAP_SETUID|1<<CAP_SETPCAP|1<<CAP_LINUX_IMMUTABLE|1<<CAP_NET_BIND_SERVICE|1<<CAP_NET_BROADCAST|1<<CAP_NET_ADMIN|1<<CAP_NET_RAW|1<<CAP_IPC_LOCK|1<<CAP_IPC_OWNER|1<<CAP_SYS_MODULE|1<<CAP_SYS_RAWIO|1<<CAP_SYS_CHROOT|1<<CAP_SYS_PTRACE|1<<CAP_SYS_PACCT|1<<CAP_SYS_ADMIN|1<<CAP_SYS_BOOT|1<<CAP_SYS_NICE|1<<CAP_SYS_RESOURCE|1<<CAP_SYS_TIME|1<<CAP_SYS_TTY_CONFIG|1<<CAP_MKNOD|1<<CAP_LEASE|1<<CAP_AUDIT_WRITE|1<<CAP_AUDIT_CONTROL|1<<CAP_SETFCAP|1<<CAP_MAC_OVERRIDE|1<<CAP_MAC_ADMIN|1<<CAP_SYSLOG|1<<CAP_WAKE_ALARM|1<<CAP_BLOCK_SUSPEND, 0}) = 0
capget({_LINUX_CAPABILITY_VERSION_3, 0}, NULL) = -1 EFAULT (Bad address)
capset({_LINUX_CAPABILITY_VERSION_3, 0}, {1<<CAP_CHOWN|1<<CAP_DAC_OVERRIDE|1<<CAP_DAC_READ_SEARCH|1<<CAP_FOWNER|1<<CAP_FSETID|1<<CAP_KILL|1<<CAP_SETGID|1<<CAP_SETUID|1<<CAP_SETPCAP|1<<CAP_LINUX_IMMUTABLE|1<<CAP_NET_BIND_SERVICE|1<<CAP_NET_BROADCAST|1<<CAP_NET_ADMIN|1<<CAP_NET_RAW|1<<CAP_IPC_LOCK|1<<CAP_IPC_OWNER|1<<CAP_SYS_MODULE|1<<CAP_SYS_RAWIO|1<<CAP_SYS_CHROOT|1<<CAP_SYS_PTRACE|1<<CAP_SYS_PACCT|1<<CAP_SYS_ADMIN|1<<CAP_SYS_BOOT|1<<CAP_SYS_NICE|1<<CAP_SYS_RESOURCE|1<<CAP_SYS_TIME|1<<CAP_SYS_TTY_CONFIG|1<<CAP_MKNOD|1<<CAP_LEASE|1<<CAP_AUDIT_WRITE|1<<CAP_AUDIT_CONTROL|1<<CAP_SETFCAP|1<<CAP_MAC_OVERRIDE|1<<CAP_MAC_ADMIN|1<<CAP_SYSLOG|1<<CAP_WAKE_ALARM|1<<CAP_BLOCK_SUSPEND, 1<<CAP_CHOWN|1<<CAP_DAC_OVERRIDE|1<<CAP_DAC_READ_SEARCH|1<<CAP_FOWNER|1<<CAP_FSETID|1<<CAP_KILL|1<<CAP_SETGID|1<<CAP_SETUID|1<<CAP_SETPCAP|1<<CAP_LINUX_IMMUTABLE|1<<CAP_NET_BIND_SERVICE|1<<CAP_NET_BROADCAST|1<<CAP_NET_ADMIN|1<<CAP_NET_RAW|1<<CAP_IPC_LOCK|1<<CAP_IPC_OWNER|1<<CAP_SYS_MODULE|1<<CAP_SYS_RAWIO|1<<CAP_SYS_CHROOT|1<<CAP_SYS_PTRACE|1<<CAP_SYS_PACCT|1<<CAP_SYS_ADMIN|1<<CAP_SYS_BOOT|1<<CAP_SYS_NICE|1<<CAP_SYS_RESOURCE|1<<CAP_SYS_TIME|1<<CAP_SYS_TTY_CONFIG|1<<CAP_MKNOD|1<<CAP_LEASE|1<<CAP_AUDIT_WRITE|1<<CAP_AUDIT_CONTROL|1<<CAP_SETFCAP|1<<CAP_MAC_OVERRIDE|1<<CAP_MAC_ADMIN|1<<CAP_SYSLOG|1<<CAP_WAKE_ALARM|1<<CAP_BLOCK_SUSPEND, 0}) = 0
lstat("/usr/sbin/ping", {st_mode=S_IFREG|0755, st_size=61200, ...}) = 0
setxattr("/usr/sbin/ping", "security.capability", "\1\0\0\2\0 \0\0\0\0\0\0\0\0\0\0\0\0\0", 20, 0) = -1 EOPNOTSUPP (Operation not supported)
write(2, "Failed to set capabilities on fi"..., 78Failed to set capabilities on file `/usr/sbin/ping' (Operation not supported)
) = 78
write(2, "usage: setcap [-q] [-v] (-r|-|<c"..., 140usage: setcap [-q] [-v] (-r|-|<caps>) <filename> [ ... (-r|-|<capsN>) <filenameN> ]

 Note <filename> must be a regular (non-symlink) file.
) = 140
exit_group(1)                           = ?
+++ exited with 1 +++

and here is the strace of getcap /usr/sbin/ping

execve("/usr/sbin/getcap", ["getcap", "/usr/sbin/ping"], [/* 17 vars */]) = 0
brk(NULL)                               = 0x24ce000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=23610, ...}) = 0
mmap(NULL, 23610, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7fe6c97df000
close(3)                                = 0
open("/usr/lib/libcap.so.2", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0`\25\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0644, st_size=17256, ...}) = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fe6c97d0000
mmap(NULL, 2112504, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7fe6c91f0000
mprotect(0x7fe6c91f4000, 2093056, PROT_NONE) = 0
mmap(0x7fe6c93f3000, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x3000) = 0x7fe6c93f3000
close(3)                                = 0
open("/usr/lib/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\260\3\2\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=1951744, ...}) = 0
mmap(NULL, 3791152, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7fe6c8e50000
mprotect(0x7fe6c8fe5000, 2093056, PROT_NONE) = 0
mmap(0x7fe6c91e4000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x194000) = 0x7fe6c91e4000
mmap(0x7fe6c91ea000, 14640, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7fe6c91ea000
close(3)                                = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fe6c97c0000
arch_prctl(ARCH_SET_FS, 0x7fe6c97c0700) = 0
mprotect(0x7fe6c91e4000, 16384, PROT_READ) = 0
mprotect(0x7fe6c9622000, 4096, PROT_READ) = 0
munmap(0x7fe6c97df000, 23610)           = 0
lstat("/usr/sbin/ping", {st_mode=S_IFREG|0755, st_size=61200, ...}) = 0
brk(NULL)                               = 0x24ce000
brk(0x24ef000)                          = 0x24ef000
capget({_LINUX_CAPABILITY_VERSION_3, 0}, NULL) = -1 EFAULT (Bad address)
getxattr("/usr/sbin/ping", "security.capability", 0x7fffed629ea0, 20) = -1 ENODATA (No data available)
exit_group(0)                           = ?
+++ exited with 0 +++

@fpqc fpqc reopened this Nov 2, 2016
@fpqc fpqc changed the title Arch Linux Ping fails Arch Linux Ping fails (capabilities problems) Nov 2, 2016
@sunilmut
Copy link
Member

sunilmut commented Nov 2, 2016

Thanks @fpqc. Looks like the extended attributes for 'security.capability' is not supported, but we do enforce capability checks. Adding @stehufntdev to comment on the extended attribute part.

setxattr("/usr/sbin/ping", "security.capability", "\1\0\0\2\0 \0\0\0\0\0\0\0\0\0\0\0\0\0", 20, 0) = -1 EOPNOTSUPP (Operation not supported)

@fpqc
Copy link
Author

fpqc commented Nov 2, 2016

@sunilmut I'm guessing that whatever capability ping should have, it does actually have, but the
capget is failing, so it's being detected as not having the capability.

Also, I confirmed that getcap and setcap don't work on ubuntu either (but this is mitigated by the fact that ping is setuid in ubuntu, while it's not in Arch).

@stehufntdev
Copy link
Collaborator

@sunilmut - setting extended attributes is not currently supported but the work is being tracked.

@RoliSoft
Copy link

RoliSoft commented Nov 2, 2016

@stehufntdev Are capabilities stored in the [user.]security.capability NTFS extended attribute, as setxattr wishes to store it?

Tried setting it outside of WSL with NtSetEaFile:

getfattr -d ping
# file: ping
user.lxattrb=0sAAABAO2JAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADyqmpTAAAAAPKqalMAAAAA8qpqUwAAAAA=
user.security.capability=0sAQAAAgAgAAAAAAAAAAAAAAAAAA==

But it seems to have had no effect, as under WSL both getfattr -d /bin/ping and getcap /bin/ping have an empty response.

@stehufntdev
Copy link
Collaborator

Sorry should have said that extended attributes are not currently supported in WSL. It's not just set but all extended attribute support.

@benhillis
Copy link
Member

Support for the security.capability xattr was added in build 16226. Marking this as a duplicate of #574.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants