Received: by 2002:a25:4158:0:0:0:0:0 with SMTP id o85csp1632423yba; Thu, 25 Apr 2019 03:09:43 -0700 (PDT) X-Google-Smtp-Source: APXvYqzPqgRtgmmOxayEM9KoII5na2jZdnJi05dboOqcoyJbLjshEMsr0PVgt6AdhEBs6G1cN/bo X-Received: by 2002:a62:12c9:: with SMTP id 70mr38509867pfs.156.1556186983266; Thu, 25 Apr 2019 03:09:43 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1556186983; cv=none; d=google.com; s=arc-20160816; b=KiL2oLzITc7pFXJ6MiE8nVRLjTckQ0mWJoALxE3dax66jzFH2Kfc+ghJWkOXdq/B8G WQmU+Srk6f2SKbuysOFX36os/Gf7oF4xe9G3S0NipI8+61lzpHEG4qDRg4AV0ikhLjzl Jg9jyWS2PqWqpC1nJlvmeTptvPUdj8+ihiDfxohPuHDnX0yKdPIQUU+9z/u5U/NsnZld jFBuFQfSkUFvXlugJQicgjZ7E2qLh2Q9dSZ9al1r03abULN66xf/KiXxaZTBWd+BR2z5 iNlPHA/Uwb0acsfL7BTI4WTth6RZxAEY1oINidlC9XCt1TgwcL41L3AWryPZEmkVGHmy fE3A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:user-agent:in-reply-to :content-transfer-encoding:content-disposition:mime-version :references:message-id:subject:cc:to:from:date; bh=A+XW6Hl6/bFZ8lHXJKardx/8GjqXMaTIKD6TI3MKNwQ=; b=Bso2JHRbaTJEvouAedQFzyTTzsIDIrWpHZ0/kxEluZ9UI08BThvgO++XRW3CBBntqw ktLvgJaS6PAbplcIiamIH12ugUpGAcFQxE5igQiMLDJhl3RQqnT+dq82bzCn8U2vE9Qi 3IT3rfdrEvyqPykpnX+wgo8BqaoONdk5CoBBCFg4EdHHRo0zB+Vk3vXvuE8hg6G95Lhm HRlLNSPBVApClPqlIo2FBpPQaKeAPgQPgpFvs0U3H64+UpQdmNO+qoggNyfb9UvFa6jw 4YCb87cT1VGBh3egg9ikFaeB25/ZodIV73di7zRBLiUeiBYWY6hEw/0GSIaSXL4dIonJ LzUQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id h3si18999560pld.302.2019.04.25.03.09.27; Thu, 25 Apr 2019 03:09:43 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727276AbfDXW4r (ORCPT + 99 others); Wed, 24 Apr 2019 18:56:47 -0400 Received: from zeniv.linux.org.uk ([195.92.253.2]:33674 "EHLO ZenIV.linux.org.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726829AbfDXW4r (ORCPT ); Wed, 24 Apr 2019 18:56:47 -0400 Received: from viro by ZenIV.linux.org.uk with local (Exim 4.92 #3 (Red Hat Linux)) id 1hJQok-0005Ws-2B; Wed, 24 Apr 2019 22:56:42 +0000 Date: Wed, 24 Apr 2019 23:56:42 +0100 From: Al Viro To: Mukesh Ojha Cc: "dmitry.torokhov@gmail.com" , linux-input@vger.kernel.org, linux-kernel@vger.kernel.org, Gaurav Kohli , Peter Hutterer , Martin Kepplinger , "Paul E. McKenney" Subject: Re: [PATCH v2] Input: uinput: Avoid Object-Already-Free with a global lock Message-ID: <20190424225641.GQ2217@ZenIV.linux.org.uk> References: <20190419071152.x5ghvbybjhv76uxt@penguin> <20190423032839.xvbldglrmjxkdntj@penguin> <17f4a0be-ab04-8537-9197-32fbca807f3f@codeaurora.org> <20190423084944.gj2boxfcg7lp4zad@penguin> <20190423110611.GL2217@ZenIV.linux.org.uk> <5614f04f-827d-1668-9ed0-60d93e110b8e@codeaurora.org> <20190424130711.GP2217@ZenIV.linux.org.uk> <5b02ac1e-df3e-d9cd-ecf3-fe60cda2cece@codeaurora.org> MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <5b02ac1e-df3e-d9cd-ecf3-fe60cda2cece@codeaurora.org> User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Wed, Apr 24, 2019 at 07:39:03PM +0530, Mukesh Ojha wrote: > This was my simple program no multithreading just to understand f_counting > > int main() > { > ??????? int fd = open("/dev/uinput", O_WRONLY | O_NONBLOCK); > ??????? ioctl(fd, UI_SET_EVBIT, EV_KEY); > ??????? close(fd); > ??????? return 0; > } > > ? ? ? ?? ? uinput-532?? [002] ....??? 45.312044: SYSC_ioctl: 2 ? <= f_count Er... So how does it manage to hit ioctl(2) before open(2)? Confused... > >??? ????????? uinput-532?? [002] ....??? 45.312055: SYSC_ioctl: 2??????????? > ????????? uinput-532?? [004] ....??? 45.313766: uinput_open: uinput: 1?? /* > This is from the uinput driver uinput_open()*/ > > ? =>>>> ? ? ? ? ? ? ? ? ? ? ? ? /* All the above calls happened for the > open() in userspace*/ > > ????????? uinput-532?? [004] ....??? 45.313783: SYSC_ioctl: 1 /* This print > is for the trace, i put after fdget */ > ????????? uinput-532?? [004] ....??? 45.313788: uinput_ioctl_handler: > uinput: uinput_ioctl_handler, 1 /* This print is from the uinput_ioctl > driver */ > > ????????? uinput-532?? [004] ....??? 45.313835: SYSC_ioctl: 1 /* This print > is for the trace, i put after fdput*/ > ????????? uinput-532?? [004] ....??? 45.313843: uinput_release: uinput:? 0 > /* And this is from the close()? */ > > > Should fdget not suppose to increment the f_count here, as it is coming 1 ? > This f_count to one is done at the open, but i have no idea how this? below > f_count 2 came before open() for > this simple program. If descriptor table is not shared, fdget() will simply return you the reference from there, without bothering to bump the refcount. _And_ having it marked "don't drop refcount" in struct fd. Rationale: since it's not shared, nobody other than our process can modify it. So unless we remove (and drop) the reference from it ourselves (which we certainly have no business doing in ->ioctl() and do not do anywhere in drivers/input), it will remain there until we return from syscall. Nobody is allowed to modify descriptor table other than their own. And if it's not shared, no other owners can appear while the only existing one is in the middle of syscall other than clone() (with CLONE_FILES in flags, at that). For shared descriptor table fdget() bumps file refcount, since there the reference in descriptor table itself could be removed and dropped by another thread. And fdget() marks whether fput() is needed in fd.flags, so that fdput() does the right thing.