Skip to content

Commit

Permalink
Merge branch 'uaccess.misc' of git://git.kernel.org/pub/scm/linux/ker…
Browse files Browse the repository at this point in the history
…nel/git/viro/vfs

Pull misc uaccess updates from Al Viro:
 "Assorted uaccess patches for this cycle - the stuff that didn't fit
  into thematic series"

* 'uaccess.misc' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
  bpf: make bpf_check_uarg_tail_zero() use check_zeroed_user()
  x86: kvm_hv_set_msr(): use __put_user() instead of 32bit __clear_user()
  user_regset_copyout_zero(): use clear_user()
  TEST_ACCESS_OK _never_ had been checked anywhere
  x86: switch cp_stat64() to unsafe_put_user()
  binfmt_flat: don't use __put_user()
  binfmt_elf_fdpic: don't use __... uaccess primitives
  binfmt_elf: don't bother with __{put,copy_to}_user()
  pselect6() and friends: take handling the combined 6th/7th args into helper
  • Loading branch information
Linus Torvalds committed Jun 10, 2020
2 parents 79ca035 + b7e4b65 commit 4382a79
Show file tree
Hide file tree
Showing 9 changed files with 135 additions and 122 deletions.
7 changes: 0 additions & 7 deletions arch/x86/include/asm/pgtable_32.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,6 @@ extern pmd_t initial_pg_pmd[];
void paging_init(void);
void sync_initial_page_table(void);

/*
* Define this if things work differently on an i386 and an i486:
* it will (on an i486) warn about kernel memory accesses that are
* done without a 'access_ok( ..)'
*/
#undef TEST_ACCESS_OK

#ifdef CONFIG_X86_PAE
# include <asm/pgtable-3level.h>
#else
Expand Down
40 changes: 22 additions & 18 deletions arch/x86/kernel/sys_ia32.c
Original file line number Diff line number Diff line change
Expand Up @@ -135,26 +135,30 @@ static int cp_stat64(struct stat64 __user *ubuf, struct kstat *stat)
typeof(ubuf->st_gid) gid = 0;
SET_UID(uid, from_kuid_munged(current_user_ns(), stat->uid));
SET_GID(gid, from_kgid_munged(current_user_ns(), stat->gid));
if (!access_ok(ubuf, sizeof(struct stat64)) ||
__put_user(huge_encode_dev(stat->dev), &ubuf->st_dev) ||
__put_user(stat->ino, &ubuf->__st_ino) ||
__put_user(stat->ino, &ubuf->st_ino) ||
__put_user(stat->mode, &ubuf->st_mode) ||
__put_user(stat->nlink, &ubuf->st_nlink) ||
__put_user(uid, &ubuf->st_uid) ||
__put_user(gid, &ubuf->st_gid) ||
__put_user(huge_encode_dev(stat->rdev), &ubuf->st_rdev) ||
__put_user(stat->size, &ubuf->st_size) ||
__put_user(stat->atime.tv_sec, &ubuf->st_atime) ||
__put_user(stat->atime.tv_nsec, &ubuf->st_atime_nsec) ||
__put_user(stat->mtime.tv_sec, &ubuf->st_mtime) ||
__put_user(stat->mtime.tv_nsec, &ubuf->st_mtime_nsec) ||
__put_user(stat->ctime.tv_sec, &ubuf->st_ctime) ||
__put_user(stat->ctime.tv_nsec, &ubuf->st_ctime_nsec) ||
__put_user(stat->blksize, &ubuf->st_blksize) ||
__put_user(stat->blocks, &ubuf->st_blocks))
if (!user_write_access_begin(ubuf, sizeof(struct stat64)))
return -EFAULT;
unsafe_put_user(huge_encode_dev(stat->dev), &ubuf->st_dev, Efault);
unsafe_put_user(stat->ino, &ubuf->__st_ino, Efault);
unsafe_put_user(stat->ino, &ubuf->st_ino, Efault);
unsafe_put_user(stat->mode, &ubuf->st_mode, Efault);
unsafe_put_user(stat->nlink, &ubuf->st_nlink, Efault);
unsafe_put_user(uid, &ubuf->st_uid, Efault);
unsafe_put_user(gid, &ubuf->st_gid, Efault);
unsafe_put_user(huge_encode_dev(stat->rdev), &ubuf->st_rdev, Efault);
unsafe_put_user(stat->size, &ubuf->st_size, Efault);
unsafe_put_user(stat->atime.tv_sec, &ubuf->st_atime, Efault);
unsafe_put_user(stat->atime.tv_nsec, &ubuf->st_atime_nsec, Efault);
unsafe_put_user(stat->mtime.tv_sec, &ubuf->st_mtime, Efault);
unsafe_put_user(stat->mtime.tv_nsec, &ubuf->st_mtime_nsec, Efault);
unsafe_put_user(stat->ctime.tv_sec, &ubuf->st_ctime, Efault);
unsafe_put_user(stat->ctime.tv_nsec, &ubuf->st_ctime_nsec, Efault);
unsafe_put_user(stat->blksize, &ubuf->st_blksize, Efault);
unsafe_put_user(stat->blocks, &ubuf->st_blocks, Efault);
user_access_end();
return 0;
Efault:
user_write_access_end();
return -EFAULT;
}

COMPAT_SYSCALL_DEFINE2(ia32_stat64, const char __user *, filename,
Expand Down
2 changes: 1 addition & 1 deletion arch/x86/kvm/hyperv.c
Original file line number Diff line number Diff line change
Expand Up @@ -1252,7 +1252,7 @@ static int kvm_hv_set_msr(struct kvm_vcpu *vcpu, u32 msr, u64 data, bool host)
* only, there can be valuable data in the rest which needs
* to be preserved e.g. on migration.
*/
if (__clear_user((void __user *)addr, sizeof(u32)))
if (__put_user(0, (u32 __user *)addr))
return 1;
hv_vcpu->hv_vapic = data;
kvm_vcpu_mark_page_dirty(vcpu, gfn);
Expand Down
16 changes: 8 additions & 8 deletions fs/binfmt_elf.c
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ create_elf_tables(struct linux_binprm *bprm, const struct elfhdr *exec,
size_t len = strlen(k_platform) + 1;

u_platform = (elf_addr_t __user *)STACK_ALLOC(p, len);
if (__copy_to_user(u_platform, k_platform, len))
if (copy_to_user(u_platform, k_platform, len))
return -EFAULT;
}

Expand All @@ -221,7 +221,7 @@ create_elf_tables(struct linux_binprm *bprm, const struct elfhdr *exec,
size_t len = strlen(k_base_platform) + 1;

u_base_platform = (elf_addr_t __user *)STACK_ALLOC(p, len);
if (__copy_to_user(u_base_platform, k_base_platform, len))
if (copy_to_user(u_base_platform, k_base_platform, len))
return -EFAULT;
}

Expand All @@ -231,7 +231,7 @@ create_elf_tables(struct linux_binprm *bprm, const struct elfhdr *exec,
get_random_bytes(k_rand_bytes, sizeof(k_rand_bytes));
u_rand_bytes = (elf_addr_t __user *)
STACK_ALLOC(p, sizeof(k_rand_bytes));
if (__copy_to_user(u_rand_bytes, k_rand_bytes, sizeof(k_rand_bytes)))
if (copy_to_user(u_rand_bytes, k_rand_bytes, sizeof(k_rand_bytes)))
return -EFAULT;

/* Create the ELF interpreter info */
Expand Down Expand Up @@ -314,36 +314,36 @@ create_elf_tables(struct linux_binprm *bprm, const struct elfhdr *exec,
return -EFAULT;

/* Now, let's put argc (and argv, envp if appropriate) on the stack */
if (__put_user(argc, sp++))
if (put_user(argc, sp++))
return -EFAULT;

/* Populate list of argv pointers back to argv strings. */
p = mm->arg_end = mm->arg_start;
while (argc-- > 0) {
size_t len;
if (__put_user((elf_addr_t)p, sp++))
if (put_user((elf_addr_t)p, sp++))
return -EFAULT;
len = strnlen_user((void __user *)p, MAX_ARG_STRLEN);
if (!len || len > MAX_ARG_STRLEN)
return -EINVAL;
p += len;
}
if (__put_user(0, sp++))
if (put_user(0, sp++))
return -EFAULT;
mm->arg_end = p;

/* Populate list of envp pointers back to envp strings. */
mm->env_end = mm->env_start = p;
while (envc-- > 0) {
size_t len;
if (__put_user((elf_addr_t)p, sp++))
if (put_user((elf_addr_t)p, sp++))
return -EFAULT;
len = strnlen_user((void __user *)p, MAX_ARG_STRLEN);
if (!len || len > MAX_ARG_STRLEN)
return -EINVAL;
p += len;
}
if (__put_user(0, sp++))
if (put_user(0, sp++))
return -EFAULT;
mm->env_end = p;

Expand Down
31 changes: 19 additions & 12 deletions fs/binfmt_elf_fdpic.c
Original file line number Diff line number Diff line change
Expand Up @@ -536,7 +536,7 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm,
platform_len = strlen(k_platform) + 1;
sp -= platform_len;
u_platform = (char __user *) sp;
if (__copy_to_user(u_platform, k_platform, platform_len) != 0)
if (copy_to_user(u_platform, k_platform, platform_len) != 0)
return -EFAULT;
}

Expand All @@ -551,7 +551,7 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm,
platform_len = strlen(k_base_platform) + 1;
sp -= platform_len;
u_base_platform = (char __user *) sp;
if (__copy_to_user(u_base_platform, k_base_platform, platform_len) != 0)
if (copy_to_user(u_base_platform, k_base_platform, platform_len) != 0)
return -EFAULT;
}

Expand Down Expand Up @@ -603,11 +603,13 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm,
/* put the ELF interpreter info on the stack */
#define NEW_AUX_ENT(id, val) \
do { \
struct { unsigned long _id, _val; } __user *ent; \
struct { unsigned long _id, _val; } __user *ent, v; \
\
ent = (void __user *) csp; \
__put_user((id), &ent[nr]._id); \
__put_user((val), &ent[nr]._val); \
v._id = (id); \
v._val = (val); \
if (copy_to_user(ent + nr, &v, sizeof(v))) \
return -EFAULT; \
nr++; \
} while (0)

Expand Down Expand Up @@ -674,7 +676,8 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm,

/* stack argc */
csp -= sizeof(unsigned long);
__put_user(bprm->argc, (unsigned long __user *) csp);
if (put_user(bprm->argc, (unsigned long __user *) csp))
return -EFAULT;

BUG_ON(csp != sp);

Expand All @@ -688,25 +691,29 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm,

p = (char __user *) current->mm->arg_start;
for (loop = bprm->argc; loop > 0; loop--) {
__put_user((elf_caddr_t) p, argv++);
if (put_user((elf_caddr_t) p, argv++))
return -EFAULT;
len = strnlen_user(p, MAX_ARG_STRLEN);
if (!len || len > MAX_ARG_STRLEN)
return -EINVAL;
p += len;
}
__put_user(NULL, argv);
if (put_user(NULL, argv))
return -EFAULT;
current->mm->arg_end = (unsigned long) p;

/* fill in the envv[] array */
current->mm->env_start = (unsigned long) p;
for (loop = bprm->envc; loop > 0; loop--) {
__put_user((elf_caddr_t)(unsigned long) p, envp++);
if (put_user((elf_caddr_t)(unsigned long) p, envp++))
return -EFAULT;
len = strnlen_user(p, MAX_ARG_STRLEN);
if (!len || len > MAX_ARG_STRLEN)
return -EINVAL;
p += len;
}
__put_user(NULL, envp);
if (put_user(NULL, envp))
return -EFAULT;
current->mm->env_end = (unsigned long) p;

mm->start_stack = (unsigned long) sp;
Expand Down Expand Up @@ -848,8 +855,8 @@ static int elf_fdpic_map_file(struct elf_fdpic_params *params,

tmp = phdr->p_memsz / sizeof(Elf32_Dyn);
dyn = (Elf32_Dyn __user *)params->dynamic_addr;
__get_user(d_tag, &dyn[tmp - 1].d_tag);
if (d_tag != 0)
if (get_user(d_tag, &dyn[tmp - 1].d_tag) ||
d_tag != 0)
goto dynamic_error;
break;
}
Expand Down
22 changes: 14 additions & 8 deletions fs/binfmt_flat.c
Original file line number Diff line number Diff line change
Expand Up @@ -138,35 +138,40 @@ static int create_flat_tables(struct linux_binprm *bprm, unsigned long arg_start
current->mm->start_stack = (unsigned long)sp & -FLAT_STACK_ALIGN;
sp = (unsigned long __user *)current->mm->start_stack;

__put_user(bprm->argc, sp++);
if (put_user(bprm->argc, sp++))
return -EFAULT;
if (IS_ENABLED(CONFIG_BINFMT_FLAT_ARGVP_ENVP_ON_STACK)) {
unsigned long argv, envp;
argv = (unsigned long)(sp + 2);
envp = (unsigned long)(sp + 2 + bprm->argc + 1);
__put_user(argv, sp++);
__put_user(envp, sp++);
if (put_user(argv, sp++) || put_user(envp, sp++))
return -EFAULT;
}

current->mm->arg_start = (unsigned long)p;
for (i = bprm->argc; i > 0; i--) {
__put_user((unsigned long)p, sp++);
if (put_user((unsigned long)p, sp++))
return -EFAULT;
len = strnlen_user(p, MAX_ARG_STRLEN);
if (!len || len > MAX_ARG_STRLEN)
return -EINVAL;
p += len;
}
__put_user(0, sp++);
if (put_user(0, sp++))
return -EFAULT;
current->mm->arg_end = (unsigned long)p;

current->mm->env_start = (unsigned long) p;
for (i = bprm->envc; i > 0; i--) {
__put_user((unsigned long)p, sp++);
if (put_user((unsigned long)p, sp++))
return -EFAULT;
len = strnlen_user(p, MAX_ARG_STRLEN);
if (!len || len > MAX_ARG_STRLEN)
return -EINVAL;
p += len;
}
__put_user(0, sp++);
if (put_user(0, sp++))
return -EFAULT;
current->mm->env_end = (unsigned long)p;

return 0;
Expand Down Expand Up @@ -996,7 +1001,8 @@ static int load_flat_binary(struct linux_binprm *bprm)
unsigned long __user *sp;
current->mm->start_stack -= sizeof(unsigned long);
sp = (unsigned long __user *)current->mm->start_stack;
__put_user(start_addr, sp);
if (put_user(start_addr, sp))
return -EFAULT;
start_addr = libinfo.lib_list[i].entry;
}
}
Expand Down
Loading

0 comments on commit 4382a79

Please sign in to comment.