From owner-freebsd-bluetooth@FreeBSD.ORG Mon Dec 5 23:00:30 2005 Return-Path: X-Original-To: freebsd-bluetooth@freebsd.org Delivered-To: freebsd-bluetooth@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id A13CB16A41F for ; Mon, 5 Dec 2005 23:00:30 +0000 (GMT) (envelope-from maksim.yevmenkin@savvis.net) Received: from ismybrain.com (ismybrain.com [64.246.42.25]) by mx1.FreeBSD.org (Postfix) with ESMTP id B99B343D62 for ; Mon, 5 Dec 2005 23:00:27 +0000 (GMT) (envelope-from maksim.yevmenkin@savvis.net) Received: from [10.254.186.111] (localhost.localdomain [127.0.0.1]) by ismybrain.com (8.11.6/8.11.6) with ESMTP id jB5N0PJ17542; Mon, 5 Dec 2005 18:00:26 -0500 Message-ID: <4394C687.9060108@savvis.net> Date: Mon, 05 Dec 2005 15:00:23 -0800 From: Maksim Yevmenkin User-Agent: Mozilla Thunderbird 1.0.2 (X11/20050404) X-Accept-Language: en-us, en MIME-Version: 1.0 To: freebsd-bluetooth@freebsd.org References: <4394A53E.1050109@Zahemszky.HU> <4394B211.1080503@savvis.net> In-Reply-To: <4394B211.1080503@savvis.net> Content-Type: multipart/mixed; boundary="------------060006020806080006030503" Cc: =?ISO-8859-1?Q?Zahemszky_G=E1bor?= Subject: Re: [PATCH] Local browsing: permission denied X-BeenThere: freebsd-bluetooth@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Using Bluetooth in FreeBSD environments List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 05 Dec 2005 23:00:30 -0000 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 #include +#include #include +#include #include #include #include #include #include #include +#include #include #include #include @@ -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--