2

I've got a pretty deep question here that I hope someone can answer. In macOS, regular users can ping as well as root. Normally, root access is required to open the raw socket necessary to run ping. I've noticed on Linux that this usually accomplished by adding extended attributes to the ping program file to allow root-level access for opening raw sockets (in the past, this was done by just setting the setuid bit on the ping program, allowing it to do anything in its programming as root).

I've looked at /sbin/ping on macOS (High Sierra, specifically), and no such attributes are set, and neither is setuid. So what is macOS doing to allow Standard (non-root) users to ping? Are they sending ICMP packets over TCP or UDP? If so (or if there's another mechanism I'm just missing entirely), can you point me to some docs? Any help would be appreciated.

  • ICMP is one level below the transport layer (TCP, UDP...)! – klanomath Jan 19 '18 at 19:47
  • 1
    Could you document “normally, root acces is required to open the raw socket”. This appears to be simply macOS doesn’t meet your expectations and I’d like to avoid closing this as unclear / looking for off site references. Quite simply, the security model doesn’t require the prohibitions Linux chose. – bmike Jan 19 '18 at 19:48
  • Are you asking how to ping as a standard user or how Apple allows standard users to ping? Just for some clarity. – Melvin Jefferson Jan 19 '18 at 19:53
  • @bmike - I'm not sure of what you mean by "looking for off site references". I haven't seen a rule in Stack Exchange that prohibits/discourages linking to other sites. On the contrary, that's a common and useful practice. Maybe I'm misinterpreting your statement, so if you have a (on-site) link that spells out that and other rules I need to know, I'd appreciate it. – le_jawa Jan 19 '18 at 22:06
4

Let's take a look at the source code for Apple's ping implementation. Notably, we see this:

if (getuid())
    s = socket(AF_INET, SOCK_DGRAM, IPPROTO_ICMP);
else
    s = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
sockerrno = errno;

getuid returns 0 if root. So this code is saying, "open the socket in DGRAM (datagram mode) if we are not root. If we are root, open as raw".

So a raw socket is only used when you are root. An IMCP ping packet is a standard DGRAM packet and does not require raw sockets.

However, there are some flags that can be passed to ping that do require root, and for those you will get an "Operation Not Permitted". For example:

>ping -f
ping: -f flag: Operation not permitted

When run as root, I do not get the operation not permitted. So Apple's implementation will let you do standard ping operations which does not require root, but require you to run as root for certain flags and operations.

Depending on if you are root, it may set some additional socket options:

if (uid == 0)
    (void)setsockopt(s, SOL_SOCKET, SO_SNDBUF, (char *)&hold,
        sizeof(hold));
  • I had no idea Apple had released that source code. Fantastic! And that does answer my question, thank you much. – le_jawa Jan 19 '18 at 20:28

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .