From: Takashi Iwai <tiwai@suse.de>
Subject: kABI workaround for bluetooth l2cap_ops filter addition
Patch-mainline: Never, kABI workaround for SLE15-SP2
References: CVE-2020-12351 bsc#1177724
The recent fix for adding a new field to struct l2cap_ops breaks kABI.
We may protect the new field with __GENKSYMS__, but this still needs
some check not to access the unexisting field in the old code.
Fix it by checking a new bit field in caps->flags additionally.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
include/net/bluetooth/l2cap.h | 8 ++++++++
net/bluetooth/l2cap_core.c | 4 +++-
net/bluetooth/l2cap_sock.c | 2 ++
3 files changed, 13 insertions(+), 1 deletion(-)
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -623,8 +623,13 @@ struct l2cap_ops {
struct sk_buff *(*alloc_skb) (struct l2cap_chan *chan,
unsigned long hdr_len,
unsigned long len, int nb);
+#ifndef __GENKSYMS__
+ /* XXX: kABI workaround for SLE15-SP2; for enabling this ops,
+ * you need to set FLAG_CHAN_OPS_SK_FILTER to chan->flags, too
+ */
int (*filter) (struct l2cap_chan * chan,
struct sk_buff *skb);
+#endif
};
struct l2cap_conn {
@@ -730,6 +735,9 @@ enum {
FLAG_HOLD_HCI_CONN,
};
+/* XXX: a special flag for SLE15-SP2 kABI workaround */
+#define FLAG_CHAN_OPS_SK_FILTER 30
+
/* Lock nesting levels for L2CAP channels. We need these because lockdep
* otherwise considers all channels equal and will e.g. complain about a
* connection oriented channel triggering SMP procedures or a listening
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -6701,7 +6701,9 @@ static int l2cap_data_rcv(struct l2cap_c
goto drop;
}
- if (chan->ops->filter) {
+ /* XXX: kABI workaround for SLE15-SP2; checking the special flag */
+ if (test_bit(FLAG_CHAN_OPS_SK_FILTER, &chan->flags) &&
+ chan->ops->filter) {
if (chan->ops->filter(chan, skb))
goto drop;
}
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -1602,6 +1602,8 @@ static void l2cap_sock_init(struct sock
chan->data = sk;
chan->ops = &l2cap_chan_ops;
+ /* XXX: a special flag for SLE15-SP2 kABI workaround */
+ set_bit(FLAG_CHAN_OPS_SK_FILTER, &chan->flags);
}
static struct proto l2cap_proto = {