Received: by 2002:a25:86ce:0:0:0:0:0 with SMTP id y14csp2092382ybm; Thu, 23 May 2019 11:14:23 -0700 (PDT) X-Google-Smtp-Source: APXvYqy7whaRaQtVVp8V7PXxu6zwmFGFjtJcO4UT9x0vPVzxeEOPYKgu4qXTn5RdXZPpvKNSPIG0 X-Received: by 2002:a63:d252:: with SMTP id t18mr100674347pgi.131.1558635263606; Thu, 23 May 2019 11:14:23 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1558635263; cv=none; d=google.com; s=arc-20160816; b=DdyISlRBbB9DKATOyXYSkHSY2Qffa2ykr1I8TY52lyys6m2U4+kt1T5PkAymf7htpG +xLcs2FnqBMkIj0rYRFG2pxrQ7q6hMC+00iIl3Mx+Qc/3Ev7Yo4UrwdoBKb1RYS2dahx II8jD/Rvtt8X9dYFFvwOOBToqzmo5fOR+xYxAxemwITi8yhXnWxp7SwSH6miY3/ykuvR Yna4R5jYoF+LfXD52zQjdRoxIf7aUz/jijbkOr/fbLxpC8Oz2CZNcFKmbV40eW4AhfmP nubg3meVi8vBcngHS3mZjQL0okodYSb6iMJzk+UKxbr+dMguIfhJEC/jOwqTHK7sbucx B2Cw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:message-id:in-reply-to :subject:cc:to:from:date; bh=DgUVCgL4MWCiGmCnamgYKANXW0pWaYYjTolZXzh1SkE=; b=QHWEtZPZsuitZETiBeWM+C1UZ6uUs4s8HBhbfnblqZXIxVBiWgNjRtYRtwzGn5xS2A sMTn80vFZGTf2wjPqzahxvvEA5fDXV9lc/sbGAS6F7Uwg+ABlCD4PTa4+ZQ6rdTSsLrP ZUDjeqzNtNmFXQK37uolNcEBkYFTv1ecSOwfttiCgSpesu2yiI896cJePf5jMfyPe+5W Jy8RhAHP0d9eB/d8VCEV0fXlKHrcW/HBfy0+nC10Q9ZM5jOKaPG0lawI3+zXHoyGDeaN f2DD1JSbrVk/HkPpxSstQK4nntQ8nDZ539IRkW5CY5V+xCQjukID1EXUsN0Pv/Ud6Aeb WTwA== 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 d191si236322pga.454.2019.05.23.11.14.06; Thu, 23 May 2019 11:14:23 -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 S1731379AbfEWSM6 (ORCPT + 99 others); Thu, 23 May 2019 14:12:58 -0400 Received: from iolanthe.rowland.org ([192.131.102.54]:34504 "HELO iolanthe.rowland.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with SMTP id S1731275AbfEWSM6 (ORCPT ); Thu, 23 May 2019 14:12:58 -0400 Received: (qmail 24557 invoked by uid 2102); 23 May 2019 14:12:57 -0400 Received: from localhost (sendmail-bs@127.0.0.1) by localhost with SMTP; 23 May 2019 14:12:57 -0400 Date: Thu, 23 May 2019 14:12:57 -0400 (EDT) From: Alan Stern X-X-Sender: stern@iolanthe.rowland.org To: "Eric W. Biederman" cc: linux-usb@vger.kernel.org, Greg Kroah-Hartman , Oliver Neukum , Subject: Re: [PATCH] signal/usb: Replace kill_pid_info_as_cred with kill_pid_usb_asyncio In-Reply-To: <87o93ujh0s.fsf@xmission.com> Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Wed, 22 May 2019, Eric W. Biederman wrote: > Perhaps this will work as a diagram. I don't know if there is a better > way to say it in my patch description. In struct siginfo there are 3 > fields in fixed positions: > > int si_signo; > int si_errno; > int si_code; > > After that there is a union. The si_signo and si_code fields are > examined to see which union member is valid (see siginfo_layout). > In every other case a si_code of SI_ASYNCIO corresponds to > the the _rt union member which has the fields: > > int si_pid; > int si_uid; > sigval_t si_sigval; Yuu mean it's actually a union of structures containing these fields, not a union of these fields, right? > However when usb started using SI_ASYNCIO the _sigfault union member > that (except for special exceptions) only has the field: > > void __user *si_addr; > > Or in short the relevant piece of the union looks like: > > 0 1 2 3 4 5 6 7 > +---+---+---+---+---+---+---+---+ > | si_pid | si_uid | > +---+---+---+---+---+---+---+---+ > | si_addr | (64bit) > +---+---+---+---+---+---+---+---+ > | si_addr | (32bit) > +---+---+---+---+ > > Which means if siginfo is copied field by field on 32bit everything > works because si_pid and si_addr are in the same location. When you say "copied field by field", you mean that the si_pid, si_uid, and si_sigval values are copied individually? > Similarly if siginfo is copied field by field on 64bit everything > works because there is no padding between si_pid and si_uid. So > copying both of those fields results in the entire si_addr being > copied. > > It is the compat case that gets tricky. Half of the bits are > zero. If those zero bits show up in bytes 4-7 and the data > shows up in bytes 0-3 (aka little endian) everything works. > If those zero bits show in in bytes 0-3 (aka big endian) userspace sees > a NULL pointer instead of the value it passed. The problem is that the compat translation layer copies si_pid and si_uid from the 64-bit kernel structure to the 32-bit user structure. And since the system is big-endian, the 64-bit si_addr value has zeros in bytes 0-3. But those zeros are what userspace ends up seeing in its 32-bit version of si_addr. So the solution is to store the address in the si_sigval part instead. Wouldn't it have been easier to have a compat routine somewhere just do something like: sinfo->si_pid = (u32) sinfo->si_addr; /* Compensate for USB */ That would work regardless of the endianness, wouldn't it? > Fixing this while maintaining some modicum of sanity is the tricky bit. > The interface is made to kill_pid_usb_asyncio is made a sigval_t so the > standard signal compat tricks can be used. sigval_t is a union of: > > int sival_int; > void __user *sival_ptr; > > 0 1 2 3 4 5 6 7 > +---+---+---+---+---+---+---+---+ > | sival_ptr | (64bit) > +---+---+---+---+---+---+---+---+ > | sival_ptr | (32bit) > +---+---+---+---+ > | sival_int | > +---+---+---+---+ > > The signal code solves the compat issues for sigval_t by storing the > 32bit pointers in sival_int. So they meaningful bits are guaranteed to > be in the low 32bits, just like the 32bit sival_ptr. > > After a bunch of build BUG_ONs to verify my reasonable assumptions > of but the siginfo layout are actually true, the code that generates > the siginfo just copies a sigval_t to si_pid. And assumes the code > in the usb stack placed the pointer in the proper part of the sigval_t > when it read the information from userspace. > > I don't know if that helps make it easy to understand but I figured I > would give it a shot. I think I understand now. Thanks. Alan