Skip to content

Commit 342528f

Browse files
committed
Merge tag 'uml-for-linus-6.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/uml/linux
Pull uml updates from Richard Weinberger: - Make stub data pages configurable - Make it harder to mix user and kernel code by accident * tag 'uml-for-linus-6.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/uml/linux: um: make stub data pages size tweakable um: prevent user code in modules um: further clean up user_syms um: don't export printf() um: hostfs: define our own API boundary um: add __weak for exported functions
2 parents 9f26923 + 6032aca commit 342528f

13 files changed

Lines changed: 78 additions & 114 deletions

File tree

arch/um/include/shared/as-layout.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@
2323
#define STUB_START stub_start
2424
#define STUB_CODE STUB_START
2525
#define STUB_DATA (STUB_CODE + UM_KERN_PAGE_SIZE)
26-
#define STUB_END (STUB_DATA + UM_KERN_PAGE_SIZE)
26+
#define STUB_DATA_PAGES 1 /* must be a power of two */
27+
#define STUB_END (STUB_DATA + STUB_DATA_PAGES * UM_KERN_PAGE_SIZE)
2728

2829
#ifndef __ASSEMBLY__
2930

arch/um/kernel/skas/clone.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,12 @@
2424
void __attribute__ ((__section__ (".__syscall_stub")))
2525
stub_clone_handler(void)
2626
{
27-
struct stub_data *data = get_stub_page();
27+
struct stub_data *data = get_stub_data();
2828
long err;
2929

3030
err = stub_syscall2(__NR_clone, CLONE_PARENT | CLONE_FILES | SIGCHLD,
31-
(unsigned long)data + UM_KERN_PAGE_SIZE / 2);
31+
(unsigned long)data +
32+
STUB_DATA_PAGES * UM_KERN_PAGE_SIZE / 2);
3233
if (err) {
3334
data->parent_err = err;
3435
goto done;

arch/um/kernel/skas/mmu.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ int init_new_context(struct task_struct *task, struct mm_struct *mm)
2121
unsigned long stack = 0;
2222
int ret = -ENOMEM;
2323

24-
stack = get_zeroed_page(GFP_KERNEL);
24+
stack = __get_free_pages(GFP_KERNEL | __GFP_ZERO, ilog2(STUB_DATA_PAGES));
2525
if (stack == 0)
2626
goto out;
2727

@@ -52,7 +52,7 @@ int init_new_context(struct task_struct *task, struct mm_struct *mm)
5252

5353
out_free:
5454
if (to_mm->id.stack != 0)
55-
free_page(to_mm->id.stack);
55+
free_pages(to_mm->id.stack, ilog2(STUB_DATA_PAGES));
5656
out:
5757
return ret;
5858
}
@@ -74,6 +74,6 @@ void destroy_context(struct mm_struct *mm)
7474
}
7575
os_kill_ptraced_process(mmu->id.u.pid, 1);
7676

77-
free_page(mmu->id.stack);
77+
free_pages(mmu->id.stack, ilog2(STUB_DATA_PAGES));
7878
free_ldt(mmu);
7979
}

arch/um/kernel/um_arch.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -326,9 +326,13 @@ int __init linux_main(int argc, char **argv)
326326
add_arg(DEFAULT_COMMAND_LINE_CONSOLE);
327327

328328
host_task_size = os_get_top_address();
329-
/* reserve two pages for the stubs */
330-
host_task_size -= 2 * PAGE_SIZE;
331-
stub_start = host_task_size;
329+
/* reserve a few pages for the stubs (taking care of data alignment) */
330+
/* align the data portion */
331+
BUILD_BUG_ON(!is_power_of_2(STUB_DATA_PAGES));
332+
stub_start = (host_task_size - 1) & ~(STUB_DATA_PAGES * PAGE_SIZE - 1);
333+
/* another page for the code portion */
334+
stub_start -= PAGE_SIZE;
335+
host_task_size = stub_start;
332336

333337
/*
334338
* TASK_SIZE needs to be PGDIR_SIZE aligned or else exit_mmap craps

arch/um/os-Linux/skas/process.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,7 @@ static int userspace_tramp(void *stack)
262262
if (stack != NULL) {
263263
fd = phys_mapping(uml_to_phys(stack), &offset);
264264
addr = mmap((void *) STUB_DATA,
265-
UM_KERN_PAGE_SIZE, PROT_READ | PROT_WRITE,
265+
STUB_DATA_PAGES * UM_KERN_PAGE_SIZE, PROT_READ | PROT_WRITE,
266266
MAP_FIXED | MAP_SHARED, fd, offset);
267267
if (addr == MAP_FAILED) {
268268
printk(UM_KERN_ERR "mapping segfault stack at 0x%lx failed, errno = %d\n",
@@ -277,7 +277,7 @@ static int userspace_tramp(void *stack)
277277
(unsigned long) stub_segv_handler -
278278
(unsigned long) __syscall_stub_start;
279279

280-
set_sigstack((void *) STUB_DATA, UM_KERN_PAGE_SIZE);
280+
set_sigstack((void *) STUB_DATA, STUB_DATA_PAGES * UM_KERN_PAGE_SIZE);
281281
sigemptyset(&sa.sa_mask);
282282
sa.sa_flags = SA_ONSTACK | SA_NODEFER | SA_SIGINFO;
283283
sa.sa_sigaction = (void *) v;
@@ -515,7 +515,7 @@ static int __init init_thread_regs(void)
515515
thread_regs[REGS_IP_INDEX] = STUB_CODE +
516516
(unsigned long) stub_clone_handler -
517517
(unsigned long) __syscall_stub_start;
518-
thread_regs[REGS_SP_INDEX] = STUB_DATA + UM_KERN_PAGE_SIZE -
518+
thread_regs[REGS_SP_INDEX] = STUB_DATA + STUB_DATA_PAGES * UM_KERN_PAGE_SIZE -
519519
sizeof(void *);
520520
#ifdef __SIGNAL_FRAMESIZE
521521
thread_regs[REGS_SP_INDEX] -= __SIGNAL_FRAMESIZE;

arch/um/os-Linux/user_syms.c

Lines changed: 16 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -3,112 +3,40 @@
33
#include <linux/types.h>
44
#include <linux/module.h>
55

6-
/* Some of this are builtin function (some are not but could in the future),
7-
* so I *must* declare good prototypes for them and then EXPORT them.
8-
* The kernel code uses the macro defined by include/linux/string.h,
9-
* so I undef macros; the userspace code does not include that and I
10-
* add an EXPORT for the glibc one.
6+
/*
7+
* This file exports some critical string functions and compiler
8+
* built-in functions (where calls are emitted by the compiler
9+
* itself that we cannot avoid even in kernel code) to modules.
10+
*
11+
* "_user.c" code that previously used exports here such as hostfs
12+
* really should be considered part of the 'hypervisor' and define
13+
* its own API boundary like hostfs does now; don't add exports to
14+
* this file for such cases.
1115
*/
1216

13-
#undef strlen
14-
#undef strstr
15-
#undef memcpy
16-
#undef memset
17-
18-
extern size_t strlen(const char *);
19-
extern void *memmove(void *, const void *, size_t);
20-
extern void *memset(void *, int, size_t);
21-
extern int printf(const char *, ...);
22-
2317
/* If it's not defined, the export is included in lib/string.c.*/
2418
#ifdef __HAVE_ARCH_STRSTR
19+
#undef strstr
2520
EXPORT_SYMBOL(strstr);
2621
#endif
2722

2823
#ifndef __x86_64__
24+
#undef memcpy
2925
extern void *memcpy(void *, const void *, size_t);
3026
EXPORT_SYMBOL(memcpy);
27+
extern void *memmove(void *, const void *, size_t);
3128
EXPORT_SYMBOL(memmove);
29+
#undef memset
30+
extern void *memset(void *, int, size_t);
3231
EXPORT_SYMBOL(memset);
3332
#endif
3433

35-
EXPORT_SYMBOL(printf);
36-
37-
/* Here, instead, I can provide a fake prototype. Yes, someone cares: genksyms.
38-
* However, the modules will use the CRC defined *here*, no matter if it is
39-
* good; so the versions of these symbols will always match
40-
*/
41-
#define EXPORT_SYMBOL_PROTO(sym) \
42-
int sym(void); \
43-
EXPORT_SYMBOL(sym);
44-
45-
extern void readdir64(void) __attribute__((weak));
46-
EXPORT_SYMBOL(readdir64);
47-
extern void truncate64(void) __attribute__((weak));
48-
EXPORT_SYMBOL(truncate64);
49-
5034
#ifdef CONFIG_ARCH_REUSE_HOST_VSYSCALL_AREA
35+
/* needed for __access_ok() */
5136
EXPORT_SYMBOL(vsyscall_ehdr);
5237
EXPORT_SYMBOL(vsyscall_end);
5338
#endif
5439

55-
EXPORT_SYMBOL_PROTO(__errno_location);
56-
57-
EXPORT_SYMBOL_PROTO(access);
58-
EXPORT_SYMBOL_PROTO(open);
59-
EXPORT_SYMBOL_PROTO(open64);
60-
EXPORT_SYMBOL_PROTO(close);
61-
EXPORT_SYMBOL_PROTO(read);
62-
EXPORT_SYMBOL_PROTO(write);
63-
EXPORT_SYMBOL_PROTO(dup2);
64-
EXPORT_SYMBOL_PROTO(__xstat);
65-
EXPORT_SYMBOL_PROTO(__lxstat);
66-
EXPORT_SYMBOL_PROTO(__lxstat64);
67-
EXPORT_SYMBOL_PROTO(__fxstat64);
68-
EXPORT_SYMBOL_PROTO(lseek);
69-
EXPORT_SYMBOL_PROTO(lseek64);
70-
EXPORT_SYMBOL_PROTO(chown);
71-
EXPORT_SYMBOL_PROTO(fchown);
72-
EXPORT_SYMBOL_PROTO(truncate);
73-
EXPORT_SYMBOL_PROTO(ftruncate64);
74-
EXPORT_SYMBOL_PROTO(utime);
75-
EXPORT_SYMBOL_PROTO(utimes);
76-
EXPORT_SYMBOL_PROTO(futimes);
77-
EXPORT_SYMBOL_PROTO(chmod);
78-
EXPORT_SYMBOL_PROTO(fchmod);
79-
EXPORT_SYMBOL_PROTO(rename);
80-
EXPORT_SYMBOL_PROTO(__xmknod);
81-
82-
EXPORT_SYMBOL_PROTO(symlink);
83-
EXPORT_SYMBOL_PROTO(link);
84-
EXPORT_SYMBOL_PROTO(unlink);
85-
EXPORT_SYMBOL_PROTO(readlink);
86-
87-
EXPORT_SYMBOL_PROTO(mkdir);
88-
EXPORT_SYMBOL_PROTO(rmdir);
89-
EXPORT_SYMBOL_PROTO(opendir);
90-
EXPORT_SYMBOL_PROTO(readdir);
91-
EXPORT_SYMBOL_PROTO(closedir);
92-
EXPORT_SYMBOL_PROTO(seekdir);
93-
EXPORT_SYMBOL_PROTO(telldir);
94-
95-
EXPORT_SYMBOL_PROTO(ioctl);
96-
97-
EXPORT_SYMBOL_PROTO(pread64);
98-
EXPORT_SYMBOL_PROTO(pwrite64);
99-
100-
EXPORT_SYMBOL_PROTO(statfs);
101-
EXPORT_SYMBOL_PROTO(statfs64);
102-
103-
EXPORT_SYMBOL_PROTO(getuid);
104-
105-
EXPORT_SYMBOL_PROTO(fsync);
106-
EXPORT_SYMBOL_PROTO(fdatasync);
107-
108-
EXPORT_SYMBOL_PROTO(lstat64);
109-
EXPORT_SYMBOL_PROTO(fstat64);
110-
EXPORT_SYMBOL_PROTO(mknod);
111-
11240
/* Export symbols used by GCC for the stack protector. */
11341
extern void __stack_smash_handler(void *) __attribute__((weak));
11442
EXPORT_SYMBOL(__stack_smash_handler);
@@ -117,6 +45,6 @@ extern long __guard __attribute__((weak));
11745
EXPORT_SYMBOL(__guard);
11846

11947
#ifdef _FORTIFY_SOURCE
120-
extern int __sprintf_chk(char *str, int flag, size_t strlen, const char *format);
48+
extern int __sprintf_chk(char *str, int flag, size_t len, const char *format);
12149
EXPORT_SYMBOL(__sprintf_chk);
12250
#endif

arch/um/scripts/Makefile.rules

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
# ===========================================================================
55

66
USER_SINGLE_OBJS := \
7-
$(foreach f,$(patsubst %.o,%,$(obj-y) $(obj-m)),$($(f)-objs))
8-
USER_OBJS += $(filter %_user.o,$(obj-y) $(obj-m) $(USER_SINGLE_OBJS))
7+
$(foreach f,$(patsubst %.o,%,$(obj-y)),$($(f)-objs))
8+
USER_OBJS += $(filter %_user.o,$(obj-y) $(USER_SINGLE_OBJS))
99
USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file))
1010

1111
$(USER_OBJS:.o=.%): \

arch/x86/um/shared/sysdep/stub_32.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -89,27 +89,27 @@ static inline void remap_stack_and_trap(void)
8989
"addl %4,%%ebx ; movl %%eax, (%%ebx) ;"
9090
"int $3"
9191
: :
92-
"g" (~(UM_KERN_PAGE_SIZE - 1)),
92+
"g" (~(STUB_DATA_PAGES * UM_KERN_PAGE_SIZE - 1)),
9393
"g" (STUB_MMAP_NR),
9494
"g" (UML_STUB_FIELD_FD),
9595
"g" (UML_STUB_FIELD_OFFSET),
9696
"g" (UML_STUB_FIELD_CHILD_ERR),
97-
"c" (UM_KERN_PAGE_SIZE),
97+
"c" (STUB_DATA_PAGES * UM_KERN_PAGE_SIZE),
9898
"d" (PROT_READ | PROT_WRITE),
9999
"S" (MAP_FIXED | MAP_SHARED)
100100
:
101101
"memory");
102102
}
103103

104-
static __always_inline void *get_stub_page(void)
104+
static __always_inline void *get_stub_data(void)
105105
{
106106
unsigned long ret;
107107

108108
asm volatile (
109109
"movl %%esp,%0 ;"
110110
"andl %1,%0"
111111
: "=a" (ret)
112-
: "g" (~(UM_KERN_PAGE_SIZE - 1)));
112+
: "g" (~(STUB_DATA_PAGES * UM_KERN_PAGE_SIZE - 1)));
113113

114114
return (void *)ret;
115115
}

arch/x86/um/shared/sysdep/stub_64.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -98,26 +98,26 @@ static inline void remap_stack_and_trap(void)
9898
"int3"
9999
: :
100100
"g" (STUB_MMAP_NR),
101-
"g" (~(UM_KERN_PAGE_SIZE - 1)),
101+
"g" (~(STUB_DATA_PAGES * UM_KERN_PAGE_SIZE - 1)),
102102
"g" (MAP_FIXED | MAP_SHARED),
103103
"g" (UML_STUB_FIELD_FD),
104104
"g" (UML_STUB_FIELD_OFFSET),
105105
"g" (UML_STUB_FIELD_CHILD_ERR),
106-
"S" (UM_KERN_PAGE_SIZE),
106+
"S" (STUB_DATA_PAGES * UM_KERN_PAGE_SIZE),
107107
"d" (PROT_READ | PROT_WRITE)
108108
:
109109
__syscall_clobber, "r10", "r8", "r9");
110110
}
111111

112-
static __always_inline void *get_stub_page(void)
112+
static __always_inline void *get_stub_data(void)
113113
{
114114
unsigned long ret;
115115

116116
asm volatile (
117117
"movq %%rsp,%0 ;"
118118
"andq %1,%0"
119119
: "=a" (ret)
120-
: "g" (~(UM_KERN_PAGE_SIZE - 1)));
120+
: "g" (~(STUB_DATA_PAGES * UM_KERN_PAGE_SIZE - 1)));
121121

122122
return (void *)ret;
123123
}

arch/x86/um/stub_segv.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
void __attribute__ ((__section__ (".__syscall_stub")))
1212
stub_segv_handler(int sig, siginfo_t *info, void *p)
1313
{
14-
struct faultinfo *f = get_stub_page();
14+
struct faultinfo *f = get_stub_data();
1515
ucontext_t *uc = p;
1616

1717
GET_FAULTINFO_FROM_MC(*f, &uc->uc_mcontext);

0 commit comments

Comments
 (0)