mbuf

admin 2020年8月10日17:43:06评论463 views字数 4381阅读14分36秒阅读模式

The beginning of the story

In recent years, we observed some security vulnerabilities in the XNU caused by disclosed sockets. Ned Will from Google Project Zero has released a vulnerability in in6_pcbdetach. Here, we first introduce his vulnerability in detail . Understanding the cause of this vulnerability is very helpful to discover new vulnerabilities.


Vulnerability Review 1


Details: Issue 1806: XNU: Use-after-free due to stale pointer left by in6_pcbdetach

mbuf

Root Cause:

mbuf

According to the poc, we noticed that disconnectx changed the status of a socket : the options are freed but not cleared, so they can be used after they are freed, leading to a security issue.

After learning the vulnerability, we tried to find some new functions, which may change the status of socket like disconnectx(). Finally, we found the function shutdown().

There are three modes for shutdown: SHUT_WR, SHUT_RD, and SHUT_RDWR. When you call the function shutdown on a socket with mode SHUT_RD or SHUT_RDWR, it will add SB_DROP flag to the socket.

mbuf

And we found that, in the function sbappend(), SB_DROP flag is a condition to check whether a mbuf needs to be freed or not. As we can see below, at the very beginning of sbappend, if a socket has the SB_DROP flag enabled, sbappend will release the mbuf and return 0.

mbuf

Then we begin to check the code where sbappend is called, at last we found a double free vulnerability in nstat_control_send.


Vulnerability 1 ==> nstat_control_send

By sending data to a network statistics kernel control socket, we can run into the function nstat_control_send in the kernel. Function nstat_control_send calls the function ctl_enqueuembuf that will enqueue an mbuf into the socket’s rcvlist. In case of error, nstat_control_send will free the mbuf. The following code snippet shows the process. 

mbuf

Inside ctl_enqueuembuf, it will call the function sbappend to add the mbuf to the rcv list. Note that if sbappend fails, ENOBUFS will be returned.

mbuf

From the code execution above, we can see that, when we send data to a networkstatistics kernel control socket that has the SB_DROP flag enabled, the function sbappend will first free the mbuf struct, and the return 0; then ctl_enqueuembuf returns ENOBUFS to nstat_control_send. At this point, nstat_control_send will free the mbuf struct again, resulting in a double free vulnerability.


Not the End

Shortly after we reported it to Apple,we noticed that Ned Will also released a very similar vulnerability in the function ip6_notify_pmtu. The both vulnerabilities are actually caused by the opaque semantic of the function sbappend*(). But Ned Will trigger it in a different way.


Vulnerability Review 2







Details :Issue1976: XNU: Remote mbuf-double-free in ip6_notify_pmtu

mbuf

Root Cause:

mbuf

After we studied this vulnerability again, we found there are two ways to make sbappendaddr() free the mbuf and return 0.

Our way to trigger it:

mbuf

when we send data to a socket that has the SB_DROP flag enabled,the function sbappendaddr will first free the m_mtu, and the return 0. At this point, ip6_notify_pmtu will free m_mtu again, resulting in a double free vulnerability.

Ned Will's :

mbuf

Let's take a closer look at sbconcat_mbufs. If the sockaddr have a super long socket length, this will make sbconcat_mbufs failure, and then leads to sbappendchain returning 0. As a consequence, sbappendaddr will m_free m0, and return an error.

mbuf


Vulnerability 2 ==> flow_divert_data_out

After we studied the vulnerability and investigated the usage of sbappend* family functions in XNU, we developed a static anlayzer and wrote a rule to help us find similar vulnerabilities. At last, we found a new mbuf double free vulnerability in the function flow_divert_data_out. Vulnerability characteristics are as follows:

mbuf

Let’s take a look at the function flow_divert_data_out. We can find that flow_divert_data_out invokes function flow_divert_send_app_data, and if flow_divert_send_app_data fails ,then flow_divert_data_out will call mbuf_freem to release data.

mbuf

Inside function flow_divert_send_app_data, we can find that, for a DGRAM socket, flow_divert_send_app_data calls the function sbappendaddr to append the mbuf to the socket sending queue. The question is, if the destination address (i.e., toaddr) is incorrect, for example, having a super long socket length, this will make sbconcat_mbufs fail, and then leads to sbappendchain returning 0. As a consequence, sbappendaddr will m_free m0, and returns an error.

mbuf

Let’s go back to flow_divert_data_out. When function flow_divert_send_app_data returns an error, flow_divert_data_out will m_free data again. However, data (that is m0 in sbappendaddr) is already freed by sbappendaddr, resulting in an mbuf double release vulnerability.

 The End 

Studying publicly available vulnerabilities is very important to security research. In this article, we shared how we make the study process more effective and efficiency. We not only analyzed the root causes of a vulnerability, but also asked ourselves, why the developers made this mistake, how can we apply variant analysis to find other similar vulnerabilities, how to create static and dynamic tools to accelerate the analysis? Now, it's your turn!



  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2020年8月10日17:43:06
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   mbufhttp://cn-sec.com/archives/83452.html

发表评论

匿名网友 填写信息