From: Al Viro <viro@zeniv.linux.org.uk>
To: Arnd Bergmann <arnd@arndb.de>
Cc: Linux FS-devel Mailing List <linux-fsdevel@vger.kernel.org>,
y2038 Mailman List <y2038@lists.linaro.org>,
Linux Kernel Mailing List <linux-kernel@vger.kernel.org>,
Paul Mackerras <paulus@samba.org>,
"David S. Miller" <davem@davemloft.net>,
Michal Ostrowski <mostrows@earthlink.net>,
Dmitry Kozlov <xeb@mail.ru>, James Chapman <jchapman@katalix.com>,
linux-ppp@vger.kernel.org, Networking <netdev@vger.kernel.org>
Subject: Re: [PATCH v3 02/26] compat_ioctl: move simple ppp command handling into driver
Date: Thu, 18 Apr 2019 00:53:00 +0100 [thread overview]
Message-ID: <20190417235300.GB2217@ZenIV.linux.org.uk> (raw)
In-Reply-To: <CAK8P3a1tiRew6uqegUXsKbNQG7=sPVFMY3yXf0M7OjJdkxM=_g@mail.gmail.com>
On Thu, Apr 18, 2019 at 12:03:07AM +0200, Arnd Bergmann wrote:
> On Wed, Apr 17, 2019 at 11:13 PM Al Viro <viro@zeniv.linux.org.uk> wrote:
> >
> > On Tue, Apr 16, 2019 at 10:19:40PM +0200, Arnd Bergmann wrote:
> > > diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c
> > > index c708400fff4a..04252c3492ee 100644
> > > --- a/drivers/net/ppp/ppp_generic.c
> > > +++ b/drivers/net/ppp/ppp_generic.c
> > > @@ -899,6 +899,7 @@ static const struct file_operations ppp_device_fops = {
> > > .write = ppp_write,
> > > .poll = ppp_poll,
> > > .unlocked_ioctl = ppp_ioctl,
> > > + .compat_ioctl = ppp_ioctl,
> >
> > Oh? What happens on e.g. s390 with something like PPPIOCNEWUNIT?
> > Current kernel:
> > * no ->compat_ioctl()
> > * ->unlock_ioctl() is present
> > * found by compat_ioctl_check_table()
> > * pass (unsigned long)compat_ptr(arg) to do_vfs_ioctl()
> > * pass that to ppp_ioctl()
> > * pass that to ppp_unattached_ioctl()
> > * fetch int from (int __user *)compat_ptr(arg)
> >
> > With your patch:
> > * call ppp_ioctl()
> > * pass arg to ppp_unattached_ioctl()
> > * fetch int from (int __user *)arg
> >
> > AFAICS, that's broken...
>
> Correct. I had added this patch to the series from an older set of
> patches (predating
> the compat_ptr_ioctl() series) , and did not check for this issue again. When
> I originally created the patch, I assumed that even on s390 it would be no
> problem.
>
> > Looking at that ppp_ioctl(),
> > pointer to arch-independent type or ignored:
> > PPPIOCNEWUNIT PPPIOCATTACH PPPIOCATTCHAN PPPIOCSMRU PPPIOCSFLAGS
> > PPPIOCGFLAGS PPPIOCGUNIT PPPIOCSDEBUG PPPIOCSMAXCID PPPIOCCONNECT
> > PPPIOCGDEBUG PPPIOCSMAXCID PPPIOCSMRRU
> > PPPIOCDETACH PPPIOCDISCONN
> > PPPIOCGASYNCMAP PPPIOCSASYNCMAP PPPIOCGRASYNCMAP PPPIOCSRASYNCMAP
> > PPPIOCGXASYNCMAP PPPIOCSXASYNCMAP
> > PPPIOCGNPMODE PPPIOCSNPMODE
> > pointer to struct ppp_option_data (with further pointer-chasing in it):
> > PPPIOCSCOMPRESS
> > pointer to struct ppp_idle:
> > PPPIOCGIDLE
> > pointer to struct sock_filter (with hidden pointer-chasing, AFAICS):
> > PPPIOCSPASS PPPIOCSACTIVE
> >
> > Pretty much all of them take pointers. What's more, reaction to
> > unknown is -ENOTTY, not -ENOIOCTLCM, so that patch will have
> > prevent the translated ones from reaching do_ioctl_trans()
>
> Good point, this patch sequence does break bisection.
>
> > What am I missing here? Why not simply do
> >
> > compat_ppp_ioctl()
> > {
> > PPPIOCSCOMPRESS32 => deal with it
> > PPPIOCGIDLE32 => deal with it
> > PPPIOCSPASS32 / PPPIOCSACTIVE32 => deal with it
> > default: pass compat_ptr(arg) to ppp_ioctl() and be done with that
> > }
> >
> > with BPF-related bits (both compat and native) taken to e.g. net/core/bpf-ppp.c,
> > picked by both generic and isdn? IDGI...
>
> I was trying to unify the native and compat code paths as much
> as possible here. Handling the four PPPIO*32 commands in
> compat_ppp_ioctl would either require duplicating large chunks
> of ppp_ioctl, or keeping the extra compat_alloc_user_space()
> copy from the existing implementation.
>
> I'll try to come up with a different way to structure the patches.
Huh? Instead of
case PPPIOCSCOMPRESS:
err = ppp_set_compress(ppp, arg);
break;
in native, have
struct ppp_option_data data;
...
case PPPIOCSCOMPRESS:
if (copy_from_user(&data, argp, sizeof(data)))
err = -EFAULT;
else
err = ppp_set_compress(ppp, &data);
break;
while in compat do
struct ppp_option_data32 data32;
case PPPIOCSCOMPRESS32:
if (copy_from_user(&data32, argp, sizeof(data32)))
err = -EFAULT;
else
err = ppp_set_compress(ppp, &(struct ppp_option_data){
.ptr = compat_ptr(data32.ptr),
.length = data32.length,
.transmit = data32.transmit
});
break;
PPPIOCGIDLE is small to start with - not a lot to copy there.
And as for the filters... What you need is something like
struct bpf_prog *get_ppp_bpf(struct sock_fprog __user *p)
{
struct sock_fprog uprog;
struct sock_fprog_kern fprog;
struct sock_filter *code = NULL;
struct bpf_prog *res;
int err;
if (copy_from_user(&uprog, p, sizeof(uprog)))
return ERR_PTR(-EFAULT);
if (!uprog.len)
return NULL;
fprog.len = uprog.len * sizeof(struct sock_filter);
code = fprog.filter = memdup_user(uprog.filter, fprog.len);
if (IS_ERR(code))
return ERR_CAST(code);
err = bpf_prog_create(&res, &fprog);
kfree(code);
if (err)
return ERR_PTR(err);
return res;
}
in net/core/ppp-filter.c (or in net/core/filter.c, for that matter, under
appropriate ifdef)) with obvious compat counterpart next to it. Hell,
turn the above into
static struct bpf_prog *__get_ppp_bpf(struct sock_fprog *kp)
{
struct sock_fprog_kern fprog;
struct sock_filter *code = NULL;
struct bpf_prog *res;
int err;
if (!kp->len)
return NULL;
fprog.len = kp->len * sizeof(struct sock_filter);
code = fprog.filter = memdup_user(kp->filter, fprog.len);
if (IS_ERR(code))
return ERR_CAST(code);
err = bpf_prog_create(&res, &fprog);
kfree(code);
if (err)
return ERR_PTR(err);
return res;
}
struct bpf_prog *get_ppp_bpf(struct sock_fprog __user *p)
{
struct sock_fprog uprog;
if (copy_from_user(&uprog, p, sizeof(uprog)))
return ERR_PTR(-EFAULT);
return __get_ppp_bpf(&uprog);
}
struct bpf_prog *compat_get_ppp_bpf(struct sock_fprog32 __user *p)
{
struct sock_fprog uprog32;
if (copy_from_user(&uprog32, p, sizeof(uprog32)))
return ERR_PTR(-EFAULT);
return __get_ppp_bpf(&(struct sock_fprog){
.len = uprog32.len,
.filter = compat_ptr(uprog32.filter)});
}
Then in native ioctl do
case PPPIOCSPASS:
case PPPIOCSACTIVE:
{
struct bpf_prog *filter = get_bpf_ppp(argp);
if (IS_ERR(filter)) {
err = PTR_ERR(filter);
} else {
struct bpf_prog **which;
if (cmd == PPPIOCSPASS)
which = &ppp->pass_filter;
else
which = &ppp->active_filter;
ppp_lock(ppp);
if (*which)
bpf_prog_destroy(*which);
*which = filter;
ppp_unlock(ppp);
err = 0;
}
break;
}
in native and similar in compat, with get_bpf_ppp() replaced
with call of compat_get_bpf_ppp() and ioctl numbers obviously
adjusted. All there is to it... Helpers obviously shared
with isdn and yes, all crap gone from fs/compat_ioctl.c...
Why would you want to duplicate large chunks of anything?
The above is not even compile-tested, but... I can put
together a patch if you wish. Or am I missing something
here?
next prev parent reply other threads:[~2019-04-17 23:53 UTC|newest]
Thread overview: 30+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-04-16 20:19 [PATCH v3 00/26] compat_ioctl: cleanups Arnd Bergmann
2019-04-16 20:19 ` [PATCH v3 01/26] compat_ioctl: pppoe: fix PPPOEIOCSFWD handling Arnd Bergmann
2019-04-16 20:19 ` [PATCH v3 02/26] compat_ioctl: move simple ppp command handling into driver Arnd Bergmann
2019-04-17 21:13 ` Al Viro
2019-04-17 22:03 ` Arnd Bergmann
2019-04-17 23:53 ` Al Viro [this message]
2019-04-18 5:57 ` Al Viro
2019-04-18 15:14 ` Arnd Bergmann
2019-04-16 20:19 ` [PATCH v3 04/26] compat_ioctl: move PPPIOCSCOMPRESS32 to ppp-generic.c Arnd Bergmann
2019-04-17 21:16 ` Al Viro
2019-04-17 21:44 ` Arnd Bergmann
2019-04-16 20:19 ` [PATCH v3 05/26] compat_ioctl: move PPPIOCSPASS32/PPPIOCSACTIVE32 to ppp_generic.c Arnd Bergmann
2019-04-16 20:19 ` [PATCH v3 06/26] compat_ioctl: handle PPPIOCGIDLE for 64-bit time_t Arnd Bergmann
2019-04-16 20:19 ` [PATCH v3 09/26] compat_ioctl: move drivers to compat_ptr_ioctl Arnd Bergmann
2019-04-16 20:31 ` Jiri Kosina
2019-04-18 11:10 ` Stefan Hajnoczi
2019-04-19 23:16 ` Michael S. Tsirkin
2019-04-16 20:25 ` [PATCH v3 12/26] compat_ioctl: move more " Arnd Bergmann
2019-04-16 20:25 ` [PATCH v3 15/26] compat_ioctl: move isdn/capi ioctl translation into driver Arnd Bergmann
2019-04-16 20:25 ` [PATCH v3 16/26] compat_ioctl: move rfcomm handlers " Arnd Bergmann
2019-04-16 20:25 ` [PATCH v3 17/26] compat_ioctl: move hci_sock " Arnd Bergmann
2019-04-25 15:21 ` [PATCH v3 12/26] compat_ioctl: move more drivers to compat_ptr_ioctl Mauro Carvalho Chehab
2019-04-25 15:32 ` Arnd Bergmann
2019-04-25 15:35 ` Al Viro
2019-04-25 15:53 ` Mauro Carvalho Chehab
2019-04-25 15:55 ` Arnd Bergmann
2019-04-25 16:42 ` Al Viro
2019-04-25 21:25 ` Johannes Berg
2019-04-26 7:46 ` Arnd Bergmann
2019-04-16 22:33 ` [PATCH v3 00/26] compat_ioctl: cleanups Douglas Gilbert
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190417235300.GB2217@ZenIV.linux.org.uk \
--to=viro@zeniv.linux.org.uk \
--cc=arnd@arndb.de \
--cc=davem@davemloft.net \
--cc=jchapman@katalix.com \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-ppp@vger.kernel.org \
--cc=mostrows@earthlink.net \
--cc=netdev@vger.kernel.org \
--cc=paulus@samba.org \
--cc=xeb@mail.ru \
--cc=y2038@lists.linaro.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).