[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH] Local browsing: permission denied
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
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 */