LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Haren Myneni <haren@linux.ibm.com>
To: Michael Ellerman <mpe@ellerman.id.au>
Cc: mikey@neuling.org, herbert@gondor.apana.org.au,
	npiggin@gmail.com, hch@infradead.org, oohall@gmail.com,
	sukadev@linux.vnet.ibm.com, linuxppc-dev@lists.ozlabs.org,
	ajd@linux.ibm.com
Subject: Re: [PATCH V7 09/14] powerpc/vas: Update CSB and notify process for fault CRBs
Date: Tue, 17 Mar 2020 12:27:43 -0700	[thread overview]
Message-ID: <1584473263.9256.14791.camel@hbabu-laptop> (raw)
In-Reply-To: <877dzj35z8.fsf@mpe.ellerman.id.au>

On Tue, 2020-03-17 at 16:28 +1100, Michael Ellerman wrote:
> Haren Myneni <haren@linux.ibm.com> writes:
> > For each fault CRB, update fault address in CRB (fault_storage_addr)
> > and translation error status in CSB so that user space can touch the
> > fault address and resend the request. If the user space passed invalid
> > CSB address send signal to process with SIGSEGV.
> >
> > Signed-off-by: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
> > Signed-off-by: Haren Myneni <haren@linux.ibm.com>
> > ---
> >  arch/powerpc/platforms/powernv/vas-fault.c | 114 +++++++++++++++++++++++++++++
> >  1 file changed, 114 insertions(+)
> >
> > diff --git a/arch/powerpc/platforms/powernv/vas-fault.c b/arch/powerpc/platforms/powernv/vas-fault.c
> > index 1c6d5cc..751ce48 100644
> > --- a/arch/powerpc/platforms/powernv/vas-fault.c
> > +++ b/arch/powerpc/platforms/powernv/vas-fault.c
> > @@ -11,6 +11,7 @@
> >  #include <linux/slab.h>
> >  #include <linux/uaccess.h>
> >  #include <linux/kthread.h>
> > +#include <linux/sched/signal.h>
> >  #include <linux/mmu_context.h>
> >  #include <asm/icswx.h>
> >  
> > @@ -26,6 +27,118 @@
> >  #define VAS_FAULT_WIN_FIFO_SIZE	(4 << 20)
> >  
> >  /*
> > + * Update the CSB to indicate a translation error.
> > + *
> > + * If we are unable to update the CSB means copy_to_user failed due to
> > + * invalid csb_addr, send a signal to the process.
> > + *
> > + * Remaining settings in the CSB are based on wait_for_csb() of
> > + * NX-GZIP.
> > + */
> > +static void update_csb(struct vas_window *window,
> > +			struct coprocessor_request_block *crb)
> > +{
> > +	int rc;
> > +	struct pid *pid;
> > +	void __user *csb_addr;
> > +	struct task_struct *tsk;
> > +	struct kernel_siginfo info;
> > +	struct coprocessor_status_block csb;
> 
> csb is on the stack, and later copied to user, which is a risk for
> creating an infoleak.
> 
> Also please use reverse Christmas tree layout for your variables.
> 
> > +
> > +	/*
> > +	 * NX user space windows can not be opened for task->mm=NULL
> > +	 * and faults will not be generated for kernel requests.
> > +	 */
> > +	if (!window->mm || !window->user_win)
> > +		return;
> 
> If that's a should-never-happen condition then should it do a
> WARN_ON_ONCE() rather than silently returning?

Will add WARN_ON

> 
> > +	csb_addr = (void __user *)be64_to_cpu(crb->csb_addr);
> > +
> > +	csb.cc = CSB_CC_TRANSLATION;
> > +	csb.ce = CSB_CE_TERMINATION;
> > +	csb.cs = 0;
> > +	csb.count = 0;
> > +
> > +	/*
> > +	 * NX operates and returns in BE format as defined CRB struct.
> > +	 * So return fault_storage_addr in BE as NX pastes in FIFO and
> > +	 * expects user space to convert to CPU format.
> > +	 */
> > +	csb.address = crb->stamp.nx.fault_storage_addr;
> > +	csb.flags = 0;
> 
> I'm pretty sure this has initialised all the fields of csb.
> 
> But, I'd still be much happier if you zeroed the whole struct to begin
> with, that way we know for sure we can't leak any uninitialised bytes to
> userspace. It's only 16 bytes so it shouldn't add any noticeable
> overhead.
Sure, will initialize csb
> 
> > +
> > +	pid = window->pid;
> > +	tsk = get_pid_task(pid, PIDTYPE_PID);
> > +	/*
> > +	 * Send window will be closed after processing all NX requests
> > +	 * and process exits after closing all windows. In multi-thread
> > +	 * applications, thread may not exists, but does not close FD
> > +	 * (means send window) upon exit. Parent thread (tgid) can use
> > +	 * and close the window later.
> > +	 * pid and mm references are taken when window is opened by
> > +	 * process (pid). So tgid is used only when child thread opens
> > +	 * a window and exits without closing it in multithread tasks.
> > +	 */
> > +	if (!tsk) {
> > +		pid = window->tgid;
> > +		tsk = get_pid_task(pid, PIDTYPE_PID);
> > +		/*
> > +		 * Parent thread will be closing window during its exit.
> > +		 * So should not get here.
> > +		 */
> > +		if (!tsk)
> > +			return;
> 
> Similar question on WARN_ON_ONCE()
Yes, we can add WARN_ON
> 
> > +	}
> > +
> > +	/* Return if the task is exiting. */
> 
> Why? Just because it's no use? It's racy isn't it, so it can't be for
> correctness?
Yes process is exiting and no need to update CSB. We release the
task->usage refcount after copy_to_user().

> 
> > +	if (tsk->flags & PF_EXITING) {
> > +		put_task_struct(tsk);
> > +		return;
> > +	}
> > +
> > +	use_mm(window->mm);
> 
> There's no check that csb_addr is actually pointing into userspace, but
> copy_to_user() does it for you.
> 
> > +	rc = copy_to_user(csb_addr, &csb, sizeof(csb));
> > +	/*
> > +	 * User space polls on csb.flags (first byte). So add barrier
> > +	 * then copy first byte with csb flags update.
> > +	 */
> > +	smp_mb();
> 
> You only need to order the stores above vs the store below to csb.flags.
> So you should only need an smp_wmb() here.
Sure, will add
if (!rc) {
	csb.flags = CSB_V;
	smp_mb();
	rc = copy_to_user(csb_addr, &csb, sizeof(u8));
}

> 
> > +	if (!rc) {
> > +		csb.flags = CSB_V;
> > +		rc = copy_to_user(csb_addr, &csb, sizeof(u8));
> > +	}
> > +	unuse_mm(window->mm);
> > +	put_task_struct(tsk);
> > +
> > +	/* Success */
> > +	if (!rc)
> > +		return;
> > +
> > +	pr_debug("Invalid CSB address 0x%p signalling pid(%d)\n",
> > +			csb_addr, pid_vnr(pid));
> > +
> > +	clear_siginfo(&info);
> > +	info.si_signo = SIGSEGV;
> > +	info.si_errno = EFAULT;
> > +	info.si_code = SEGV_MAPERR;
> > +	info.si_addr = csb_addr;
> > +
> > +	/*
> > +	 * process will be polling on csb.flags after request is sent to
> > +	 * NX. So generally CSB update should not fail except when an
> > +	 * application does not follow the process properly. So an error
> > +	 * message will be displayed and leave it to user space whether
> > +	 * to ignore or handle this signal.
> > +	 */
> > +	rcu_read_lock();
> > +	rc = kill_pid_info(SIGSEGV, &info, pid);
> > +	rcu_read_unlock();
> 
> Shouldn't this be using force_sig_fault_to_task() or another helper,
> rather than open-coding?

Applications or nxz library can ignore this signal based on si_addr or
take action like resend new request with valid csb_addr. Hence I did not
use force_sig_info_to_task().

> 
> > +
> > +	pr_devel("%s(): pid %d kill_proc_info() rc %d\n", __func__,
> > +			pid_vnr(pid), rc);
> > +}
> > +
> > +/*
> >   * Process valid CRBs in fault FIFO.
> >   */
> >  irqreturn_t vas_fault_thread_fn(int irq, void *data)
> > @@ -111,6 +224,7 @@ irqreturn_t vas_fault_thread_fn(int irq, void *data)
> >  			return IRQ_HANDLED;
> >  		}
> >  
> > +		update_csb(window, crb);
> >  	} while (true);
> >  }
> >  
> > -- 
> > 1.8.3.1
> 
> cheers



  reply	other threads:[~2020-03-17 19:30 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-03-06 20:07 [PATCH V7 00/14] powerpc/vas: Page fault handling for user space NX requests Haren Myneni
2020-03-06 20:12 ` [PATCH V7 01/14] powerpc/xive: Define xive_native_alloc_irq_on_chip() Haren Myneni
2020-03-06 20:12 ` [PATCH V7 02/14] powerpc/xive: Define xive_native_alloc_get_irq_info() Haren Myneni
2020-03-06 20:13 ` [PATCH V7 03/14] powerpc/vas: Define nx_fault_stamp in coprocessor_request_block Haren Myneni
2020-03-06 20:13 ` [PATCH V7 04/14] powerpc/vas: Alloc and setup IRQ and trigger port address Haren Myneni
2020-03-06 20:14 ` [PATCH V7 05/14] powerpc/vas: Setup fault window per VAS instance Haren Myneni
2020-03-06 20:14 ` [PATCH V7 06/14] powerpc/vas: Setup thread IRQ handler " Haren Myneni
2020-03-06 20:15 ` [PATCH V7 07/14] powerpc/vas: Register NX with fault window ID and IRQ port value Haren Myneni
2020-03-06 20:16 ` [PATCH V7 08/14] powerpc/vas: Take reference to PID and mm for user space windows Haren Myneni
2020-03-17  4:09   ` Michael Ellerman
2020-03-17 19:13     ` Haren Myneni
2020-03-06 20:16 ` [PATCH V7 09/14] powerpc/vas: Update CSB and notify process for fault CRBs Haren Myneni
2020-03-17  5:28   ` Michael Ellerman
2020-03-17 19:27     ` Haren Myneni [this message]
2020-03-23  0:06       ` Nicholas Piggin
2020-03-23  1:06         ` Haren Myneni
2020-03-06 20:17 ` [PATCH V7 10/14] powerpc/vas: Print CRB and FIFO values Haren Myneni
2020-03-06 20:18 ` [PATCH V7 11/14] powerpc/vas: Do not use default credits for receive window Haren Myneni
2020-03-06 20:18 ` [PATCH V7 12/14] powerpc/vas: Return credits after handling fault Haren Myneni
2020-03-06 20:19 ` [PATCH V7 13/14] powerpc/vas: Display process stuck message Haren Myneni
2020-03-06 20:20 ` [PATCH V7 14/14] powerpc/vas: Free send window in VAS instance after credits returned Haren Myneni

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=1584473263.9256.14791.camel@hbabu-laptop \
    --to=haren@linux.ibm.com \
    --cc=ajd@linux.ibm.com \
    --cc=hch@infradead.org \
    --cc=herbert@gondor.apana.org.au \
    --cc=linuxppc-dev@lists.ozlabs.org \
    --cc=mikey@neuling.org \
    --cc=mpe@ellerman.id.au \
    --cc=npiggin@gmail.com \
    --cc=oohall@gmail.com \
    --cc=sukadev@linux.vnet.ibm.com \
    /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