Received: by 2002:a25:1506:0:0:0:0:0 with SMTP id 6csp3860563ybv; Mon, 10 Feb 2020 07:43:21 -0800 (PST) X-Google-Smtp-Source: APXvYqyR8bThHxLFPBnXaQBLsWqAeddw8GAvnE+/kzHBgxm/Fl7BDJL8vMNQ4Q97jUZXQANn0N7a X-Received: by 2002:a05:6808:3b4:: with SMTP id n20mr1167324oie.78.1581349401464; Mon, 10 Feb 2020 07:43:21 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1581349401; cv=none; d=google.com; s=arc-20160816; b=xtFkzYd2X/on78dW3mVxME6L9Cc4baLd9pdA1gKATlg9GFPJySChWl3mMShjacWG+R 6sfolasazjUE5dMiQtKFqz4l0m37+R5zSm3KsUeH5BIPoTLlevxd+4zKSYbqHoXfFgJo ItYfYAR0dyoneKz7bHGVo0BCynSv7kKRf1HJT6BMsUJrgBEcFt1T0qvT7yr6jpHBIs8/ DWqu0qf0dZxovAxITxkQIN1LMFS4QzIwQ91A7MDEA35ivRruzrj32hag8T6v8BOSoYco qAe/3M31zISOUxfmTZPDzDTUSpdMDRdr/TUqo87ja5VxP9qozvtA0CFLLGSmnMdT5kRM EdQQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:cc:to:subject :message-id:date:from:in-reply-to:references:mime-version :dkim-signature; bh=vxeX3iDS3qAf3x+JMLRj0YdyqYpgOcBfoAPBACaCp4A=; b=KSizWMIQal9U5cJhJFLuwo5k4+PQ2aUHb8luP/9Zk8RXuo05vXxKdgsGXPGiRRzZae jTPeEBIwaGLwtLnK+iEK+cK75XbaTGRAleJrsBYGGDIKYImy9e7IvUqFZq4YGNFSziqg iVxsmYzs3Fbt/z8E0WtFwVrPmn60YKnJ6Yw3cu/NCFYXWYKEbuwZNR4b53ghQvgtsB5d b7Jr62tjTsRR31fyKX6roOzxpXvrUETET66d9kJo27TtaW+nLQoXJZDKoAdzeWc8BQbD u0IQ+Iw9hzhRFeG+p+YgtUUaDILeAA2mQaZJA/swMng/B7RJ4o2XseWZ0qtXpCbXWRe/ EQGA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=ydZH6vB5; 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; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id f16si290835oib.269.2020.02.10.07.43.09; Mon, 10 Feb 2020 07:43:21 -0800 (PST) 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; dkim=pass header.i=@linaro.org header.s=google header.b=ydZH6vB5; 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; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727609AbgBJPlr (ORCPT + 99 others); Mon, 10 Feb 2020 10:41:47 -0500 Received: from mail-lj1-f193.google.com ([209.85.208.193]:39818 "EHLO mail-lj1-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726809AbgBJPlq (ORCPT ); Mon, 10 Feb 2020 10:41:46 -0500 Received: by mail-lj1-f193.google.com with SMTP id o15so7687283ljg.6 for ; Mon, 10 Feb 2020 07:41:45 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc:content-transfer-encoding; bh=vxeX3iDS3qAf3x+JMLRj0YdyqYpgOcBfoAPBACaCp4A=; b=ydZH6vB5q5uqqUEAchV6QpyAqs+jXxS4xZMDXS3nRhJKyBZCJ1jQQBaohMTDbypzIT hpGq+wfdtNo/Z2tjM7MkfkUVH+VHx3XsQld4hVCGwJuLFpMfixr5BPVkrL5yMAzU2Lv8 IUdehmritbgsGuDrp5CwcEJfSjtNYNwS8AUzeBK9zuHnwgZKXSHlJIcykzzwzZr7YVx+ r7SSbAHl56IlF9A7gRVz23NecVWpHCgcN+qIXrd9Hw0uY5uDfTArpm1JUH9DMQM/M6nX e55KnpdQoJzdzpfy6JnWZS+Zx5Xl3heQBEaocUI5nAr4XAloNPgA4d4bdSunZJkMQkFi RMCg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc:content-transfer-encoding; bh=vxeX3iDS3qAf3x+JMLRj0YdyqYpgOcBfoAPBACaCp4A=; b=qRA7ZTAVBfirahaPKENNL2biFmZbNblLtzSy8+uTbQ5NOtZBWZr34UFyUjBQw2srsq q/1bAuIyzs8Pf8AYT4PeJQR5Sg39kDtvLroQWIckeIPkD8G61oHy9KrJSAhD9S9olpiV olY1HbY432RqqSyansEBcL43X2mphasmfLA+Chqior/rUAVWVn42gJeV0r3O/y6yAxH0 DCeZaHKq0l3FZWyVN61xD+aATnvyseXydItIyXTpIpunioJWkbj9vsAfEl/b8fj6sFez NZF7foMHCNbh6A7YRTZevPiRxhByfBBYra8wEgaOoyZArtKLEjHadqRIsPruG54yC2Qk 6Onw== X-Gm-Message-State: APjAAAWpYLCOX6sM9DiDZA3oTpuocQCpsQGXvb3yBhHOJVHI9FlyAANf L2uGjCCPSR//PNsfXk08/h/HL2g2TqOfF5l4RnZ4Hg== X-Received: by 2002:a2e:9008:: with SMTP id h8mr1259917ljg.217.1581349303995; Mon, 10 Feb 2020 07:41:43 -0800 (PST) MIME-Version: 1.0 References: <20200210122423.695146547@linuxfoundation.org> <20200210122450.176337512@linuxfoundation.org> In-Reply-To: <20200210122450.176337512@linuxfoundation.org> From: Naresh Kamboju Date: Mon, 10 Feb 2020 21:11:32 +0530 Message-ID: Subject: Re: [PATCH 5.5 284/367] compat: scsi: sg: fix v3 compat read/write interface To: Greg Kroah-Hartman , Arnd Bergmann Cc: open list , linux- stable , Ben Hutchings , Sasha Levin , lkft-triage@lists.linaro.org, Basil Eljuse Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The arm64 architecture 64k page size enabled build failed on stable rc 5.5 CONFIG_ARM64_64K_PAGES=3Dy CROSS_COMPILE=3Daarch64-linux-gnu- Toolchain gcc-9 In file included from ../block/scsi_ioctl.c:23: ../include/scsi/sg.h:75:2: error: unknown type name =E2=80=98compat_int_t= =E2=80=99 compat_int_t interface_id; /* [i] 'S' for SCSI generic (required) */ ^~~~~~~~~~~~ ../include/scsi/sg.h:76:2: error: unknown type name =E2=80=98compat_int_t= =E2=80=99 compat_int_t dxfer_direction; /* [i] data transfer direction */ ^~~~~~~~~~~~ ... ../include/scsi/sg.h:97:2: error: unknown type name =E2=80=98compat_uint_t= =E2=80=99 compat_uint_t info; /* [o] auxiliary information */ ^~~~~~~~~~~~~ make[2]: *** [../scripts/Makefile.build:266: block/bsg.o] Error Ref: https://gitlab.com/Linaro/lkft/kernel-runs/-/jobs/431659186 On Mon, 10 Feb 2020 at 18:18, Greg Kroah-Hartman wrote: > > From: Arnd Bergmann > > commit 78ed001d9e7106171e0ee761cd854137dd731302 upstream. > > In the v5.4 merge window, a cleanup patch from Al Viro conflicted > with my rework of the compat handling for sg.c read(). Linus Torvalds > did a correct merge but pointed out that the resulting code is still > unsatisfactory. > > I later noticed that the sg_new_read() function still gets the compat > mode wrong, when the 'count' argument is large enough to pass a > compat_sg_io_hdr object, but not a nativ sg_io_hdr. > > To address both of these, move the definition of compat_sg_io_hdr > into a scsi/sg.h to make it visible to sg.c and rewrite the logic > for reading req_pack_id as well as the size check to a simpler > version that gets the expected results. > > Fixes: c35a5cfb4150 ("scsi: sg: sg_read(): simplify reading ->pack_id of = userland sg_io_hdr_t") > Fixes: 98aaaec4a150 ("compat_ioctl: reimplement SG_IO handling") > Reviewed-by: Ben Hutchings > Signed-off-by: Arnd Bergmann > Signed-off-by: Greg Kroah-Hartman > > --- > block/scsi_ioctl.c | 29 ------------ > drivers/scsi/sg.c | 126 ++++++++++++++++++++++++----------------------= ------- > include/scsi/sg.h | 30 ++++++++++++ > 3 files changed, 90 insertions(+), 95 deletions(-) > > --- a/block/scsi_ioctl.c > +++ b/block/scsi_ioctl.c > @@ -20,6 +20,7 @@ > #include > #include > #include > +#include > > struct blk_cmd_filter { > unsigned long read_ok[BLK_SCSI_CMD_PER_LONG]; > @@ -550,34 +551,6 @@ static inline int blk_send_start_stop(st > return __blk_send_generic(q, bd_disk, GPCMD_START_STOP_UNIT, data= ); > } > > -#ifdef CONFIG_COMPAT > -struct compat_sg_io_hdr { > - compat_int_t interface_id; /* [i] 'S' for SCSI generic (requ= ired) */ > - compat_int_t dxfer_direction; /* [i] data transfer direction *= / > - unsigned char cmd_len; /* [i] SCSI command length ( <=3D= 16 bytes) */ > - unsigned char mx_sb_len; /* [i] max length to write to sbp= */ > - unsigned short iovec_count; /* [i] 0 implies no scatter gathe= r */ > - compat_uint_t dxfer_len; /* [i] byte count of data transfe= r */ > - compat_uint_t dxferp; /* [i], [*io] points to data tran= sfer memory > - or scatter gather list */ > - compat_uptr_t cmdp; /* [i], [*i] points to command to= perform */ > - compat_uptr_t sbp; /* [i], [*o] points to sense_buff= er memory */ > - compat_uint_t timeout; /* [i] MAX_UINT->no timeout (unit= : millisec) */ > - compat_uint_t flags; /* [i] 0 -> default, see SG_FLAG.= .. */ > - compat_int_t pack_id; /* [i->o] unused internally (norm= ally) */ > - compat_uptr_t usr_ptr; /* [i->o] unused internally */ > - unsigned char status; /* [o] scsi status */ > - unsigned char masked_status; /* [o] shifted, masked scsi statu= s */ > - unsigned char msg_status; /* [o] messaging level data (opti= onal) */ > - unsigned char sb_len_wr; /* [o] byte count actually writte= n to sbp */ > - unsigned short host_status; /* [o] errors from host adapter *= / > - unsigned short driver_status; /* [o] errors from software drive= r */ > - compat_int_t resid; /* [o] dxfer_len - actual_transfe= rred */ > - compat_uint_t duration; /* [o] time taken by cmd (unit: m= illisec) */ > - compat_uint_t info; /* [o] auxiliary information */ > -}; > -#endif > - > int put_sg_io_hdr(const struct sg_io_hdr *hdr, void __user *argp) > { > #ifdef CONFIG_COMPAT > --- a/drivers/scsi/sg.c > +++ b/drivers/scsi/sg.c > @@ -405,6 +405,38 @@ sg_release(struct inode *inode, struct f > return 0; > } > > +static int get_sg_io_pack_id(int *pack_id, void __user *buf, size_t coun= t) > +{ > + struct sg_header __user *old_hdr =3D buf; > + int reply_len; > + > + if (count >=3D SZ_SG_HEADER) { > + /* negative reply_len means v3 format, otherwise v1/v2 */ > + if (get_user(reply_len, &old_hdr->reply_len)) > + return -EFAULT; > + > + if (reply_len >=3D 0) > + return get_user(*pack_id, &old_hdr->pack_id); > + > + if (in_compat_syscall() && > + count >=3D sizeof(struct compat_sg_io_hdr)) { > + struct compat_sg_io_hdr __user *hp =3D buf; > + > + return get_user(*pack_id, &hp->pack_id); > + } > + > + if (count >=3D sizeof(struct sg_io_hdr)) { > + struct sg_io_hdr __user *hp =3D buf; > + > + return get_user(*pack_id, &hp->pack_id); > + } > + } > + > + /* no valid header was passed, so ignore the pack_id */ > + *pack_id =3D -1; > + return 0; > +} > + > static ssize_t > sg_read(struct file *filp, char __user *buf, size_t count, loff_t * ppos= ) > { > @@ -413,8 +445,8 @@ sg_read(struct file *filp, char __user * > Sg_request *srp; > int req_pack_id =3D -1; > sg_io_hdr_t *hp; > - struct sg_header *old_hdr =3D NULL; > - int retval =3D 0; > + struct sg_header *old_hdr; > + int retval; > > /* > * This could cause a response to be stranded. Close the associat= ed > @@ -429,79 +461,34 @@ sg_read(struct file *filp, char __user * > SCSI_LOG_TIMEOUT(3, sg_printk(KERN_INFO, sdp, > "sg_read: count=3D%d\n", (int) coun= t)); > > - if (sfp->force_packid && (count >=3D SZ_SG_HEADER)) { > - old_hdr =3D memdup_user(buf, SZ_SG_HEADER); > - if (IS_ERR(old_hdr)) > - return PTR_ERR(old_hdr); > - if (old_hdr->reply_len < 0) { > - if (count >=3D SZ_SG_IO_HDR) { > - /* > - * This is stupid. > - * > - * We're copying the whole sg_io_hdr_t fr= om user > - * space just to get the 'pack_id' field.= But the > - * field is at different offsets for the = compat > - * case, so we'll use "get_sg_io_hdr()" t= o copy > - * the whole thing and convert it. > - * > - * We could do something like just calcul= ating the > - * offset based of 'in_compat_syscall()',= but the > - * 'compat_sg_io_hdr' definition is in th= e wrong > - * place for that. > - */ > - sg_io_hdr_t *new_hdr; > - new_hdr =3D kmalloc(SZ_SG_IO_HDR, GFP_KER= NEL); > - if (!new_hdr) { > - retval =3D -ENOMEM; > - goto free_old_hdr; > - } > - retval =3D get_sg_io_hdr(new_hdr, buf); > - req_pack_id =3D new_hdr->pack_id; > - kfree(new_hdr); > - if (retval) { > - retval =3D -EFAULT; > - goto free_old_hdr; > - } > - } > - } else > - req_pack_id =3D old_hdr->pack_id; > - } > + if (sfp->force_packid) > + retval =3D get_sg_io_pack_id(&req_pack_id, buf, count); > + if (retval) > + return retval; > + > srp =3D sg_get_rq_mark(sfp, req_pack_id); > if (!srp) { /* now wait on packet to arrive */ > - if (atomic_read(&sdp->detaching)) { > - retval =3D -ENODEV; > - goto free_old_hdr; > - } > - if (filp->f_flags & O_NONBLOCK) { > - retval =3D -EAGAIN; > - goto free_old_hdr; > - } > + if (atomic_read(&sdp->detaching)) > + return -ENODEV; > + if (filp->f_flags & O_NONBLOCK) > + return -EAGAIN; > retval =3D wait_event_interruptible(sfp->read_wait, > (atomic_read(&sdp->detaching) || > (srp =3D sg_get_rq_mark(sfp, req_pack_id)))); > - if (atomic_read(&sdp->detaching)) { > - retval =3D -ENODEV; > - goto free_old_hdr; > - } > - if (retval) { > + if (atomic_read(&sdp->detaching)) > + return -ENODEV; > + if (retval) > /* -ERESTARTSYS as signal hit process */ > - goto free_old_hdr; > - } > - } > - if (srp->header.interface_id !=3D '\0') { > - retval =3D sg_new_read(sfp, buf, count, srp); > - goto free_old_hdr; > + return retval; > } > + if (srp->header.interface_id !=3D '\0') > + return sg_new_read(sfp, buf, count, srp); > > hp =3D &srp->header; > - if (old_hdr =3D=3D NULL) { > - old_hdr =3D kmalloc(SZ_SG_HEADER, GFP_KERNEL); > - if (! old_hdr) { > - retval =3D -ENOMEM; > - goto free_old_hdr; > - } > - } > - memset(old_hdr, 0, SZ_SG_HEADER); > + old_hdr =3D kzalloc(SZ_SG_HEADER, GFP_KERNEL); > + if (!old_hdr) > + return -ENOMEM; > + > old_hdr->reply_len =3D (int) hp->timeout; > old_hdr->pack_len =3D old_hdr->reply_len; /* old, strange behavio= ur */ > old_hdr->pack_id =3D hp->pack_id; > @@ -575,7 +562,12 @@ sg_new_read(Sg_fd * sfp, char __user *bu > int err =3D 0, err2; > int len; > > - if (count < SZ_SG_IO_HDR) { > + if (in_compat_syscall()) { > + if (count < sizeof(struct compat_sg_io_hdr)) { > + err =3D -EINVAL; > + goto err_out; > + } > + } else if (count < SZ_SG_IO_HDR) { > err =3D -EINVAL; > goto err_out; > } > --- a/include/scsi/sg.h > +++ b/include/scsi/sg.h > @@ -68,6 +68,36 @@ typedef struct sg_io_hdr > unsigned int info; /* [o] auxiliary information */ > } sg_io_hdr_t; /* 64 bytes long (on i386) */ > > +#if defined(__KERNEL__) > +#include > + > +struct compat_sg_io_hdr { > + compat_int_t interface_id; /* [i] 'S' for SCSI generic (requ= ired) */ > + compat_int_t dxfer_direction; /* [i] data transfer direction *= / > + unsigned char cmd_len; /* [i] SCSI command length ( <=3D= 16 bytes) */ > + unsigned char mx_sb_len; /* [i] max length to write to sbp= */ > + unsigned short iovec_count; /* [i] 0 implies no scatter gathe= r */ > + compat_uint_t dxfer_len; /* [i] byte count of data transfe= r */ > + compat_uint_t dxferp; /* [i], [*io] points to data tran= sfer memory > + or scatter gather list */ > + compat_uptr_t cmdp; /* [i], [*i] points to command to= perform */ > + compat_uptr_t sbp; /* [i], [*o] points to sense_buff= er memory */ > + compat_uint_t timeout; /* [i] MAX_UINT->no timeout (unit= : millisec) */ > + compat_uint_t flags; /* [i] 0 -> default, see SG_FLAG.= .. */ > + compat_int_t pack_id; /* [i->o] unused internally (norm= ally) */ > + compat_uptr_t usr_ptr; /* [i->o] unused internally */ > + unsigned char status; /* [o] scsi status */ > + unsigned char masked_status; /* [o] shifted, masked scsi statu= s */ > + unsigned char msg_status; /* [o] messaging level data (opti= onal) */ > + unsigned char sb_len_wr; /* [o] byte count actually writte= n to sbp */ > + unsigned short host_status; /* [o] errors from host adapter *= / > + unsigned short driver_status; /* [o] errors from software drive= r */ > + compat_int_t resid; /* [o] dxfer_len - actual_transfe= rred */ > + compat_uint_t duration; /* [o] time taken by cmd (unit: m= illisec) */ > + compat_uint_t info; /* [o] auxiliary information */ > +}; > +#endif > + > #define SG_INTERFACE_ID_ORIG 'S' > > /* Use negative values to flag difference from original sg_header struct= ure */ > > --=20 Linaro LKFT https://lkft.linaro.org