Received: by 2002:a05:6a10:206:0:0:0:0 with SMTP id 6csp487360pxj; Thu, 10 Jun 2021 05:49:45 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyV4oAy4OBI5v9maVee4Dh31SZMIiAG+l7f3+tILyLnEKxHgrkKaF3d9zCUz8YTdSob/IXi X-Received: by 2002:a17:906:b88e:: with SMTP id hb14mr4256786ejb.396.1623329384839; Thu, 10 Jun 2021 05:49:44 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1623329384; cv=none; d=google.com; s=arc-20160816; b=YtWsKmnI5MypMn8/rgmLUBq4y5cKKqGL9HkZnzjoGzNFK1+1sxeKjE7c9MVljxQuc+ i7iNbZSk0KrF+Oew7xpOeM3IQlyo+nJYs2fE+ycBaQ7t2V2VDLz3llmaK55USZscyvvd qQ2pwku0YOsoKO+lFHljpgudsigTUVga0cmHntlXfbCF4Dkhm5e/papiiumBxC4VvqF6 v5GN1TLKTRduSvjCPfQKR9XP8WugBuZIiAhFwnX1FkBYxmBYl1iBJRoDtQYya7/inEKe QnO7O/cQ1cPtg77bNW1XDki54YJwAHCTpLEWE9X+f/Pv2qQndPciMfg052CaH1//iGTq tHRQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:date:cc:to:from:subject :message-id; bh=DUl2JW+US0nP777OuB9LHyxmku5VK+N2MKr11mbJqTQ=; b=eGyohFKkkK/QywvKnzg61DbrfPZLpvVlTtuoOI5wjPyMxESuUlsVIE5Nn0pALXlqkJ LRR6qrvZ2V6PvZqksu1YlNi3tUWuX5o76XxG/qM4aujkK3cQl2gM1HTy84o/Ze1tBJ+R pSZ+iEH8fo5CvYih6Zb5bVd0SM6AAU92FJYngOSV5Lqz03XUyA+Ox/KpKCSOcgC2C/Bi X2meNjTQf18VaSOmhuoTPG/IHYQsQylmxibu7waFMOVTbBdfr0F2HabnITIWcOllWkq3 uLorlOZBs6IwCquHKhj1B54dDdn2c2LVQwQHON7urVFlPlWcwRbl+CmPbOMOcjR4RtN6 ZrTg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-bluetooth-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-bluetooth-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id gh25si2156123ejb.170.2021.06.10.05.49.05; Thu, 10 Jun 2021 05:49:44 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-bluetooth-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-bluetooth-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-bluetooth-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230001AbhFJMrU (ORCPT + 99 others); Thu, 10 Jun 2021 08:47:20 -0400 Received: from relay12.mail.gandi.net ([217.70.178.232]:45371 "EHLO relay12.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230299AbhFJMrT (ORCPT ); Thu, 10 Jun 2021 08:47:19 -0400 Received: (Authenticated sender: hadess@hadess.net) by relay12.mail.gandi.net (Postfix) with ESMTPSA id 0CA9420000B; Thu, 10 Jun 2021 12:45:19 +0000 (UTC) Message-ID: Subject: Re: [PATCH] rfkill: Fix reading from rfkill socket From: Bastien Nocera To: Benjamin Berg , linux-bluetooth@vger.kernel.org Cc: Benjamin Berg Date: Thu, 10 Jun 2021 14:45:19 +0200 In-Reply-To: <20210503131210.90066-1-benjamin@sipsolutions.net> References: <20210503131210.90066-1-benjamin@sipsolutions.net> Content-Type: text/plain; charset="UTF-8" User-Agent: Evolution 3.40.1 (3.40.1-1.fc34) MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org On Mon, 2021-05-03 at 15:12 +0200, Benjamin Berg wrote: > From: Benjamin Berg > > The kernel will always send exactly one event, but the size of the > passed struct will depend on the length of the submitted read() and the > kernel version. i.e. the interface can be extended and we need to > expect > for a read to be longer than expected if we ask for it. > > Fix this by only requesting the needed length and explicitly check the > length against the V1 version of the structure to make the code a bit > more future proof in case the internal copy of the struct is updated to > contain new fields. This fixes a bug in GNOME where to enable Bluetooth, we removed a soft rfkill block on the Bluetooth interface. Without this, the bluetooth rfkill gets unblocked, but bluetoothd doesn't see it as unblocked so never powers it on, causing the UI to appear broken, as we expect Bluetooth devices to be either blocked through rfkill, or powered on. The equivalent gnome-settings-daemon fix (which deals with rfkill) was reviewed by Hans de Goede: https://gitlab.gnome.org/GNOME/gnome-settings-daemon/-/merge_requests/234 Benjamin, it might be worth resending this with a better commit message explaining exactly what it fixes and referencing the gnome-bluetooth bug: https://gitlab.gnome.org/GNOME/gnome-bluetooth/-/issues/38 Cheers > --- >  src/rfkill.c | 24 +++++++++++------------- >  1 file changed, 11 insertions(+), 13 deletions(-) > > diff --git a/src/rfkill.c b/src/rfkill.c > index ec9fcdfdd..2099c5ac5 100644 > --- a/src/rfkill.c > +++ b/src/rfkill.c > @@ -53,12 +53,12 @@ struct rfkill_event { >         uint8_t  soft; >         uint8_t  hard; >  }; > +#define RFKILL_EVENT_SIZE_V1    8 >   >  static gboolean rfkill_event(GIOChannel *chan, >                                 GIOCondition cond, gpointer data) >  { > -       unsigned char buf[32]; > -       struct rfkill_event *event = (void *) buf; > +       struct rfkill_event event = { 0 }; >         struct btd_adapter *adapter; >         char sysname[PATH_MAX]; >         ssize_t len; > @@ -69,34 +69,32 @@ static gboolean rfkill_event(GIOChannel *chan, >   >         fd = g_io_channel_unix_get_fd(chan); >   > -       memset(buf, 0, sizeof(buf)); > - > -       len = read(fd, buf, sizeof(buf)); > +       len = read(fd, &event, sizeof(event)); >         if (len < 0) { >                 if (errno == EAGAIN) >                         return TRUE; >                 return FALSE; >         } >   > -       if (len != sizeof(struct rfkill_event)) > +       if (len < RFKILL_EVENT_SIZE_V1) >                 return TRUE; >   >         DBG("RFKILL event idx %u type %u op %u soft %u hard %u", > -                                       event->idx, event->type, event- > >op, > -                                               event->soft, event- > >hard); > +                                       event.idx, event.type, > event.op, > +                                               event.soft, > event.hard); >   > -       if (event->soft || event->hard) > +       if (event.soft || event.hard) >                 return TRUE; >   > -       if (event->op != RFKILL_OP_CHANGE) > +       if (event.op != RFKILL_OP_CHANGE) >                 return TRUE; >   > -       if (event->type != RFKILL_TYPE_BLUETOOTH && > -                                       event->type != RFKILL_TYPE_ALL) > +       if (event.type != RFKILL_TYPE_BLUETOOTH && > +                                       event.type != RFKILL_TYPE_ALL) >                 return TRUE; >   >         snprintf(sysname, sizeof(sysname) - 1, > -                       "/sys/class/rfkill/rfkill%u/name", event->idx); > +                       "/sys/class/rfkill/rfkill%u/name", event.idx); >   >         fd = open(sysname, O_RDONLY); >         if (fd < 0)