diff mbox series

[v4,1/4] Bluetooth: hci_sock: Add support for BT_{SND,RCV}BUF

Message ID 20210915233600.4129808-1-luiz.dentz@gmail.com
State Superseded
Headers show
Series [v4,1/4] Bluetooth: hci_sock: Add support for BT_{SND,RCV}BUF | expand

Commit Message

Luiz Augusto von Dentz Sept. 15, 2021, 11:35 p.m. UTC
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

This adds support for BT_{SND,RCV}BUF so userspace can set MTU based on
the channel usage.

Fixes: https://github.com/bluez/bluez/issues/201

Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
---
 net/bluetooth/hci_sock.c | 105 +++++++++++++++++++++++++++++++++++----
 1 file changed, 94 insertions(+), 11 deletions(-)

Comments

Tedd Ho-Jeong An Sept. 16, 2021, 12:04 a.m. UTC | #1
Hi Luiz,

On Wed, 2021-09-15 at 16:35 -0700, Luiz Augusto von Dentz wrote:
> From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

> 

> This adds support for BT_{SND,RCV}BUF so userspace can set MTU based on

> the channel usage.

> 

> Fixes: https://github.com/bluez/bluez/issues/201

> 

> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

> ---

>  net/bluetooth/hci_sock.c | 105 +++++++++++++++++++++++++++++++++++----

>  1 file changed, 94 insertions(+), 11 deletions(-)

> 


Tested-by: Tedd Ho-Jeong An <tedd.an@intel.com>


Regards,
Tedd
Tedd Ho-Jeong An Sept. 16, 2021, 12:07 a.m. UTC | #2
Hi Luiz

On Wed, 2021-09-15 at 16:35 -0700, Luiz Augusto von Dentz wrote:
> From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

> 

> This makes use of bt_skb_sendmsg instead of allocating a different

> buffer to be used with memcpy_from_msg which cause one extra copy.

> 

> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

> ---

>  net/bluetooth/hci_sock.c | 100 +++++++++++++++------------------------

>  1 file changed, 37 insertions(+), 63 deletions(-)

> 

Tested-by: Tedd Ho-Jeong An <tedd.an@intel.com>
Tedd Ho-Jeong An Sept. 16, 2021, 12:07 a.m. UTC | #3
Hi Luiz,

On Wed, 2021-09-15 at 16:35 -0700, Luiz Augusto von Dentz wrote:
> From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

> 

> Passing NULL to PTR_ERR will result in 0 (success), also since the likes of

> bt_skb_sendmsg does never return NULL it is safe to replace the instances of

> IS_ERR_OR_NULL with IS_ERR when checking its return.

> 

> Reported-by: Dan Carpenter <dan.carpenter@oracle.com>

> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>


Tested-by: Tedd Ho-Jeong An <tedd.an@intel.com>
kernel test robot Sept. 16, 2021, 4:18 a.m. UTC | #4
Hi Luiz,

I love your patch! Perhaps something to improve:

[auto build test WARNING on bluetooth-next/master]
[also build test WARNING on bluetooth/master]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Luiz-Augusto-von-Dentz/Bluetooth-hci_sock-Add-support-for-BT_-SND-RCV-BUF/20210916-073730
base:   https://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next.git master
config: mips-allyesconfig (attached as .config)
compiler: mips-linux-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/8298fef36eee7525d4e8c7d2c8da9f9473342308
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Luiz-Augusto-von-Dentz/Bluetooth-hci_sock-Add-support-for-BT_-SND-RCV-BUF/20210916-073730
        git checkout 8298fef36eee7525d4e8c7d2c8da9f9473342308
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross ARCH=mips 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

   net/bluetooth/hci_sock.c: In function 'hci_sock_getsockopt':
>> net/bluetooth/hci_sock.c:2058:13: warning: variable 'len' set but not used [-Wunused-but-set-variable]

    2058 |         int len, err = 0;
         |             ^~~


vim +/len +2058 net/bluetooth/hci_sock.c

  2053	
  2054	static int hci_sock_getsockopt(struct socket *sock, int level, int optname,
  2055				       char __user *optval, int __user *optlen)
  2056	{
  2057		struct sock *sk = sock->sk;
> 2058		int len, err = 0;

  2059	
  2060		BT_DBG("sk %p, opt %d", sk, optname);
  2061	
  2062		if (level == SOL_HCI)
  2063			return hci_sock_getsockopt_old(sock, level, optname, optval,
  2064						       optlen);
  2065	
  2066		if (level != SOL_BLUETOOTH)
  2067			return -ENOPROTOOPT;
  2068	
  2069		if (get_user(len, optlen))
  2070			return -EFAULT;
  2071	
  2072		lock_sock(sk);
  2073	
  2074		switch (optname) {
  2075		case BT_SNDMTU:
  2076		case BT_RCVMTU:
  2077			if (put_user(hci_pi(sk)->mtu, (u32 __user *)optval))
  2078				err = -EFAULT;
  2079			break;
  2080	
  2081		default:
  2082			err = -ENOPROTOOPT;
  2083			break;
  2084		}
  2085	
  2086		release_sock(sk);
  2087		return err;
  2088	}
  2089	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
diff mbox series

Patch

diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c
index 55b0d177375b..e481eee8e61e 100644
--- a/net/bluetooth/hci_sock.c
+++ b/net/bluetooth/hci_sock.c
@@ -57,6 +57,7 @@  struct hci_pinfo {
 	unsigned long     flags;
 	__u32             cookie;
 	char              comm[TASK_COMM_LEN];
+	unsigned int      mtu;
 };
 
 static struct hci_dev *hci_hdev_from_sock(struct sock *sk)
@@ -1374,6 +1375,10 @@  static int hci_sock_bind(struct socket *sock, struct sockaddr *addr,
 		break;
 	}
 
+	/* Default MTU to HCI_MAX_FRAME_SIZE if not set */
+	if (!hci_pi(sk)->mtu)
+		hci_pi(sk)->mtu = HCI_MAX_FRAME_SIZE;
+
 	sk->sk_state = BT_BOUND;
 
 done:
@@ -1719,7 +1724,7 @@  static int hci_sock_sendmsg(struct socket *sock, struct msghdr *msg,
 	if (flags & ~(MSG_DONTWAIT | MSG_NOSIGNAL | MSG_ERRQUEUE | MSG_CMSG_COMPAT))
 		return -EINVAL;
 
-	if (len < 4 || len > HCI_MAX_FRAME_SIZE)
+	if (len < 4 || len > hci_pi(sk)->mtu)
 		return -EINVAL;
 
 	buf = kmalloc(len, GFP_KERNEL);
@@ -1849,8 +1854,8 @@  static int hci_sock_sendmsg(struct socket *sock, struct msghdr *msg,
 	goto done;
 }
 
-static int hci_sock_setsockopt(struct socket *sock, int level, int optname,
-			       sockptr_t optval, unsigned int len)
+static int hci_sock_setsockopt_old(struct socket *sock, int level, int optname,
+				   sockptr_t optval, unsigned int len)
 {
 	struct hci_ufilter uf = { .opcode = 0 };
 	struct sock *sk = sock->sk;
@@ -1858,9 +1863,6 @@  static int hci_sock_setsockopt(struct socket *sock, int level, int optname,
 
 	BT_DBG("sk %p, opt %d", sk, optname);
 
-	if (level != SOL_HCI)
-		return -ENOPROTOOPT;
-
 	lock_sock(sk);
 
 	if (hci_pi(sk)->channel != HCI_CHANNEL_RAW) {
@@ -1935,18 +1937,63 @@  static int hci_sock_setsockopt(struct socket *sock, int level, int optname,
 	return err;
 }
 
-static int hci_sock_getsockopt(struct socket *sock, int level, int optname,
-			       char __user *optval, int __user *optlen)
+static int hci_sock_setsockopt(struct socket *sock, int level, int optname,
+			       sockptr_t optval, unsigned int len)
 {
-	struct hci_ufilter uf;
 	struct sock *sk = sock->sk;
-	int len, opt, err = 0;
+	int err = 0, opt = 0;
 
 	BT_DBG("sk %p, opt %d", sk, optname);
 
-	if (level != SOL_HCI)
+	if (level == SOL_HCI)
+		return hci_sock_setsockopt_old(sock, level, optname, optval,
+					       len);
+
+	if (level != SOL_BLUETOOTH)
 		return -ENOPROTOOPT;
 
+	lock_sock(sk);
+
+	switch (optname) {
+	case BT_SNDMTU:
+	case BT_RCVMTU:
+		switch (hci_pi(sk)->channel) {
+		/* Don't allow changing MTU for channels that are meant for HCI
+		 * traffic only.
+		 */
+		case HCI_CHANNEL_RAW:
+		case HCI_CHANNEL_USER:
+			err = -ENOPROTOOPT;
+			goto done;
+		}
+
+		if (copy_from_sockptr(&opt, optval, sizeof(u16))) {
+			err = -EFAULT;
+			break;
+		}
+
+		hci_pi(sk)->mtu = opt;
+		break;
+
+	default:
+		err = -ENOPROTOOPT;
+		break;
+	}
+
+done:
+	release_sock(sk);
+	return err;
+}
+
+static int hci_sock_getsockopt_old(struct socket *sock, int level, int optname,
+				   char __user *optval, int __user *optlen)
+{
+	struct hci_ufilter uf;
+	struct sock *sk = sock->sk;
+	int len, opt, err = 0;
+
+	BT_DBG("sk %p, opt %d", sk, optname);
+
 	if (get_user(len, optlen))
 		return -EFAULT;
 
@@ -2004,6 +2051,42 @@  static int hci_sock_getsockopt(struct socket *sock, int level, int optname,
 	return err;
 }
 
+static int hci_sock_getsockopt(struct socket *sock, int level, int optname,
+			       char __user *optval, int __user *optlen)
+{
+	struct sock *sk = sock->sk;
+	int len, err = 0;
+
+	BT_DBG("sk %p, opt %d", sk, optname);
+
+	if (level == SOL_HCI)
+		return hci_sock_getsockopt_old(sock, level, optname, optval,
+					       optlen);
+
+	if (level != SOL_BLUETOOTH)
+		return -ENOPROTOOPT;
+
+	if (get_user(len, optlen))
+		return -EFAULT;
+
+	lock_sock(sk);
+
+	switch (optname) {
+	case BT_SNDMTU:
+	case BT_RCVMTU:
+		if (put_user(hci_pi(sk)->mtu, (u32 __user *)optval))
+			err = -EFAULT;
+		break;
+
+	default:
+		err = -ENOPROTOOPT;
+		break;
+	}
+
+	release_sock(sk);
+	return err;
+}
+
 static const struct proto_ops hci_sock_ops = {
 	.family		= PF_BLUETOOTH,
 	.owner		= THIS_MODULE,