Merge 99f6cf61f1
("Merge branch 'mtd/fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux") into android-mainline
steps along the way to 5.9-rc1 Change-Id: I3090afff778aaa50064b4d8cce21cd7d8bf746a4 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
commit
003fccf2e7
@ -355,9 +355,6 @@ static int mtdchar_writeoob(struct file *file, struct mtd_info *mtd,
|
||||
uint32_t retlen;
|
||||
int ret = 0;
|
||||
|
||||
if (!(file->f_mode & FMODE_WRITE))
|
||||
return -EPERM;
|
||||
|
||||
if (length > 4096)
|
||||
return -EINVAL;
|
||||
|
||||
@ -643,6 +640,48 @@ static int mtdchar_ioctl(struct file *file, u_int cmd, u_long arg)
|
||||
|
||||
pr_debug("MTD_ioctl\n");
|
||||
|
||||
/*
|
||||
* Check the file mode to require "dangerous" commands to have write
|
||||
* permissions.
|
||||
*/
|
||||
switch (cmd) {
|
||||
/* "safe" commands */
|
||||
case MEMGETREGIONCOUNT:
|
||||
case MEMGETREGIONINFO:
|
||||
case MEMGETINFO:
|
||||
case MEMREADOOB:
|
||||
case MEMREADOOB64:
|
||||
case MEMLOCK:
|
||||
case MEMUNLOCK:
|
||||
case MEMISLOCKED:
|
||||
case MEMGETOOBSEL:
|
||||
case MEMGETBADBLOCK:
|
||||
case MEMSETBADBLOCK:
|
||||
case OTPSELECT:
|
||||
case OTPGETREGIONCOUNT:
|
||||
case OTPGETREGIONINFO:
|
||||
case OTPLOCK:
|
||||
case ECCGETLAYOUT:
|
||||
case ECCGETSTATS:
|
||||
case MTDFILEMODE:
|
||||
case BLKPG:
|
||||
case BLKRRPART:
|
||||
break;
|
||||
|
||||
/* "dangerous" commands */
|
||||
case MEMERASE:
|
||||
case MEMERASE64:
|
||||
case MEMWRITEOOB:
|
||||
case MEMWRITEOOB64:
|
||||
case MEMWRITE:
|
||||
if (!(file->f_mode & FMODE_WRITE))
|
||||
return -EPERM;
|
||||
break;
|
||||
|
||||
default:
|
||||
return -ENOTTY;
|
||||
}
|
||||
|
||||
switch (cmd) {
|
||||
case MEMGETREGIONCOUNT:
|
||||
if (copy_to_user(argp, &(mtd->numeraseregions), sizeof(int)))
|
||||
@ -690,9 +729,6 @@ static int mtdchar_ioctl(struct file *file, u_int cmd, u_long arg)
|
||||
{
|
||||
struct erase_info *erase;
|
||||
|
||||
if(!(file->f_mode & FMODE_WRITE))
|
||||
return -EPERM;
|
||||
|
||||
erase=kzalloc(sizeof(struct erase_info),GFP_KERNEL);
|
||||
if (!erase)
|
||||
ret = -ENOMEM;
|
||||
@ -985,9 +1021,6 @@ static int mtdchar_ioctl(struct file *file, u_int cmd, u_long arg)
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
ret = -ENOTTY;
|
||||
}
|
||||
|
||||
return ret;
|
||||
@ -1031,6 +1064,11 @@ static long mtdchar_compat_ioctl(struct file *file, unsigned int cmd,
|
||||
struct mtd_oob_buf32 buf;
|
||||
struct mtd_oob_buf32 __user *buf_user = argp;
|
||||
|
||||
if (!(file->f_mode & FMODE_WRITE)) {
|
||||
ret = -EPERM;
|
||||
break;
|
||||
}
|
||||
|
||||
if (copy_from_user(&buf, argp, sizeof(buf)))
|
||||
ret = -EFAULT;
|
||||
else
|
||||
|
@ -339,7 +339,6 @@ static inline bool userfaultfd_must_wait(struct userfaultfd_ctx *ctx,
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Should pair with userfaultfd_signal_pending() */
|
||||
static inline long userfaultfd_get_blocking_state(unsigned int flags)
|
||||
{
|
||||
if (flags & FAULT_FLAG_INTERRUPTIBLE)
|
||||
@ -351,18 +350,6 @@ static inline long userfaultfd_get_blocking_state(unsigned int flags)
|
||||
return TASK_UNINTERRUPTIBLE;
|
||||
}
|
||||
|
||||
/* Should pair with userfaultfd_get_blocking_state() */
|
||||
static inline bool userfaultfd_signal_pending(unsigned int flags)
|
||||
{
|
||||
if (flags & FAULT_FLAG_INTERRUPTIBLE)
|
||||
return signal_pending(current);
|
||||
|
||||
if (flags & FAULT_FLAG_KILLABLE)
|
||||
return fatal_signal_pending(current);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* The locking rules involved in returning VM_FAULT_RETRY depending on
|
||||
* FAULT_FLAG_ALLOW_RETRY, FAULT_FLAG_RETRY_NOWAIT and
|
||||
@ -516,33 +503,9 @@ vm_fault_t handle_userfault(struct vm_fault *vmf, unsigned long reason)
|
||||
vmf->flags, reason);
|
||||
mmap_read_unlock(mm);
|
||||
|
||||
if (likely(must_wait && !READ_ONCE(ctx->released) &&
|
||||
!userfaultfd_signal_pending(vmf->flags))) {
|
||||
if (likely(must_wait && !READ_ONCE(ctx->released))) {
|
||||
wake_up_poll(&ctx->fd_wqh, EPOLLIN);
|
||||
schedule();
|
||||
ret |= VM_FAULT_MAJOR;
|
||||
|
||||
/*
|
||||
* False wakeups can orginate even from rwsem before
|
||||
* up_read() however userfaults will wait either for a
|
||||
* targeted wakeup on the specific uwq waitqueue from
|
||||
* wake_userfault() or for signals or for uffd
|
||||
* release.
|
||||
*/
|
||||
while (!READ_ONCE(uwq.waken)) {
|
||||
/*
|
||||
* This needs the full smp_store_mb()
|
||||
* guarantee as the state write must be
|
||||
* visible to other CPUs before reading
|
||||
* uwq.waken from other CPUs.
|
||||
*/
|
||||
set_current_state(blocking_state);
|
||||
if (READ_ONCE(uwq.waken) ||
|
||||
READ_ONCE(ctx->released) ||
|
||||
userfaultfd_signal_pending(vmf->flags))
|
||||
break;
|
||||
schedule();
|
||||
}
|
||||
}
|
||||
|
||||
__set_current_state(TASK_RUNNING);
|
||||
|
Loading…
Reference in New Issue
Block a user