Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 05 Dec 2005 15:00:23 -0800
From:      Maksim Yevmenkin <maksim.yevmenkin@savvis.net>
To:        freebsd-bluetooth@freebsd.org
Cc:        =?ISO-8859-1?Q?Zahemszky_G=E1bor?= <Gabor@Zahemszky.HU>
Subject:   Re: [PATCH] Local browsing: permission denied
Message-ID:  <4394C687.9060108@savvis.net>
In-Reply-To: <4394B211.1080503@savvis.net>
References:  <4394A53E.1050109@Zahemszky.HU> <4394B211.1080503@savvis.net>

next in thread | previous in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format.
--------------060006020806080006030503
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit

Hello,

please try the attached patch for sdpd(8) daemon. with this patch
sdpd(8) will

1) change permission on the control socket,

2) check peer's credential

3) accept register/remove/change service requests only if peer has 
effective user id the same as 'root' user id

it should be now possible to run 'sdpcontrol -l' as regular user.

thanks,
max

--------------060006020806080006030503
Content-Type: text/plain;
 name="sdpd.diff.txt"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="sdpd.diff.txt"

Index: scr.c
===================================================================
RCS file: /usr/local/cvs/usr.sbin/bluetooth/sdpd/scr.c,v
retrieving revision 1.2
diff -u -r1.2 scr.c
--- scr.c	23 Aug 2004 18:42:21 -0000	1.2
+++ scr.c	5 Dec 2005 22:46:47 -0000
@@ -58,7 +58,8 @@
 	 * value32	- handle 4 bytes
 	 */
 
-	if (!srv->fdidx[fd].control || req_end - req < 4)
+	if (!srv->fdidx[fd].control ||
+	    !srv->fdidx[fd].priv || req_end - req < 4)
 		return (SDP_ERROR_CODE_INVALID_REQUEST_SYNTAX);
 
 	/* Get handle */
Index: server.c
===================================================================
RCS file: /usr/local/cvs/usr.sbin/bluetooth/sdpd/server.c,v
retrieving revision 1.7
diff -u -r1.7 server.c
--- server.c	23 Aug 2004 18:42:21 -0000	1.7
+++ server.c	5 Dec 2005 22:34:33 -0000
@@ -29,14 +29,18 @@
  * $FreeBSD: src/usr.sbin/bluetooth/sdpd/server.c,v 1.1 2004/01/20 20:48:26 emax Exp $
  */
 
+#include <sys/param.h>
 #include <sys/select.h>
+#include <sys/stat.h>
 #include <sys/queue.h>
+#include <sys/ucred.h>
 #include <sys/un.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <assert.h>
 #include <bluetooth.h>
 #include <errno.h>
+#include <pwd.h>
 #include <sdp.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -96,6 +100,13 @@
 		return (-1);
 	}
 
+	if (chmod(control, S_IRWXU|S_IRWXG|S_IRWXO) < 0) {
+		log_crit("Could not change permissions on control socket. " \
+			"%s (%d)", strerror(errno), errno);
+		close(unsock);
+		return (-1);
+	}
+
 	if (listen(unsock, 10) < 0) {
 		log_crit("Could not listen on control socket. %s (%d)",
 			strerror(errno), errno);
@@ -185,6 +196,7 @@
 	srv->fdidx[unsock].valid = 1;
 	srv->fdidx[unsock].server = 1;
 	srv->fdidx[unsock].control = 1;
+	srv->fdidx[unsock].priv = 0;
 	srv->fdidx[unsock].rsp_cs = 0;
 	srv->fdidx[unsock].rsp_size = 0;
 	srv->fdidx[unsock].rsp_limit = 0;
@@ -195,6 +207,7 @@
 	srv->fdidx[l2sock].valid = 1;
 	srv->fdidx[l2sock].server = 1;
 	srv->fdidx[l2sock].control = 0;
+	srv->fdidx[l2sock].priv = 0;
 	srv->fdidx[l2sock].rsp_cs = 0;
 	srv->fdidx[l2sock].rsp_size = 0;
 	srv->fdidx[l2sock].rsp_limit = 0;
@@ -276,7 +289,7 @@
 server_accept_client(server_p srv, int32_t fd)
 {
 	uint8_t		*rsp = NULL;
-	int32_t		 cfd, size;
+	int32_t		 cfd, size, priv;
 	uint16_t	 omtu;
 
 	do {
@@ -293,6 +306,8 @@
 	assert(!FD_ISSET(cfd, &srv->fdset));
 	assert(!srv->fdidx[cfd].valid);
 
+	priv = 0;
+
 	if (!srv->fdidx[fd].control) {
 		/* Get local BD_ADDR */
 		size = sizeof(srv->req_sa);
@@ -326,6 +341,28 @@
 			return;
 		}
 	} else {
+		struct xucred	 cr;
+		struct passwd	*pw;
+
+		/* Get peer's credentials */
+		memset(&cr, 0, sizeof(cr));
+		size = sizeof(cr);
+
+		if (getsockopt(cfd, 0, LOCAL_PEERCRED, &cr, &size) < 0) {
+			log_err("Could not get peer's credentials. %s (%d)",
+				strerror(errno), errno);
+			close(cfd);
+			return;
+		}
+
+		/* Check credentials */
+		pw = getpwuid(cr.cr_uid);
+		if (pw != NULL)
+			priv = (strcmp(pw->pw_name, "root") == 0);
+		else
+			log_warning("Could not verify credentials for uid %d",
+				cr.cr_uid);
+
 		memcpy(&srv->req_sa.l2cap_bdaddr, NG_HCI_BDADDR_ANY,
 			sizeof(srv->req_sa.l2cap_bdaddr));
 
@@ -351,6 +388,7 @@
 	srv->fdidx[cfd].valid = 1;
 	srv->fdidx[cfd].server = 0;
 	srv->fdidx[cfd].control = srv->fdidx[fd].control;
+	srv->fdidx[cfd].priv = priv;
 	srv->fdidx[cfd].rsp_cs = 0;
 	srv->fdidx[cfd].rsp_size = 0;
 	srv->fdidx[cfd].rsp_limit = 0;
Index: server.h
===================================================================
RCS file: /usr/local/cvs/usr.sbin/bluetooth/sdpd/server.h,v
retrieving revision 1.6
diff -u -r1.6 server.h
--- server.h	23 Aug 2004 18:42:21 -0000	1.6
+++ server.h	5 Dec 2005 22:30:31 -0000
@@ -41,7 +41,8 @@
 	unsigned	 valid    : 1;	/* descriptor is valid */
 	unsigned	 server   : 1;	/* descriptor is listening */
 	unsigned	 control  : 1;	/* descriptor is a control socket */
-	unsigned	 reserved : 2;
+	unsigned	 priv     : 1;	/* descriptor is privileged */
+	unsigned	 reserved : 1;
 	unsigned	 rsp_cs   : 11; /* response continuation state */
 	uint16_t	 rsp_size;	/* response size */
 	uint16_t	 rsp_limit;	/* response limit */
Index: srr.c
===================================================================
RCS file: /usr/local/cvs/usr.sbin/bluetooth/sdpd/srr.c,v
retrieving revision 1.2
diff -u -r1.2 srr.c
--- srr.c	23 Aug 2004 18:42:21 -0000	1.2
+++ srr.c	5 Dec 2005 22:47:20 -0000
@@ -65,7 +65,8 @@
 	 * bdaddr	- BD_ADDR 6 bytes
 	 */
 
-	if (!srv->fdidx[fd].control || req_end - req < 8)
+	if (!srv->fdidx[fd].control ||
+	    !srv->fdidx[fd].priv || req_end - req < 8)
 		return (SDP_ERROR_CODE_INVALID_REQUEST_SYNTAX);
 
 	/* Get ServiceClass UUID */
Index: sur.c
===================================================================
RCS file: /usr/local/cvs/usr.sbin/bluetooth/sdpd/sur.c,v
retrieving revision 1.2
diff -u -r1.2 sur.c
--- sur.c	23 Aug 2004 18:42:21 -0000	1.2
+++ sur.c	5 Dec 2005 22:47:36 -0000
@@ -58,7 +58,8 @@
 	 * value32	- uuid 4 bytes
 	 */
 
-	if (!srv->fdidx[fd].control || req_end - req < 4)
+	if (!srv->fdidx[fd].control ||
+            !srv->fdidx[fd].priv || req_end - req < 4)
 		return (SDP_ERROR_CODE_INVALID_REQUEST_SYNTAX);
 
 	/* Get handle */

--------------060006020806080006030503--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?4394C687.9060108>