Skip to content

Commit 4382a79

Browse files
committed
Merge branch 'uaccess.misc' of git://git.kernel.org/pub/scm/linux/kernel/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
2 parents 79ca035 + b7e4b65 commit 4382a79

File tree

9 files changed

+135
-122
lines changed

9 files changed

+135
-122
lines changed

arch/x86/include/asm/pgtable_32.h

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,6 @@ extern pmd_t initial_pg_pmd[];
3232
void paging_init(void);
3333
void sync_initial_page_table(void);
3434

35-
/*
36-
* Define this if things work differently on an i386 and an i486:
37-
* it will (on an i486) warn about kernel memory accesses that are
38-
* done without a 'access_ok( ..)'
39-
*/
40-
#undef TEST_ACCESS_OK
41-
4235
#ifdef CONFIG_X86_PAE
4336
# include <asm/pgtable-3level.h>
4437
#else

arch/x86/kernel/sys_ia32.c

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -135,26 +135,30 @@ static int cp_stat64(struct stat64 __user *ubuf, struct kstat *stat)
135135
typeof(ubuf->st_gid) gid = 0;
136136
SET_UID(uid, from_kuid_munged(current_user_ns(), stat->uid));
137137
SET_GID(gid, from_kgid_munged(current_user_ns(), stat->gid));
138-
if (!access_ok(ubuf, sizeof(struct stat64)) ||
139-
__put_user(huge_encode_dev(stat->dev), &ubuf->st_dev) ||
140-
__put_user(stat->ino, &ubuf->__st_ino) ||
141-
__put_user(stat->ino, &ubuf->st_ino) ||
142-
__put_user(stat->mode, &ubuf->st_mode) ||
143-
__put_user(stat->nlink, &ubuf->st_nlink) ||
144-
__put_user(uid, &ubuf->st_uid) ||
145-
__put_user(gid, &ubuf->st_gid) ||
146-
__put_user(huge_encode_dev(stat->rdev), &ubuf->st_rdev) ||
147-
__put_user(stat->size, &ubuf->st_size) ||
148-
__put_user(stat->atime.tv_sec, &ubuf->st_atime) ||
149-
__put_user(stat->atime.tv_nsec, &ubuf->st_atime_nsec) ||
150-
__put_user(stat->mtime.tv_sec, &ubuf->st_mtime) ||
151-
__put_user(stat->mtime.tv_nsec, &ubuf->st_mtime_nsec) ||
152-
__put_user(stat->ctime.tv_sec, &ubuf->st_ctime) ||
153-
__put_user(stat->ctime.tv_nsec, &ubuf->st_ctime_nsec) ||
154-
__put_user(stat->blksize, &ubuf->st_blksize) ||
155-
__put_user(stat->blocks, &ubuf->st_blocks))
138+
if (!user_write_access_begin(ubuf, sizeof(struct stat64)))
156139
return -EFAULT;
140+
unsafe_put_user(huge_encode_dev(stat->dev), &ubuf->st_dev, Efault);
141+
unsafe_put_user(stat->ino, &ubuf->__st_ino, Efault);
142+
unsafe_put_user(stat->ino, &ubuf->st_ino, Efault);
143+
unsafe_put_user(stat->mode, &ubuf->st_mode, Efault);
144+
unsafe_put_user(stat->nlink, &ubuf->st_nlink, Efault);
145+
unsafe_put_user(uid, &ubuf->st_uid, Efault);
146+
unsafe_put_user(gid, &ubuf->st_gid, Efault);
147+
unsafe_put_user(huge_encode_dev(stat->rdev), &ubuf->st_rdev, Efault);
148+
unsafe_put_user(stat->size, &ubuf->st_size, Efault);
149+
unsafe_put_user(stat->atime.tv_sec, &ubuf->st_atime, Efault);
150+
unsafe_put_user(stat->atime.tv_nsec, &ubuf->st_atime_nsec, Efault);
151+
unsafe_put_user(stat->mtime.tv_sec, &ubuf->st_mtime, Efault);
152+
unsafe_put_user(stat->mtime.tv_nsec, &ubuf->st_mtime_nsec, Efault);
153+
unsafe_put_user(stat->ctime.tv_sec, &ubuf->st_ctime, Efault);
154+
unsafe_put_user(stat->ctime.tv_nsec, &ubuf->st_ctime_nsec, Efault);
155+
unsafe_put_user(stat->blksize, &ubuf->st_blksize, Efault);
156+
unsafe_put_user(stat->blocks, &ubuf->st_blocks, Efault);
157+
user_access_end();
157158
return 0;
159+
Efault:
160+
user_write_access_end();
161+
return -EFAULT;
158162
}
159163

160164
COMPAT_SYSCALL_DEFINE2(ia32_stat64, const char __user *, filename,

arch/x86/kvm/hyperv.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1252,7 +1252,7 @@ static int kvm_hv_set_msr(struct kvm_vcpu *vcpu, u32 msr, u64 data, bool host)
12521252
* only, there can be valuable data in the rest which needs
12531253
* to be preserved e.g. on migration.
12541254
*/
1255-
if (__clear_user((void __user *)addr, sizeof(u32)))
1255+
if (__put_user(0, (u32 __user *)addr))
12561256
return 1;
12571257
hv_vcpu->hv_vapic = data;
12581258
kvm_vcpu_mark_page_dirty(vcpu, gfn);

fs/binfmt_elf.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ create_elf_tables(struct linux_binprm *bprm, const struct elfhdr *exec,
208208
size_t len = strlen(k_platform) + 1;
209209

210210
u_platform = (elf_addr_t __user *)STACK_ALLOC(p, len);
211-
if (__copy_to_user(u_platform, k_platform, len))
211+
if (copy_to_user(u_platform, k_platform, len))
212212
return -EFAULT;
213213
}
214214

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

223223
u_base_platform = (elf_addr_t __user *)STACK_ALLOC(p, len);
224-
if (__copy_to_user(u_base_platform, k_base_platform, len))
224+
if (copy_to_user(u_base_platform, k_base_platform, len))
225225
return -EFAULT;
226226
}
227227

@@ -231,7 +231,7 @@ create_elf_tables(struct linux_binprm *bprm, const struct elfhdr *exec,
231231
get_random_bytes(k_rand_bytes, sizeof(k_rand_bytes));
232232
u_rand_bytes = (elf_addr_t __user *)
233233
STACK_ALLOC(p, sizeof(k_rand_bytes));
234-
if (__copy_to_user(u_rand_bytes, k_rand_bytes, sizeof(k_rand_bytes)))
234+
if (copy_to_user(u_rand_bytes, k_rand_bytes, sizeof(k_rand_bytes)))
235235
return -EFAULT;
236236

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

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

320320
/* Populate list of argv pointers back to argv strings. */
321321
p = mm->arg_end = mm->arg_start;
322322
while (argc-- > 0) {
323323
size_t len;
324-
if (__put_user((elf_addr_t)p, sp++))
324+
if (put_user((elf_addr_t)p, sp++))
325325
return -EFAULT;
326326
len = strnlen_user((void __user *)p, MAX_ARG_STRLEN);
327327
if (!len || len > MAX_ARG_STRLEN)
328328
return -EINVAL;
329329
p += len;
330330
}
331-
if (__put_user(0, sp++))
331+
if (put_user(0, sp++))
332332
return -EFAULT;
333333
mm->arg_end = p;
334334

335335
/* Populate list of envp pointers back to envp strings. */
336336
mm->env_end = mm->env_start = p;
337337
while (envc-- > 0) {
338338
size_t len;
339-
if (__put_user((elf_addr_t)p, sp++))
339+
if (put_user((elf_addr_t)p, sp++))
340340
return -EFAULT;
341341
len = strnlen_user((void __user *)p, MAX_ARG_STRLEN);
342342
if (!len || len > MAX_ARG_STRLEN)
343343
return -EINVAL;
344344
p += len;
345345
}
346-
if (__put_user(0, sp++))
346+
if (put_user(0, sp++))
347347
return -EFAULT;
348348
mm->env_end = p;
349349

fs/binfmt_elf_fdpic.c

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -536,7 +536,7 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm,
536536
platform_len = strlen(k_platform) + 1;
537537
sp -= platform_len;
538538
u_platform = (char __user *) sp;
539-
if (__copy_to_user(u_platform, k_platform, platform_len) != 0)
539+
if (copy_to_user(u_platform, k_platform, platform_len) != 0)
540540
return -EFAULT;
541541
}
542542

@@ -551,7 +551,7 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm,
551551
platform_len = strlen(k_base_platform) + 1;
552552
sp -= platform_len;
553553
u_base_platform = (char __user *) sp;
554-
if (__copy_to_user(u_base_platform, k_base_platform, platform_len) != 0)
554+
if (copy_to_user(u_base_platform, k_base_platform, platform_len) != 0)
555555
return -EFAULT;
556556
}
557557

@@ -603,11 +603,13 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm,
603603
/* put the ELF interpreter info on the stack */
604604
#define NEW_AUX_ENT(id, val) \
605605
do { \
606-
struct { unsigned long _id, _val; } __user *ent; \
606+
struct { unsigned long _id, _val; } __user *ent, v; \
607607
\
608608
ent = (void __user *) csp; \
609-
__put_user((id), &ent[nr]._id); \
610-
__put_user((val), &ent[nr]._val); \
609+
v._id = (id); \
610+
v._val = (val); \
611+
if (copy_to_user(ent + nr, &v, sizeof(v))) \
612+
return -EFAULT; \
611613
nr++; \
612614
} while (0)
613615

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

675677
/* stack argc */
676678
csp -= sizeof(unsigned long);
677-
__put_user(bprm->argc, (unsigned long __user *) csp);
679+
if (put_user(bprm->argc, (unsigned long __user *) csp))
680+
return -EFAULT;
678681

679682
BUG_ON(csp != sp);
680683

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

689692
p = (char __user *) current->mm->arg_start;
690693
for (loop = bprm->argc; loop > 0; loop--) {
691-
__put_user((elf_caddr_t) p, argv++);
694+
if (put_user((elf_caddr_t) p, argv++))
695+
return -EFAULT;
692696
len = strnlen_user(p, MAX_ARG_STRLEN);
693697
if (!len || len > MAX_ARG_STRLEN)
694698
return -EINVAL;
695699
p += len;
696700
}
697-
__put_user(NULL, argv);
701+
if (put_user(NULL, argv))
702+
return -EFAULT;
698703
current->mm->arg_end = (unsigned long) p;
699704

700705
/* fill in the envv[] array */
701706
current->mm->env_start = (unsigned long) p;
702707
for (loop = bprm->envc; loop > 0; loop--) {
703-
__put_user((elf_caddr_t)(unsigned long) p, envp++);
708+
if (put_user((elf_caddr_t)(unsigned long) p, envp++))
709+
return -EFAULT;
704710
len = strnlen_user(p, MAX_ARG_STRLEN);
705711
if (!len || len > MAX_ARG_STRLEN)
706712
return -EINVAL;
707713
p += len;
708714
}
709-
__put_user(NULL, envp);
715+
if (put_user(NULL, envp))
716+
return -EFAULT;
710717
current->mm->env_end = (unsigned long) p;
711718

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

849856
tmp = phdr->p_memsz / sizeof(Elf32_Dyn);
850857
dyn = (Elf32_Dyn __user *)params->dynamic_addr;
851-
__get_user(d_tag, &dyn[tmp - 1].d_tag);
852-
if (d_tag != 0)
858+
if (get_user(d_tag, &dyn[tmp - 1].d_tag) ||
859+
d_tag != 0)
853860
goto dynamic_error;
854861
break;
855862
}

fs/binfmt_flat.c

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -138,35 +138,40 @@ static int create_flat_tables(struct linux_binprm *bprm, unsigned long arg_start
138138
current->mm->start_stack = (unsigned long)sp & -FLAT_STACK_ALIGN;
139139
sp = (unsigned long __user *)current->mm->start_stack;
140140

141-
__put_user(bprm->argc, sp++);
141+
if (put_user(bprm->argc, sp++))
142+
return -EFAULT;
142143
if (IS_ENABLED(CONFIG_BINFMT_FLAT_ARGVP_ENVP_ON_STACK)) {
143144
unsigned long argv, envp;
144145
argv = (unsigned long)(sp + 2);
145146
envp = (unsigned long)(sp + 2 + bprm->argc + 1);
146-
__put_user(argv, sp++);
147-
__put_user(envp, sp++);
147+
if (put_user(argv, sp++) || put_user(envp, sp++))
148+
return -EFAULT;
148149
}
149150

150151
current->mm->arg_start = (unsigned long)p;
151152
for (i = bprm->argc; i > 0; i--) {
152-
__put_user((unsigned long)p, sp++);
153+
if (put_user((unsigned long)p, sp++))
154+
return -EFAULT;
153155
len = strnlen_user(p, MAX_ARG_STRLEN);
154156
if (!len || len > MAX_ARG_STRLEN)
155157
return -EINVAL;
156158
p += len;
157159
}
158-
__put_user(0, sp++);
160+
if (put_user(0, sp++))
161+
return -EFAULT;
159162
current->mm->arg_end = (unsigned long)p;
160163

161164
current->mm->env_start = (unsigned long) p;
162165
for (i = bprm->envc; i > 0; i--) {
163-
__put_user((unsigned long)p, sp++);
166+
if (put_user((unsigned long)p, sp++))
167+
return -EFAULT;
164168
len = strnlen_user(p, MAX_ARG_STRLEN);
165169
if (!len || len > MAX_ARG_STRLEN)
166170
return -EINVAL;
167171
p += len;
168172
}
169-
__put_user(0, sp++);
173+
if (put_user(0, sp++))
174+
return -EFAULT;
170175
current->mm->env_end = (unsigned long)p;
171176

172177
return 0;
@@ -996,7 +1001,8 @@ static int load_flat_binary(struct linux_binprm *bprm)
9961001
unsigned long __user *sp;
9971002
current->mm->start_stack -= sizeof(unsigned long);
9981003
sp = (unsigned long __user *)current->mm->start_stack;
999-
__put_user(start_addr, sp);
1004+
if (put_user(start_addr, sp))
1005+
return -EFAULT;
10001006
start_addr = libinfo.lib_list[i].entry;
10011007
}
10021008
}

0 commit comments

Comments
 (0)