From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751457AbcBKSbj (ORCPT ); Thu, 11 Feb 2016 13:31:39 -0500 Received: from tiger.mobileactivedefense.com ([217.174.251.109]:44587 "EHLO tiger.mobileactivedefense.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750784AbcBKSbh convert rfc822-to-8bit (ORCPT ); Thu, 11 Feb 2016 13:31:37 -0500 From: Rainer Weikusat To: Ben Hutchings Cc: Rainer Weikusat , Philipp Hahn , Hannes Frederic Sowa , Sasha Levin , "David S. Miller" , linux-kernel@vger.kernel.org, Karolin Seeger , Jason Baron , Greg Kroah-Hartman , Arvid Requate , Stefan Gohmann Subject: Re: Bug 4.1.16: self-detected stall in net/unix/? In-Reply-To: <87r3gjjgbu.fsf@doppelsaurus.mobileactivedefense.com> (Rainer Weikusat's message of "Thu, 11 Feb 2016 17:40:37 +0000") References: <56B4BF9D.9070609@pmhahn.de> <56BC90E7.7040007@pmhahn.de> <87fuwzkzr5.fsf@doppelsaurus.mobileactivedefense.com> <1455210224.2801.21.camel@decadent.org.uk> <87r3gjjgbu.fsf@doppelsaurus.mobileactivedefense.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.4 (gnu/linux) Date: Thu, 11 Feb 2016 18:31:04 +0000 Message-ID: <87egcjcd5j.fsf@doppelsaurus.mobileactivedefense.com> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8BIT X-Greylist: Sender succeeded SMTP AUTH, not delayed by milter-greylist-4.4.3 (tiger.mobileactivedefense.com [217.174.251.109]); Thu, 11 Feb 2016 18:31:14 +0000 (GMT) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Rainer Weikusat writes: > Ben Hutchings writes: [...] >> unix: Fix potential double-unlock in unix_dgram_sendmsg() >> >> A datagram socket may be peered with itself, so that sk == other.  We >> use unix_state_double_lock() to lock sk and other in the right order, >> which also guards against this and only locks the socket once, but we >> then end up trying to unlock it twice.  Add the check for sk != other. [...] > other was found via > > if (!other) { > err = -ECONNRESET; > if (sunaddr == NULL) > goto out_free; > > other = unix_find_other(net, sunaddr, namelen, sk->sk_type, > hash, &err); > if (other == NULL) > goto out_free; > } > > and the if-block leading to the double lock should never have been > executed as it's supposed to deal with the case where sk is connect to > other but other not to sk (eg, /dev/log). Test program triggering a double unlock (w/o the MSG_DONTWAIT, it blocks which it isn't supposed to do): -------- #include #include #include #include #define SUN_NAME "\0other-is-me" int main(int argc, char **argv) { struct sockaddr_un sun; unsigned max; int sk, rc; sk = socket(AF_UNIX, SOCK_DGRAM, 0); sun.sun_family = AF_UNIX; strncpy(sun.sun_path, SUN_NAME, sizeof(sun.sun_path)); bind(sk, (struct sockaddr *)&sun, sizeof(sun)); max = 12; do sendto(sk, &sun, sizeof(sun), MSG_DONTWAIT, (struct sockaddr *)&sun, sizeof(sun)); while (--max); return 0; }