aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth/rfcomm
diff options
context:
space:
mode:
authorDean Jenkins <Dean_Jenkins@mentor.com>2013-02-28 09:21:55 -0500
committerGustavo Padovan <gustavo.padovan@collabora.co.uk>2013-03-08 08:40:24 -0500
commit8ff52f7d04d9cc31f1e81dcf9a2ba6335ed34905 (patch)
tree681a2468209aff5c83cd7c3bafe1eb6c38123c63 /net/bluetooth/rfcomm
parentc06f7d532aa6f78b2847e3b651c0da27fc3296c0 (diff)
Bluetooth: Return RFCOMM session ptrs to avoid freed session
Unfortunately, the design retains local copies of the s RFCOMM session pointer in various code blocks and this invites the erroneous access to a freed RFCOMM session structure. Therefore, return the RFCOMM session pointer back up the call stack to avoid accessing a freed RFCOMM session structure. When the RFCOMM session is deleted, NULL is passed up the call stack. If active DLCs exist when the rfcomm session is terminating, avoid a memory leak of rfcomm_dlc structures by ensuring that rfcomm_session_close() is used instead of rfcomm_session_del(). Signed-off-by: Dean Jenkins <Dean_Jenkins@mentor.com> Acked-by: Marcel Holtmann <marcel@holtmann.org> Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
Diffstat (limited to 'net/bluetooth/rfcomm')
-rw-r--r--net/bluetooth/rfcomm/core.c106
1 files changed, 56 insertions, 50 deletions
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c
index d9e97cf1792b..2b5c543638ba 100644
--- a/net/bluetooth/rfcomm/core.c
+++ b/net/bluetooth/rfcomm/core.c
@@ -69,7 +69,7 @@ static struct rfcomm_session *rfcomm_session_create(bdaddr_t *src,
69 u8 sec_level, 69 u8 sec_level,
70 int *err); 70 int *err);
71static struct rfcomm_session *rfcomm_session_get(bdaddr_t *src, bdaddr_t *dst); 71static struct rfcomm_session *rfcomm_session_get(bdaddr_t *src, bdaddr_t *dst);
72static void rfcomm_session_del(struct rfcomm_session *s); 72static struct rfcomm_session *rfcomm_session_del(struct rfcomm_session *s);
73 73
74/* ---- RFCOMM frame parsing macros ---- */ 74/* ---- RFCOMM frame parsing macros ---- */
75#define __get_dlci(b) ((b & 0xfc) >> 2) 75#define __get_dlci(b) ((b & 0xfc) >> 2)
@@ -108,10 +108,12 @@ static void rfcomm_schedule(void)
108 wake_up_process(rfcomm_thread); 108 wake_up_process(rfcomm_thread);
109} 109}
110 110
111static void rfcomm_session_put(struct rfcomm_session *s) 111static struct rfcomm_session *rfcomm_session_put(struct rfcomm_session *s)
112{ 112{
113 if (atomic_dec_and_test(&s->refcnt)) 113 if (s && atomic_dec_and_test(&s->refcnt))
114 rfcomm_session_del(s); 114 s = rfcomm_session_del(s);
115
116 return s;
115} 117}
116 118
117/* ---- RFCOMM FCS computation ---- */ 119/* ---- RFCOMM FCS computation ---- */
@@ -631,7 +633,7 @@ static struct rfcomm_session *rfcomm_session_add(struct socket *sock, int state)
631 return s; 633 return s;
632} 634}
633 635
634static void rfcomm_session_del(struct rfcomm_session *s) 636static struct rfcomm_session *rfcomm_session_del(struct rfcomm_session *s)
635{ 637{
636 int state = s->state; 638 int state = s->state;
637 639
@@ -648,6 +650,8 @@ static void rfcomm_session_del(struct rfcomm_session *s)
648 650
649 if (state != BT_LISTEN) 651 if (state != BT_LISTEN)
650 module_put(THIS_MODULE); 652 module_put(THIS_MODULE);
653
654 return NULL;
651} 655}
652 656
653static struct rfcomm_session *rfcomm_session_get(bdaddr_t *src, bdaddr_t *dst) 657static struct rfcomm_session *rfcomm_session_get(bdaddr_t *src, bdaddr_t *dst)
@@ -666,7 +670,8 @@ static struct rfcomm_session *rfcomm_session_get(bdaddr_t *src, bdaddr_t *dst)
666 return NULL; 670 return NULL;
667} 671}
668 672
669static void rfcomm_session_close(struct rfcomm_session *s, int err) 673static struct rfcomm_session *rfcomm_session_close(struct rfcomm_session *s,
674 int err)
670{ 675{
671 struct rfcomm_dlc *d; 676 struct rfcomm_dlc *d;
672 struct list_head *p, *n; 677 struct list_head *p, *n;
@@ -685,7 +690,7 @@ static void rfcomm_session_close(struct rfcomm_session *s, int err)
685 } 690 }
686 691
687 rfcomm_session_clear_timer(s); 692 rfcomm_session_clear_timer(s);
688 rfcomm_session_put(s); 693 return rfcomm_session_put(s);
689} 694}
690 695
691static struct rfcomm_session *rfcomm_session_create(bdaddr_t *src, 696static struct rfcomm_session *rfcomm_session_create(bdaddr_t *src,
@@ -737,8 +742,7 @@ static struct rfcomm_session *rfcomm_session_create(bdaddr_t *src,
737 if (*err == 0 || *err == -EINPROGRESS) 742 if (*err == 0 || *err == -EINPROGRESS)
738 return s; 743 return s;
739 744
740 rfcomm_session_del(s); 745 return rfcomm_session_del(s);
741 return NULL;
742 746
743failed: 747failed:
744 sock_release(sock); 748 sock_release(sock);
@@ -1127,7 +1131,7 @@ static void rfcomm_make_uih(struct sk_buff *skb, u8 addr)
1127} 1131}
1128 1132
1129/* ---- RFCOMM frame reception ---- */ 1133/* ---- RFCOMM frame reception ---- */
1130static int rfcomm_recv_ua(struct rfcomm_session *s, u8 dlci) 1134static struct rfcomm_session *rfcomm_recv_ua(struct rfcomm_session *s, u8 dlci)
1131{ 1135{
1132 BT_DBG("session %p state %ld dlci %d", s, s->state, dlci); 1136 BT_DBG("session %p state %ld dlci %d", s, s->state, dlci);
1133 1137
@@ -1136,7 +1140,7 @@ static int rfcomm_recv_ua(struct rfcomm_session *s, u8 dlci)
1136 struct rfcomm_dlc *d = rfcomm_dlc_get(s, dlci); 1140 struct rfcomm_dlc *d = rfcomm_dlc_get(s, dlci);
1137 if (!d) { 1141 if (!d) {
1138 rfcomm_send_dm(s, dlci); 1142 rfcomm_send_dm(s, dlci);
1139 return 0; 1143 return s;
1140 } 1144 }
1141 1145
1142 switch (d->state) { 1146 switch (d->state) {
@@ -1172,25 +1176,14 @@ static int rfcomm_recv_ua(struct rfcomm_session *s, u8 dlci)
1172 break; 1176 break;
1173 1177
1174 case BT_DISCONN: 1178 case BT_DISCONN:
1175 /* rfcomm_session_put is called later so don't do 1179 s = rfcomm_session_close(s, ECONNRESET);
1176 * anything here otherwise we will mess up the session
1177 * reference counter:
1178 *
1179 * (a) when we are the initiator dlc_unlink will drive
1180 * the reference counter to 0 (there is no initial put
1181 * after session_add)
1182 *
1183 * (b) when we are not the initiator rfcomm_rx_process
1184 * will explicitly call put to balance the initial hold
1185 * done after session add.
1186 */
1187 break; 1180 break;
1188 } 1181 }
1189 } 1182 }
1190 return 0; 1183 return s;
1191} 1184}
1192 1185
1193static int rfcomm_recv_dm(struct rfcomm_session *s, u8 dlci) 1186static struct rfcomm_session *rfcomm_recv_dm(struct rfcomm_session *s, u8 dlci)
1194{ 1187{
1195 int err = 0; 1188 int err = 0;
1196 1189
@@ -1215,12 +1208,13 @@ static int rfcomm_recv_dm(struct rfcomm_session *s, u8 dlci)
1215 err = ECONNRESET; 1208 err = ECONNRESET;
1216 1209
1217 s->state = BT_CLOSED; 1210 s->state = BT_CLOSED;
1218 rfcomm_session_close(s, err); 1211 s = rfcomm_session_close(s, err);
1219 } 1212 }
1220 return 0; 1213 return s;
1221} 1214}
1222 1215
1223static int rfcomm_recv_disc(struct rfcomm_session *s, u8 dlci) 1216static struct rfcomm_session *rfcomm_recv_disc(struct rfcomm_session *s,
1217 u8 dlci)
1224{ 1218{
1225 int err = 0; 1219 int err = 0;
1226 1220
@@ -1250,10 +1244,9 @@ static int rfcomm_recv_disc(struct rfcomm_session *s, u8 dlci)
1250 err = ECONNRESET; 1244 err = ECONNRESET;
1251 1245
1252 s->state = BT_CLOSED; 1246 s->state = BT_CLOSED;
1253 rfcomm_session_close(s, err); 1247 s = rfcomm_session_close(s, err);
1254 } 1248 }
1255 1249 return s;
1256 return 0;
1257} 1250}
1258 1251
1259void rfcomm_dlc_accept(struct rfcomm_dlc *d) 1252void rfcomm_dlc_accept(struct rfcomm_dlc *d)
@@ -1674,11 +1667,18 @@ drop:
1674 return 0; 1667 return 0;
1675} 1668}
1676 1669
1677static int rfcomm_recv_frame(struct rfcomm_session *s, struct sk_buff *skb) 1670static struct rfcomm_session *rfcomm_recv_frame(struct rfcomm_session *s,
1671 struct sk_buff *skb)
1678{ 1672{
1679 struct rfcomm_hdr *hdr = (void *) skb->data; 1673 struct rfcomm_hdr *hdr = (void *) skb->data;
1680 u8 type, dlci, fcs; 1674 u8 type, dlci, fcs;
1681 1675
1676 if (!s) {
1677 /* no session, so free socket data */
1678 kfree_skb(skb);
1679 return s;
1680 }
1681
1682 dlci = __get_dlci(hdr->addr); 1682 dlci = __get_dlci(hdr->addr);
1683 type = __get_type(hdr->ctrl); 1683 type = __get_type(hdr->ctrl);
1684 1684
@@ -1689,7 +1689,7 @@ static int rfcomm_recv_frame(struct rfcomm_session *s, struct sk_buff *skb)
1689 if (__check_fcs(skb->data, type, fcs)) { 1689 if (__check_fcs(skb->data, type, fcs)) {
1690 BT_ERR("bad checksum in packet"); 1690 BT_ERR("bad checksum in packet");
1691 kfree_skb(skb); 1691 kfree_skb(skb);
1692 return -EILSEQ; 1692 return s;
1693 } 1693 }
1694 1694
1695 if (__test_ea(hdr->len)) 1695 if (__test_ea(hdr->len))
@@ -1705,22 +1705,23 @@ static int rfcomm_recv_frame(struct rfcomm_session *s, struct sk_buff *skb)
1705 1705
1706 case RFCOMM_DISC: 1706 case RFCOMM_DISC:
1707 if (__test_pf(hdr->ctrl)) 1707 if (__test_pf(hdr->ctrl))
1708 rfcomm_recv_disc(s, dlci); 1708 s = rfcomm_recv_disc(s, dlci);
1709 break; 1709 break;
1710 1710
1711 case RFCOMM_UA: 1711 case RFCOMM_UA:
1712 if (__test_pf(hdr->ctrl)) 1712 if (__test_pf(hdr->ctrl))
1713 rfcomm_recv_ua(s, dlci); 1713 s = rfcomm_recv_ua(s, dlci);
1714 break; 1714 break;
1715 1715
1716 case RFCOMM_DM: 1716 case RFCOMM_DM:
1717 rfcomm_recv_dm(s, dlci); 1717 s = rfcomm_recv_dm(s, dlci);
1718 break; 1718 break;
1719 1719
1720 case RFCOMM_UIH: 1720 case RFCOMM_UIH:
1721 if (dlci) 1721 if (dlci) {
1722 return rfcomm_recv_data(s, dlci, __test_pf(hdr->ctrl), skb); 1722 rfcomm_recv_data(s, dlci, __test_pf(hdr->ctrl), skb);
1723 1723 return s;
1724 }
1724 rfcomm_recv_mcc(s, skb); 1725 rfcomm_recv_mcc(s, skb);
1725 break; 1726 break;
1726 1727
@@ -1729,7 +1730,7 @@ static int rfcomm_recv_frame(struct rfcomm_session *s, struct sk_buff *skb)
1729 break; 1730 break;
1730 } 1731 }
1731 kfree_skb(skb); 1732 kfree_skb(skb);
1732 return 0; 1733 return s;
1733} 1734}
1734 1735
1735/* ---- Connection and data processing ---- */ 1736/* ---- Connection and data processing ---- */
@@ -1866,7 +1867,7 @@ static void rfcomm_process_dlcs(struct rfcomm_session *s)
1866 } 1867 }
1867} 1868}
1868 1869
1869static void rfcomm_process_rx(struct rfcomm_session *s) 1870static struct rfcomm_session *rfcomm_process_rx(struct rfcomm_session *s)
1870{ 1871{
1871 struct socket *sock = s->sock; 1872 struct socket *sock = s->sock;
1872 struct sock *sk = sock->sk; 1873 struct sock *sk = sock->sk;
@@ -1878,17 +1879,20 @@ static void rfcomm_process_rx(struct rfcomm_session *s)
1878 while ((skb = skb_dequeue(&sk->sk_receive_queue))) { 1879 while ((skb = skb_dequeue(&sk->sk_receive_queue))) {
1879 skb_orphan(skb); 1880 skb_orphan(skb);
1880 if (!skb_linearize(skb)) 1881 if (!skb_linearize(skb))
1881 rfcomm_recv_frame(s, skb); 1882 s = rfcomm_recv_frame(s, skb);
1882 else 1883 else
1883 kfree_skb(skb); 1884 kfree_skb(skb);
1884 } 1885 }
1885 1886
1886 if (sk->sk_state == BT_CLOSED) { 1887 if (s && (sk->sk_state == BT_CLOSED)) {
1887 if (!s->initiator) 1888 if (!s->initiator)
1888 rfcomm_session_put(s); 1889 s = rfcomm_session_put(s);
1889 1890
1890 rfcomm_session_close(s, sk->sk_err); 1891 if (s)
1892 s = rfcomm_session_close(s, sk->sk_err);
1891 } 1893 }
1894
1895 return s;
1892} 1896}
1893 1897
1894static void rfcomm_accept_connection(struct rfcomm_session *s) 1898static void rfcomm_accept_connection(struct rfcomm_session *s)
@@ -1925,7 +1929,7 @@ static void rfcomm_accept_connection(struct rfcomm_session *s)
1925 sock_release(nsock); 1929 sock_release(nsock);
1926} 1930}
1927 1931
1928static void rfcomm_check_connection(struct rfcomm_session *s) 1932static struct rfcomm_session *rfcomm_check_connection(struct rfcomm_session *s)
1929{ 1933{
1930 struct sock *sk = s->sock->sk; 1934 struct sock *sk = s->sock->sk;
1931 1935
@@ -1944,9 +1948,10 @@ static void rfcomm_check_connection(struct rfcomm_session *s)
1944 1948
1945 case BT_CLOSED: 1949 case BT_CLOSED:
1946 s->state = BT_CLOSED; 1950 s->state = BT_CLOSED;
1947 rfcomm_session_close(s, sk->sk_err); 1951 s = rfcomm_session_close(s, sk->sk_err);
1948 break; 1952 break;
1949 } 1953 }
1954 return s;
1950} 1955}
1951 1956
1952static void rfcomm_process_sessions(void) 1957static void rfcomm_process_sessions(void)
@@ -1975,15 +1980,16 @@ static void rfcomm_process_sessions(void)
1975 1980
1976 switch (s->state) { 1981 switch (s->state) {
1977 case BT_BOUND: 1982 case BT_BOUND:
1978 rfcomm_check_connection(s); 1983 s = rfcomm_check_connection(s);
1979 break; 1984 break;
1980 1985
1981 default: 1986 default:
1982 rfcomm_process_rx(s); 1987 s = rfcomm_process_rx(s);
1983 break; 1988 break;
1984 } 1989 }
1985 1990
1986 rfcomm_process_dlcs(s); 1991 if (s)
1992 rfcomm_process_dlcs(s);
1987 1993
1988 rfcomm_session_put(s); 1994 rfcomm_session_put(s);
1989 } 1995 }