]> git.pld-linux.org Git - packages/kernel.git/blame - kernel-vserver-2.3.patch
- up to 4.9.217
[packages/kernel.git] / kernel-vserver-2.3.patch
CommitLineData
3261cfd5
AM
1diff -NurpP --minimal linux-4.9.207/arch/alpha/Kconfig linux-4.9.207-vs2.3.9.11/arch/alpha/Kconfig
2--- linux-4.9.207/arch/alpha/Kconfig 2016-12-11 19:17:54.000000000 +0000
3+++ linux-4.9.207-vs2.3.9.11/arch/alpha/Kconfig 2018-10-20 04:58:12.000000000 +0000
cc23e853 4@@ -743,6 +743,8 @@ config DUMMY_CONSOLE
2380c486
JR
5 depends on VGA_HOSE
6 default y
d337f35e
JR
7
8+source "kernel/vserver/Kconfig"
9+
10 source "security/Kconfig"
11
12 source "crypto/Kconfig"
3261cfd5
AM
13diff -NurpP --minimal linux-4.9.207/arch/alpha/kernel/systbls.S linux-4.9.207-vs2.3.9.11/arch/alpha/kernel/systbls.S
14--- linux-4.9.207/arch/alpha/kernel/systbls.S 2016-12-11 19:17:54.000000000 +0000
15+++ linux-4.9.207-vs2.3.9.11/arch/alpha/kernel/systbls.S 2018-10-20 04:58:12.000000000 +0000
d337f35e
JR
16@@ -446,7 +446,7 @@ sys_call_table:
17 .quad sys_stat64 /* 425 */
18 .quad sys_lstat64
19 .quad sys_fstat64
20- .quad sys_ni_syscall /* sys_vserver */
21+ .quad sys_vserver /* sys_vserver */
22 .quad sys_ni_syscall /* sys_mbind */
23 .quad sys_ni_syscall /* sys_get_mempolicy */
24 .quad sys_ni_syscall /* sys_set_mempolicy */
3261cfd5
AM
25diff -NurpP --minimal linux-4.9.207/arch/alpha/kernel/traps.c linux-4.9.207-vs2.3.9.11/arch/alpha/kernel/traps.c
26--- linux-4.9.207/arch/alpha/kernel/traps.c 2019-12-25 15:27:26.328464250 +0000
27+++ linux-4.9.207-vs2.3.9.11/arch/alpha/kernel/traps.c 2018-10-20 04:58:12.000000000 +0000
cef7ea10 28@@ -179,7 +179,8 @@ die_if_kernel(char * str, struct pt_regs
d337f35e
JR
29 #ifdef CONFIG_SMP
30 printk("CPU %d ", hard_smp_processor_id());
31 #endif
2380c486 32- printk("%s(%d): %s %ld\n", current->comm, task_pid_nr(current), str, err);
61333608 33+ printk("%s(%d:#%u): %s %ld\n", current->comm,
2380c486 34+ task_pid_nr(current), current->xid, str, err);
d337f35e 35 dik_show_regs(regs, r9_15);
b00e13aa 36 add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE);
d337f35e 37 dik_show_trace((unsigned long *)(regs+1));
3261cfd5
AM
38diff -NurpP --minimal linux-4.9.207/arch/arm/Kconfig linux-4.9.207-vs2.3.9.11/arch/arm/Kconfig
39--- linux-4.9.207/arch/arm/Kconfig 2019-12-25 15:27:26.428462634 +0000
40+++ linux-4.9.207-vs2.3.9.11/arch/arm/Kconfig 2019-10-05 14:58:36.470454583 +0000
41@@ -2200,6 +2200,8 @@ source "fs/Kconfig"
d337f35e
JR
42
43 source "arch/arm/Kconfig.debug"
44
45+source "kernel/vserver/Kconfig"
46+
47 source "security/Kconfig"
48
49 source "crypto/Kconfig"
3261cfd5
AM
50diff -NurpP --minimal linux-4.9.207/arch/arm/kernel/calls.S linux-4.9.207-vs2.3.9.11/arch/arm/kernel/calls.S
51--- linux-4.9.207/arch/arm/kernel/calls.S 2016-12-11 19:17:54.000000000 +0000
52+++ linux-4.9.207-vs2.3.9.11/arch/arm/kernel/calls.S 2018-10-20 04:58:12.000000000 +0000
d337f35e
JR
53@@ -322,7 +322,7 @@
54 /* 310 */ CALL(sys_request_key)
55 CALL(sys_keyctl)
56 CALL(ABI(sys_semtimedop, sys_oabi_semtimedop))
57-/* vserver */ CALL(sys_ni_syscall)
58+ CALL(sys_vserver)
59 CALL(sys_ioprio_set)
60 /* 315 */ CALL(sys_ioprio_get)
61 CALL(sys_inotify_init)
3261cfd5
AM
62diff -NurpP --minimal linux-4.9.207/arch/arm/kernel/traps.c linux-4.9.207-vs2.3.9.11/arch/arm/kernel/traps.c
63--- linux-4.9.207/arch/arm/kernel/traps.c 2019-12-25 15:27:26.938454388 +0000
64+++ linux-4.9.207-vs2.3.9.11/arch/arm/kernel/traps.c 2018-10-20 04:58:12.000000000 +0000
09a55596 65@@ -279,8 +279,8 @@ static int __die(const char *str, int er
78865d5b 66
d337f35e
JR
67 print_modules();
68 __show_regs(regs);
cc23e853
AM
69- pr_emerg("Process %.*s (pid: %d, stack limit = 0x%p)\n",
70- TASK_COMM_LEN, tsk->comm, task_pid_nr(tsk), end_of_stack(tsk));
71+ pr_emerg("Process %.*s (pid: %d:%u, stack limit = 0x%p)\n",
72+ TASK_COMM_LEN, tsk->comm, task_pid_nr(tsk), tsk->xid, end_of_stack(tsk));
d337f35e
JR
73
74 if (!user_mode(regs) || in_interrupt()) {
7e46296a 75 dump_mem(KERN_EMERG, "Stack: ", regs->ARM_sp,
3261cfd5
AM
76diff -NurpP --minimal linux-4.9.207/arch/cris/Kconfig linux-4.9.207-vs2.3.9.11/arch/cris/Kconfig
77--- linux-4.9.207/arch/cris/Kconfig 2016-12-11 19:17:54.000000000 +0000
78+++ linux-4.9.207-vs2.3.9.11/arch/cris/Kconfig 2018-10-20 04:58:12.000000000 +0000
cc23e853 79@@ -583,6 +583,8 @@ source "fs/Kconfig"
d337f35e
JR
80
81 source "arch/cris/Kconfig.debug"
82
83+source "kernel/vserver/Kconfig"
84+
85 source "security/Kconfig"
86
87 source "crypto/Kconfig"
3261cfd5
AM
88diff -NurpP --minimal linux-4.9.207/arch/ia64/Kconfig linux-4.9.207-vs2.3.9.11/arch/ia64/Kconfig
89--- linux-4.9.207/arch/ia64/Kconfig 2016-12-11 19:17:54.000000000 +0000
90+++ linux-4.9.207-vs2.3.9.11/arch/ia64/Kconfig 2018-10-20 04:58:12.000000000 +0000
cc23e853 91@@ -602,6 +602,8 @@ source "fs/Kconfig"
2380c486
JR
92
93 source "arch/ia64/Kconfig.debug"
d337f35e
JR
94
95+source "kernel/vserver/Kconfig"
96+
97 source "security/Kconfig"
98
99 source "crypto/Kconfig"
3261cfd5
AM
100diff -NurpP --minimal linux-4.9.207/arch/ia64/kernel/entry.S linux-4.9.207-vs2.3.9.11/arch/ia64/kernel/entry.S
101--- linux-4.9.207/arch/ia64/kernel/entry.S 2016-12-11 19:17:54.000000000 +0000
102+++ linux-4.9.207-vs2.3.9.11/arch/ia64/kernel/entry.S 2018-10-20 04:58:12.000000000 +0000
cc23e853 103@@ -1697,7 +1697,7 @@ sys_call_table:
2380c486
JR
104 data8 sys_mq_notify
105 data8 sys_mq_getsetattr
106 data8 sys_kexec_load
107- data8 sys_ni_syscall // reserved for vserver
108+ data8 sys_vserver
109 data8 sys_waitid // 1270
110 data8 sys_add_key
111 data8 sys_request_key
3261cfd5
AM
112diff -NurpP --minimal linux-4.9.207/arch/ia64/kernel/ptrace.c linux-4.9.207-vs2.3.9.11/arch/ia64/kernel/ptrace.c
113--- linux-4.9.207/arch/ia64/kernel/ptrace.c 2019-12-25 15:27:28.308432237 +0000
114+++ linux-4.9.207-vs2.3.9.11/arch/ia64/kernel/ptrace.c 2018-10-20 04:58:12.000000000 +0000
78865d5b 115@@ -21,6 +21,7 @@
2380c486 116 #include <linux/regset.h>
d337f35e 117 #include <linux/elf.h>
ec22aa5c 118 #include <linux/tracehook.h>
d337f35e
JR
119+#include <linux/vs_base.h>
120
121 #include <asm/pgtable.h>
122 #include <asm/processor.h>
3261cfd5
AM
123diff -NurpP --minimal linux-4.9.207/arch/ia64/kernel/traps.c linux-4.9.207-vs2.3.9.11/arch/ia64/kernel/traps.c
124--- linux-4.9.207/arch/ia64/kernel/traps.c 2016-12-11 19:17:54.000000000 +0000
125+++ linux-4.9.207-vs2.3.9.11/arch/ia64/kernel/traps.c 2018-10-20 04:58:12.000000000 +0000
1e8b8f9b 126@@ -60,8 +60,9 @@ die (const char *str, struct pt_regs *re
d337f35e
JR
127 put_cpu();
128
129 if (++die.lock_owner_depth < 3) {
130- printk("%s[%d]: %s %ld [%d]\n",
2380c486 131- current->comm, task_pid_nr(current), str, err, ++die_counter);
61333608 132+ printk("%s[%d:#%u]: %s %ld [%d]\n",
2380c486 133+ current->comm, task_pid_nr(current), current->xid,
d337f35e 134+ str, err, ++die_counter);
2380c486
JR
135 if (notify_die(DIE_OOPS, str, regs, err, 255, SIGSEGV)
136 != NOTIFY_STOP)
137 show_regs(regs);
1e8b8f9b 138@@ -324,8 +325,9 @@ handle_fpu_swa (int fp_fault, struct pt_
2380c486
JR
139 if ((last.count & 15) < 5 && (ia64_fetchadd(1, &last.count, acq) & 15) < 5) {
140 last.time = current_jiffies + 5 * HZ;
141 printk(KERN_WARNING
142- "%s(%d): floating-point assist fault at ip %016lx, isr %016lx\n",
143- current->comm, task_pid_nr(current), regs->cr_iip + ia64_psr(regs)->ri, isr);
61333608 144+ "%s(%d:#%u): floating-point assist fault at ip %016lx, isr %016lx\n",
2380c486
JR
145+ current->comm, task_pid_nr(current), current->xid,
146+ regs->cr_iip + ia64_psr(regs)->ri, isr);
147 }
148 }
d337f35e 149 }
3261cfd5
AM
150diff -NurpP --minimal linux-4.9.207/arch/m32r/kernel/traps.c linux-4.9.207-vs2.3.9.11/arch/m32r/kernel/traps.c
151--- linux-4.9.207/arch/m32r/kernel/traps.c 2016-12-11 19:17:54.000000000 +0000
152+++ linux-4.9.207-vs2.3.9.11/arch/m32r/kernel/traps.c 2018-10-20 04:58:12.000000000 +0000
09be7631 153@@ -184,8 +184,9 @@ static void show_registers(struct pt_reg
d337f35e
JR
154 } else {
155 printk("SPI: %08lx\n", sp);
156 }
157- printk("Process %s (pid: %d, process nr: %d, stackpage=%08lx)",
2380c486 158- current->comm, task_pid_nr(current), 0xffff & i, 4096+(unsigned long)current);
61333608 159+ printk("Process %s (pid: %d:#%u, process nr: %d, stackpage=%08lx)",
2380c486 160+ current->comm, task_pid_nr(current), current->xid,
d337f35e
JR
161+ 0xffff & i, 4096+(unsigned long)current);
162
163 /*
164 * When in-kernel, we also print out the stack and code at the
3261cfd5
AM
165diff -NurpP --minimal linux-4.9.207/arch/m68k/Kconfig linux-4.9.207-vs2.3.9.11/arch/m68k/Kconfig
166--- linux-4.9.207/arch/m68k/Kconfig 2016-12-11 19:17:54.000000000 +0000
167+++ linux-4.9.207-vs2.3.9.11/arch/m68k/Kconfig 2018-10-20 04:58:12.000000000 +0000
cc23e853 168@@ -163,6 +163,8 @@ source "fs/Kconfig"
d337f35e
JR
169
170 source "arch/m68k/Kconfig.debug"
171
172+source "kernel/vserver/Kconfig"
173+
174 source "security/Kconfig"
175
176 source "crypto/Kconfig"
3261cfd5
AM
177diff -NurpP --minimal linux-4.9.207/arch/mips/Kconfig linux-4.9.207-vs2.3.9.11/arch/mips/Kconfig
178--- linux-4.9.207/arch/mips/Kconfig 2019-12-25 15:27:28.488429329 +0000
179+++ linux-4.9.207-vs2.3.9.11/arch/mips/Kconfig 2019-12-25 15:37:43.808561393 +0000
180@@ -3193,6 +3193,8 @@ source "fs/Kconfig"
d337f35e
JR
181
182 source "arch/mips/Kconfig.debug"
183
184+source "kernel/vserver/Kconfig"
185+
186 source "security/Kconfig"
187
188 source "crypto/Kconfig"
3261cfd5
AM
189diff -NurpP --minimal linux-4.9.207/arch/mips/kernel/ptrace.c linux-4.9.207-vs2.3.9.11/arch/mips/kernel/ptrace.c
190--- linux-4.9.207/arch/mips/kernel/ptrace.c 2019-12-25 15:27:28.848423509 +0000
191+++ linux-4.9.207-vs2.3.9.11/arch/mips/kernel/ptrace.c 2018-10-20 05:55:33.000000000 +0000
cc23e853 192@@ -30,6 +30,7 @@
2380c486
JR
193 #include <linux/audit.h>
194 #include <linux/seccomp.h>
c2e5f7c8 195 #include <linux/ftrace.h>
d337f35e
JR
196+#include <linux/vs_base.h>
197
198 #include <asm/byteorder.h>
199 #include <asm/cpu.h>
09a55596 200@@ -798,6 +799,9 @@ long arch_ptrace(struct task_struct *chi
ab30d09f
AM
201 void __user *datavp = (void __user *) data;
202 unsigned long __user *datalp = (void __user *) data;
d337f35e 203
2380c486 204+ if (!vx_check(vx_task_xid(child), VS_WATCH_P | VS_IDENT))
d337f35e
JR
205+ goto out;
206+
207 switch (request) {
208 /* when I and D space are separate, these will need to be fixed. */
209 case PTRACE_PEEKTEXT: /* read word at location addr. */
3261cfd5
AM
210diff -NurpP --minimal linux-4.9.207/arch/mips/kernel/scall32-o32.S linux-4.9.207-vs2.3.9.11/arch/mips/kernel/scall32-o32.S
211--- linux-4.9.207/arch/mips/kernel/scall32-o32.S 2019-12-25 15:27:28.848423509 +0000
212+++ linux-4.9.207-vs2.3.9.11/arch/mips/kernel/scall32-o32.S 2018-10-20 04:58:12.000000000 +0000
cc23e853 213@@ -511,7 +511,7 @@ EXPORT(sys_call_table)
c2e5f7c8
JR
214 PTR sys_mq_timedreceive
215 PTR sys_mq_notify /* 4275 */
216 PTR sys_mq_getsetattr
217- PTR sys_ni_syscall /* sys_vserver */
218+ PTR sys_vserver
219 PTR sys_waitid
220 PTR sys_ni_syscall /* available, was setaltroot */
221 PTR sys_add_key /* 4280 */
3261cfd5
AM
222diff -NurpP --minimal linux-4.9.207/arch/mips/kernel/scall64-64.S linux-4.9.207-vs2.3.9.11/arch/mips/kernel/scall64-64.S
223--- linux-4.9.207/arch/mips/kernel/scall64-64.S 2019-12-25 15:27:28.848423509 +0000
224+++ linux-4.9.207-vs2.3.9.11/arch/mips/kernel/scall64-64.S 2018-10-20 04:58:12.000000000 +0000
cc23e853 225@@ -348,7 +348,7 @@ EXPORT(sys_call_table)
d337f35e
JR
226 PTR sys_mq_timedreceive
227 PTR sys_mq_notify
228 PTR sys_mq_getsetattr /* 5235 */
229- PTR sys_ni_syscall /* sys_vserver */
230+ PTR sys_vserver
231 PTR sys_waitid
232 PTR sys_ni_syscall /* available, was setaltroot */
233 PTR sys_add_key
3261cfd5
AM
234diff -NurpP --minimal linux-4.9.207/arch/mips/kernel/scall64-n32.S linux-4.9.207-vs2.3.9.11/arch/mips/kernel/scall64-n32.S
235--- linux-4.9.207/arch/mips/kernel/scall64-n32.S 2019-12-25 15:27:28.848423509 +0000
236+++ linux-4.9.207-vs2.3.9.11/arch/mips/kernel/scall64-n32.S 2018-10-20 04:58:12.000000000 +0000
cc23e853 237@@ -343,7 +343,7 @@ EXPORT(sysn32_call_table)
d337f35e
JR
238 PTR compat_sys_mq_timedreceive
239 PTR compat_sys_mq_notify
240 PTR compat_sys_mq_getsetattr
241- PTR sys_ni_syscall /* 6240, sys_vserver */
242+ PTR sys32_vserver /* 6240 */
2380c486 243 PTR compat_sys_waitid
d337f35e
JR
244 PTR sys_ni_syscall /* available, was setaltroot */
245 PTR sys_add_key
3261cfd5
AM
246diff -NurpP --minimal linux-4.9.207/arch/mips/kernel/scall64-o32.S linux-4.9.207-vs2.3.9.11/arch/mips/kernel/scall64-o32.S
247--- linux-4.9.207/arch/mips/kernel/scall64-o32.S 2019-12-25 15:27:28.848423509 +0000
248+++ linux-4.9.207-vs2.3.9.11/arch/mips/kernel/scall64-o32.S 2019-10-05 14:58:36.920447392 +0000
cc23e853 249@@ -499,7 +499,7 @@ EXPORT(sys32_call_table)
d337f35e
JR
250 PTR compat_sys_mq_timedreceive
251 PTR compat_sys_mq_notify /* 4275 */
252 PTR compat_sys_mq_getsetattr
253- PTR sys_ni_syscall /* sys_vserver */
254+ PTR sys32_vserver
b00e13aa 255 PTR compat_sys_waitid
d337f35e
JR
256 PTR sys_ni_syscall /* available, was setaltroot */
257 PTR sys_add_key /* 4280 */
3261cfd5
AM
258diff -NurpP --minimal linux-4.9.207/arch/mips/kernel/traps.c linux-4.9.207-vs2.3.9.11/arch/mips/kernel/traps.c
259--- linux-4.9.207/arch/mips/kernel/traps.c 2019-12-25 15:27:28.848423509 +0000
260+++ linux-4.9.207-vs2.3.9.11/arch/mips/kernel/traps.c 2018-10-20 04:58:13.000000000 +0000
09a55596 261@@ -361,9 +361,10 @@ void show_registers(struct pt_regs *regs
2380c486
JR
262
263 __show_regs(regs);
d337f35e 264 print_modules();
2380c486
JR
265- printk("Process %s (pid: %d, threadinfo=%p, task=%p, tls=%0*lx)\n",
266- current->comm, current->pid, current_thread_info(), current,
267- field, current_thread_info()->tp_value);
268+ printk("Process %s (pid: %d:#%u, threadinfo=%p, task=%p, tls=%0*lx)\n",
269+ current->comm, task_pid_nr(current), current->xid,
270+ current_thread_info(), current,
271+ field, current_thread_info()->tp_value);
272 if (cpu_has_userlocal) {
273 unsigned long tls;
274
3261cfd5
AM
275diff -NurpP --minimal linux-4.9.207/arch/parisc/Kconfig linux-4.9.207-vs2.3.9.11/arch/parisc/Kconfig
276--- linux-4.9.207/arch/parisc/Kconfig 2019-12-25 15:27:29.098419467 +0000
277+++ linux-4.9.207-vs2.3.9.11/arch/parisc/Kconfig 2018-10-20 05:55:33.000000000 +0000
cc23e853 278@@ -348,6 +348,8 @@ config SECCOMP
d337f35e 279
bb20add7 280 If unsure, say Y. Only embedded should say N here.
d337f35e
JR
281
282+source "kernel/vserver/Kconfig"
283+
284 source "security/Kconfig"
285
286 source "crypto/Kconfig"
3261cfd5
AM
287diff -NurpP --minimal linux-4.9.207/arch/parisc/kernel/syscall_table.S linux-4.9.207-vs2.3.9.11/arch/parisc/kernel/syscall_table.S
288--- linux-4.9.207/arch/parisc/kernel/syscall_table.S 2019-12-25 15:27:29.198417850 +0000
289+++ linux-4.9.207-vs2.3.9.11/arch/parisc/kernel/syscall_table.S 2018-10-20 04:58:13.000000000 +0000
b00e13aa 290@@ -358,7 +358,7 @@
d337f35e
JR
291 ENTRY_COMP(mbind) /* 260 */
292 ENTRY_COMP(get_mempolicy)
293 ENTRY_COMP(set_mempolicy)
294- ENTRY_SAME(ni_syscall) /* 263: reserved for vserver */
295+ ENTRY_DIFF(vserver)
296 ENTRY_SAME(add_key)
297 ENTRY_SAME(request_key) /* 265 */
cc23e853 298 ENTRY_COMP(keyctl)
3261cfd5
AM
299diff -NurpP --minimal linux-4.9.207/arch/parisc/kernel/traps.c linux-4.9.207-vs2.3.9.11/arch/parisc/kernel/traps.c
300--- linux-4.9.207/arch/parisc/kernel/traps.c 2019-12-25 15:27:29.208417686 +0000
301+++ linux-4.9.207-vs2.3.9.11/arch/parisc/kernel/traps.c 2019-02-22 08:37:49.463155825 +0000
cc23e853 302@@ -235,8 +235,9 @@ void die_if_kernel(char *str, struct pt_
d337f35e
JR
303 return; /* STFU */
304
98968f7b
JR
305 parisc_printk_ratelimited(1, regs,
306- KERN_CRIT "%s (pid %d): %s (code %ld) at " RFMT "\n",
2380c486 307- current->comm, task_pid_nr(current), str, err, regs->iaoq[0]);
98968f7b 308+ KERN_CRIT "%s (pid %d:#%u): %s (code %ld) at " RFMT "\n",
2380c486 309+ current->comm, task_pid_nr(current), current->xid,
d337f35e 310+ str, err, regs->iaoq[0]);
98968f7b
JR
311
312 return;
313 }
cc23e853 314@@ -266,8 +267,8 @@ void die_if_kernel(char *str, struct pt_
d337f35e
JR
315 pdc_console_restart();
316
2380c486
JR
317 if (err)
318- printk(KERN_CRIT "%s (pid %d): %s (code %ld)\n",
319- current->comm, task_pid_nr(current), str, err);
320+ printk(KERN_CRIT "%s (pid %d:#%u): %s (code %ld)\n",
321+ current->comm, task_pid_nr(current), current->xid, str, err);
322
323 /* Wot's wrong wif bein' racy? */
324 if (current->thread.flags & PARISC_KERNEL_DEATH) {
3261cfd5
AM
325diff -NurpP --minimal linux-4.9.207/arch/powerpc/include/uapi/asm/unistd.h linux-4.9.207-vs2.3.9.11/arch/powerpc/include/uapi/asm/unistd.h
326--- linux-4.9.207/arch/powerpc/include/uapi/asm/unistd.h 2016-12-11 19:17:54.000000000 +0000
327+++ linux-4.9.207-vs2.3.9.11/arch/powerpc/include/uapi/asm/unistd.h 2018-10-20 04:58:13.000000000 +0000
adc1caaa
AM
328@@ -275,7 +275,7 @@
329 #endif
330 #define __NR_rtas 255
331 #define __NR_sys_debug_setcontext 256
332-/* Number 257 is reserved for vserver */
333+#define __NR_vserver 257
334 #define __NR_migrate_pages 258
335 #define __NR_mbind 259
336 #define __NR_get_mempolicy 260
3261cfd5
AM
337diff -NurpP --minimal linux-4.9.207/arch/powerpc/Kconfig linux-4.9.207-vs2.3.9.11/arch/powerpc/Kconfig
338--- linux-4.9.207/arch/powerpc/Kconfig 2019-12-25 15:27:29.218417525 +0000
339+++ linux-4.9.207-vs2.3.9.11/arch/powerpc/Kconfig 2019-10-05 14:58:37.110444356 +0000
340@@ -1091,6 +1091,8 @@ source "lib/Kconfig"
d33d7b00 341
3261cfd5 342 source "arch/powerpc/Kconfig.debug"
d33d7b00
AM
343
344+source "kernel/vserver/Kconfig"
345+
346 source "security/Kconfig"
0411181d 347
d33d7b00 348 source "crypto/Kconfig"
3261cfd5
AM
349diff -NurpP --minimal linux-4.9.207/arch/s390/include/asm/tlb.h linux-4.9.207-vs2.3.9.11/arch/s390/include/asm/tlb.h
350--- linux-4.9.207/arch/s390/include/asm/tlb.h 2016-12-11 19:17:54.000000000 +0000
351+++ linux-4.9.207-vs2.3.9.11/arch/s390/include/asm/tlb.h 2018-10-20 04:58:13.000000000 +0000
dd5f3080 352@@ -24,6 +24,7 @@
0411181d 353 #include <linux/mm.h>
d33d7b00 354 #include <linux/pagemap.h>
0411181d 355 #include <linux/swap.h>
0411181d
AM
356+
357 #include <asm/processor.h>
358 #include <asm/pgalloc.h>
763640ca 359 #include <asm/tlbflush.h>
3261cfd5
AM
360diff -NurpP --minimal linux-4.9.207/arch/s390/include/uapi/asm/unistd.h linux-4.9.207-vs2.3.9.11/arch/s390/include/uapi/asm/unistd.h
361--- linux-4.9.207/arch/s390/include/uapi/asm/unistd.h 2016-12-11 19:17:54.000000000 +0000
362+++ linux-4.9.207-vs2.3.9.11/arch/s390/include/uapi/asm/unistd.h 2018-10-20 04:58:13.000000000 +0000
92598135 363@@ -200,7 +200,7 @@
cc23e853
AM
364 #define __NR_clock_gettime 260
365 #define __NR_clock_getres 261
366 #define __NR_clock_nanosleep 262
0411181d
AM
367-/* Number 263 is reserved for vserver */
368+#define __NR_vserver 263
369 #define __NR_statfs64 265
370 #define __NR_fstatfs64 266
371 #define __NR_remap_file_pages 267
3261cfd5
AM
372diff -NurpP --minimal linux-4.9.207/arch/s390/Kconfig linux-4.9.207-vs2.3.9.11/arch/s390/Kconfig
373--- linux-4.9.207/arch/s390/Kconfig 2019-12-25 15:27:30.238401034 +0000
374+++ linux-4.9.207-vs2.3.9.11/arch/s390/Kconfig 2018-10-20 04:58:13.000000000 +0000
375@@ -775,6 +775,8 @@ source "fs/Kconfig"
376
377 source "arch/s390/Kconfig.debug"
378
379+source "kernel/vserver/Kconfig"
380+
381 source "security/Kconfig"
382
383 source "crypto/Kconfig"
384diff -NurpP --minimal linux-4.9.207/arch/s390/kernel/ptrace.c linux-4.9.207-vs2.3.9.11/arch/s390/kernel/ptrace.c
385--- linux-4.9.207/arch/s390/kernel/ptrace.c 2019-12-25 15:27:30.598395214 +0000
386+++ linux-4.9.207-vs2.3.9.11/arch/s390/kernel/ptrace.c 2018-10-20 04:58:13.000000000 +0000
db55b927 387@@ -21,6 +21,7 @@
ec22aa5c
AM
388 #include <linux/tracehook.h>
389 #include <linux/seccomp.h>
969f5c41 390 #include <linux/compat.h>
db55b927 391+#include <linux/vs_base.h>
ec22aa5c 392 #include <trace/syscall.h>
d337f35e 393 #include <asm/segment.h>
db55b927 394 #include <asm/page.h>
3261cfd5
AM
395diff -NurpP --minimal linux-4.9.207/arch/s390/kernel/syscalls.S linux-4.9.207-vs2.3.9.11/arch/s390/kernel/syscalls.S
396--- linux-4.9.207/arch/s390/kernel/syscalls.S 2019-12-25 15:27:30.598395214 +0000
397+++ linux-4.9.207-vs2.3.9.11/arch/s390/kernel/syscalls.S 2018-10-20 04:58:13.000000000 +0000
cc23e853
AM
398@@ -271,7 +271,7 @@ SYSCALL(sys_clock_settime,compat_sys_clo
399 SYSCALL(sys_clock_gettime,compat_sys_clock_gettime) /* 260 */
400 SYSCALL(sys_clock_getres,compat_sys_clock_getres)
401 SYSCALL(sys_clock_nanosleep,compat_sys_clock_nanosleep)
402-NI_SYSCALL /* reserved for vserver */
d337f35e 403+SYSCALL(sys_vserver,sys_vserver,sys32_vserver)
cc23e853
AM
404 SYSCALL(sys_ni_syscall,compat_sys_s390_fadvise64_64)
405 SYSCALL(sys_statfs64,compat_sys_statfs64)
406 SYSCALL(sys_fstatfs64,compat_sys_fstatfs64)
3261cfd5
AM
407diff -NurpP --minimal linux-4.9.207/arch/sh/Kconfig linux-4.9.207-vs2.3.9.11/arch/sh/Kconfig
408--- linux-4.9.207/arch/sh/Kconfig 2016-12-11 19:17:54.000000000 +0000
409+++ linux-4.9.207-vs2.3.9.11/arch/sh/Kconfig 2018-10-20 04:58:13.000000000 +0000
cc23e853 410@@ -904,6 +904,8 @@ source "fs/Kconfig"
d337f35e
JR
411
412 source "arch/sh/Kconfig.debug"
413
414+source "kernel/vserver/Kconfig"
415+
416 source "security/Kconfig"
417
418 source "crypto/Kconfig"
3261cfd5
AM
419diff -NurpP --minimal linux-4.9.207/arch/sh/kernel/irq.c linux-4.9.207-vs2.3.9.11/arch/sh/kernel/irq.c
420--- linux-4.9.207/arch/sh/kernel/irq.c 2016-12-11 19:17:54.000000000 +0000
421+++ linux-4.9.207-vs2.3.9.11/arch/sh/kernel/irq.c 2018-10-20 04:58:13.000000000 +0000
f86f0b53 422@@ -14,6 +14,7 @@
7e46296a 423 #include <linux/ftrace.h>
76514441 424 #include <linux/delay.h>
763640ca 425 #include <linux/ratelimit.h>
f86f0b53 426+// #include <linux/vs_context.h>
d337f35e 427 #include <asm/processor.h>
2380c486 428 #include <asm/machvec.h>
f86f0b53 429 #include <asm/uaccess.h>
3261cfd5
AM
430diff -NurpP --minimal linux-4.9.207/arch/sparc/include/uapi/asm/unistd.h linux-4.9.207-vs2.3.9.11/arch/sparc/include/uapi/asm/unistd.h
431--- linux-4.9.207/arch/sparc/include/uapi/asm/unistd.h 2016-12-11 19:17:54.000000000 +0000
432+++ linux-4.9.207-vs2.3.9.11/arch/sparc/include/uapi/asm/unistd.h 2018-10-20 04:58:13.000000000 +0000
537831f9 433@@ -332,7 +332,7 @@
ec22aa5c
AM
434 #define __NR_timer_getoverrun 264
435 #define __NR_timer_delete 265
436 #define __NR_timer_create 266
437-/* #define __NR_vserver 267 Reserved for VSERVER */
438+#define __NR_vserver 267
439 #define __NR_io_setup 268
440 #define __NR_io_destroy 269
441 #define __NR_io_submit 270
3261cfd5
AM
442diff -NurpP --minimal linux-4.9.207/arch/sparc/Kconfig linux-4.9.207-vs2.3.9.11/arch/sparc/Kconfig
443--- linux-4.9.207/arch/sparc/Kconfig 2019-12-25 15:27:31.178385837 +0000
444+++ linux-4.9.207-vs2.3.9.11/arch/sparc/Kconfig 2019-02-22 08:37:49.523154806 +0000
445@@ -584,6 +584,8 @@ source "fs/Kconfig"
446
447 source "arch/sparc/Kconfig.debug"
448
449+source "kernel/vserver/Kconfig"
450+
451 source "security/Kconfig"
452
453 source "crypto/Kconfig"
454diff -NurpP --minimal linux-4.9.207/arch/sparc/kernel/systbls_32.S linux-4.9.207-vs2.3.9.11/arch/sparc/kernel/systbls_32.S
455--- linux-4.9.207/arch/sparc/kernel/systbls_32.S 2016-12-11 19:17:54.000000000 +0000
456+++ linux-4.9.207-vs2.3.9.11/arch/sparc/kernel/systbls_32.S 2018-10-20 04:58:13.000000000 +0000
50e68740 457@@ -70,7 +70,7 @@ sys_call_table:
a168f21d 458 /*250*/ .long sys_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_ni_syscall
50e68740
JR
459 /*255*/ .long sys_sync_file_range, sys_clock_settime, sys_clock_gettime, sys_clock_getres, sys_clock_nanosleep
460 /*260*/ .long sys_sched_getaffinity, sys_sched_setaffinity, sys_timer_settime, sys_timer_gettime, sys_timer_getoverrun
461-/*265*/ .long sys_timer_delete, sys_timer_create, sys_nis_syscall, sys_io_setup, sys_io_destroy
462+/*265*/ .long sys_timer_delete, sys_timer_create, sys_vserver, sys_io_setup, sys_io_destroy
463 /*270*/ .long sys_io_submit, sys_io_cancel, sys_io_getevents, sys_mq_open, sys_mq_unlink
464 /*275*/ .long sys_mq_timedsend, sys_mq_timedreceive, sys_mq_notify, sys_mq_getsetattr, sys_waitid
465 /*280*/ .long sys_tee, sys_add_key, sys_request_key, sys_keyctl, sys_openat
3261cfd5
AM
466diff -NurpP --minimal linux-4.9.207/arch/sparc/kernel/systbls_64.S linux-4.9.207-vs2.3.9.11/arch/sparc/kernel/systbls_64.S
467--- linux-4.9.207/arch/sparc/kernel/systbls_64.S 2016-12-11 19:17:54.000000000 +0000
468+++ linux-4.9.207-vs2.3.9.11/arch/sparc/kernel/systbls_64.S 2018-10-20 04:58:13.000000000 +0000
50e68740 469@@ -71,7 +71,7 @@ sys_call_table32:
b00e13aa 470 /*250*/ .word sys_mremap, compat_sys_sysctl, sys_getsid, sys_fdatasync, sys_nis_syscall
50e68740
JR
471 .word sys32_sync_file_range, compat_sys_clock_settime, compat_sys_clock_gettime, compat_sys_clock_getres, sys32_clock_nanosleep
472 /*260*/ .word compat_sys_sched_getaffinity, compat_sys_sched_setaffinity, sys32_timer_settime, compat_sys_timer_gettime, sys_timer_getoverrun
473- .word sys_timer_delete, compat_sys_timer_create, sys_ni_syscall, compat_sys_io_setup, sys_io_destroy
474+ .word sys_timer_delete, compat_sys_timer_create, sys32_vserver, compat_sys_io_setup, sys_io_destroy
475 /*270*/ .word sys32_io_submit, sys_io_cancel, compat_sys_io_getevents, sys32_mq_open, sys_mq_unlink
476 .word compat_sys_mq_timedsend, compat_sys_mq_timedreceive, compat_sys_mq_notify, compat_sys_mq_getsetattr, compat_sys_waitid
b00e13aa 477 /*280*/ .word sys_tee, sys_add_key, sys_request_key, compat_sys_keyctl, compat_sys_openat
cc23e853 478@@ -152,7 +152,7 @@ sys_call_table:
a168f21d 479 /*250*/ .word sys_64_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_nis_syscall
50e68740
JR
480 .word sys_sync_file_range, sys_clock_settime, sys_clock_gettime, sys_clock_getres, sys_clock_nanosleep
481 /*260*/ .word sys_sched_getaffinity, sys_sched_setaffinity, sys_timer_settime, sys_timer_gettime, sys_timer_getoverrun
482- .word sys_timer_delete, sys_timer_create, sys_ni_syscall, sys_io_setup, sys_io_destroy
483+ .word sys_timer_delete, sys_timer_create, sys_vserver, sys_io_setup, sys_io_destroy
484 /*270*/ .word sys_io_submit, sys_io_cancel, sys_io_getevents, sys_mq_open, sys_mq_unlink
485 .word sys_mq_timedsend, sys_mq_timedreceive, sys_mq_notify, sys_mq_getsetattr, sys_waitid
486 /*280*/ .word sys_tee, sys_add_key, sys_request_key, sys_keyctl, sys_openat
3261cfd5
AM
487diff -NurpP --minimal linux-4.9.207/arch/um/Kconfig.rest linux-4.9.207-vs2.3.9.11/arch/um/Kconfig.rest
488--- linux-4.9.207/arch/um/Kconfig.rest 2016-12-11 19:17:54.000000000 +0000
489+++ linux-4.9.207-vs2.3.9.11/arch/um/Kconfig.rest 2018-10-20 04:58:13.000000000 +0000
f6c5ef8b 490@@ -12,6 +12,8 @@ source "arch/um/Kconfig.net"
d33d7b00
AM
491
492 source "fs/Kconfig"
493
494+source "kernel/vserver/Kconfig"
495+
496 source "security/Kconfig"
497
498 source "crypto/Kconfig"
3261cfd5
AM
499diff -NurpP --minimal linux-4.9.207/arch/x86/entry/syscalls/syscall_32.tbl linux-4.9.207-vs2.3.9.11/arch/x86/entry/syscalls/syscall_32.tbl
500--- linux-4.9.207/arch/x86/entry/syscalls/syscall_32.tbl 2016-12-11 19:17:54.000000000 +0000
501+++ linux-4.9.207-vs2.3.9.11/arch/x86/entry/syscalls/syscall_32.tbl 2018-10-20 04:58:13.000000000 +0000
db55b927
AM
502@@ -279,7 +279,7 @@
503 270 i386 tgkill sys_tgkill
504 271 i386 utimes sys_utimes compat_sys_utimes
505 272 i386 fadvise64_64 sys_fadvise64_64 sys32_fadvise64_64
506-273 i386 vserver
507+273 i386 vserver sys_vserver sys32_vserver
508 274 i386 mbind sys_mbind
509 275 i386 get_mempolicy sys_get_mempolicy compat_sys_get_mempolicy
510 276 i386 set_mempolicy sys_set_mempolicy
3261cfd5
AM
511diff -NurpP --minimal linux-4.9.207/arch/x86/entry/syscalls/syscall_64.tbl linux-4.9.207-vs2.3.9.11/arch/x86/entry/syscalls/syscall_64.tbl
512--- linux-4.9.207/arch/x86/entry/syscalls/syscall_64.tbl 2016-12-11 19:17:54.000000000 +0000
513+++ linux-4.9.207-vs2.3.9.11/arch/x86/entry/syscalls/syscall_64.tbl 2018-10-20 04:58:13.000000000 +0000
db55b927 514@@ -242,7 +242,7 @@
1e8b8f9b
AM
515 233 common epoll_ctl sys_epoll_ctl
516 234 common tgkill sys_tgkill
517 235 common utimes sys_utimes
db55b927
AM
518-236 64 vserver
519+236 64 vserver sys_vserver
1e8b8f9b
AM
520 237 common mbind sys_mbind
521 238 common set_mempolicy sys_set_mempolicy
522 239 common get_mempolicy sys_get_mempolicy
3261cfd5
AM
523diff -NurpP --minimal linux-4.9.207/arch/x86/Kconfig linux-4.9.207-vs2.3.9.11/arch/x86/Kconfig
524--- linux-4.9.207/arch/x86/Kconfig 2019-12-25 15:27:31.878374518 +0000
525+++ linux-4.9.207-vs2.3.9.11/arch/x86/Kconfig 2019-12-25 15:37:44.298553484 +0000
526@@ -2810,6 +2810,8 @@ source "fs/Kconfig"
527
528 source "arch/x86/Kconfig.debug"
529
530+source "kernel/vserver/Kconfig"
531+
532 source "security/Kconfig"
533
534 source "crypto/Kconfig"
535diff -NurpP --minimal linux-4.9.207/block/ioprio.c linux-4.9.207-vs2.3.9.11/block/ioprio.c
536--- linux-4.9.207/block/ioprio.c 2016-12-11 19:17:54.000000000 +0000
537+++ linux-4.9.207-vs2.3.9.11/block/ioprio.c 2018-10-20 04:58:13.000000000 +0000
bb20add7
AM
538@@ -28,6 +28,7 @@
539 #include <linux/syscalls.h>
540 #include <linux/security.h>
541 #include <linux/pid_namespace.h>
542+#include <linux/vs_base.h>
543
544 int set_task_ioprio(struct task_struct *task, int ioprio)
545 {
546@@ -105,6 +106,8 @@ SYSCALL_DEFINE3(ioprio_set, int, which,
547 else
548 pgrp = find_vpid(who);
549 do_each_pid_thread(pgrp, PIDTYPE_PGID, p) {
550+ if (!vx_check(p->xid, VS_ADMIN_P | VS_IDENT))
551+ continue;
552 ret = set_task_ioprio(p, ioprio);
553 if (ret)
554 break;
cc23e853 555@@ -203,6 +206,8 @@ SYSCALL_DEFINE2(ioprio_get, int, which,
bb20add7
AM
556 else
557 pgrp = find_vpid(who);
558 do_each_pid_thread(pgrp, PIDTYPE_PGID, p) {
559+ if (!vx_check(p->xid, VS_ADMIN_P | VS_IDENT))
560+ continue;
561 tmpio = get_task_ioprio(p);
562 if (tmpio < 0)
563 continue;
3261cfd5
AM
564diff -NurpP --minimal linux-4.9.207/Documentation/vserver/debug.txt linux-4.9.207-vs2.3.9.11/Documentation/vserver/debug.txt
565--- linux-4.9.207/Documentation/vserver/debug.txt 1970-01-01 00:00:00.000000000 +0000
566+++ linux-4.9.207-vs2.3.9.11/Documentation/vserver/debug.txt 2018-10-20 04:58:12.000000000 +0000
567@@ -0,0 +1,154 @@
d337f35e 568+
3261cfd5
AM
569+debug_cvirt:
570+
571+ 2 4 "vx_map_tgid: %p/%llx: %d -> %d"
572+ "vx_rmap_tgid: %p/%llx: %d -> %d"
573+
574+debug_dlim:
575+
576+ 0 1 "ALLOC (%p,#%d)%c inode (%d)"
577+ "FREE (%p,#%d)%c inode"
578+ 1 2 "ALLOC (%p,#%d)%c %lld bytes (%d)"
579+ "FREE (%p,#%d)%c %lld bytes"
580+ 2 4 "ADJUST: %lld,%lld on %ld,%ld [mult=%d]"
581+ 3 8 "ext3_has_free_blocks(%p): %lu<%lu+1, %c, %u!=%u r=%d"
582+ "ext3_has_free_blocks(%p): free=%lu, root=%lu"
583+ "rcu_free_dl_info(%p)"
584+ 4 10 "alloc_dl_info(%p,%d) = %p"
585+ "dealloc_dl_info(%p)"
586+ "get_dl_info(%p[#%d.%d])"
587+ "put_dl_info(%p[#%d.%d])"
588+ 5 20 "alloc_dl_info(%p,%d)*"
589+ 6 40 "__hash_dl_info: %p[#%d]"
590+ "__unhash_dl_info: %p[#%d]"
591+ 7 80 "locate_dl_info(%p,#%d) = %p"
592+
593+debug_misc:
594+
595+ 0 1 "destroy_dqhash: %p [#0x%08x] c=%d"
596+ "new_dqhash: %p [#0x%08x]"
597+ "vroot[%d]_clr_dev: dev=%p[%lu,%d:%d]"
598+ "vroot[%d]_get_real_bdev: dev=%p[%lu,%d:%d]"
599+ "vroot[%d]_set_dev: dev=%p[%lu,%d:%d]"
600+ "vroot_get_real_bdev not set"
601+ 1 2 "cow_break_link(?%s?)"
602+ "temp copy ?%s?"
603+ 2 4 "dentry_open(new): %p"
604+ "dentry_open(old): %p"
605+ "lookup_create(new): %p"
606+ "old path ?%s?"
607+ "path_lookup(old): %d"
608+ "vfs_create(new): %d"
609+ "vfs_rename: %d"
610+ "vfs_sendfile: %d"
611+ 3 8 "fput(new_file=%p[#%d])"
612+ "fput(old_file=%p[#%d])"
613+ 4 10 "vx_info_kill(%p[#%d],%d,%d) = %d"
614+ "vx_info_kill(%p[#%d],%d,%d)*"
615+ 5 20 "vs_reboot(%p[#%d],%d)"
616+ 6 40 "dropping task %p[#%u,%u] for %p[#%u,%u]"
617+
618+debug_net:
619+
620+ 2 4 "nx_addr_conflict(%p,%p) %d.%d,%d.%d"
621+ 3 8 "inet_bind(%p) %d.%d.%d.%d, %d.%d.%d.%d, %d.%d.%d.%d"
622+ "inet_bind(%p)* %p,%p;%lx %d.%d.%d.%d"
623+ 4 10 "ip_route_connect(%p) %p,%p;%lx"
624+ 5 20 "__addr_in_socket(%p,%d.%d.%d.%d) %p:%d.%d.%d.%d %p;%lx"
625+ 6 40 "sk,egf: %p [#%d] (from %d)"
626+ "sk,egn: %p [#%d] (from %d)"
627+ "sk,req: %p [#%d] (from %d)"
628+ "sk: %p [#%d] (from %d)"
629+ "tw: %p [#%d] (from %d)"
630+ 7 80 "__sock_recvmsg: %p[%p,%p,%p;%d]:%d/%d"
631+ "__sock_sendmsg: %p[%p,%p,%p;%d]:%d/%d"
632+
633+debug_nid:
634+
635+ 0 1 "__lookup_nx_info(#%u): %p[#%u]"
636+ "alloc_nx_info(%d) = %p"
637+ "create_nx_info(%d) (dynamic rejected)"
638+ "create_nx_info(%d) = %p (already there)"
639+ "create_nx_info(%d) = %p (new)"
640+ "dealloc_nx_info(%p)"
641+ 1 2 "alloc_nx_info(%d)*"
642+ "create_nx_info(%d)*"
643+ 2 4 "get_nx_info(%p[#%d.%d])"
644+ "put_nx_info(%p[#%d.%d])"
645+ 3 8 "claim_nx_info(%p[#%d.%d.%d]) %p"
646+ "clr_nx_info(%p[#%d.%d])"
647+ "init_nx_info(%p[#%d.%d])"
648+ "release_nx_info(%p[#%d.%d.%d]) %p"
649+ "set_nx_info(%p[#%d.%d])"
650+ 4 10 "__hash_nx_info: %p[#%d]"
651+ "__nx_dynamic_id: [#%d]"
652+ "__unhash_nx_info: %p[#%d.%d.%d]"
653+ 5 20 "moved task %p into nxi:%p[#%d]"
654+ "nx_migrate_task(%p,%p[#%d.%d.%d])"
655+ "task_get_nx_info(%p)"
656+ 6 40 "nx_clear_persistent(%p[#%d])"
657+
658+debug_quota:
659+
660+ 0 1 "quota_sync_dqh(%p,%d) discard inode %p"
661+ 1 2 "quota_sync_dqh(%p,%d)"
662+ "sync_dquots(%p,%d)"
663+ "sync_dquots_dqh(%p,%d)"
664+ 3 8 "do_quotactl(%p,%d,cmd=%d,id=%d,%p)"
665+
666+debug_switch:
667+
668+ 0 1 "vc: VCMD_%02d_%d[%d], %d,%p [%d,%d,%x,%x]"
669+ 1 2 "vc: VCMD_%02d_%d[%d] = %08lx(%ld) [%d,%d]"
670+ 4 10 "%s: (%s %s) returned %s with %d"
671+
672+debug_tag:
673+
674+ 7 80 "dx_parse_tag(?%s?): %d:#%d"
675+ "dx_propagate_tag(%p[#%lu.%d]): %d,%d"
676+
677+debug_xid:
678+
679+ 0 1 "__lookup_vx_info(#%u): %p[#%u]"
680+ "alloc_vx_info(%d) = %p"
681+ "alloc_vx_info(%d)*"
682+ "create_vx_info(%d) (dynamic rejected)"
683+ "create_vx_info(%d) = %p (already there)"
684+ "create_vx_info(%d) = %p (new)"
685+ "dealloc_vx_info(%p)"
686+ "loc_vx_info(%d) = %p (found)"
687+ "loc_vx_info(%d) = %p (new)"
688+ "loc_vx_info(%d) = %p (not available)"
689+ 1 2 "create_vx_info(%d)*"
690+ "loc_vx_info(%d)*"
691+ 2 4 "get_vx_info(%p[#%d.%d])"
692+ "put_vx_info(%p[#%d.%d])"
693+ 3 8 "claim_vx_info(%p[#%d.%d.%d]) %p"
694+ "clr_vx_info(%p[#%d.%d])"
695+ "init_vx_info(%p[#%d.%d])"
696+ "release_vx_info(%p[#%d.%d.%d]) %p"
697+ "set_vx_info(%p[#%d.%d])"
698+ 4 10 "__hash_vx_info: %p[#%d]"
699+ "__unhash_vx_info: %p[#%d.%d.%d]"
700+ "__vx_dynamic_id: [#%d]"
701+ 5 20 "enter_vx_info(%p[#%d],%p) %p[#%d,%p]"
702+ "leave_vx_info(%p[#%d,%p]) %p[#%d,%p]"
703+ "moved task %p into vxi:%p[#%d]"
704+ "task_get_vx_info(%p)"
705+ "vx_migrate_task(%p,%p[#%d.%d])"
706+ 6 40 "vx_clear_persistent(%p[#%d])"
707+ "vx_exit_init(%p[#%d],%p[#%d,%d,%d])"
708+ "vx_set_init(%p[#%d],%p[#%d,%d,%d])"
709+ "vx_set_persistent(%p[#%d])"
710+ "vx_set_reaper(%p[#%d],%p[#%d,%d])"
711+ 7 80 "vx_child_reaper(%p[#%u,%u]) = %p[#%u,%u]"
712+
713+
714+debug_limit:
715+
716+ n 2^n "vx_acc_cres[%5d,%s,%2d]: %5d%s"
717+ "vx_cres_avail[%5d,%s,%2d]: %5ld > %5d + %5d"
718+
719+ m 2^m "vx_acc_page[%5d,%s,%2d]: %5d%s"
720+ "vx_acc_pages[%5d,%s,%2d]: %5d += %5d"
721+ "vx_pages_avail[%5d,%s,%2d]: %5ld > %5d + %5d"
722diff -NurpP --minimal linux-4.9.207/drivers/block/Kconfig linux-4.9.207-vs2.3.9.11/drivers/block/Kconfig
723--- linux-4.9.207/drivers/block/Kconfig 2016-12-11 19:17:54.000000000 +0000
724+++ linux-4.9.207-vs2.3.9.11/drivers/block/Kconfig 2018-10-20 04:58:13.000000000 +0000
725@@ -273,6 +273,13 @@ config BLK_DEV_CRYPTOLOOP
726
727 source "drivers/block/drbd/Kconfig"
728
729+config BLK_DEV_VROOT
730+ tristate "Virtual Root device support"
731+ depends on QUOTACTL
732+ ---help---
733+ Saying Y here will allow you to use quota/fs ioctls on a shared
734+ partition within a virtual server without compromising security.
735+
736 config BLK_DEV_NBD
737 tristate "Network block device support"
738 depends on NET
739diff -NurpP --minimal linux-4.9.207/drivers/block/loop.c linux-4.9.207-vs2.3.9.11/drivers/block/loop.c
740--- linux-4.9.207/drivers/block/loop.c 2019-12-25 15:27:36.368301926 +0000
741+++ linux-4.9.207-vs2.3.9.11/drivers/block/loop.c 2019-12-25 15:37:45.418535409 +0000
742@@ -76,6 +76,7 @@
743 #include <linux/miscdevice.h>
744 #include <linux/falloc.h>
745 #include <linux/uio.h>
746+#include <linux/vs_context.h>
747 #include "loop.h"
748
749 #include <asm/uaccess.h>
750@@ -936,6 +937,7 @@ static int loop_set_fd(struct loop_devic
751 lo->lo_blocksize = lo_blocksize;
752 lo->lo_device = bdev;
753 lo->lo_flags = lo_flags;
754+ lo->lo_xid = vx_current_xid();
755 lo->lo_backing_file = file;
756 lo->transfer = NULL;
757 lo->ioctl = NULL;
758@@ -1056,6 +1058,7 @@ static int loop_clr_fd(struct loop_devic
759 lo->lo_offset = 0;
760 lo->lo_sizelimit = 0;
761 lo->lo_encrypt_key_size = 0;
762+ lo->lo_xid = 0;
763 memset(lo->lo_encrypt_key, 0, LO_KEY_SIZE);
764 memset(lo->lo_crypt_name, 0, LO_NAME_SIZE);
765 memset(lo->lo_file_name, 0, LO_NAME_SIZE);
766@@ -1102,7 +1105,7 @@ loop_set_status(struct loop_device *lo,
767
768 if (lo->lo_encrypt_key_size &&
537831f9 769 !uid_eq(lo->lo_key_owner, uid) &&
d337f35e
JR
770- !capable(CAP_SYS_ADMIN))
771+ !vx_capable(CAP_SYS_ADMIN, VXC_ADMIN_CLOOP))
772 return -EPERM;
773 if (lo->lo_state != Lo_bound)
774 return -ENXIO;
09a55596 775@@ -1207,7 +1210,8 @@ loop_get_status(struct loop_device *lo,
d337f35e
JR
776 memcpy(info->lo_crypt_name, lo->lo_crypt_name, LO_NAME_SIZE);
777 info->lo_encrypt_type =
778 lo->lo_encryption ? lo->lo_encryption->number : 0;
779- if (lo->lo_encrypt_key_size && capable(CAP_SYS_ADMIN)) {
780+ if (lo->lo_encrypt_key_size &&
781+ vx_capable(CAP_SYS_ADMIN, VXC_ADMIN_CLOOP)) {
782 info->lo_encrypt_key_size = lo->lo_encrypt_key_size;
783 memcpy(info->lo_encrypt_key, lo->lo_encrypt_key,
784 lo->lo_encrypt_key_size);
3261cfd5 785@@ -1569,6 +1573,11 @@ static int lo_open(struct block_device *
a168f21d
AM
786 goto out;
787 }
d337f35e 788
dd5f3080 789+ if (!vx_check(lo->lo_xid, VS_IDENT|VS_HOSTID|VS_ADMIN_P)) {
790+ err = -EACCES;
791+ goto out;
792+ }
d337f35e 793+
cc23e853
AM
794 atomic_inc(&lo->lo_refcnt);
795 out:
796 mutex_unlock(&loop_index_mutex);
3261cfd5
AM
797diff -NurpP --minimal linux-4.9.207/drivers/block/loop.h linux-4.9.207-vs2.3.9.11/drivers/block/loop.h
798--- linux-4.9.207/drivers/block/loop.h 2019-12-25 15:27:36.388301601 +0000
799+++ linux-4.9.207-vs2.3.9.11/drivers/block/loop.h 2019-10-05 14:58:39.110412393 +0000
cc23e853 800@@ -43,6 +43,7 @@ struct loop_device {
c2e5f7c8
JR
801 struct loop_func_table *lo_encryption;
802 __u32 lo_init[2];
803 kuid_t lo_key_owner; /* Who set the key */
804+ vxid_t lo_xid;
805 int (*ioctl)(struct loop_device *, int cmd,
806 unsigned long arg);
807
3261cfd5
AM
808diff -NurpP --minimal linux-4.9.207/drivers/block/Makefile linux-4.9.207-vs2.3.9.11/drivers/block/Makefile
809--- linux-4.9.207/drivers/block/Makefile 2016-12-11 19:17:54.000000000 +0000
810+++ linux-4.9.207-vs2.3.9.11/drivers/block/Makefile 2018-10-20 04:58:13.000000000 +0000
811@@ -31,6 +31,7 @@ obj-$(CONFIG_VIRTIO_BLK) += virtio_blk.o
812
813 obj-$(CONFIG_BLK_DEV_SX8) += sx8.o
814 obj-$(CONFIG_BLK_DEV_HD) += hd.o
815+obj-$(CONFIG_BLK_DEV_VROOT) += vroot.o
816
817 obj-$(CONFIG_XEN_BLKDEV_FRONTEND) += xen-blkfront.o
818 obj-$(CONFIG_XEN_BLKDEV_BACKEND) += xen-blkback/
819diff -NurpP --minimal linux-4.9.207/drivers/block/vroot.c linux-4.9.207-vs2.3.9.11/drivers/block/vroot.c
820--- linux-4.9.207/drivers/block/vroot.c 1970-01-01 00:00:00.000000000 +0000
821+++ linux-4.9.207-vs2.3.9.11/drivers/block/vroot.c 2018-10-20 04:58:13.000000000 +0000
cc23e853 822@@ -0,0 +1,291 @@
d337f35e
JR
823+/*
824+ * linux/drivers/block/vroot.c
825+ *
cc23e853
AM
826+ * written by Herbert P?tzl, 9/11/2002
827+ * ported to 2.6.10 by Herbert P?tzl, 30/12/2004
d337f35e
JR
828+ *
829+ * based on the loop.c code by Theodore Ts'o.
830+ *
cc23e853 831+ * Copyright (C) 2002-2007 by Herbert P?tzl.
d337f35e
JR
832+ * Redistribution of this file is permitted under the
833+ * GNU General Public License.
834+ *
835+ */
836+
837+#include <linux/module.h>
838+#include <linux/moduleparam.h>
839+#include <linux/file.h>
840+#include <linux/major.h>
841+#include <linux/blkdev.h>
76514441 842+#include <linux/slab.h>
d337f35e
JR
843+
844+#include <linux/vroot.h>
845+#include <linux/vs_context.h>
846+
847+
848+static int max_vroot = 8;
849+
850+static struct vroot_device *vroot_dev;
851+static struct gendisk **disks;
852+
853+
854+static int vroot_set_dev(
855+ struct vroot_device *vr,
d337f35e
JR
856+ struct block_device *bdev,
857+ unsigned int arg)
858+{
859+ struct block_device *real_bdev;
860+ struct file *file;
861+ struct inode *inode;
862+ int error;
863+
864+ error = -EBUSY;
865+ if (vr->vr_state != Vr_unbound)
866+ goto out;
867+
868+ error = -EBADF;
869+ file = fget(arg);
870+ if (!file)
871+ goto out;
872+
873+ error = -EINVAL;
cc23e853 874+ inode = file->f_path.dentry->d_inode;
d337f35e
JR
875+
876+
877+ if (S_ISBLK(inode->i_mode)) {
878+ real_bdev = inode->i_bdev;
879+ vr->vr_device = real_bdev;
880+ __iget(real_bdev->bd_inode);
881+ } else
882+ goto out_fput;
883+
884+ vxdprintk(VXD_CBIT(misc, 0),
885+ "vroot[%d]_set_dev: dev=" VXF_DEV,
886+ vr->vr_number, VXD_DEV(real_bdev));
887+
888+ vr->vr_state = Vr_bound;
889+ error = 0;
890+
891+ out_fput:
892+ fput(file);
893+ out:
894+ return error;
895+}
896+
897+static int vroot_clr_dev(
898+ struct vroot_device *vr,
d337f35e
JR
899+ struct block_device *bdev)
900+{
901+ struct block_device *real_bdev;
902+
903+ if (vr->vr_state != Vr_bound)
904+ return -ENXIO;
905+ if (vr->vr_refcnt > 1) /* we needed one fd for the ioctl */
906+ return -EBUSY;
907+
908+ real_bdev = vr->vr_device;
909+
910+ vxdprintk(VXD_CBIT(misc, 0),
911+ "vroot[%d]_clr_dev: dev=" VXF_DEV,
912+ vr->vr_number, VXD_DEV(real_bdev));
913+
914+ bdput(real_bdev);
915+ vr->vr_state = Vr_unbound;
916+ vr->vr_device = NULL;
917+ return 0;
918+}
919+
920+
ec22aa5c 921+static int vr_ioctl(struct block_device *bdev, fmode_t mode,
d337f35e
JR
922+ unsigned int cmd, unsigned long arg)
923+{
ec22aa5c 924+ struct vroot_device *vr = bdev->bd_disk->private_data;
d337f35e
JR
925+ int err;
926+
927+ down(&vr->vr_ctl_mutex);
928+ switch (cmd) {
929+ case VROOT_SET_DEV:
ec22aa5c 930+ err = vroot_set_dev(vr, bdev, arg);
d337f35e
JR
931+ break;
932+ case VROOT_CLR_DEV:
ec22aa5c 933+ err = vroot_clr_dev(vr, bdev);
d337f35e
JR
934+ break;
935+ default:
936+ err = -EINVAL;
937+ break;
938+ }
939+ up(&vr->vr_ctl_mutex);
940+ return err;
941+}
942+
ec22aa5c 943+static int vr_open(struct block_device *bdev, fmode_t mode)
d337f35e 944+{
ec22aa5c 945+ struct vroot_device *vr = bdev->bd_disk->private_data;
d337f35e
JR
946+
947+ down(&vr->vr_ctl_mutex);
948+ vr->vr_refcnt++;
949+ up(&vr->vr_ctl_mutex);
950+ return 0;
951+}
952+
09be7631 953+static void vr_release(struct gendisk *disk, fmode_t mode)
d337f35e 954+{
ec22aa5c 955+ struct vroot_device *vr = disk->private_data;
d337f35e
JR
956+
957+ down(&vr->vr_ctl_mutex);
958+ --vr->vr_refcnt;
959+ up(&vr->vr_ctl_mutex);
d337f35e
JR
960+}
961+
962+static struct block_device_operations vr_fops = {
963+ .owner = THIS_MODULE,
964+ .open = vr_open,
965+ .release = vr_release,
966+ .ioctl = vr_ioctl,
967+};
968+
cc23e853 969+static blk_qc_t vroot_make_request(struct request_queue *q, struct bio *bio)
b3b0d4fd
AM
970+{
971+ printk("vroot_make_request %p, %p\n", q, bio);
972+ bio_io_error(bio);
cc23e853 973+ return BLK_QC_T_NONE;
b3b0d4fd
AM
974+}
975+
d337f35e
JR
976+struct block_device *__vroot_get_real_bdev(struct block_device *bdev)
977+{
978+ struct inode *inode = bdev->bd_inode;
979+ struct vroot_device *vr;
980+ struct block_device *real_bdev;
981+ int minor = iminor(inode);
982+
983+ vr = &vroot_dev[minor];
984+ real_bdev = vr->vr_device;
985+
986+ vxdprintk(VXD_CBIT(misc, 0),
987+ "vroot[%d]_get_real_bdev: dev=" VXF_DEV,
988+ vr->vr_number, VXD_DEV(real_bdev));
989+
990+ if (vr->vr_state != Vr_bound)
991+ return ERR_PTR(-ENXIO);
992+
993+ __iget(real_bdev->bd_inode);
994+ return real_bdev;
995+}
996+
b3b0d4fd
AM
997+
998+
d337f35e
JR
999+/*
1000+ * And now the modules code and kernel interface.
1001+ */
1002+
1003+module_param(max_vroot, int, 0);
1004+
1005+MODULE_PARM_DESC(max_vroot, "Maximum number of vroot devices (1-256)");
1006+MODULE_LICENSE("GPL");
1007+MODULE_ALIAS_BLOCKDEV_MAJOR(VROOT_MAJOR);
1008+
cc23e853 1009+MODULE_AUTHOR ("Herbert P?tzl");
d337f35e
JR
1010+MODULE_DESCRIPTION ("Virtual Root Device Mapper");
1011+
1012+
1013+int __init vroot_init(void)
1014+{
1015+ int err, i;
1016+
1017+ if (max_vroot < 1 || max_vroot > 256) {
1018+ max_vroot = MAX_VROOT_DEFAULT;
1019+ printk(KERN_WARNING "vroot: invalid max_vroot "
1020+ "(must be between 1 and 256), "
1021+ "using default (%d)\n", max_vroot);
1022+ }
1023+
1024+ if (register_blkdev(VROOT_MAJOR, "vroot"))
1025+ return -EIO;
1026+
1027+ err = -ENOMEM;
1028+ vroot_dev = kmalloc(max_vroot * sizeof(struct vroot_device), GFP_KERNEL);
1029+ if (!vroot_dev)
1030+ goto out_mem1;
1031+ memset(vroot_dev, 0, max_vroot * sizeof(struct vroot_device));
1032+
1033+ disks = kmalloc(max_vroot * sizeof(struct gendisk *), GFP_KERNEL);
1034+ if (!disks)
1035+ goto out_mem2;
1036+
1037+ for (i = 0; i < max_vroot; i++) {
1038+ disks[i] = alloc_disk(1);
1039+ if (!disks[i])
1040+ goto out_mem3;
2380c486
JR
1041+ disks[i]->queue = blk_alloc_queue(GFP_KERNEL);
1042+ if (!disks[i]->queue)
1043+ goto out_mem3;
b3b0d4fd 1044+ blk_queue_make_request(disks[i]->queue, vroot_make_request);
d337f35e
JR
1045+ }
1046+
1047+ for (i = 0; i < max_vroot; i++) {
1048+ struct vroot_device *vr = &vroot_dev[i];
1049+ struct gendisk *disk = disks[i];
1050+
1051+ memset(vr, 0, sizeof(*vr));
5a9fc8e8 1052+ sema_init(&vr->vr_ctl_mutex, 1);
d337f35e
JR
1053+ vr->vr_number = i;
1054+ disk->major = VROOT_MAJOR;
1055+ disk->first_minor = i;
1056+ disk->fops = &vr_fops;
1057+ sprintf(disk->disk_name, "vroot%d", i);
1058+ disk->private_data = vr;
1059+ }
1060+
1061+ err = register_vroot_grb(&__vroot_get_real_bdev);
1062+ if (err)
1063+ goto out_mem3;
1064+
1065+ for (i = 0; i < max_vroot; i++)
1066+ add_disk(disks[i]);
1067+ printk(KERN_INFO "vroot: loaded (max %d devices)\n", max_vroot);
1068+ return 0;
1069+
1070+out_mem3:
1071+ while (i--)
1072+ put_disk(disks[i]);
1073+ kfree(disks);
1074+out_mem2:
1075+ kfree(vroot_dev);
1076+out_mem1:
1077+ unregister_blkdev(VROOT_MAJOR, "vroot");
1078+ printk(KERN_ERR "vroot: ran out of memory\n");
1079+ return err;
1080+}
1081+
1082+void vroot_exit(void)
1083+{
1084+ int i;
1085+
1086+ if (unregister_vroot_grb(&__vroot_get_real_bdev))
1087+ printk(KERN_WARNING "vroot: cannot unregister grb\n");
1088+
1089+ for (i = 0; i < max_vroot; i++) {
1090+ del_gendisk(disks[i]);
1091+ put_disk(disks[i]);
1092+ }
2380c486 1093+ unregister_blkdev(VROOT_MAJOR, "vroot");
d337f35e
JR
1094+
1095+ kfree(disks);
1096+ kfree(vroot_dev);
1097+}
1098+
1099+module_init(vroot_init);
1100+module_exit(vroot_exit);
1101+
1102+#ifndef MODULE
1103+
1104+static int __init max_vroot_setup(char *str)
1105+{
1106+ max_vroot = simple_strtol(str, NULL, 0);
1107+ return 1;
1108+}
1109+
1110+__setup("max_vroot=", max_vroot_setup);
1111+
1112+#endif
1113+
3261cfd5
AM
1114diff -NurpP --minimal linux-4.9.207/drivers/md/dm.c linux-4.9.207-vs2.3.9.11/drivers/md/dm.c
1115--- linux-4.9.207/drivers/md/dm.c 2019-12-25 15:28:01.727891912 +0000
1116+++ linux-4.9.207-vs2.3.9.11/drivers/md/dm.c 2019-12-25 15:37:45.988526209 +0000
1117@@ -22,6 +22,7 @@
1118 #include <linux/wait.h>
1119 #include <linux/pr.h>
1120 #include <linux/vmalloc.h>
1121+#include <linux/vs_base.h>
3bac966d 1122
3261cfd5 1123 #define DM_MSG_PREFIX "core"
3bac966d 1124
3261cfd5
AM
1125@@ -300,6 +301,7 @@ int dm_deleting_md(struct mapped_device
1126 static int dm_blk_open(struct block_device *bdev, fmode_t mode)
a168f21d
AM
1127 {
1128 struct mapped_device *md;
3261cfd5 1129+ int ret = -ENXIO;
a168f21d 1130
3261cfd5 1131 spin_lock(&_minor_lock);
d33d7b00 1132
cc23e853 1133@@ -308,17 +310,19 @@ static int dm_blk_open(struct block_devi
d33d7b00
AM
1134 goto out;
1135
1136 if (test_bit(DMF_FREEING, &md->flags) ||
1137- dm_deleting_md(md)) {
1138- md = NULL;
1139+ dm_deleting_md(md))
1140+ goto out;
1141+
1142+ ret = -EACCES;
1143+ if (!vx_check(md->xid, VS_IDENT|VS_HOSTID))
1144 goto out;
1145- }
1146
1147 dm_get(md);
1148 atomic_inc(&md->open_count);
d33d7b00
AM
1149+ ret = 0;
1150 out:
1151 spin_unlock(&_minor_lock);
1152-
1153- return md ? 0 : -ENXIO;
1154+ return ret;
1155 }
1156
09be7631 1157 static void dm_blk_close(struct gendisk *disk, fmode_t mode)
cc23e853 1158@@ -744,6 +748,14 @@ int dm_set_geometry(struct mapped_device
d33d7b00
AM
1159 return 0;
1160 }
1161
1162+/*
1163+ * Get the xid associated with a dm device
1164+ */
61333608 1165+vxid_t dm_get_xid(struct mapped_device *md)
d33d7b00
AM
1166+{
1167+ return md->xid;
1168+}
1169+
1170 /*-----------------------------------------------------------------
1171 * CRUD START:
1172 * A more elegant soln is in the works that uses the queue
09a55596 1173@@ -1549,6 +1561,7 @@ static struct mapped_device *alloc_dev(i
cc23e853 1174 INIT_LIST_HEAD(&md->uevent_list);
bb20add7 1175 INIT_LIST_HEAD(&md->table_devices);
d33d7b00 1176 spin_lock_init(&md->uevent_lock);
d33d7b00 1177+ md->xid = vx_current_xid();
cc23e853
AM
1178
1179 md->queue = blk_alloc_queue_node(GFP_KERNEL, numa_node_id);
d33d7b00 1180 if (!md->queue)
3261cfd5
AM
1181diff -NurpP --minimal linux-4.9.207/drivers/md/dm-core.h linux-4.9.207-vs2.3.9.11/drivers/md/dm-core.h
1182--- linux-4.9.207/drivers/md/dm-core.h 2019-12-25 15:28:01.677892718 +0000
1183+++ linux-4.9.207-vs2.3.9.11/drivers/md/dm-core.h 2018-10-20 04:58:13.000000000 +0000
1184@@ -52,6 +52,7 @@ struct mapped_device {
1185
1186 atomic_t holders;
1187 atomic_t open_count;
1188+ vxid_t xid;
1189
1190 struct dm_target *immutable_target;
1191 struct target_type *immutable_target_type;
1192diff -NurpP --minimal linux-4.9.207/drivers/md/dm.h linux-4.9.207-vs2.3.9.11/drivers/md/dm.h
1193--- linux-4.9.207/drivers/md/dm.h 2016-12-11 19:17:54.000000000 +0000
1194+++ linux-4.9.207-vs2.3.9.11/drivers/md/dm.h 2018-10-20 04:58:13.000000000 +0000
cc23e853 1195@@ -45,6 +45,8 @@ struct dm_dev_internal {
d33d7b00
AM
1196 struct dm_table;
1197 struct dm_md_mempools;
1198
61333608 1199+vxid_t dm_get_xid(struct mapped_device *md);
d33d7b00
AM
1200+
1201 /*-----------------------------------------------------------------
1202 * Internal table functions.
1203 *---------------------------------------------------------------*/
3261cfd5
AM
1204diff -NurpP --minimal linux-4.9.207/drivers/md/dm-ioctl.c linux-4.9.207-vs2.3.9.11/drivers/md/dm-ioctl.c
1205--- linux-4.9.207/drivers/md/dm-ioctl.c 2019-12-25 15:28:01.687892558 +0000
1206+++ linux-4.9.207-vs2.3.9.11/drivers/md/dm-ioctl.c 2019-02-22 08:37:51.173126752 +0000
1207@@ -16,6 +16,7 @@
1208 #include <linux/dm-ioctl.h>
1209 #include <linux/hdreg.h>
1210 #include <linux/compat.h>
1211+#include <linux/vs_context.h>
1212
1213 #include <asm/uaccess.h>
1214
1215@@ -114,7 +115,8 @@ static struct hash_cell *__get_name_cell
1216 unsigned int h = hash_str(str);
1217
1218 list_for_each_entry (hc, _name_buckets + h, name_list)
1219- if (!strcmp(hc->name, str)) {
1220+ if (vx_check(dm_get_xid(hc->md), VS_WATCH_P | VS_IDENT) &&
1221+ !strcmp(hc->name, str)) {
1222 dm_get(hc->md);
1223 return hc;
1224 }
1225@@ -128,7 +130,8 @@ static struct hash_cell *__get_uuid_cell
1226 unsigned int h = hash_str(str);
1227
1228 list_for_each_entry (hc, _uuid_buckets + h, uuid_list)
1229- if (!strcmp(hc->uuid, str)) {
1230+ if (vx_check(dm_get_xid(hc->md), VS_WATCH_P | VS_IDENT) &&
1231+ !strcmp(hc->uuid, str)) {
1232 dm_get(hc->md);
1233 return hc;
1234 }
1235@@ -139,13 +142,15 @@ static struct hash_cell *__get_uuid_cell
1236 static struct hash_cell *__get_dev_cell(uint64_t dev)
1237 {
1238 struct mapped_device *md;
1239- struct hash_cell *hc;
1240+ struct hash_cell *hc = NULL;
1241
1242 md = dm_get_md(huge_decode_dev(dev));
1243 if (!md)
1244 return NULL;
1245
1246- hc = dm_get_mdptr(md);
1247+ if (vx_check(dm_get_xid(md), VS_WATCH_P | VS_IDENT))
1248+ hc = dm_get_mdptr(md);
1249+
1250 if (!hc) {
1251 dm_put(md);
1252 return NULL;
1253@@ -467,6 +472,9 @@ typedef int (*ioctl_fn)(struct dm_ioctl
1254
1255 static int remove_all(struct dm_ioctl *param, size_t param_size)
1256 {
1257+ if (!vx_check(0, VS_ADMIN))
1258+ return -EPERM;
1259+
1260 dm_hash_remove_all(true, !!(param->flags & DM_DEFERRED_REMOVE), false);
1261 param->data_size = 0;
1262 return 0;
1263@@ -514,6 +522,8 @@ static int list_devices(struct dm_ioctl
1264 */
1265 for (i = 0; i < NUM_BUCKETS; i++) {
1266 list_for_each_entry (hc, _name_buckets + i, name_list) {
1267+ if (!vx_check(dm_get_xid(hc->md), VS_WATCH_P | VS_IDENT))
1268+ continue;
1269 needed += sizeof(struct dm_name_list);
1270 needed += strlen(hc->name) + 1;
1271 needed += ALIGN_MASK;
1272@@ -537,6 +547,8 @@ static int list_devices(struct dm_ioctl
1273 */
1274 for (i = 0; i < NUM_BUCKETS; i++) {
1275 list_for_each_entry (hc, _name_buckets + i, name_list) {
1276+ if (!vx_check(dm_get_xid(hc->md), VS_WATCH_P | VS_IDENT))
1277+ continue;
1278 if (old_nl)
1279 old_nl->next = (uint32_t) ((void *) nl -
1280 (void *) old_nl);
1281@@ -1799,8 +1811,8 @@ static int ctl_ioctl(uint command, struc
1282 size_t input_param_size;
1283 struct dm_ioctl param_kernel;
1284
1285- /* only root can play with this */
1286- if (!capable(CAP_SYS_ADMIN))
1287+ /* only root and certain contexts can play with this */
1288+ if (!vx_capable(CAP_SYS_ADMIN, VXC_ADMIN_MAPPER))
1289 return -EACCES;
1290
1291 if (_IOC_TYPE(command) != DM_IOCTL)
1292diff -NurpP --minimal linux-4.9.207/drivers/net/tun.c linux-4.9.207-vs2.3.9.11/drivers/net/tun.c
1293--- linux-4.9.207/drivers/net/tun.c 2019-12-25 15:28:13.097708081 +0000
1294+++ linux-4.9.207-vs2.3.9.11/drivers/net/tun.c 2019-10-05 14:58:41.040381546 +0000
c2e5f7c8 1295@@ -65,6 +65,7 @@
d33d7b00
AM
1296 #include <linux/nsproxy.h>
1297 #include <linux/virtio_net.h>
1298 #include <linux/rcupdate.h>
1299+#include <linux/vs_network.h>
1300 #include <net/net_namespace.h>
1301 #include <net/netns/generic.h>
cc23e853
AM
1302 #include <net/rtnetlink.h>
1303@@ -194,6 +195,7 @@ struct tun_struct {
d33d7b00 1304 unsigned int flags;
537831f9
AM
1305 kuid_t owner;
1306 kgid_t group;
61333608 1307+ vnid_t nid;
d33d7b00
AM
1308
1309 struct net_device *dev;
db55b927 1310 netdev_features_t set_features;
cc23e853 1311@@ -490,6 +492,7 @@ static inline bool tun_not_capable(struc
b00e13aa
AM
1312 return ((uid_valid(tun->owner) && !uid_eq(cred->euid, tun->owner)) ||
1313 (gid_valid(tun->group) && !in_egroup_p(tun->group))) &&
1314 !ns_capable(net->user_ns, CAP_NET_ADMIN);
1315+ /* !cap_raised(current_cap(), CAP_NET_ADMIN) */
1316 }
1317
1318 static void tun_set_real_num_queues(struct tun_struct *tun)
5ba7a31c 1319@@ -1558,6 +1561,7 @@ static void tun_setup(struct net_device
2380c486 1320
537831f9
AM
1321 tun->owner = INVALID_UID;
1322 tun->group = INVALID_GID;
1323+ tun->nid = nx_current_nid();
2380c486 1324
ec22aa5c
AM
1325 dev->ethtool_ops = &tun_ethtool_ops;
1326 dev->destructor = tun_free_netdev;
3261cfd5 1327@@ -1771,7 +1775,7 @@ static int tun_set_iff(struct net *net,
b00e13aa
AM
1328 int queues = ifr->ifr_flags & IFF_MULTI_QUEUE ?
1329 MAX_TAP_QUEUES : 1;
1330
1331- if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
c2e5f7c8 1332+ if (!nx_ns_capable(net->user_ns, CAP_NET_ADMIN, NXC_TUN_CREATE))
b00e13aa
AM
1333 return -EPERM;
1334 err = security_tun_dev_create();
1335 if (err < 0)
3261cfd5 1336@@ -2140,6 +2144,16 @@ static long __tun_chr_ioctl(struct file
537831f9 1337 from_kgid(&init_user_ns, tun->group));
2380c486 1338 break;
d337f35e 1339
2380c486
JR
1340+ case TUNSETNID:
1341+ if (!capable(CAP_CONTEXT))
1342+ return -EPERM;
d337f35e 1343+
2380c486 1344+ /* Set nid owner of the device */
61333608 1345+ tun->nid = (vnid_t) arg;
d337f35e 1346+
763640ca 1347+ tun_debug(KERN_INFO, tun, "nid owner set to %u\n", tun->nid);
2380c486 1348+ break;
d337f35e 1349+
2380c486
JR
1350 case TUNSETLINK:
1351 /* Only allow setting the type when the interface is down */
ec22aa5c 1352 if (tun->dev->flags & IFF_UP) {
3261cfd5
AM
1353diff -NurpP --minimal linux-4.9.207/drivers/scsi/cxgbi/libcxgbi.c linux-4.9.207-vs2.3.9.11/drivers/scsi/cxgbi/libcxgbi.c
1354--- linux-4.9.207/drivers/scsi/cxgbi/libcxgbi.c 2019-12-25 15:28:19.947597331 +0000
1355+++ linux-4.9.207-vs2.3.9.11/drivers/scsi/cxgbi/libcxgbi.c 2019-10-05 14:58:43.270345911 +0000
1356@@ -776,7 +776,8 @@ static struct cxgbi_sock *cxgbi_check_ro
bb20add7
AM
1357 struct inet6_dev *idev = ip6_dst_idev((struct dst_entry *)rt);
1358
1359 err = ipv6_dev_get_saddr(&init_net, idev ? idev->dev : NULL,
1360- &daddr6->sin6_addr, 0, &pref_saddr);
1361+ &daddr6->sin6_addr, 0, &pref_saddr,
1362+ NULL);
1363 if (err) {
1364 pr_info("failed to get source address to reach %pI6\n",
1365 &daddr6->sin6_addr);
3261cfd5
AM
1366diff -NurpP --minimal linux-4.9.207/drivers/tty/sysrq.c linux-4.9.207-vs2.3.9.11/drivers/tty/sysrq.c
1367--- linux-4.9.207/drivers/tty/sysrq.c 2019-12-25 15:28:24.267527483 +0000
1368+++ linux-4.9.207-vs2.3.9.11/drivers/tty/sysrq.c 2018-10-20 04:58:13.000000000 +0000
bb20add7 1369@@ -47,6 +47,7 @@
c2e5f7c8
JR
1370 #include <linux/syscalls.h>
1371 #include <linux/of.h>
bb20add7 1372 #include <linux/rcupdate.h>
ab30d09f
AM
1373+#include <linux/vserver/debug.h>
1374
1375 #include <asm/ptrace.h>
1376 #include <asm/irq_regs.h>
cc23e853 1377@@ -428,6 +429,21 @@ static struct sysrq_key_op sysrq_unrt_op
ab30d09f
AM
1378 .enable_mask = SYSRQ_ENABLE_RTNICE,
1379 };
1380
1381+
1382+#ifdef CONFIG_VSERVER_DEBUG
1383+static void sysrq_handle_vxinfo(int key)
1384+{
1385+ dump_vx_info_inactive((key == 'x') ? 0 : 1);
1386+}
1387+
1388+static struct sysrq_key_op sysrq_showvxinfo_op = {
1389+ .handler = sysrq_handle_vxinfo,
1390+ .help_msg = "conteXt",
1391+ .action_msg = "Show Context Info",
1392+ .enable_mask = SYSRQ_ENABLE_DUMP,
1393+};
1394+#endif
1395+
1396 /* Key Operations table and lock */
1397 static DEFINE_SPINLOCK(sysrq_key_table_lock);
1398
cc23e853
AM
1399@@ -484,7 +500,11 @@ static struct sysrq_key_op *sysrq_key_ta
1400 /* x: May be registered on mips for TLB dump */
ab30d09f 1401 /* x: May be registered on ppc/powerpc for xmon */
537831f9 1402 /* x: May be registered on sparc64 for global PMU dump */
ab30d09f
AM
1403+#ifdef CONFIG_VSERVER_DEBUG
1404+ &sysrq_showvxinfo_op, /* x */
1405+#else
4bf69007 1406 NULL, /* x */
ab30d09f
AM
1407+#endif
1408 /* y: May be registered on sparc64 for global register dump */
1409 NULL, /* y */
1410 &sysrq_ftrace_dump_op, /* z */
cc23e853 1411@@ -499,6 +519,8 @@ static int sysrq_key_table_key2index(int
ab30d09f
AM
1412 retval = key - '0';
1413 else if ((key >= 'a') && (key <= 'z'))
1414 retval = key + 10 - 'a';
1415+ else if ((key >= 'A') && (key <= 'Z'))
1416+ retval = key + 10 - 'A';
1417 else
1418 retval = -1;
1419 return retval;
3261cfd5
AM
1420diff -NurpP --minimal linux-4.9.207/drivers/tty/tty_io.c linux-4.9.207-vs2.3.9.11/drivers/tty/tty_io.c
1421--- linux-4.9.207/drivers/tty/tty_io.c 2019-12-25 15:28:24.287527162 +0000
1422+++ linux-4.9.207-vs2.3.9.11/drivers/tty/tty_io.c 2019-10-05 14:58:43.980334565 +0000
1e8b8f9b 1423@@ -104,6 +104,7 @@
ab30d09f
AM
1424
1425 #include <linux/kmod.h>
1426 #include <linux/nsproxy.h>
1427+#include <linux/vs_pid.h>
1428
1429 #undef TTY_DEBUG_HANGUP
cc23e853 1430 #ifdef TTY_DEBUG_HANGUP
3261cfd5 1431@@ -2318,7 +2319,8 @@ static int tiocsti(struct tty_struct *tt
ab30d09f
AM
1432 char ch, mbz = 0;
1433 struct tty_ldisc *ld;
1434
1435- if ((current->signal->tty != tty) && !capable(CAP_SYS_ADMIN))
1436+ if (((current->signal->tty != tty) &&
1437+ !vx_capable(CAP_SYS_ADMIN, VXC_TIOCSTI)))
1438 return -EPERM;
1439 if (get_user(ch, p))
1440 return -EFAULT;
3261cfd5 1441@@ -2634,6 +2636,7 @@ static int tiocspgrp(struct tty_struct *
ab30d09f
AM
1442 return -ENOTTY;
1443 if (get_user(pgrp_nr, p))
1444 return -EFAULT;
1445+ pgrp_nr = vx_rmap_pid(pgrp_nr);
1446 if (pgrp_nr < 0)
1447 return -EINVAL;
1448 rcu_read_lock();
3261cfd5
AM
1449diff -NurpP --minimal linux-4.9.207/fs/attr.c linux-4.9.207-vs2.3.9.11/fs/attr.c
1450--- linux-4.9.207/fs/attr.c 2016-12-11 19:17:54.000000000 +0000
1451+++ linux-4.9.207-vs2.3.9.11/fs/attr.c 2018-10-20 04:58:13.000000000 +0000
537831f9 1452@@ -15,6 +15,9 @@
d337f35e 1453 #include <linux/security.h>
f6c5ef8b 1454 #include <linux/evm.h>
537831f9 1455 #include <linux/ima.h>
d337f35e
JR
1456+#include <linux/proc_fs.h>
1457+#include <linux/devpts_fs.h>
2380c486 1458+#include <linux/vs_tag.h>
d337f35e 1459
93de0823 1460 /**
cc23e853
AM
1461 * setattr_prepare - check if attribute changes to a dentry are allowed
1462@@ -90,6 +93,10 @@ kill_priv:
1463 return error;
d337f35e 1464 }
93de0823
AM
1465
1466+ /* check for inode tag permission */
2380c486 1467+ if (dx_permission(inode, MAY_WRITE))
93de0823 1468+ return -EACCES;
2380c486 1469+
93de0823
AM
1470 return 0;
1471 }
cc23e853
AM
1472 EXPORT_SYMBOL(setattr_prepare);
1473@@ -160,6 +167,8 @@ void setattr_copy(struct inode *inode, c
d337f35e
JR
1474 inode->i_uid = attr->ia_uid;
1475 if (ia_valid & ATTR_GID)
1476 inode->i_gid = attr->ia_gid;
1477+ if ((ia_valid & ATTR_TAG) && IS_TAGGED(inode))
1478+ inode->i_tag = attr->ia_tag;
1479 if (ia_valid & ATTR_ATIME)
1480 inode->i_atime = timespec_trunc(attr->ia_atime,
1481 inode->i_sb->s_time_gran);
cc23e853 1482@@ -210,7 +219,8 @@ int notify_change(struct dentry * dentry
92598135 1483
cc23e853 1484 WARN_ON_ONCE(!inode_is_locked(inode));
78865d5b
AM
1485
1486- if (ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID | ATTR_TIMES_SET)) {
1487+ if (ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID |
1488+ ATTR_TAG | ATTR_TIMES_SET)) {
1489 if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
1490 return -EPERM;
1491 }
3261cfd5
AM
1492diff -NurpP --minimal linux-4.9.207/fs/block_dev.c linux-4.9.207-vs2.3.9.11/fs/block_dev.c
1493--- linux-4.9.207/fs/block_dev.c 2019-12-25 15:28:35.697342685 +0000
1494+++ linux-4.9.207-vs2.3.9.11/fs/block_dev.c 2019-02-22 08:37:54.463070814 +0000
cc23e853
AM
1495@@ -31,6 +31,7 @@
1496 #include <linux/dax.h>
1497 #include <linux/badblocks.h>
1498 #include <linux/falloc.h>
2380c486
JR
1499+#include <linux/vs_device.h>
1500 #include <asm/uaccess.h>
1501 #include "internal.h"
1502
3261cfd5 1503@@ -734,6 +735,7 @@ struct block_device *bdget(dev_t dev)
2380c486
JR
1504 bdev->bd_invalidated = 0;
1505 inode->i_mode = S_IFBLK;
1506 inode->i_rdev = dev;
1507+ inode->i_mdev = dev;
1508 inode->i_bdev = bdev;
1509 inode->i_data.a_ops = &def_blk_aops;
1510 mapping_set_gfp_mask(&inode->i_data, GFP_USER);
3261cfd5 1511@@ -780,6 +782,11 @@ EXPORT_SYMBOL(bdput);
2380c486
JR
1512 static struct block_device *bd_acquire(struct inode *inode)
1513 {
1514 struct block_device *bdev;
1515+ dev_t mdev;
1516+
1517+ if (!vs_map_blkdev(inode->i_rdev, &mdev, DATTR_OPEN))
1518+ return NULL;
1519+ inode->i_mdev = mdev;
1520
1521 spin_lock(&bdev_lock);
1522 bdev = inode->i_bdev;
3261cfd5 1523@@ -790,7 +797,7 @@ static struct block_device *bd_acquire(s
2380c486
JR
1524 }
1525 spin_unlock(&bdev_lock);
1526
1527- bdev = bdget(inode->i_rdev);
1528+ bdev = bdget(mdev);
1529 if (bdev) {
1530 spin_lock(&bdev_lock);
1531 if (!inode->i_bdev) {
3261cfd5
AM
1532diff -NurpP --minimal linux-4.9.207/fs/btrfs/ctree.h linux-4.9.207-vs2.3.9.11/fs/btrfs/ctree.h
1533--- linux-4.9.207/fs/btrfs/ctree.h 2019-12-25 15:28:35.767341551 +0000
1534+++ linux-4.9.207-vs2.3.9.11/fs/btrfs/ctree.h 2019-02-22 08:37:54.473070642 +0000
cc23e853 1535@@ -1321,6 +1321,8 @@ static inline u32 BTRFS_MAX_XATTR_SIZE(c
c2e5f7c8 1536 #define BTRFS_DEFAULT_COMMIT_INTERVAL (30)
cc23e853 1537 #define BTRFS_DEFAULT_MAX_INLINE (2048)
e22b5178
AM
1538
1539+#define BTRFS_MOUNT_TAGGED (1 << 24)
1540+
1541 #define btrfs_clear_opt(o, opt) ((o) &= ~BTRFS_MOUNT_##opt)
1542 #define btrfs_set_opt(o, opt) ((o) |= BTRFS_MOUNT_##opt)
b00e13aa 1543 #define btrfs_raw_test_opt(o, opt) ((o) & BTRFS_MOUNT_##opt)
3261cfd5 1544@@ -1671,6 +1673,7 @@ BTRFS_SETGET_FUNCS(inode_block_group, st
e22b5178
AM
1545 BTRFS_SETGET_FUNCS(inode_nlink, struct btrfs_inode_item, nlink, 32);
1546 BTRFS_SETGET_FUNCS(inode_uid, struct btrfs_inode_item, uid, 32);
1547 BTRFS_SETGET_FUNCS(inode_gid, struct btrfs_inode_item, gid, 32);
1548+BTRFS_SETGET_FUNCS(inode_tag, struct btrfs_inode_item, tag, 16);
1549 BTRFS_SETGET_FUNCS(inode_mode, struct btrfs_inode_item, mode, 32);
1550 BTRFS_SETGET_FUNCS(inode_rdev, struct btrfs_inode_item, rdev, 64);
1551 BTRFS_SETGET_FUNCS(inode_flags, struct btrfs_inode_item, flags, 64);
3261cfd5 1552@@ -1718,6 +1721,10 @@ BTRFS_SETGET_FUNCS(extent_flags, struct
78865d5b
AM
1553
1554 BTRFS_SETGET_FUNCS(extent_refs_v0, struct btrfs_extent_item_v0, refs, 32);
1555
1556+#define BTRFS_INODE_IXUNLINK (1 << 24)
1557+#define BTRFS_INODE_BARRIER (1 << 25)
1558+#define BTRFS_INODE_COW (1 << 26)
1559+
1560
1561 BTRFS_SETGET_FUNCS(tree_block_level, struct btrfs_tree_block_info, level, 8);
1562
3261cfd5 1563@@ -3201,6 +3208,7 @@ int btrfs_ioctl_get_supported_features(v
d4263eb0
JR
1564 void btrfs_update_iflags(struct inode *inode);
1565 void btrfs_inherit_iflags(struct inode *inode, struct inode *dir);
c2e5f7c8 1566 int btrfs_is_empty_uuid(u8 *uuid);
d4263eb0 1567+int btrfs_sync_flags(struct inode *inode, int, int);
763640ca
JR
1568 int btrfs_defrag_file(struct inode *inode, struct file *file,
1569 struct btrfs_ioctl_defrag_range_args *range,
1570 u64 newer_than, unsigned long max_pages);
3261cfd5
AM
1571diff -NurpP --minimal linux-4.9.207/fs/btrfs/disk-io.c linux-4.9.207-vs2.3.9.11/fs/btrfs/disk-io.c
1572--- linux-4.9.207/fs/btrfs/disk-io.c 2019-12-25 15:28:35.787341229 +0000
1573+++ linux-4.9.207-vs2.3.9.11/fs/btrfs/disk-io.c 2019-02-22 08:37:54.473070642 +0000
1574@@ -2706,6 +2706,9 @@ int open_ctree(struct super_block *sb,
763640ca 1575 goto fail_alloc;
e22b5178
AM
1576 }
1577
cc23e853 1578+ if (btrfs_test_opt(fs_info, TAGGED))
e22b5178
AM
1579+ sb->s_flags |= MS_TAGGED;
1580+
1581 features = btrfs_super_incompat_flags(disk_super) &
1582 ~BTRFS_FEATURE_INCOMPAT_SUPP;
1583 if (features) {
3261cfd5
AM
1584diff -NurpP --minimal linux-4.9.207/fs/btrfs/inode.c linux-4.9.207-vs2.3.9.11/fs/btrfs/inode.c
1585--- linux-4.9.207/fs/btrfs/inode.c 2019-12-25 15:28:35.847340258 +0000
1586+++ linux-4.9.207-vs2.3.9.11/fs/btrfs/inode.c 2019-12-25 15:37:51.118443417 +0000
c2e5f7c8 1587@@ -43,6 +43,7 @@
b00e13aa 1588 #include <linux/blkdev.h>
c2e5f7c8 1589 #include <linux/posix_acl_xattr.h>
cc23e853 1590 #include <linux/uio.h>
e22b5178 1591+#include <linux/vs_tag.h>
e22b5178
AM
1592 #include "ctree.h"
1593 #include "disk-io.h"
c2e5f7c8 1594 #include "transaction.h"
09a55596 1595@@ -3701,6 +3702,9 @@ static int btrfs_read_locked_inode(struc
bb20add7 1596 unsigned long ptr;
e22b5178 1597 int maybe_acls;
e22b5178 1598 u32 rdev;
a4a22af8
AM
1599+ kuid_t kuid;
1600+ kgid_t kgid;
1601+ ktag_t ktag;
e22b5178 1602 int ret;
763640ca 1603 bool filled = false;
bb20add7 1604 int first_xattr_slot;
09a55596 1605@@ -3733,8 +3737,14 @@ static int btrfs_read_locked_inode(struc
a168f21d 1606 struct btrfs_inode_item);
e22b5178 1607 inode->i_mode = btrfs_inode_mode(leaf, inode_item);
f6c5ef8b 1608 set_nlink(inode, btrfs_inode_nlink(leaf, inode_item));
537831f9
AM
1609- i_uid_write(inode, btrfs_inode_uid(leaf, inode_item));
1610- i_gid_write(inode, btrfs_inode_gid(leaf, inode_item));
e22b5178 1611+
a4a22af8
AM
1612+ kuid = make_kuid(&init_user_ns, btrfs_inode_uid(leaf, inode_item));
1613+ kgid = make_kgid(&init_user_ns, btrfs_inode_gid(leaf, inode_item));
1614+ ktag = make_ktag(&init_user_ns, btrfs_inode_tag(leaf, inode_item));
1615+
1616+ inode->i_uid = INOTAG_KUID(DX_TAG(inode), kuid, kgid);
1617+ inode->i_gid = INOTAG_KGID(DX_TAG(inode), kuid, kgid);
1618+ inode->i_tag = INOTAG_KTAG(DX_TAG(inode), kuid, kgid, ktag);
e22b5178
AM
1619 btrfs_i_size_write(inode, btrfs_inode_size(leaf, inode_item));
1620
cc23e853 1621 inode->i_atime.tv_sec = btrfs_timespec_sec(leaf, &inode_item->atime);
09a55596 1622@@ -3889,11 +3899,18 @@ static void fill_inode_item(struct btrfs
e22b5178
AM
1623 struct inode *inode)
1624 {
b00e13aa 1625 struct btrfs_map_token token;
a4a22af8
AM
1626+ uid_t uid = from_kuid(&init_user_ns,
1627+ TAGINO_KUID(DX_TAG(inode), inode->i_uid, inode->i_tag));
1628+ gid_t gid = from_kgid(&init_user_ns,
1629+ TAGINO_KGID(DX_TAG(inode), inode->i_gid, inode->i_tag));
b00e13aa
AM
1630
1631 btrfs_init_map_token(&token);
1632
1633- btrfs_set_token_inode_uid(leaf, item, i_uid_read(inode), &token);
1634- btrfs_set_token_inode_gid(leaf, item, i_gid_read(inode), &token);
1635+ btrfs_set_token_inode_uid(leaf, item, uid, &token);
1636+ btrfs_set_token_inode_gid(leaf, item, gid, &token);
e22b5178 1637+#ifdef CONFIG_TAGGING_INTERN
b00e13aa 1638+ btrfs_set_token_inode_tag(leaf, item, i_tag_read(inode), &token);
e22b5178 1639+#endif
b00e13aa
AM
1640 btrfs_set_token_inode_size(leaf, item, BTRFS_I(inode)->disk_i_size,
1641 &token);
1642 btrfs_set_token_inode_mode(leaf, item, inode->i_mode, &token);
3261cfd5 1643@@ -10649,6 +10666,7 @@ static const struct inode_operations btr
cc23e853 1644 .mknod = btrfs_mknod,
d4263eb0 1645 .listxattr = btrfs_listxattr,
d4263eb0
JR
1646 .permission = btrfs_permission,
1647+ .sync_flags = btrfs_sync_flags,
a168f21d 1648 .get_acl = btrfs_get_acl,
f15949f2 1649 .set_acl = btrfs_set_acl,
c2e5f7c8 1650 .update_time = btrfs_update_time,
3261cfd5 1651@@ -10657,6 +10675,7 @@ static const struct inode_operations btr
7e46296a 1652 static const struct inode_operations btrfs_dir_ro_inode_operations = {
d4263eb0 1653 .lookup = btrfs_lookup,
d4263eb0 1654 .permission = btrfs_permission,
d4263eb0 1655+ .sync_flags = btrfs_sync_flags,
c2e5f7c8 1656 .update_time = btrfs_update_time,
cc23e853
AM
1657 };
1658
3261cfd5 1659@@ -10722,6 +10741,7 @@ static const struct inode_operations btr
cc23e853 1660 .listxattr = btrfs_listxattr,
c2e5f7c8
JR
1661 .permission = btrfs_permission,
1662 .fiemap = btrfs_fiemap,
1663+ .sync_flags = btrfs_sync_flags,
1664 .get_acl = btrfs_get_acl,
bb20add7 1665 .set_acl = btrfs_set_acl,
c2e5f7c8 1666 .update_time = btrfs_update_time,
3261cfd5
AM
1667diff -NurpP --minimal linux-4.9.207/fs/btrfs/ioctl.c linux-4.9.207-vs2.3.9.11/fs/btrfs/ioctl.c
1668--- linux-4.9.207/fs/btrfs/ioctl.c 2019-12-25 15:28:35.847340258 +0000
1669+++ linux-4.9.207-vs2.3.9.11/fs/btrfs/ioctl.c 2019-10-05 14:58:45.120316346 +0000
cc23e853 1670@@ -110,10 +110,13 @@ static unsigned int btrfs_flags_to_ioctl
d4263eb0
JR
1671 {
1672 unsigned int iflags = 0;
1673
1674- if (flags & BTRFS_INODE_SYNC)
1675- iflags |= FS_SYNC_FL;
1676 if (flags & BTRFS_INODE_IMMUTABLE)
1677 iflags |= FS_IMMUTABLE_FL;
1678+ if (flags & BTRFS_INODE_IXUNLINK)
1679+ iflags |= FS_IXUNLINK_FL;
1680+
1681+ if (flags & BTRFS_INODE_SYNC)
1682+ iflags |= FS_SYNC_FL;
1683 if (flags & BTRFS_INODE_APPEND)
1684 iflags |= FS_APPEND_FL;
1685 if (flags & BTRFS_INODE_NODUMP)
cc23e853
AM
1686@@ -130,34 +133,84 @@ static unsigned int btrfs_flags_to_ioctl
1687 else if (flags & BTRFS_INODE_COMPRESS)
1688 iflags |= FS_COMPR_FL;
d4263eb0
JR
1689
1690+ if (flags & BTRFS_INODE_BARRIER)
1691+ iflags |= FS_BARRIER_FL;
1692+ if (flags & BTRFS_INODE_COW)
1693+ iflags |= FS_COW_FL;
1694 return iflags;
1695 }
1696
1697 /*
1698- * Update inode->i_flags based on the btrfs internal flags.
1699+ * Update inode->i_(v)flags based on the btrfs internal flags.
1700 */
1701 void btrfs_update_iflags(struct inode *inode)
1702 {
1703 struct btrfs_inode *ip = BTRFS_I(inode);
bb20add7 1704 unsigned int new_fl = 0;
d4263eb0
JR
1705
1706- if (ip->flags & BTRFS_INODE_SYNC)
bb20add7 1707- new_fl |= S_SYNC;
d4263eb0 1708 if (ip->flags & BTRFS_INODE_IMMUTABLE)
bb20add7 1709 new_fl |= S_IMMUTABLE;
d4263eb0 1710+ if (ip->flags & BTRFS_INODE_IXUNLINK)
bb20add7 1711+ new_fl |= S_IXUNLINK;
d4263eb0
JR
1712+
1713+ if (ip->flags & BTRFS_INODE_SYNC)
bb20add7 1714+ new_fl |= S_SYNC;
d4263eb0 1715 if (ip->flags & BTRFS_INODE_APPEND)
bb20add7 1716 new_fl |= S_APPEND;
d4263eb0 1717 if (ip->flags & BTRFS_INODE_NOATIME)
bb20add7 1718 new_fl |= S_NOATIME;
d4263eb0 1719 if (ip->flags & BTRFS_INODE_DIRSYNC)
bb20add7
AM
1720 new_fl |= S_DIRSYNC;
1721-
1722 set_mask_bits(&inode->i_flags,
1723- S_SYNC | S_APPEND | S_IMMUTABLE | S_NOATIME | S_DIRSYNC,
1724+ S_SYNC | S_APPEND | S_IMMUTABLE | S_IXUNLINK | S_NOATIME | S_DIRSYNC,
1725 new_fl);
d4263eb0 1726+
bb20add7 1727+ new_fl = 0;
d4263eb0 1728+ if (ip->flags & BTRFS_INODE_BARRIER)
bb20add7 1729+ new_fl |= V_BARRIER;
d4263eb0 1730+ if (ip->flags & BTRFS_INODE_COW)
bb20add7 1731+ new_fl |= V_COW;
d4263eb0 1732+
bb20add7
AM
1733+ set_mask_bits(&inode->i_vflags,
1734+ V_BARRIER | V_COW, new_fl);
1735 }
1736
1737 /*
d4263eb0
JR
1738+ * Update btrfs internal flags from inode->i_(v)flags.
1739+ */
1740+void btrfs_update_flags(struct inode *inode)
1741+{
1742+ struct btrfs_inode *ip = BTRFS_I(inode);
1743+
1744+ unsigned int flags = inode->i_flags;
1745+ unsigned int vflags = inode->i_vflags;
1746+
1747+ ip->flags &= ~(BTRFS_INODE_SYNC | BTRFS_INODE_APPEND |
1748+ BTRFS_INODE_IMMUTABLE | BTRFS_INODE_IXUNLINK |
1749+ BTRFS_INODE_NOATIME | BTRFS_INODE_DIRSYNC |
1750+ BTRFS_INODE_BARRIER | BTRFS_INODE_COW);
1751+
1752+ if (flags & S_IMMUTABLE)
1753+ ip->flags |= BTRFS_INODE_IMMUTABLE;
1754+ if (flags & S_IXUNLINK)
1755+ ip->flags |= BTRFS_INODE_IXUNLINK;
1756+
1757+ if (flags & S_SYNC)
1758+ ip->flags |= BTRFS_INODE_SYNC;
1759+ if (flags & S_APPEND)
1760+ ip->flags |= BTRFS_INODE_APPEND;
1761+ if (flags & S_NOATIME)
1762+ ip->flags |= BTRFS_INODE_NOATIME;
1763+ if (flags & S_DIRSYNC)
1764+ ip->flags |= BTRFS_INODE_DIRSYNC;
1765+
1766+ if (vflags & V_BARRIER)
1767+ ip->flags |= BTRFS_INODE_BARRIER;
1768+ if (vflags & V_COW)
1769+ ip->flags |= BTRFS_INODE_COW;
bb20add7
AM
1770+ }
1771+
1772+/*
1773 * Inherit flags from the parent inode.
1774 *
1775 * Currently only the compression flags and the cow flags are inherited.
cc23e853 1776@@ -170,6 +223,7 @@ void btrfs_inherit_iflags(struct inode *
f6c5ef8b 1777 return;
d4263eb0 1778
f6c5ef8b
AM
1779 flags = BTRFS_I(dir)->flags;
1780+ flags &= ~BTRFS_INODE_BARRIER;
d4263eb0 1781
f6c5ef8b
AM
1782 if (flags & BTRFS_INODE_NOCOMPRESS) {
1783 BTRFS_I(inode)->flags &= ~BTRFS_INODE_COMPRESS;
cc23e853 1784@@ -188,6 +242,30 @@ void btrfs_inherit_iflags(struct inode *
d4263eb0
JR
1785 btrfs_update_iflags(inode);
1786 }
1787
1788+int btrfs_sync_flags(struct inode *inode, int flags, int vflags)
1789+{
1790+ struct btrfs_inode *ip = BTRFS_I(inode);
1791+ struct btrfs_root *root = ip->root;
1792+ struct btrfs_trans_handle *trans;
1793+ int ret;
1794+
763640ca 1795+ trans = btrfs_join_transaction(root);
d4263eb0
JR
1796+ BUG_ON(!trans);
1797+
d4263eb0
JR
1798+ inode->i_flags = flags;
1799+ inode->i_vflags = vflags;
1800+ btrfs_update_flags(inode);
e22b5178
AM
1801+
1802+ ret = btrfs_update_inode(trans, root, inode);
1803+ BUG_ON(ret);
1804+
1805+ btrfs_update_iflags(inode);
d4263eb0
JR
1806+ inode->i_ctime = CURRENT_TIME;
1807+ btrfs_end_transaction(trans, root);
1808+
1809+ return 0;
1810+}
1811+
1812 static int btrfs_ioctl_getflags(struct file *file, void __user *arg)
1813 {
b00e13aa 1814 struct btrfs_inode *ip = BTRFS_I(file_inode(file));
cc23e853 1815@@ -250,21 +328,27 @@ static int btrfs_ioctl_setflags(struct f
d4263eb0
JR
1816
1817 flags = btrfs_mask_flags(inode->i_mode, flags);
1818 oldflags = btrfs_flags_to_ioctl(ip->flags);
1819- if ((flags ^ oldflags) & (FS_APPEND_FL | FS_IMMUTABLE_FL)) {
1820+ if ((flags ^ oldflags) & (FS_APPEND_FL |
1821+ FS_IMMUTABLE_FL | FS_IXUNLINK_FL)) {
1822 if (!capable(CAP_LINUX_IMMUTABLE)) {
1823 ret = -EPERM;
1824 goto out_unlock;
92598135
AM
1825 }
1826 }
d4263eb0
JR
1827
1828- if (flags & FS_SYNC_FL)
1829- ip->flags |= BTRFS_INODE_SYNC;
1830- else
1831- ip->flags &= ~BTRFS_INODE_SYNC;
1832 if (flags & FS_IMMUTABLE_FL)
1833 ip->flags |= BTRFS_INODE_IMMUTABLE;
1834 else
1835 ip->flags &= ~BTRFS_INODE_IMMUTABLE;
1836+ if (flags & FS_IXUNLINK_FL)
1837+ ip->flags |= BTRFS_INODE_IXUNLINK;
1838+ else
1839+ ip->flags &= ~BTRFS_INODE_IXUNLINK;
1840+
1841+ if (flags & FS_SYNC_FL)
1842+ ip->flags |= BTRFS_INODE_SYNC;
1843+ else
1844+ ip->flags &= ~BTRFS_INODE_SYNC;
1845 if (flags & FS_APPEND_FL)
1846 ip->flags |= BTRFS_INODE_APPEND;
1847 else
3261cfd5
AM
1848diff -NurpP --minimal linux-4.9.207/fs/btrfs/super.c linux-4.9.207-vs2.3.9.11/fs/btrfs/super.c
1849--- linux-4.9.207/fs/btrfs/super.c 2019-12-25 15:28:35.857340098 +0000
1850+++ linux-4.9.207-vs2.3.9.11/fs/btrfs/super.c 2019-02-22 08:37:54.503070133 +0000
cc23e853
AM
1851@@ -327,7 +327,7 @@ enum {
1852 #ifdef CONFIG_BTRFS_DEBUG
1853 Opt_fragment_data, Opt_fragment_metadata, Opt_fragment_all,
1854 #endif
db55b927 1855- Opt_err,
f6c5ef8b 1856+ Opt_tag, Opt_notag, Opt_tagid, Opt_err,
e22b5178
AM
1857 };
1858
cc23e853
AM
1859 static const match_table_t tokens = {
1860@@ -388,6 +388,9 @@ static const match_table_t tokens = {
1861 {Opt_fragment_metadata, "fragment=metadata"},
1862 {Opt_fragment_all, "fragment=all"},
1863 #endif
e22b5178
AM
1864+ {Opt_tag, "tag"},
1865+ {Opt_notag, "notag"},
1866+ {Opt_tagid, "tagid=%u"},
1867 {Opt_err, NULL},
1868 };
1869
cc23e853
AM
1870@@ -833,6 +836,22 @@ int btrfs_parse_options(struct btrfs_roo
1871 btrfs_set_opt(info->mount_opt, FRAGMENT_DATA);
1e8b8f9b 1872 break;
cc23e853 1873 #endif
e22b5178
AM
1874+#ifndef CONFIG_TAGGING_NONE
1875+ case Opt_tag:
1876+ printk(KERN_INFO "btrfs: use tagging\n");
1877+ btrfs_set_opt(info->mount_opt, TAGGED);
1878+ break;
1879+ case Opt_notag:
1880+ printk(KERN_INFO "btrfs: disabled tagging\n");
1881+ btrfs_clear_opt(info->mount_opt, TAGGED);
1882+ break;
1883+#endif
1884+#ifdef CONFIG_PROPAGATE
1885+ case Opt_tagid:
1886+ /* use args[0] */
1887+ btrfs_set_opt(info->mount_opt, TAGGED);
1888+ break;
1889+#endif
2bf5ad28 1890 case Opt_err:
cc23e853
AM
1891 btrfs_info(root->fs_info,
1892 "unrecognized mount option '%s'", p);
1893@@ -1754,6 +1773,12 @@ static int btrfs_remount(struct super_bl
42bc425c
AM
1894 btrfs_resize_thread_pool(fs_info,
1895 fs_info->thread_pool_size, old_thread_pool_size);
e22b5178 1896
cc23e853 1897+ if (btrfs_test_opt(fs_info, TAGGED) && !(sb->s_flags & MS_TAGGED)) {
e22b5178
AM
1898+ printk("btrfs: %s: tagging not permitted on remount.\n",
1899+ sb->s_id);
1900+ return -EINVAL;
1901+ }
1902+
1903 if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY))
b00e13aa 1904 goto out;
e22b5178 1905
3261cfd5
AM
1906diff -NurpP --minimal linux-4.9.207/fs/char_dev.c linux-4.9.207-vs2.3.9.11/fs/char_dev.c
1907--- linux-4.9.207/fs/char_dev.c 2019-12-25 15:28:36.037337186 +0000
1908+++ linux-4.9.207-vs2.3.9.11/fs/char_dev.c 2019-10-05 14:58:45.140316026 +0000
4744a4b1 1909@@ -21,6 +21,8 @@
2380c486
JR
1910 #include <linux/mutex.h>
1911 #include <linux/backing-dev.h>
7942c842 1912 #include <linux/tty.h>
2380c486
JR
1913+#include <linux/vs_context.h>
1914+#include <linux/vs_device.h>
1915
ec22aa5c
AM
1916 #include "internal.h"
1917
3261cfd5 1918@@ -360,14 +362,21 @@ static int chrdev_open(struct inode *ino
2380c486
JR
1919 struct cdev *p;
1920 struct cdev *new = NULL;
1921 int ret = 0;
1922+ dev_t mdev;
1923+
1924+ if (!vs_map_chrdev(inode->i_rdev, &mdev, DATTR_OPEN))
1925+ return -EPERM;
1926+ inode->i_mdev = mdev;
1927
1928 spin_lock(&cdev_lock);
1929 p = inode->i_cdev;
1930 if (!p) {
1931 struct kobject *kobj;
1932 int idx;
1933+
1934 spin_unlock(&cdev_lock);
1935- kobj = kobj_lookup(cdev_map, inode->i_rdev, &idx);
1936+
1937+ kobj = kobj_lookup(cdev_map, mdev, &idx);
1938 if (!kobj)
1939 return -ENXIO;
1940 new = container_of(kobj, struct cdev, kobj);
3261cfd5
AM
1941diff -NurpP --minimal linux-4.9.207/fs/dcache.c linux-4.9.207-vs2.3.9.11/fs/dcache.c
1942--- linux-4.9.207/fs/dcache.c 2019-12-25 15:28:36.257333629 +0000
1943+++ linux-4.9.207-vs2.3.9.11/fs/dcache.c 2019-10-05 14:58:45.150315864 +0000
cc23e853 1944@@ -39,6 +39,7 @@
f6c5ef8b 1945 #include <linux/ratelimit.h>
c2e5f7c8 1946 #include <linux/list_lru.h>
cc23e853 1947 #include <linux/kasan.h>
d337f35e 1948+#include <linux/vs_limit.h>
cc23e853 1949
d337f35e 1950 #include "internal.h"
db55b927 1951 #include "mount.h"
09a55596 1952@@ -690,6 +691,7 @@ static inline bool fast_dput(struct dent
cc23e853
AM
1953 spin_lock(&dentry->d_lock);
1954 if (dentry->d_lockref.count > 1) {
1955 dentry->d_lockref.count--;
1956+ vx_dentry_dec(dentry);
1957 spin_unlock(&dentry->d_lock);
1958 return 1;
1959 }
09a55596 1960@@ -821,6 +823,7 @@ repeat:
cc23e853 1961 dentry_lru_add(dentry);
d337f35e 1962
cc23e853
AM
1963 dentry->d_lockref.count--;
1964+ vx_dentry_dec(dentry);
1965 spin_unlock(&dentry->d_lock);
1966 return;
1967
09a55596 1968@@ -838,6 +841,7 @@ EXPORT_SYMBOL(dput);
d33d7b00 1969 static inline void __dget_dlock(struct dentry *dentry)
2380c486 1970 {
c2e5f7c8 1971 dentry->d_lockref.count++;
2380c486 1972+ vx_dentry_inc(dentry);
d337f35e 1973 }
2380c486 1974
d33d7b00 1975 static inline void __dget(struct dentry *dentry)
09a55596 1976@@ -850,6 +854,8 @@ struct dentry *dget_parent(struct dentry
bb20add7
AM
1977 int gotref;
1978 struct dentry *ret;
1979
1980+ vx_dentry_dec(dentry);
1981+
1982 /*
1983 * Do optimistic parent lookup without any
1984 * locking.
09a55596 1985@@ -880,6 +886,7 @@ repeat:
cc23e853
AM
1986 rcu_read_unlock();
1987 BUG_ON(!ret->d_lockref.count);
1988 ret->d_lockref.count++;
1989+ vx_dentry_inc(ret);
1990 spin_unlock(&ret->d_lock);
1991 return ret;
1992 }
09a55596 1993@@ -1034,6 +1041,7 @@ static void shrink_dentry_list(struct li
cc23e853
AM
1994 parent = lock_parent(dentry);
1995 if (dentry->d_lockref.count != 1) {
1996 dentry->d_lockref.count--;
1997+ vx_dentry_dec(dentry);
1998 spin_unlock(&dentry->d_lock);
1999 if (parent)
2000 spin_unlock(&parent->d_lock);
3261cfd5 2001@@ -1594,6 +1602,9 @@ struct dentry *__d_alloc(struct super_bl
d337f35e 2002 char *dname;
cc23e853 2003 int err;
d337f35e
JR
2004
2005+ if (!vx_dentry_avail(1))
2006+ return NULL;
2007+
2380c486 2008 dentry = kmem_cache_alloc(dentry_cache, GFP_KERNEL);
d337f35e
JR
2009 if (!dentry)
2010 return NULL;
3261cfd5 2011@@ -1637,6 +1648,7 @@ struct dentry *__d_alloc(struct super_bl
d337f35e 2012
c2e5f7c8 2013 dentry->d_lockref.count = 1;
763640ca 2014 dentry->d_flags = 0;
ab30d09f 2015+ vx_dentry_inc(dentry);
ab30d09f 2016 spin_lock_init(&dentry->d_lock);
d33d7b00 2017 seqcount_init(&dentry->d_seq);
763640ca 2018 dentry->d_inode = NULL;
3261cfd5 2019@@ -2310,6 +2322,7 @@ struct dentry *__d_lookup(const struct d
cc23e853 2020 goto next;
2380c486 2021
c2e5f7c8 2022 dentry->d_lockref.count++;
2380c486
JR
2023+ vx_dentry_inc(dentry);
2024 found = dentry;
d337f35e 2025 spin_unlock(&dentry->d_lock);
2380c486 2026 break;
3261cfd5 2027@@ -3568,6 +3581,7 @@ static enum d_walk_ret d_genocide_kill(v
cc23e853
AM
2028 if (!(dentry->d_flags & DCACHE_GENOCIDE)) {
2029 dentry->d_flags |= DCACHE_GENOCIDE;
2030 dentry->d_lockref.count--;
2031+ vx_dentry_dec(dentry);
2032 }
2033 }
2034 return D_WALK_CONTINUE;
3261cfd5
AM
2035diff -NurpP --minimal linux-4.9.207/fs/devpts/inode.c linux-4.9.207-vs2.3.9.11/fs/devpts/inode.c
2036--- linux-4.9.207/fs/devpts/inode.c 2019-12-25 15:28:36.287333144 +0000
2037+++ linux-4.9.207-vs2.3.9.11/fs/devpts/inode.c 2019-10-05 14:58:45.150315864 +0000
bb20add7 2038@@ -27,6 +27,7 @@
d337f35e 2039 #include <linux/parser.h>
2380c486
JR
2040 #include <linux/fsnotify.h>
2041 #include <linux/seq_file.h>
d337f35e
JR
2042+#include <linux/vs_base.h>
2043
2380c486 2044 #define DEVPTS_DEFAULT_MODE 0600
ec22aa5c 2045 /*
bb20add7 2046@@ -38,6 +39,21 @@
ec22aa5c
AM
2047 #define DEVPTS_DEFAULT_PTMX_MODE 0000
2048 #define PTMX_MINOR 2
2380c486 2049
a168f21d 2050+static int devpts_permission(struct inode *inode, int mask)
d337f35e
JR
2051+{
2052+ int ret = -EACCES;
2053+
2054+ /* devpts is xid tagged */
61333608 2055+ if (vx_check((vxid_t)i_tag_read(inode), VS_WATCH_P | VS_IDENT))
a168f21d 2056+ ret = generic_permission(inode, mask);
d337f35e
JR
2057+ return ret;
2058+}
2059+
2060+static struct inode_operations devpts_file_inode_operations = {
2061+ .permission = devpts_permission,
2062+};
2380c486 2063+
1e8b8f9b
AM
2064+
2065 /*
2066 * sysctl support for setting limits on the number of Unix98 ptys allocated.
2067 * Otherwise one can eat up all kernel memory by opening /dev/ptmx repeatedly.
cc23e853 2068@@ -363,6 +379,34 @@ static int devpts_show_options(struct se
d337f35e
JR
2069 return 0;
2070 }
2071
2072+static int devpts_filter(struct dentry *de)
2073+{
61333608 2074+ vxid_t xid = 0;
b3b0d4fd 2075+
d337f35e 2076+ /* devpts is xid tagged */
b3b0d4fd 2077+ if (de && de->d_inode)
61333608 2078+ xid = (vxid_t)i_tag_read(de->d_inode);
b3b0d4fd
AM
2079+#ifdef CONFIG_VSERVER_WARN_DEVPTS
2080+ else
2081+ vxwprintk_task(1, "devpts " VS_Q("%.*s") " without inode.",
2082+ de->d_name.len, de->d_name.name);
2083+#endif
2084+ return vx_check(xid, VS_WATCH_P | VS_IDENT);
d337f35e
JR
2085+}
2086+
c2e5f7c8 2087+static int devpts_readdir(struct file * filp, struct dir_context *ctx)
d337f35e 2088+{
c2e5f7c8 2089+ return dcache_readdir_filter(filp, ctx, devpts_filter);
d337f35e
JR
2090+}
2091+
2092+static struct file_operations devpts_dir_operations = {
2093+ .open = dcache_dir_open,
2094+ .release = dcache_dir_close,
2095+ .llseek = dcache_dir_lseek,
2096+ .read = generic_read_dir,
c2e5f7c8 2097+ .iterate = devpts_readdir,
d337f35e
JR
2098+};
2099+
2380c486 2100 static const struct super_operations devpts_sops = {
d337f35e
JR
2101 .statfs = simple_statfs,
2102 .remount_fs = devpts_remount,
3261cfd5 2103@@ -416,8 +460,10 @@ devpts_fill_super(struct super_block *s,
cc23e853 2104 inode->i_mtime = inode->i_atime = inode->i_ctime = current_time(inode);
d337f35e
JR
2105 inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO | S_IWUSR;
2106 inode->i_op = &simple_dir_inode_operations;
2107- inode->i_fop = &simple_dir_operations;
2108+ inode->i_fop = &devpts_dir_operations;
f6c5ef8b 2109 set_nlink(inode, 2);
d337f35e 2110+ /* devpts is xid tagged */
61333608 2111+ i_tag_write(inode, (vtag_t)vx_current_xid());
d337f35e 2112
1e8b8f9b 2113 s->s_root = d_make_root(inode);
cc23e853 2114 if (!s->s_root) {
3261cfd5 2115@@ -543,6 +589,9 @@ struct dentry *devpts_pty_new(struct pts
ec22aa5c 2116 inode->i_gid = opts->setgid ? opts->gid : current_fsgid();
cc23e853
AM
2117 inode->i_mtime = inode->i_atime = inode->i_ctime = current_time(inode);
2118 init_special_inode(inode, S_IFCHR|opts->mode, MKDEV(UNIX98_PTY_SLAVE_MAJOR, index));
d337f35e 2119+ /* devpts is xid tagged */
61333608 2120+ i_tag_write(inode, (vtag_t)vx_current_xid());
d337f35e 2121+ inode->i_op = &devpts_file_inode_operations;
d337f35e 2122
b00e13aa 2123 sprintf(s, "%d", index);
cc23e853 2124
3261cfd5
AM
2125diff -NurpP --minimal linux-4.9.207/fs/ext2/balloc.c linux-4.9.207-vs2.3.9.11/fs/ext2/balloc.c
2126--- linux-4.9.207/fs/ext2/balloc.c 2016-12-11 19:17:54.000000000 +0000
2127+++ linux-4.9.207-vs2.3.9.11/fs/ext2/balloc.c 2018-10-20 04:58:13.000000000 +0000
b00e13aa 2128@@ -693,7 +693,6 @@ ext2_try_to_allocate(struct super_block
2380c486
JR
2129 start = 0;
2130 end = EXT2_BLOCKS_PER_GROUP(sb);
d337f35e 2131 }
2380c486
JR
2132-
2133 BUG_ON(start > EXT2_BLOCKS_PER_GROUP(sb));
2134
2135 repeat:
3261cfd5
AM
2136diff -NurpP --minimal linux-4.9.207/fs/ext2/ext2.h linux-4.9.207-vs2.3.9.11/fs/ext2/ext2.h
2137--- linux-4.9.207/fs/ext2/ext2.h 2016-12-11 19:17:54.000000000 +0000
2138+++ linux-4.9.207-vs2.3.9.11/fs/ext2/ext2.h 2018-10-20 04:58:13.000000000 +0000
cc23e853 2139@@ -247,8 +247,12 @@ struct ext2_group_desc
1e8b8f9b
AM
2140 #define EXT2_NOTAIL_FL FS_NOTAIL_FL /* file tail should not be merged */
2141 #define EXT2_DIRSYNC_FL FS_DIRSYNC_FL /* dirsync behaviour (directories only) */
2142 #define EXT2_TOPDIR_FL FS_TOPDIR_FL /* Top of directory hierarchies*/
2143+#define EXT2_IXUNLINK_FL FS_IXUNLINK_FL /* Immutable invert on unlink */
2144 #define EXT2_RESERVED_FL FS_RESERVED_FL /* reserved for ext2 lib */
2145
2146+#define EXT2_BARRIER_FL FS_BARRIER_FL /* Barrier for chroot() */
2147+#define EXT2_COW_FL FS_COW_FL /* Copy on Write marker */
2148+
2149 #define EXT2_FL_USER_VISIBLE FS_FL_USER_VISIBLE /* User visible flags */
2150 #define EXT2_FL_USER_MODIFIABLE FS_FL_USER_MODIFIABLE /* User modifiable flags */
2151
cc23e853 2152@@ -332,7 +336,8 @@ struct ext2_inode {
1e8b8f9b
AM
2153 __u16 i_pad1;
2154 __le16 l_i_uid_high; /* these 2 fields */
2155 __le16 l_i_gid_high; /* were reserved2[0] */
2156- __u32 l_i_reserved2;
2157+ __le16 l_i_tag; /* Context Tag */
2158+ __u16 l_i_reserved2;
2159 } linux2;
2160 struct {
2161 __u8 h_i_frag; /* Fragment number */
cc23e853 2162@@ -360,6 +365,7 @@ struct ext2_inode {
1e8b8f9b
AM
2163 #define i_gid_low i_gid
2164 #define i_uid_high osd2.linux2.l_i_uid_high
2165 #define i_gid_high osd2.linux2.l_i_gid_high
2166+#define i_raw_tag osd2.linux2.l_i_tag
2167 #define i_reserved2 osd2.linux2.l_i_reserved2
2168
2169 /*
cc23e853
AM
2170@@ -393,6 +399,7 @@ struct ext2_inode {
2171 #else
2172 #define EXT2_MOUNT_DAX 0
2173 #endif
2174+#define EXT2_MOUNT_TAGGED 0x200000 /* Enable Context Tags */
1e8b8f9b
AM
2175
2176
2177 #define clear_opt(o, opt) o &= ~EXT2_MOUNT_##opt
cc23e853 2178@@ -782,6 +789,7 @@ extern void ext2_set_inode_flags(struct
93de0823
AM
2179 extern void ext2_get_inode_flags(struct ext2_inode_info *);
2180 extern int ext2_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
2181 u64 start, u64 len);
d4263eb0
JR
2182+extern int ext2_sync_flags(struct inode *, int, int);
2183
2184 /* ioctl.c */
2185 extern long ext2_ioctl(struct file *, unsigned int, unsigned long);
3261cfd5
AM
2186diff -NurpP --minimal linux-4.9.207/fs/ext2/file.c linux-4.9.207-vs2.3.9.11/fs/ext2/file.c
2187--- linux-4.9.207/fs/ext2/file.c 2016-12-11 19:17:54.000000000 +0000
2188+++ linux-4.9.207-vs2.3.9.11/fs/ext2/file.c 2018-10-20 04:58:13.000000000 +0000
cc23e853 2189@@ -247,4 +247,5 @@ const struct inode_operations ext2_file_
a168f21d 2190 .get_acl = ext2_get_acl,
bb20add7 2191 .set_acl = ext2_set_acl,
ec22aa5c 2192 .fiemap = ext2_fiemap,
d337f35e
JR
2193+ .sync_flags = ext2_sync_flags,
2194 };
3261cfd5
AM
2195diff -NurpP --minimal linux-4.9.207/fs/ext2/ialloc.c linux-4.9.207-vs2.3.9.11/fs/ext2/ialloc.c
2196--- linux-4.9.207/fs/ext2/ialloc.c 2016-12-11 19:17:54.000000000 +0000
2197+++ linux-4.9.207-vs2.3.9.11/fs/ext2/ialloc.c 2018-10-20 04:58:13.000000000 +0000
e22b5178
AM
2198@@ -17,6 +17,7 @@
2199 #include <linux/backing-dev.h>
2200 #include <linux/buffer_head.h>
2201 #include <linux/random.h>
2202+#include <linux/vs_tag.h>
2203 #include "ext2.h"
2204 #include "xattr.h"
2205 #include "acl.h"
cc23e853 2206@@ -551,6 +552,7 @@ got:
76514441
AM
2207 inode->i_mode = mode;
2208 inode->i_uid = current_fsuid();
2209 inode->i_gid = dir->i_gid;
a4a22af8 2210+ i_tag_write(inode, dx_current_fstag(sb));
e22b5178 2211 } else
76514441 2212 inode_init_owner(inode, dir, mode);
e22b5178 2213
3261cfd5
AM
2214diff -NurpP --minimal linux-4.9.207/fs/ext2/inode.c linux-4.9.207-vs2.3.9.11/fs/ext2/inode.c
2215--- linux-4.9.207/fs/ext2/inode.c 2019-12-25 15:28:36.507329586 +0000
2216+++ linux-4.9.207-vs2.3.9.11/fs/ext2/inode.c 2019-12-25 15:37:51.438438255 +0000
cc23e853
AM
2217@@ -35,6 +35,7 @@
2218 #include <linux/iomap.h>
ec22aa5c 2219 #include <linux/namei.h>
cc23e853 2220 #include <linux/uio.h>
d337f35e
JR
2221+#include <linux/vs_tag.h>
2222 #include "ext2.h"
2223 #include "acl.h"
cc23e853 2224 #include "xattr.h"
3261cfd5 2225@@ -1360,39 +1361,61 @@ void ext2_set_inode_flags(struct inode *
d337f35e
JR
2226 {
2227 unsigned int flags = EXT2_I(inode)->i_flags;
2228
cc23e853
AM
2229- inode->i_flags &= ~(S_SYNC | S_APPEND | S_IMMUTABLE | S_NOATIME |
2230- S_DIRSYNC | S_DAX);
2231+ inode->i_flags &= ~(S_IMMUTABLE | S_IXUNLINK | S_DAX |
d337f35e
JR
2232+ S_SYNC | S_APPEND | S_NOATIME | S_DIRSYNC);
2233+
2234+ if (flags & EXT2_IMMUTABLE_FL)
2235+ inode->i_flags |= S_IMMUTABLE;
2380c486
JR
2236+ if (flags & EXT2_IXUNLINK_FL)
2237+ inode->i_flags |= S_IXUNLINK;
d337f35e
JR
2238 if (flags & EXT2_SYNC_FL)
2239 inode->i_flags |= S_SYNC;
2240 if (flags & EXT2_APPEND_FL)
2241 inode->i_flags |= S_APPEND;
2242- if (flags & EXT2_IMMUTABLE_FL)
2243- inode->i_flags |= S_IMMUTABLE;
2244 if (flags & EXT2_NOATIME_FL)
2245 inode->i_flags |= S_NOATIME;
2246 if (flags & EXT2_DIRSYNC_FL)
2247 inode->i_flags |= S_DIRSYNC;
cc23e853
AM
2248 if (test_opt(inode->i_sb, DAX) && S_ISREG(inode->i_mode))
2249 inode->i_flags |= S_DAX;
2380c486
JR
2250+
2251+ inode->i_vflags &= ~(V_BARRIER | V_COW);
2252+
2253+ if (flags & EXT2_BARRIER_FL)
2254+ inode->i_vflags |= V_BARRIER;
2255+ if (flags & EXT2_COW_FL)
2256+ inode->i_vflags |= V_COW;
2257 }
2258
2259 /* Propagate flags from i_flags to EXT2_I(inode)->i_flags */
2260 void ext2_get_inode_flags(struct ext2_inode_info *ei)
2261 {
2262 unsigned int flags = ei->vfs_inode.i_flags;
2263+ unsigned int vflags = ei->vfs_inode.i_vflags;
2264+
2265+ ei->i_flags &= ~(EXT2_SYNC_FL | EXT2_APPEND_FL |
2266+ EXT2_IMMUTABLE_FL | EXT2_IXUNLINK_FL |
2267+ EXT2_NOATIME_FL | EXT2_DIRSYNC_FL |
2268+ EXT2_BARRIER_FL | EXT2_COW_FL);
2269+
2270+ if (flags & S_IMMUTABLE)
2271+ ei->i_flags |= EXT2_IMMUTABLE_FL;
2272+ if (flags & S_IXUNLINK)
2273+ ei->i_flags |= EXT2_IXUNLINK_FL;
2274
2275- ei->i_flags &= ~(EXT2_SYNC_FL|EXT2_APPEND_FL|
2276- EXT2_IMMUTABLE_FL|EXT2_NOATIME_FL|EXT2_DIRSYNC_FL);
2277 if (flags & S_SYNC)
2278 ei->i_flags |= EXT2_SYNC_FL;
2279 if (flags & S_APPEND)
2280 ei->i_flags |= EXT2_APPEND_FL;
2281- if (flags & S_IMMUTABLE)
2282- ei->i_flags |= EXT2_IMMUTABLE_FL;
2283 if (flags & S_NOATIME)
2284 ei->i_flags |= EXT2_NOATIME_FL;
2285 if (flags & S_DIRSYNC)
2286 ei->i_flags |= EXT2_DIRSYNC_FL;
2287+
2288+ if (vflags & V_BARRIER)
2289+ ei->i_flags |= EXT2_BARRIER_FL;
2290+ if (vflags & V_COW)
2291+ ei->i_flags |= EXT2_COW_FL;
d337f35e
JR
2292 }
2293
2380c486 2294 struct inode *ext2_iget (struct super_block *sb, unsigned long ino)
3261cfd5 2295@@ -1428,8 +1451,10 @@ struct inode *ext2_iget (struct super_bl
42bc425c
AM
2296 i_uid |= le16_to_cpu(raw_inode->i_uid_high) << 16;
2297 i_gid |= le16_to_cpu(raw_inode->i_gid_high) << 16;
d337f35e 2298 }
42bc425c
AM
2299- i_uid_write(inode, i_uid);
2300- i_gid_write(inode, i_gid);
2301+ i_uid_write(inode, INOTAG_UID(DX_TAG(inode), i_uid, i_gid));
2302+ i_gid_write(inode, INOTAG_GID(DX_TAG(inode), i_uid, i_gid));
537831f9
AM
2303+ i_tag_write(inode, INOTAG_TAG(DX_TAG(inode), i_uid, i_gid,
2304+ le16_to_cpu(raw_inode->i_raw_tag)));
f6c5ef8b 2305 set_nlink(inode, le16_to_cpu(raw_inode->i_links_count));
d337f35e 2306 inode->i_size = le32_to_cpu(raw_inode->i_size);
2380c486 2307 inode->i_atime.tv_sec = (signed)le32_to_cpu(raw_inode->i_atime);
3261cfd5 2308@@ -1536,8 +1561,10 @@ static int __ext2_write_inode(struct ino
d337f35e
JR
2309 struct ext2_inode_info *ei = EXT2_I(inode);
2310 struct super_block *sb = inode->i_sb;
2311 ino_t ino = inode->i_ino;
42bc425c
AM
2312- uid_t uid = i_uid_read(inode);
2313- gid_t gid = i_gid_read(inode);
a4a22af8
AM
2314+ uid_t uid = from_kuid(&init_user_ns,
2315+ TAGINO_KUID(DX_TAG(inode), inode->i_uid, inode->i_tag));
2316+ gid_t gid = from_kgid(&init_user_ns,
2317+ TAGINO_KGID(DX_TAG(inode), inode->i_gid, inode->i_tag));
d337f35e
JR
2318 struct buffer_head * bh;
2319 struct ext2_inode * raw_inode = ext2_get_inode(sb, ino, &bh);
2320 int n;
3261cfd5 2321@@ -1573,6 +1600,9 @@ static int __ext2_write_inode(struct ino
d337f35e
JR
2322 raw_inode->i_uid_high = 0;
2323 raw_inode->i_gid_high = 0;
2324 }
2325+#ifdef CONFIG_TAGGING_INTERN
537831f9 2326+ raw_inode->i_raw_tag = cpu_to_le16(i_tag_read(inode));
d337f35e
JR
2327+#endif
2328 raw_inode->i_links_count = cpu_to_le16(inode->i_nlink);
2329 raw_inode->i_size = cpu_to_le32(inode->i_size);
2330 raw_inode->i_atime = cpu_to_le32(inode->i_atime.tv_sec);
3261cfd5 2331@@ -1656,7 +1686,8 @@ int ext2_setattr(struct dentry *dentry,
cc23e853
AM
2332 return error;
2333 }
42bc425c
AM
2334 if ((iattr->ia_valid & ATTR_UID && !uid_eq(iattr->ia_uid, inode->i_uid)) ||
2335- (iattr->ia_valid & ATTR_GID && !gid_eq(iattr->ia_gid, inode->i_gid))) {
2336+ (iattr->ia_valid & ATTR_GID && !gid_eq(iattr->ia_gid, inode->i_gid)) ||
537831f9 2337+ (iattr->ia_valid & ATTR_TAG && !tag_eq(iattr->ia_tag, inode->i_tag))) {
78865d5b 2338 error = dquot_transfer(inode, iattr);
d337f35e
JR
2339 if (error)
2340 return error;
3261cfd5
AM
2341diff -NurpP --minimal linux-4.9.207/fs/ext2/ioctl.c linux-4.9.207-vs2.3.9.11/fs/ext2/ioctl.c
2342--- linux-4.9.207/fs/ext2/ioctl.c 2016-12-11 19:17:54.000000000 +0000
2343+++ linux-4.9.207-vs2.3.9.11/fs/ext2/ioctl.c 2018-10-20 04:58:13.000000000 +0000
d4263eb0
JR
2344@@ -17,6 +17,16 @@
2345 #include <asm/uaccess.h>
2346
2347
2348+int ext2_sync_flags(struct inode *inode, int flags, int vflags)
2349+{
2350+ inode->i_flags = flags;
2351+ inode->i_vflags = vflags;
2352+ ext2_get_inode_flags(EXT2_I(inode));
2353+ inode->i_ctime = CURRENT_TIME_SEC;
2354+ mark_inode_dirty(inode);
2355+ return 0;
2356+}
2357+
2358 long ext2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
2359 {
b00e13aa 2360 struct inode *inode = file_inode(filp);
d4263eb0 2361@@ -51,6 +61,11 @@ long ext2_ioctl(struct file *filp, unsig
d337f35e 2362
ec22aa5c 2363 flags = ext2_mask_flags(inode->i_mode, flags);
d337f35e 2364
2380c486
JR
2365+ if (IS_BARRIER(inode)) {
2366+ vxwprintk_task(1, "messing with the barrier.");
2367+ return -EACCES;
2368+ }
2369+
cc23e853 2370 inode_lock(inode);
2380c486
JR
2371 /* Is it quota file? Do not allow user to mess with it */
2372 if (IS_NOQUOTA(inode)) {
d4263eb0 2373@@ -66,7 +81,9 @@ long ext2_ioctl(struct file *filp, unsig
d337f35e
JR
2374 *
2375 * This test looks nicer. Thanks to Pauline Middelink
2376 */
2377- if ((flags ^ oldflags) & (EXT2_APPEND_FL | EXT2_IMMUTABLE_FL)) {
2378+ if ((oldflags & EXT2_IMMUTABLE_FL) ||
2379+ ((flags ^ oldflags) & (EXT2_APPEND_FL |
2380c486
JR
2380+ EXT2_IMMUTABLE_FL | EXT2_IXUNLINK_FL))) {
2381 if (!capable(CAP_LINUX_IMMUTABLE)) {
cc23e853 2382 inode_unlock(inode);
2380c486 2383 ret = -EPERM;
d4263eb0
JR
2384@@ -74,7 +91,7 @@ long ext2_ioctl(struct file *filp, unsig
2385 }
2386 }
2387
2388- flags = flags & EXT2_FL_USER_MODIFIABLE;
2389+ flags &= EXT2_FL_USER_MODIFIABLE;
2390 flags |= oldflags & ~EXT2_FL_USER_MODIFIABLE;
2391 ei->i_flags = flags;
db55b927 2392
3261cfd5
AM
2393diff -NurpP --minimal linux-4.9.207/fs/ext2/namei.c linux-4.9.207-vs2.3.9.11/fs/ext2/namei.c
2394--- linux-4.9.207/fs/ext2/namei.c 2019-12-25 15:28:36.517329425 +0000
2395+++ linux-4.9.207-vs2.3.9.11/fs/ext2/namei.c 2018-10-20 04:58:13.000000000 +0000
78865d5b 2396@@ -32,6 +32,7 @@
d337f35e
JR
2397
2398 #include <linux/pagemap.h>
78865d5b 2399 #include <linux/quotaops.h>
d337f35e
JR
2400+#include <linux/vs_tag.h>
2401 #include "ext2.h"
2402 #include "xattr.h"
2403 #include "acl.h"
09a55596 2404@@ -71,6 +72,7 @@ static struct dentry *ext2_lookup(struct
a168f21d
AM
2405 (unsigned long) ino);
2406 return ERR_PTR(-EIO);
ec22aa5c 2407 }
a168f21d 2408+ dx_propagate_tag(nd, inode);
d337f35e 2409 }
a168f21d
AM
2410 return d_splice_alias(inode, dentry);
2411 }
09a55596 2412@@ -443,6 +445,7 @@ const struct inode_operations ext2_speci
cc23e853 2413 .listxattr = ext2_listxattr,
d337f35e
JR
2414 #endif
2415 .setattr = ext2_setattr,
d337f35e 2416+ .sync_flags = ext2_sync_flags,
a168f21d 2417 .get_acl = ext2_get_acl,
bb20add7 2418 .set_acl = ext2_set_acl,
d337f35e 2419 };
3261cfd5
AM
2420diff -NurpP --minimal linux-4.9.207/fs/ext2/super.c linux-4.9.207-vs2.3.9.11/fs/ext2/super.c
2421--- linux-4.9.207/fs/ext2/super.c 2019-12-25 15:28:36.537329101 +0000
2422+++ linux-4.9.207-vs2.3.9.11/fs/ext2/super.c 2019-10-05 14:58:45.150315864 +0000
cc23e853 2423@@ -411,7 +411,8 @@ enum {
d337f35e
JR
2424 Opt_err_ro, Opt_nouid32, Opt_nocheck, Opt_debug,
2425 Opt_oldalloc, Opt_orlov, Opt_nobh, Opt_user_xattr, Opt_nouser_xattr,
cc23e853 2426 Opt_acl, Opt_noacl, Opt_xip, Opt_dax, Opt_ignore, Opt_err, Opt_quota,
2380c486
JR
2427- Opt_usrquota, Opt_grpquota, Opt_reservation, Opt_noreservation
2428+ Opt_usrquota, Opt_grpquota, Opt_reservation, Opt_noreservation,
2429+ Opt_tag, Opt_notag, Opt_tagid
d337f35e
JR
2430 };
2431
ec22aa5c 2432 static const match_table_t tokens = {
cc23e853 2433@@ -439,6 +440,9 @@ static const match_table_t tokens = {
d337f35e
JR
2434 {Opt_acl, "acl"},
2435 {Opt_noacl, "noacl"},
2436 {Opt_xip, "xip"},
2437+ {Opt_tag, "tag"},
2438+ {Opt_notag, "notag"},
2439+ {Opt_tagid, "tagid=%u"},
cc23e853 2440 {Opt_dax, "dax"},
d337f35e
JR
2441 {Opt_grpquota, "grpquota"},
2442 {Opt_ignore, "noquota"},
cc23e853 2443@@ -523,6 +527,20 @@ static int parse_options(char *options,
d337f35e
JR
2444 case Opt_nouid32:
2445 set_opt (sbi->s_mount_opt, NO_UID32);
2446 break;
2447+#ifndef CONFIG_TAGGING_NONE
2448+ case Opt_tag:
2449+ set_opt (sbi->s_mount_opt, TAGGED);
2450+ break;
2451+ case Opt_notag:
2452+ clear_opt (sbi->s_mount_opt, TAGGED);
2453+ break;
2454+#endif
2455+#ifdef CONFIG_PROPAGATE
2456+ case Opt_tagid:
2457+ /* use args[0] */
2458+ set_opt (sbi->s_mount_opt, TAGGED);
2459+ break;
2460+#endif
2461 case Opt_nocheck:
2462 clear_opt (sbi->s_mount_opt, CHECK);
2463 break;
3261cfd5 2464@@ -898,6 +916,8 @@ static int ext2_fill_super(struct super_
2bf5ad28 2465 if (!parse_options((char *) data, sb))
d337f35e
JR
2466 goto failed_mount;
2467
cc23e853
AM
2468+ if (EXT2_SB(sb)->s_mount_opt & EXT2_MOUNT_TAGGED)
2469+ sb->s_flags |= MS_TAGGED;
2470 sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
2471 ((EXT2_SB(sb)->s_mount_opt & EXT2_MOUNT_POSIX_ACL) ?
2472 MS_POSIXACL : 0);
3261cfd5 2473@@ -1311,6 +1331,14 @@ static int ext2_remount (struct super_bl
cc23e853
AM
2474 err = -EINVAL;
2475 goto restore_opts;
2476 }
2477+
2478+ if ((sbi->s_mount_opt & EXT2_MOUNT_TAGGED) &&
d337f35e 2479+ !(sb->s_flags & MS_TAGGED)) {
cc23e853
AM
2480+ printk("EXT2-fs: %s: tagging not permitted on remount.\n",
2481+ sb->s_id);
d4263eb0
JR
2482+ err = -EINVAL;
2483+ goto restore_opts;
d337f35e 2484+ }
78865d5b 2485
cc23e853
AM
2486 sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
2487 ((sbi->s_mount_opt & EXT2_MOUNT_POSIX_ACL) ? MS_POSIXACL : 0);
3261cfd5
AM
2488diff -NurpP --minimal linux-4.9.207/fs/ext4/ext4.h linux-4.9.207-vs2.3.9.11/fs/ext4/ext4.h
2489--- linux-4.9.207/fs/ext4/ext4.h 2019-12-25 15:28:36.597328134 +0000
2490+++ linux-4.9.207-vs2.3.9.11/fs/ext4/ext4.h 2018-10-20 11:46:17.000000000 +0000
cc23e853 2491@@ -392,8 +392,11 @@ struct flex_groups {
2380c486 2492 #define EXT4_EXTENTS_FL 0x00080000 /* Inode uses extents */
78865d5b
AM
2493 #define EXT4_EA_INODE_FL 0x00200000 /* Inode used for large EA */
2494 #define EXT4_EOFBLOCKS_FL 0x00400000 /* Blocks allocated beyond EOF */
b00e13aa 2495+#define EXT4_BARRIER_FL 0x04000000 /* Barrier for chroot() */
2380c486 2496+#define EXT4_IXUNLINK_FL 0x08000000 /* Immutable invert on unlink */
b00e13aa 2497 #define EXT4_INLINE_DATA_FL 0x10000000 /* Inode has inline data. */
cc23e853
AM
2498 #define EXT4_PROJINHERIT_FL 0x20000000 /* Create with parents projid */
2499+#define EXT4_COW_FL 0x40000000 /* Copy on Write marker */
2380c486 2500 #define EXT4_RESERVED_FL 0x80000000 /* reserved for ext4 lib */
d337f35e 2501
cc23e853
AM
2502 #define EXT4_FL_USER_VISIBLE 0x304BDFFF /* User visible flags */
2503@@ -735,7 +738,7 @@ struct ext4_inode {
ec22aa5c
AM
2504 __le16 l_i_uid_high; /* these 2 fields */
2505 __le16 l_i_gid_high; /* were reserved2[0] */
42bc425c
AM
2506 __le16 l_i_checksum_lo;/* crc32c(uuid+inum+inode) LE */
2507- __le16 l_i_reserved;
ec22aa5c 2508+ __le16 l_i_tag; /* Context Tag */
ec22aa5c
AM
2509 } linux2;
2510 struct {
2511 __le16 h_i_reserved1; /* Obsoleted fragment number/size which are removed in ext4 */
cc23e853 2512@@ -892,6 +895,7 @@ do { \
ec22aa5c
AM
2513 #define i_gid_low i_gid
2514 #define i_uid_high osd2.linux2.l_i_uid_high
2515 #define i_gid_high osd2.linux2.l_i_gid_high
2516+#define i_raw_tag osd2.linux2.l_i_tag
42bc425c 2517 #define i_checksum_lo osd2.linux2.l_i_checksum_lo
d337f35e 2518
ec22aa5c 2519 #elif defined(__GNU__)
cc23e853
AM
2520@@ -1133,6 +1137,7 @@ struct ext4_inode_info {
2521 #define EXT4_MOUNT_DIOREAD_NOLOCK 0x400000 /* Enable support for dio read nolocking */
2522 #define EXT4_MOUNT_JOURNAL_CHECKSUM 0x800000 /* Journal checksums */
2523 #define EXT4_MOUNT_JOURNAL_ASYNC_COMMIT 0x1000000 /* Journal Async Commit */
2524+#define EXT4_MOUNT_TAGGED 0x2000000 /* Enable Context Tags */
2525 #define EXT4_MOUNT_DELALLOC 0x8000000 /* Delalloc support */
2526 #define EXT4_MOUNT_DATA_ERR_ABORT 0x10000000 /* Abort on file data write */
2527 #define EXT4_MOUNT_BLOCK_VALIDITY 0x20000000 /* Block validity checking */
09a55596 2528@@ -2492,6 +2497,7 @@ extern int ext4_punch_hole(struct inode
cc23e853
AM
2529 extern int ext4_truncate_restart_trans(handle_t *, struct inode *, int nblocks);
2530 extern void ext4_set_inode_flags(struct inode *);
2531 extern void ext4_get_inode_flags(struct ext4_inode_info *);
d4263eb0 2532+extern int ext4_sync_flags(struct inode *, int, int);
cc23e853
AM
2533 extern int ext4_alloc_da_blocks(struct inode *inode);
2534 extern void ext4_set_aops(struct inode *inode);
2535 extern int ext4_writepage_trans_blocks(struct inode *);
3261cfd5
AM
2536diff -NurpP --minimal linux-4.9.207/fs/ext4/file.c linux-4.9.207-vs2.3.9.11/fs/ext4/file.c
2537--- linux-4.9.207/fs/ext4/file.c 2019-12-25 15:28:36.617327809 +0000
2538+++ linux-4.9.207-vs2.3.9.11/fs/ext4/file.c 2019-10-05 14:58:45.150315864 +0000
2539@@ -698,5 +698,6 @@ const struct inode_operations ext4_file_
a168f21d 2540 .get_acl = ext4_get_acl,
bb20add7 2541 .set_acl = ext4_set_acl,
ec22aa5c 2542 .fiemap = ext4_fiemap,
d337f35e
JR
2543+ .sync_flags = ext4_sync_flags,
2544 };
2545
3261cfd5
AM
2546diff -NurpP --minimal linux-4.9.207/fs/ext4/ialloc.c linux-4.9.207-vs2.3.9.11/fs/ext4/ialloc.c
2547--- linux-4.9.207/fs/ext4/ialloc.c 2019-12-25 15:28:36.617327809 +0000
2548+++ linux-4.9.207-vs2.3.9.11/fs/ext4/ialloc.c 2018-10-20 05:55:42.000000000 +0000
cc23e853 2549@@ -21,6 +21,7 @@
e22b5178
AM
2550 #include <linux/random.h>
2551 #include <linux/bitops.h>
2552 #include <linux/blkdev.h>
2553+#include <linux/vs_tag.h>
2554 #include <asm/byteorder.h>
2555
2556 #include "ext4.h"
09a55596 2557@@ -777,6 +778,7 @@ struct inode *__ext4_new_inode(handle_t
76514441
AM
2558 inode->i_mode = mode;
2559 inode->i_uid = current_fsuid();
2560 inode->i_gid = dir->i_gid;
a4a22af8 2561+ i_tag_write(inode, dx_current_fstag(sb));
e22b5178 2562 } else
76514441 2563 inode_init_owner(inode, dir, mode);
cc23e853 2564
3261cfd5
AM
2565diff -NurpP --minimal linux-4.9.207/fs/ext4/inode.c linux-4.9.207-vs2.3.9.11/fs/ext4/inode.c
2566--- linux-4.9.207/fs/ext4/inode.c 2019-12-25 15:28:36.667327000 +0000
2567+++ linux-4.9.207-vs2.3.9.11/fs/ext4/inode.c 2019-12-25 15:37:51.518436962 +0000
cc23e853
AM
2568@@ -37,6 +37,7 @@
2569 #include <linux/printk.h>
2570 #include <linux/slab.h>
52afa9bd 2571 #include <linux/bitops.h>
d337f35e 2572+#include <linux/vs_tag.h>
ec22aa5c 2573
2380c486 2574 #include "ext4_jbd2.h"
d337f35e 2575 #include "xattr.h"
3261cfd5 2576@@ -4390,12 +4391,15 @@ void ext4_set_inode_flags(struct inode *
d337f35e 2577 unsigned int flags = EXT4_I(inode)->i_flags;
52afa9bd 2578 unsigned int new_fl = 0;
978063ce 2579
d337f35e 2580+ if (flags & EXT4_IMMUTABLE_FL)
52afa9bd 2581+ new_fl |= S_IMMUTABLE;
2380c486 2582+ if (flags & EXT4_IXUNLINK_FL)
52afa9bd 2583+ new_fl |= S_IXUNLINK;
978063ce 2584+
d337f35e 2585 if (flags & EXT4_SYNC_FL)
52afa9bd 2586 new_fl |= S_SYNC;
d337f35e 2587 if (flags & EXT4_APPEND_FL)
52afa9bd 2588 new_fl |= S_APPEND;
d337f35e 2589- if (flags & EXT4_IMMUTABLE_FL)
52afa9bd 2590- new_fl |= S_IMMUTABLE;
d337f35e 2591 if (flags & EXT4_NOATIME_FL)
52afa9bd 2592 new_fl |= S_NOATIME;
d337f35e 2593 if (flags & EXT4_DIRSYNC_FL)
3261cfd5 2594@@ -4403,31 +4407,52 @@ void ext4_set_inode_flags(struct inode *
cc23e853
AM
2595 if (test_opt(inode->i_sb, DAX) && S_ISREG(inode->i_mode))
2596 new_fl |= S_DAX;
ca5d134c 2597 inode_set_flags(inode, new_fl,
cc23e853
AM
2598- S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC|S_DAX);
2599+ S_IXUNLINK | S_IMMUTABLE | S_DAX |
ca5d134c 2600+ S_SYNC | S_APPEND | S_NOATIME | S_DIRSYNC);
2380c486 2601+
978063ce 2602+ new_fl = 0;
2380c486 2603+ if (flags & EXT4_BARRIER_FL)
978063ce 2604+ new_fl |= V_BARRIER;
2380c486 2605+ if (flags & EXT4_COW_FL)
978063ce
JR
2606+ new_fl |= V_COW;
2607+
2608+ set_mask_bits(&inode->i_vflags,
2609+ V_BARRIER | V_COW, new_fl);
d337f35e
JR
2610 }
2611
2380c486
JR
2612 /* Propagate flags from i_flags to EXT4_I(inode)->i_flags */
2613 void ext4_get_inode_flags(struct ext4_inode_info *ei)
2614 {
76514441
AM
2615- unsigned int vfs_fl;
2616+ unsigned int vfs_fl, vfs_vf;
2617 unsigned long old_fl, new_fl;
2380c486 2618
76514441
AM
2619 do {
2620 vfs_fl = ei->vfs_inode.i_flags;
2621+ vfs_vf = ei->vfs_inode.i_vflags;
2622 old_fl = ei->i_flags;
2623 new_fl = old_fl & ~(EXT4_SYNC_FL|EXT4_APPEND_FL|
2624 EXT4_IMMUTABLE_FL|EXT4_NOATIME_FL|
2625- EXT4_DIRSYNC_FL);
2626+ EXT4_DIRSYNC_FL|EXT4_BARRIER_FL|
2627+ EXT4_COW_FL);
2628+
2629+ if (vfs_fl & S_IMMUTABLE)
2630+ new_fl |= EXT4_IMMUTABLE_FL;
2631+ if (vfs_fl & S_IXUNLINK)
2632+ new_fl |= EXT4_IXUNLINK_FL;
2633+
2634 if (vfs_fl & S_SYNC)
2635 new_fl |= EXT4_SYNC_FL;
2636 if (vfs_fl & S_APPEND)
2637 new_fl |= EXT4_APPEND_FL;
2638- if (vfs_fl & S_IMMUTABLE)
2639- new_fl |= EXT4_IMMUTABLE_FL;
2640 if (vfs_fl & S_NOATIME)
2641 new_fl |= EXT4_NOATIME_FL;
2642 if (vfs_fl & S_DIRSYNC)
2643 new_fl |= EXT4_DIRSYNC_FL;
2644+
2645+ if (vfs_vf & V_BARRIER)
2646+ new_fl |= EXT4_BARRIER_FL;
2647+ if (vfs_vf & V_COW)
2648+ new_fl |= EXT4_COW_FL;
2649 } while (cmpxchg(&ei->i_flags, old_fl, new_fl) != old_fl);
ec22aa5c
AM
2650 }
2651
3261cfd5 2652@@ -4553,8 +4578,10 @@ struct inode *ext4_iget(struct super_blo
42bc425c
AM
2653 i_uid |= le16_to_cpu(raw_inode->i_uid_high) << 16;
2654 i_gid |= le16_to_cpu(raw_inode->i_gid_high) << 16;
d337f35e 2655 }
42bc425c
AM
2656- i_uid_write(inode, i_uid);
2657- i_gid_write(inode, i_gid);
2658+ i_uid_write(inode, INOTAG_UID(DX_TAG(inode), i_uid, i_gid));
2659+ i_gid_write(inode, INOTAG_GID(DX_TAG(inode), i_uid, i_gid));
537831f9
AM
2660+ i_tag_write(inode, INOTAG_TAG(DX_TAG(inode), i_uid, i_gid,
2661+ le16_to_cpu(raw_inode->i_raw_tag)));
cc23e853 2662 ei->i_projid = make_kprojid(&init_user_ns, i_projid);
f6c5ef8b 2663 set_nlink(inode, le16_to_cpu(raw_inode->i_links_count));
2380c486 2664
3261cfd5 2665@@ -4870,8 +4897,10 @@ static int ext4_do_update_inode(handle_t
d337f35e 2666
2380c486 2667 ext4_get_inode_flags(ei);
d337f35e 2668 raw_inode->i_mode = cpu_to_le16(inode->i_mode);
42bc425c
AM
2669- i_uid = i_uid_read(inode);
2670- i_gid = i_gid_read(inode);
a4a22af8
AM
2671+ i_uid = from_kuid(&init_user_ns,
2672+ TAGINO_KUID(DX_TAG(inode), inode->i_uid, inode->i_tag));
2673+ i_gid = from_kgid(&init_user_ns,
2674+ TAGINO_KGID(DX_TAG(inode), inode->i_gid, inode->i_tag));
cc23e853 2675 i_projid = from_kprojid(&init_user_ns, ei->i_projid);
ec22aa5c 2676 if (!(test_opt(inode->i_sb, NO_UID32))) {
42bc425c 2677 raw_inode->i_uid_low = cpu_to_le16(low_16_bits(i_uid));
3261cfd5 2678@@ -4895,6 +4924,9 @@ static int ext4_do_update_inode(handle_t
d337f35e
JR
2679 raw_inode->i_uid_high = 0;
2680 raw_inode->i_gid_high = 0;
2681 }
2682+#ifdef CONFIG_TAGGING_INTERN
537831f9 2683+ raw_inode->i_raw_tag = cpu_to_le16(i_tag_read(inode));
d337f35e
JR
2684+#endif
2685 raw_inode->i_links_count = cpu_to_le16(inode->i_nlink);
2380c486
JR
2686
2687 EXT4_INODE_SET_XTIME(i_ctime, inode, raw_inode);
3261cfd5 2688@@ -5152,7 +5184,8 @@ int ext4_setattr(struct dentry *dentry,
cc23e853
AM
2689 return error;
2690 }
42bc425c
AM
2691 if ((ia_valid & ATTR_UID && !uid_eq(attr->ia_uid, inode->i_uid)) ||
2692- (ia_valid & ATTR_GID && !gid_eq(attr->ia_gid, inode->i_gid))) {
2693+ (ia_valid & ATTR_GID && !gid_eq(attr->ia_gid, inode->i_gid)) ||
537831f9 2694+ (ia_valid & ATTR_TAG && !tag_eq(attr->ia_tag, inode->i_tag))) {
d337f35e
JR
2695 handle_t *handle;
2696
2697 /* (user+group)*(old+new) structure, inode write (sb,
3261cfd5 2698@@ -5175,6 +5208,8 @@ int ext4_setattr(struct dentry *dentry,
d337f35e
JR
2699 inode->i_uid = attr->ia_uid;
2700 if (attr->ia_valid & ATTR_GID)
2701 inode->i_gid = attr->ia_gid;
2702+ if ((attr->ia_valid & ATTR_TAG) && IS_TAGGED(inode))
2703+ inode->i_tag = attr->ia_tag;
2704 error = ext4_mark_inode_dirty(handle, inode);
2705 ext4_journal_stop(handle);
2706 }
3261cfd5
AM
2707diff -NurpP --minimal linux-4.9.207/fs/ext4/ioctl.c linux-4.9.207-vs2.3.9.11/fs/ext4/ioctl.c
2708--- linux-4.9.207/fs/ext4/ioctl.c 2019-12-25 15:28:36.707326353 +0000
2709+++ linux-4.9.207-vs2.3.9.11/fs/ext4/ioctl.c 2019-10-05 14:58:45.150315864 +0000
cc23e853 2710@@ -15,6 +15,7 @@
ec22aa5c 2711 #include <linux/file.h>
cc23e853
AM
2712 #include <linux/quotaops.h>
2713 #include <linux/uuid.h>
d337f35e
JR
2714+#include <linux/vs_tag.h>
2715 #include <asm/uaccess.h>
2380c486
JR
2716 #include "ext4_jbd2.h"
2717 #include "ext4.h"
cc23e853
AM
2718@@ -226,7 +227,9 @@ static int ext4_ioctl_setflags(struct in
2719 *
2720 * This test looks nicer. Thanks to Pauline Middelink
2721 */
2722- if ((flags ^ oldflags) & (EXT4_APPEND_FL | EXT4_IMMUTABLE_FL)) {
2723+ if ((oldflags & EXT4_IMMUTABLE_FL) ||
2724+ ((flags ^ oldflags) & (EXT4_APPEND_FL |
2725+ EXT4_IMMUTABLE_FL | EXT4_IXUNLINK_FL))) {
2726 if (!capable(CAP_LINUX_IMMUTABLE))
2727 goto flags_out;
2728 }
3261cfd5 2729@@ -432,6 +435,33 @@ static inline unsigned long ext4_xflags_
cc23e853 2730 return iflags;
09be7631 2731 }
db55b927 2732
d4263eb0
JR
2733+int ext4_sync_flags(struct inode *inode, int flags, int vflags)
2734+{
2735+ handle_t *handle = NULL;
2736+ struct ext4_iloc iloc;
2737+ int err;
2738+
b00e13aa 2739+ handle = ext4_journal_start(inode, EXT4_HT_INODE, 1);
d4263eb0
JR
2740+ if (IS_ERR(handle))
2741+ return PTR_ERR(handle);
2742+
2743+ if (IS_SYNC(inode))
2744+ ext4_handle_sync(handle);
2745+ err = ext4_reserve_inode_write(handle, inode, &iloc);
2746+ if (err)
2747+ goto flags_err;
2748+
2749+ inode->i_flags = flags;
2750+ inode->i_vflags = vflags;
2751+ ext4_get_inode_flags(EXT4_I(inode));
2752+ inode->i_ctime = ext4_current_time(inode);
2753+
2754+ err = ext4_mark_iloc_dirty(handle, inode, &iloc);
2755+flags_err:
2756+ ext4_journal_stop(handle);
2757+ return err;
2758+}
2759+
2760 long ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
2761 {
b00e13aa 2762 struct inode *inode = file_inode(filp);
3261cfd5 2763@@ -461,6 +491,11 @@ long ext4_ioctl(struct file *filp, unsig
ec22aa5c
AM
2764
2765 flags = ext4_mask_flags(inode->i_mode, flags);
2380c486
JR
2766
2767+ if (IS_BARRIER(inode)) {
2768+ vxwprintk_task(1, "messing with the barrier.");
2769+ return -EACCES;
2770+ }
2771+
cc23e853
AM
2772 inode_lock(inode);
2773 err = ext4_ioctl_setflags(inode, flags);
2774 inode_unlock(inode);
3261cfd5
AM
2775diff -NurpP --minimal linux-4.9.207/fs/ext4/namei.c linux-4.9.207-vs2.3.9.11/fs/ext4/namei.c
2776--- linux-4.9.207/fs/ext4/namei.c 2019-12-25 15:28:36.737325868 +0000
2777+++ linux-4.9.207-vs2.3.9.11/fs/ext4/namei.c 2019-10-05 14:58:45.150315864 +0000
cc23e853 2778@@ -33,6 +33,7 @@
2380c486 2779 #include <linux/quotaops.h>
d337f35e
JR
2780 #include <linux/buffer_head.h>
2781 #include <linux/bio.h>
d337f35e 2782+#include <linux/vs_tag.h>
2380c486
JR
2783 #include "ext4.h"
2784 #include "ext4_jbd2.h"
d337f35e 2785
3261cfd5 2786@@ -1474,6 +1475,7 @@ restart:
cc23e853 2787 REQ_META | REQ_PRIO,
a168f21d 2788 1, &bh);
2380c486 2789 }
d337f35e 2790+ dx_propagate_tag(nd, inode);
2380c486
JR
2791 }
2792 if ((bh = bh_use[ra_ptr++]) == NULL)
2793 goto next;
3261cfd5 2794@@ -3943,6 +3945,7 @@ const struct inode_operations ext4_dir_i
a168f21d 2795 .get_acl = ext4_get_acl,
bb20add7 2796 .set_acl = ext4_set_acl,
d4263eb0 2797 .fiemap = ext4_fiemap,
d337f35e
JR
2798+ .sync_flags = ext4_sync_flags,
2799 };
d4263eb0
JR
2800
2801 const struct inode_operations ext4_special_inode_operations = {
3261cfd5
AM
2802diff -NurpP --minimal linux-4.9.207/fs/ext4/super.c linux-4.9.207-vs2.3.9.11/fs/ext4/super.c
2803--- linux-4.9.207/fs/ext4/super.c 2019-12-25 15:28:36.737325868 +0000
2804+++ linux-4.9.207-vs2.3.9.11/fs/ext4/super.c 2019-10-05 14:58:45.150315864 +0000
2805@@ -1292,6 +1292,7 @@ enum {
78865d5b 2806 Opt_dioread_nolock, Opt_dioread_lock,
dd5f3080 2807 Opt_discard, Opt_nodiscard, Opt_init_itable, Opt_noinit_itable,
cc23e853
AM
2808 Opt_max_dir_size_kb, Opt_nojournal_checksum,
2809+ Opt_tag, Opt_notag, Opt_tagid
d337f35e
JR
2810 };
2811
ec22aa5c 2812 static const match_table_t tokens = {
3261cfd5 2813@@ -1378,6 +1379,9 @@ static const match_table_t tokens = {
1e8b8f9b
AM
2814 {Opt_removed, "reservation"}, /* mount option from ext2/3 */
2815 {Opt_removed, "noreservation"}, /* mount option from ext2/3 */
2816 {Opt_removed, "journal=%u"}, /* mount option from ext2/3 */
d337f35e
JR
2817+ {Opt_tag, "tag"},
2818+ {Opt_notag, "notag"},
2819+ {Opt_tagid, "tagid=%u"},
d337f35e 2820 {Opt_err, NULL},
d337f35e 2821 };
2380c486 2822
3261cfd5 2823@@ -1623,6 +1627,20 @@ static int handle_mount_opt(struct super
cc23e853
AM
2824 case Opt_nolazytime:
2825 sb->s_flags &= ~MS_LAZYTIME;
1e8b8f9b 2826 return 1;
d337f35e 2827+#ifndef CONFIG_TAGGING_NONE
1e8b8f9b
AM
2828+ case Opt_tag:
2829+ set_opt(sb, TAGGED);
2830+ return 1;
2831+ case Opt_notag:
2832+ clear_opt(sb, TAGGED);
2833+ return 1;
d337f35e
JR
2834+#endif
2835+#ifdef CONFIG_PROPAGATE
1e8b8f9b
AM
2836+ case Opt_tagid:
2837+ /* use args[0] */
2838+ set_opt(sb, TAGGED);
2839+ return 1;
d337f35e 2840+#endif
1e8b8f9b
AM
2841 }
2842
b00e13aa 2843 for (m = ext4_mount_opts; m->token != Opt_err; m++)
3261cfd5 2844@@ -3598,6 +3616,9 @@ static int ext4_fill_super(struct super_
cc23e853 2845 sb->s_iflags |= SB_I_CGROUPWB;
f6c5ef8b 2846 }
d337f35e
JR
2847
2848+ if (EXT4_SB(sb)->s_mount_opt & EXT4_MOUNT_TAGGED)
2849+ sb->s_flags |= MS_TAGGED;
2850+
2851 sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
78865d5b 2852 (test_opt(sb, POSIX_ACL) ? MS_POSIXACL : 0);
d337f35e 2853
3261cfd5 2854@@ -4996,6 +5017,14 @@ static int ext4_remount(struct super_blo
ec22aa5c 2855 if (sbi->s_mount_flags & EXT4_MF_FS_ABORTED)
93de0823 2856 ext4_abort(sb, "Abort forced by user");
2380c486 2857
d337f35e
JR
2858+ if ((sbi->s_mount_opt & EXT4_MOUNT_TAGGED) &&
2859+ !(sb->s_flags & MS_TAGGED)) {
2860+ printk("EXT4-fs: %s: tagging not permitted on remount.\n",
2861+ sb->s_id);
d4263eb0
JR
2862+ err = -EINVAL;
2863+ goto restore_opts;
d337f35e 2864+ }
2380c486 2865+
d337f35e 2866 sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
78865d5b 2867 (test_opt(sb, POSIX_ACL) ? MS_POSIXACL : 0);
d337f35e 2868
3261cfd5
AM
2869diff -NurpP --minimal linux-4.9.207/fs/fcntl.c linux-4.9.207-vs2.3.9.11/fs/fcntl.c
2870--- linux-4.9.207/fs/fcntl.c 2019-12-25 15:28:36.887323442 +0000
2871+++ linux-4.9.207-vs2.3.9.11/fs/fcntl.c 2018-10-20 04:58:13.000000000 +0000
bb20add7 2872@@ -22,6 +22,7 @@
2380c486 2873 #include <linux/pid_namespace.h>
92598135 2874 #include <linux/user_namespace.h>
bb20add7 2875 #include <linux/shmem_fs.h>
d337f35e
JR
2876+#include <linux/vs_limit.h>
2877
2878 #include <asm/poll.h>
2879 #include <asm/siginfo.h>
5ba7a31c 2880@@ -390,6 +391,8 @@ SYSCALL_DEFINE3(fcntl64, unsigned int, f
d337f35e 2881
537831f9 2882 if (!f.file)
2380c486
JR
2883 goto out;
2884+ if (!vx_files_avail(1))
2885+ goto out;
2886
537831f9 2887 if (unlikely(f.file->f_mode & FMODE_PATH)) {
42bc425c 2888 if (!check_fcntl_cmd(cmd))
3261cfd5
AM
2889diff -NurpP --minimal linux-4.9.207/fs/file.c linux-4.9.207-vs2.3.9.11/fs/file.c
2890--- linux-4.9.207/fs/file.c 2019-12-25 15:28:36.907323120 +0000
2891+++ linux-4.9.207-vs2.3.9.11/fs/file.c 2019-10-05 14:58:45.150315864 +0000
537831f9 2892@@ -22,6 +22,7 @@
2380c486
JR
2893 #include <linux/spinlock.h>
2894 #include <linux/rcupdate.h>
2895 #include <linux/workqueue.h>
2896+#include <linux/vs_limit.h>
2897
cc23e853
AM
2898 unsigned int sysctl_nr_open __read_mostly = 1024*1024;
2899 unsigned int sysctl_nr_open_min = BITS_PER_LONG;
2900@@ -357,6 +358,8 @@ struct files_struct *dup_fd(struct files
2380c486
JR
2901 struct file *f = *old_fds++;
2902 if (f) {
2903 get_file(f);
2904+ /* TODO: sum it first for check and performance */
2905+ vx_openfd_inc(open_files - i);
2906 } else {
2907 /*
2908 * The fd may be claimed in the fd bitmap but not yet
cc23e853 2909@@ -406,9 +409,11 @@ static struct fdtable *close_files(struc
537831f9 2910 filp_close(file, files);
bb20add7 2911 cond_resched_rcu_qs();
537831f9
AM
2912 }
2913+ vx_openfd_dec(i);
2914 }
2915 i++;
2916 set >>= 1;
2917+ cond_resched();
2918 }
2919 }
bb20add7 2920
3261cfd5 2921@@ -540,6 +545,7 @@ repeat:
2380c486 2922 else
1e8b8f9b 2923 __clear_close_on_exec(fd, fdt);
2380c486
JR
2924 error = fd;
2925+ vx_openfd_inc(fd);
2926 #if 1
2927 /* Sanity check */
bb20add7 2928 if (rcu_access_pointer(fdt->fd[fd]) != NULL) {
3261cfd5 2929@@ -570,6 +576,7 @@ static void __put_unused_fd(struct files
537831f9
AM
2930 __clear_open_fd(fd, fdt);
2931 if (fd < files->next_fd)
2932 files->next_fd = fd;
2933+ vx_openfd_dec(fd);
2934 }
2935
2936 void put_unused_fd(unsigned int fd)
3261cfd5 2937@@ -857,6 +864,8 @@ __releases(&files->file_lock)
537831f9
AM
2938
2939 if (tofree)
2940 filp_close(tofree, files);
2941+ else
2942+ vx_openfd_inc(fd); /* fd was unused */
2943
2944 return fd;
2945
3261cfd5
AM
2946diff -NurpP --minimal linux-4.9.207/fs/file_table.c linux-4.9.207-vs2.3.9.11/fs/file_table.c
2947--- linux-4.9.207/fs/file_table.c 2016-12-11 19:17:54.000000000 +0000
2948+++ linux-4.9.207-vs2.3.9.11/fs/file_table.c 2018-10-20 04:58:13.000000000 +0000
92598135 2949@@ -26,6 +26,8 @@
92598135 2950 #include <linux/task_work.h>
2bf5ad28 2951 #include <linux/ima.h>
cc23e853 2952 #include <linux/swap.h>
d337f35e
JR
2953+#include <linux/vs_limit.h>
2954+#include <linux/vs_context.h>
2955
a168f21d 2956 #include <linux/atomic.h>
d337f35e 2957
c2e5f7c8 2958@@ -137,6 +139,8 @@ struct file *get_empty_filp(void)
bb20add7 2959 mutex_init(&f->f_pos_lock);
d337f35e
JR
2960 eventpoll_init_file(f);
2961 /* f->f_version: 0 */
2962+ f->f_xid = vx_current_xid();
2963+ vx_files_inc(f);
2964 return f;
2965
2966 over:
bb20add7 2967@@ -219,6 +223,8 @@ static void __fput(struct file *file)
265de2f7
JR
2968 put_write_access(inode);
2969 __mnt_drop_write(mnt);
2970 }
d337f35e
JR
2971+ vx_files_dec(file);
2972+ file->f_xid = 0;
92598135
AM
2973 file->f_path.dentry = NULL;
2974 file->f_path.mnt = NULL;
b00e13aa 2975 file->f_inode = NULL;
bb20add7 2976@@ -305,6 +311,8 @@ void put_filp(struct file *file)
d337f35e 2977 {
2380c486 2978 if (atomic_long_dec_and_test(&file->f_count)) {
d337f35e
JR
2979 security_file_free(file);
2980+ vx_files_dec(file);
2981+ file->f_xid = 0;
d337f35e
JR
2982 file_free(file);
2983 }
c2e5f7c8 2984 }
3261cfd5
AM
2985diff -NurpP --minimal linux-4.9.207/fs/fs_struct.c linux-4.9.207-vs2.3.9.11/fs/fs_struct.c
2986--- linux-4.9.207/fs/fs_struct.c 2016-12-11 19:17:54.000000000 +0000
2987+++ linux-4.9.207-vs2.3.9.11/fs/fs_struct.c 2018-10-20 04:58:13.000000000 +0000
ec22aa5c
AM
2988@@ -4,6 +4,7 @@
2989 #include <linux/path.h>
2990 #include <linux/slab.h>
2991 #include <linux/fs_struct.h>
2992+#include <linux/vserver/global.h>
d33d7b00 2993 #include "internal.h"
ec22aa5c 2994
92598135
AM
2995 /*
2996@@ -87,6 +88,7 @@ void free_fs_struct(struct fs_struct *fs
ec22aa5c 2997 {
92598135
AM
2998 path_put(&fs->root);
2999 path_put(&fs->pwd);
ec22aa5c
AM
3000+ atomic_dec(&vs_global_fs);
3001 kmem_cache_free(fs_cachep, fs);
3002 }
3003
537831f9 3004@@ -124,6 +126,7 @@ struct fs_struct *copy_fs_struct(struct
d33d7b00 3005 fs->pwd = old->pwd;
92598135 3006 path_get(&fs->pwd);
d33d7b00 3007 spin_unlock(&old->lock);
ec22aa5c
AM
3008+ atomic_inc(&vs_global_fs);
3009 }
3010 return fs;
3011 }
3261cfd5
AM
3012diff -NurpP --minimal linux-4.9.207/fs/gfs2/file.c linux-4.9.207-vs2.3.9.11/fs/gfs2/file.c
3013--- linux-4.9.207/fs/gfs2/file.c 2019-12-25 15:28:37.037321018 +0000
3014+++ linux-4.9.207-vs2.3.9.11/fs/gfs2/file.c 2018-10-20 04:58:13.000000000 +0000
cc23e853 3015@@ -137,6 +137,9 @@ static const u32 fsflags_to_gfs2[32] = {
e22b5178
AM
3016 [12] = GFS2_DIF_EXHASH,
3017 [14] = GFS2_DIF_INHERIT_JDATA,
92598135 3018 [17] = GFS2_DIF_TOPDIR,
e22b5178
AM
3019+ [27] = GFS2_DIF_IXUNLINK,
3020+ [26] = GFS2_DIF_BARRIER,
3021+ [29] = GFS2_DIF_COW,
3022 };
3023
3024 static const u32 gfs2_to_fsflags[32] = {
cc23e853 3025@@ -147,6 +150,9 @@ static const u32 gfs2_to_fsflags[32] = {
e22b5178 3026 [gfs2fl_ExHash] = FS_INDEX_FL,
92598135 3027 [gfs2fl_TopLevel] = FS_TOPDIR_FL,
e22b5178
AM
3028 [gfs2fl_InheritJdata] = FS_JOURNAL_DATA_FL,
3029+ [gfs2fl_IXUnlink] = FS_IXUNLINK_FL,
3030+ [gfs2fl_Barrier] = FS_BARRIER_FL,
3031+ [gfs2fl_Cow] = FS_COW_FL,
3032 };
3033
3034 static int gfs2_get_flags(struct file *filp, u32 __user *ptr)
cc23e853 3035@@ -178,12 +184,17 @@ void gfs2_set_inode_flags(struct inode *
e22b5178
AM
3036 {
3037 struct gfs2_inode *ip = GFS2_I(inode);
3038 unsigned int flags = inode->i_flags;
3039+ unsigned int vflags = inode->i_vflags;
3040+
3041+ flags &= ~(S_IMMUTABLE | S_IXUNLINK |
a168f21d 3042+ S_SYNC | S_APPEND | S_NOATIME | S_DIRSYNC | S_NOSEC);
e22b5178 3043
a168f21d
AM
3044- flags &= ~(S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC|S_NOSEC);
3045 if ((ip->i_eattr == 0) && !is_sxid(inode->i_mode))
cc23e853 3046 flags |= S_NOSEC;
e22b5178
AM
3047 if (ip->i_diskflags & GFS2_DIF_IMMUTABLE)
3048 flags |= S_IMMUTABLE;
3049+ if (ip->i_diskflags & GFS2_DIF_IXUNLINK)
3050+ flags |= S_IXUNLINK;
e22b5178
AM
3051 if (ip->i_diskflags & GFS2_DIF_APPENDONLY)
3052 flags |= S_APPEND;
3053 if (ip->i_diskflags & GFS2_DIF_NOATIME)
cc23e853 3054@@ -191,6 +202,43 @@ void gfs2_set_inode_flags(struct inode *
e22b5178
AM
3055 if (ip->i_diskflags & GFS2_DIF_SYNC)
3056 flags |= S_SYNC;
3057 inode->i_flags = flags;
3058+
3059+ vflags &= ~(V_BARRIER | V_COW);
3060+
3061+ if (ip->i_diskflags & GFS2_DIF_BARRIER)
3062+ vflags |= V_BARRIER;
3063+ if (ip->i_diskflags & GFS2_DIF_COW)
3064+ vflags |= V_COW;
3065+ inode->i_vflags = vflags;
3066+}
3067+
3068+void gfs2_get_inode_flags(struct inode *inode)
3069+{
3070+ struct gfs2_inode *ip = GFS2_I(inode);
3071+ unsigned int flags = inode->i_flags;
3072+ unsigned int vflags = inode->i_vflags;
3073+
3074+ ip->i_diskflags &= ~(GFS2_DIF_APPENDONLY |
3075+ GFS2_DIF_NOATIME | GFS2_DIF_SYNC |
3076+ GFS2_DIF_IMMUTABLE | GFS2_DIF_IXUNLINK |
3077+ GFS2_DIF_BARRIER | GFS2_DIF_COW);
3078+
3079+ if (flags & S_IMMUTABLE)
3080+ ip->i_diskflags |= GFS2_DIF_IMMUTABLE;
3081+ if (flags & S_IXUNLINK)
3082+ ip->i_diskflags |= GFS2_DIF_IXUNLINK;
3083+
3084+ if (flags & S_APPEND)
3085+ ip->i_diskflags |= GFS2_DIF_APPENDONLY;
3086+ if (flags & S_NOATIME)
3087+ ip->i_diskflags |= GFS2_DIF_NOATIME;
3088+ if (flags & S_SYNC)
3089+ ip->i_diskflags |= GFS2_DIF_SYNC;
3090+
3091+ if (vflags & V_BARRIER)
3092+ ip->i_diskflags |= GFS2_DIF_BARRIER;
3093+ if (vflags & V_COW)
3094+ ip->i_diskflags |= GFS2_DIF_COW;
3095 }
3096
3097 /* Flags that can be set by user space */
cc23e853
AM
3098@@ -306,6 +354,37 @@ static int gfs2_set_flags(struct file *f
3099 return do_gfs2_set_flags(filp, gfsflags, ~(GFS2_DIF_SYSTEM | GFS2_DIF_JDATA));
e22b5178
AM
3100 }
3101
3102+int gfs2_sync_flags(struct inode *inode, int flags, int vflags)
3103+{
3104+ struct gfs2_inode *ip = GFS2_I(inode);
3105+ struct gfs2_sbd *sdp = GFS2_SB(inode);
3106+ struct buffer_head *bh;
3107+ struct gfs2_holder gh;
3108+ int error;
3109+
3110+ error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh);
3111+ if (error)
3112+ return error;
3113+ error = gfs2_trans_begin(sdp, RES_DINODE, 0);
3114+ if (error)
3115+ goto out;
3116+ error = gfs2_meta_inode_buffer(ip, &bh);
3117+ if (error)
3118+ goto out_trans_end;
b00e13aa 3119+ gfs2_trans_add_meta(ip->i_gl, bh);
e22b5178
AM
3120+ inode->i_flags = flags;
3121+ inode->i_vflags = vflags;
3122+ gfs2_get_inode_flags(inode);
3123+ gfs2_dinode_out(ip, bh->b_data);
3124+ brelse(bh);
3125+ gfs2_set_aops(inode);
3126+out_trans_end:
3127+ gfs2_trans_end(sdp);
3128+out:
3129+ gfs2_glock_dq_uninit(&gh);
3130+ return error;
3131+}
3132+
3133 static long gfs2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
3134 {
3135 switch(cmd) {
3261cfd5
AM
3136diff -NurpP --minimal linux-4.9.207/fs/gfs2/inode.h linux-4.9.207-vs2.3.9.11/fs/gfs2/inode.h
3137--- linux-4.9.207/fs/gfs2/inode.h 2016-12-11 19:17:54.000000000 +0000
3138+++ linux-4.9.207-vs2.3.9.11/fs/gfs2/inode.h 2018-10-20 04:58:13.000000000 +0000
cc23e853 3139@@ -117,6 +117,7 @@ extern const struct file_operations gfs2
e22b5178
AM
3140 extern const struct file_operations gfs2_dir_fops_nolock;
3141
3142 extern void gfs2_set_inode_flags(struct inode *inode);
3143+extern int gfs2_sync_flags(struct inode *inode, int flags, int vflags);
3144
3145 #ifdef CONFIG_GFS2_FS_LOCKING_DLM
3146 extern const struct file_operations gfs2_file_fops;
3261cfd5
AM
3147diff -NurpP --minimal linux-4.9.207/fs/hostfs/hostfs.h linux-4.9.207-vs2.3.9.11/fs/hostfs/hostfs.h
3148--- linux-4.9.207/fs/hostfs/hostfs.h 2016-12-11 19:17:54.000000000 +0000
3149+++ linux-4.9.207-vs2.3.9.11/fs/hostfs/hostfs.h 2018-10-20 04:58:13.000000000 +0000
537831f9
AM
3150@@ -42,6 +42,7 @@ struct hostfs_iattr {
3151 unsigned short ia_mode;
3152 uid_t ia_uid;
3153 gid_t ia_gid;
61333608 3154+ vtag_t ia_tag;
537831f9
AM
3155 loff_t ia_size;
3156 struct timespec ia_atime;
3157 struct timespec ia_mtime;
3261cfd5
AM
3158diff -NurpP --minimal linux-4.9.207/fs/inode.c linux-4.9.207-vs2.3.9.11/fs/inode.c
3159--- linux-4.9.207/fs/inode.c 2019-12-25 15:28:37.147319239 +0000
3160+++ linux-4.9.207-vs2.3.9.11/fs/inode.c 2019-10-05 14:58:45.170315544 +0000
c2e5f7c8 3161@@ -18,6 +18,7 @@
763640ca 3162 #include <linux/buffer_head.h> /* for inode_has_buffers */
db55b927 3163 #include <linux/ratelimit.h>
c2e5f7c8 3164 #include <linux/list_lru.h>
76514441 3165+#include <linux/vs_tag.h>
cc23e853 3166 #include <trace/events/writeback.h>
763640ca 3167 #include "internal.h"
76514441 3168
cc23e853 3169@@ -133,6 +134,8 @@ int inode_init_always(struct super_block
ec22aa5c
AM
3170 struct address_space *const mapping = &inode->i_data;
3171
3172 inode->i_sb = sb;
3173+
3174+ /* essential because of inode slab reuse */
ec22aa5c
AM
3175 inode->i_blkbits = sb->s_blocksize_bits;
3176 inode->i_flags = 0;
3177 atomic_set(&inode->i_count, 1);
cc23e853
AM
3178@@ -144,6 +147,7 @@ int inode_init_always(struct super_block
3179 inode->i_opflags |= IOP_XATTR;
537831f9
AM
3180 i_uid_write(inode, 0);
3181 i_gid_write(inode, 0);
3182+ i_tag_write(inode, 0);
3183 atomic_set(&inode->i_writecount, 0);
3184 inode->i_size = 0;
3185 inode->i_blocks = 0;
cc23e853
AM
3186@@ -155,6 +159,7 @@ int inode_init_always(struct super_block
3187 inode->i_link = NULL;
3188 inode->i_dir_seq = 0;
ec22aa5c
AM
3189 inode->i_rdev = 0;
3190+ inode->i_mdev = 0;
3191 inode->dirtied_when = 0;
3192
cc23e853
AM
3193 #ifdef CONFIG_CGROUP_WRITEBACK
3194@@ -479,6 +484,8 @@ void __insert_inode_hash(struct inode *i
d337f35e 3195 }
763640ca 3196 EXPORT_SYMBOL(__insert_inode_hash);
d337f35e
JR
3197
3198+EXPORT_SYMBOL_GPL(__iget);
3199+
3200 /**
a168f21d 3201 * __remove_inode_hash - remove an inode from the hash
ab30d09f 3202 * @inode: inode to unhash
3261cfd5 3203@@ -1982,9 +1989,11 @@ void init_special_inode(struct inode *in
2380c486
JR
3204 if (S_ISCHR(mode)) {
3205 inode->i_fop = &def_chr_fops;
3206 inode->i_rdev = rdev;
3207+ inode->i_mdev = rdev;
3208 } else if (S_ISBLK(mode)) {
3209 inode->i_fop = &def_blk_fops;
3210 inode->i_rdev = rdev;
3211+ inode->i_mdev = rdev;
3212 } else if (S_ISFIFO(mode))
09be7631 3213 inode->i_fop = &pipefifo_fops;
2380c486 3214 else if (S_ISSOCK(mode))
3261cfd5 3215@@ -2019,6 +2028,7 @@ void inode_init_owner(struct inode *inod
76514441
AM
3216 } else
3217 inode->i_gid = current_fsgid();
3218 inode->i_mode = mode;
8ce283e1 3219+ i_tag_write(inode, dx_current_fstag(inode->i_sb));
76514441
AM
3220 }
3221 EXPORT_SYMBOL(inode_init_owner);
763640ca 3222
3261cfd5
AM
3223diff -NurpP --minimal linux-4.9.207/fs/ioctl.c linux-4.9.207-vs2.3.9.11/fs/ioctl.c
3224--- linux-4.9.207/fs/ioctl.c 2016-12-11 19:17:54.000000000 +0000
3225+++ linux-4.9.207-vs2.3.9.11/fs/ioctl.c 2018-10-20 04:58:13.000000000 +0000
ab30d09f 3226@@ -15,6 +15,9 @@
ec22aa5c
AM
3227 #include <linux/writeback.h>
3228 #include <linux/buffer_head.h>
3229 #include <linux/falloc.h>
d337f35e
JR
3230+#include <linux/proc_fs.h>
3231+#include <linux/vserver/inode.h>
3232+#include <linux/vs_tag.h>
cc23e853 3233 #include "internal.h"
d337f35e 3234
d337f35e 3235 #include <asm/ioctls.h>
3261cfd5
AM
3236diff -NurpP --minimal linux-4.9.207/fs/jfs/file.c linux-4.9.207-vs2.3.9.11/fs/jfs/file.c
3237--- linux-4.9.207/fs/jfs/file.c 2016-12-11 19:17:54.000000000 +0000
3238+++ linux-4.9.207-vs2.3.9.11/fs/jfs/file.c 2018-10-20 04:58:13.000000000 +0000
cc23e853
AM
3239@@ -113,7 +113,8 @@ int jfs_setattr(struct dentry *dentry, s
3240 return rc;
3241 }
537831f9
AM
3242 if ((iattr->ia_valid & ATTR_UID && !uid_eq(iattr->ia_uid, inode->i_uid)) ||
3243- (iattr->ia_valid & ATTR_GID && !gid_eq(iattr->ia_gid, inode->i_gid))) {
3244+ (iattr->ia_valid & ATTR_GID && !gid_eq(iattr->ia_gid, inode->i_gid)) ||
3245+ (iattr->ia_valid & ATTR_TAG && !tag_eq(iattr->ia_tag, inode->i_tag))) {
78865d5b
AM
3246 rc = dquot_transfer(inode, iattr);
3247 if (rc)
3248 return rc;
bb20add7 3249@@ -146,6 +147,7 @@ const struct inode_operations jfs_file_i
a168f21d 3250 .get_acl = jfs_get_acl,
bb20add7 3251 .set_acl = jfs_set_acl,
d337f35e
JR
3252 #endif
3253+ .sync_flags = jfs_sync_flags,
3254 };
3255
3256 const struct file_operations jfs_file_operations = {
3261cfd5
AM
3257diff -NurpP --minimal linux-4.9.207/fs/jfs/ioctl.c linux-4.9.207-vs2.3.9.11/fs/jfs/ioctl.c
3258--- linux-4.9.207/fs/jfs/ioctl.c 2016-12-11 19:17:54.000000000 +0000
3259+++ linux-4.9.207-vs2.3.9.11/fs/jfs/ioctl.c 2018-10-20 04:58:13.000000000 +0000
537831f9 3260@@ -12,6 +12,7 @@
d337f35e 3261 #include <linux/time.h>
2380c486 3262 #include <linux/sched.h>
537831f9 3263 #include <linux/blkdev.h>
d337f35e
JR
3264+#include <linux/mount.h>
3265 #include <asm/current.h>
3266 #include <asm/uaccess.h>
3267
537831f9 3268@@ -56,6 +57,16 @@ static long jfs_map_ext2(unsigned long f
d4263eb0
JR
3269 }
3270
3271
3272+int jfs_sync_flags(struct inode *inode, int flags, int vflags)
3273+{
3274+ inode->i_flags = flags;
3275+ inode->i_vflags = vflags;
3276+ jfs_get_inode_flags(JFS_IP(inode));
3277+ inode->i_ctime = CURRENT_TIME_SEC;
3278+ mark_inode_dirty(inode);
3279+ return 0;
3280+}
3281+
3282 long jfs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
3283 {
b00e13aa 3284 struct inode *inode = file_inode(filp);
537831f9 3285@@ -89,6 +100,11 @@ long jfs_ioctl(struct file *filp, unsign
2380c486
JR
3286 if (!S_ISDIR(inode->i_mode))
3287 flags &= ~JFS_DIRSYNC_FL;
d337f35e 3288
2380c486
JR
3289+ if (IS_BARRIER(inode)) {
3290+ vxwprintk_task(1, "messing with the barrier.");
3291+ return -EACCES;
3292+ }
3293+
3294 /* Is it quota file? Do not allow user to mess with it */
3295 if (IS_NOQUOTA(inode)) {
3296 err = -EPERM;
537831f9 3297@@ -106,8 +122,8 @@ long jfs_ioctl(struct file *filp, unsign
d337f35e
JR
3298 * the relevant capability.
3299 */
3300 if ((oldflags & JFS_IMMUTABLE_FL) ||
3301- ((flags ^ oldflags) &
3302- (JFS_APPEND_FL | JFS_IMMUTABLE_FL))) {
3303+ ((flags ^ oldflags) & (JFS_APPEND_FL |
2380c486
JR
3304+ JFS_IMMUTABLE_FL | JFS_IXUNLINK_FL))) {
3305 if (!capable(CAP_LINUX_IMMUTABLE)) {
cc23e853 3306 inode_unlock(inode);
2380c486 3307 err = -EPERM;
537831f9 3308@@ -115,7 +131,7 @@ long jfs_ioctl(struct file *filp, unsign
d4263eb0
JR
3309 }
3310 }
3311
3312- flags = flags & JFS_FL_USER_MODIFIABLE;
3313+ flags &= JFS_FL_USER_MODIFIABLE;
3314 flags |= oldflags & ~JFS_FL_USER_MODIFIABLE;
3315 jfs_inode->mode2 = flags;
3316
3261cfd5
AM
3317diff -NurpP --minimal linux-4.9.207/fs/jfs/jfs_dinode.h linux-4.9.207-vs2.3.9.11/fs/jfs/jfs_dinode.h
3318--- linux-4.9.207/fs/jfs/jfs_dinode.h 2016-12-11 19:17:54.000000000 +0000
3319+++ linux-4.9.207-vs2.3.9.11/fs/jfs/jfs_dinode.h 2018-10-20 04:58:13.000000000 +0000
2380c486
JR
3320@@ -161,9 +161,13 @@ struct dinode {
3321
d337f35e
JR
3322 #define JFS_APPEND_FL 0x01000000 /* writes to file may only append */
3323 #define JFS_IMMUTABLE_FL 0x02000000 /* Immutable file */
2380c486 3324+#define JFS_IXUNLINK_FL 0x08000000 /* Immutable invert on unlink */
d337f35e
JR
3325
3326-#define JFS_FL_USER_VISIBLE 0x03F80000
2380c486 3327-#define JFS_FL_USER_MODIFIABLE 0x03F80000
d337f35e 3328+#define JFS_BARRIER_FL 0x04000000 /* Barrier for chroot() */
2380c486 3329+#define JFS_COW_FL 0x20000000 /* Copy on Write marker */
d337f35e 3330+
2380c486
JR
3331+#define JFS_FL_USER_VISIBLE 0x07F80000
3332+#define JFS_FL_USER_MODIFIABLE 0x07F80000
3333 #define JFS_FL_INHERIT 0x03C80000
d337f35e
JR
3334
3335 /* These are identical to EXT[23]_IOC_GETFLAGS/SETFLAGS */
3261cfd5
AM
3336diff -NurpP --minimal linux-4.9.207/fs/jfs/jfs_filsys.h linux-4.9.207-vs2.3.9.11/fs/jfs/jfs_filsys.h
3337--- linux-4.9.207/fs/jfs/jfs_filsys.h 2016-12-11 19:17:54.000000000 +0000
3338+++ linux-4.9.207-vs2.3.9.11/fs/jfs/jfs_filsys.h 2018-10-20 04:58:13.000000000 +0000
537831f9 3339@@ -266,6 +266,7 @@
ec22aa5c
AM
3340 #define JFS_NAME_MAX 255
3341 #define JFS_PATH_MAX BPSIZE
bd427b06 3342
ec22aa5c 3343+#define JFS_TAGGED 0x00800000 /* Context Tagging */
bd427b06 3344
ec22aa5c
AM
3345 /*
3346 * file system state (superblock state)
3261cfd5
AM
3347diff -NurpP --minimal linux-4.9.207/fs/jfs/jfs_imap.c linux-4.9.207-vs2.3.9.11/fs/jfs/jfs_imap.c
3348--- linux-4.9.207/fs/jfs/jfs_imap.c 2016-12-11 19:17:54.000000000 +0000
3349+++ linux-4.9.207-vs2.3.9.11/fs/jfs/jfs_imap.c 2018-10-20 04:58:13.000000000 +0000
78865d5b 3350@@ -46,6 +46,7 @@
ec22aa5c
AM
3351 #include <linux/pagemap.h>
3352 #include <linux/quotaops.h>
78865d5b 3353 #include <linux/slab.h>
ec22aa5c 3354+#include <linux/vs_tag.h>
bd427b06 3355
ec22aa5c
AM
3356 #include "jfs_incore.h"
3357 #include "jfs_inode.h"
cc23e853 3358@@ -3046,6 +3047,8 @@ static int copy_from_dinode(struct dinod
ec22aa5c
AM
3359 {
3360 struct jfs_inode_info *jfs_ip = JFS_IP(ip);
3361 struct jfs_sb_info *sbi = JFS_SBI(ip->i_sb);
a4a22af8
AM
3362+ kuid_t kuid;
3363+ kgid_t kgid;
bd427b06 3364
ec22aa5c
AM
3365 jfs_ip->fileset = le32_to_cpu(dip->di_fileset);
3366 jfs_ip->mode2 = le32_to_cpu(dip->di_mode);
cc23e853 3367@@ -3066,14 +3069,18 @@ static int copy_from_dinode(struct dinod
d337f35e 3368 }
f6c5ef8b 3369 set_nlink(ip, le32_to_cpu(dip->di_nlink));
bd427b06 3370
537831f9 3371- jfs_ip->saved_uid = make_kuid(&init_user_ns, le32_to_cpu(dip->di_uid));
a4a22af8
AM
3372+ kuid = make_kuid(&init_user_ns, le32_to_cpu(dip->di_uid));
3373+ kgid = make_kgid(&init_user_ns, le32_to_cpu(dip->di_gid));
3374+ ip->i_tag = INOTAG_KTAG(DX_TAG(ip), kuid, kgid, GLOBAL_ROOT_TAG);
ec22aa5c 3375+
a4a22af8 3376+ jfs_ip->saved_uid = INOTAG_KUID(DX_TAG(ip), kuid, kgid);
537831f9 3377 if (!uid_valid(sbi->uid))
ec22aa5c
AM
3378 ip->i_uid = jfs_ip->saved_uid;
3379 else {
3380 ip->i_uid = sbi->uid;
bd427b06
AM
3381 }
3382
537831f9 3383- jfs_ip->saved_gid = make_kgid(&init_user_ns, le32_to_cpu(dip->di_gid));
a4a22af8 3384+ jfs_ip->saved_gid = INOTAG_KGID(DX_TAG(ip), kuid, kgid);
537831f9 3385 if (!gid_valid(sbi->gid))
d337f35e
JR
3386 ip->i_gid = jfs_ip->saved_gid;
3387 else {
cc23e853 3388@@ -3138,16 +3145,14 @@ static void copy_to_dinode(struct dinode
d337f35e
JR
3389 dip->di_size = cpu_to_le64(ip->i_size);
3390 dip->di_nblocks = cpu_to_le64(PBLK2LBLK(ip->i_sb, ip->i_blocks));
3391 dip->di_nlink = cpu_to_le32(ip->i_nlink);
537831f9
AM
3392- if (!uid_valid(sbi->uid))
3393- dip->di_uid = cpu_to_le32(i_uid_read(ip));
d337f35e 3394- else
537831f9
AM
3395- dip->di_uid =cpu_to_le32(from_kuid(&init_user_ns,
3396- jfs_ip->saved_uid));
3397- if (!gid_valid(sbi->gid))
3398- dip->di_gid = cpu_to_le32(i_gid_read(ip));
d337f35e 3399- else
537831f9
AM
3400- dip->di_gid = cpu_to_le32(from_kgid(&init_user_ns,
3401- jfs_ip->saved_gid));
3402+ dip->di_uid = cpu_to_le32(from_kuid(&init_user_ns,
a4a22af8 3403+ TAGINO_KUID(DX_TAG(ip),
537831f9
AM
3404+ !uid_valid(sbi->uid) ? ip->i_uid : jfs_ip->saved_uid,
3405+ ip->i_tag)));
a4a22af8
AM
3406+ dip->di_gid = cpu_to_le32(from_kgid(&init_user_ns,
3407+ TAGINO_KGID(DX_TAG(ip),
537831f9
AM
3408+ !gid_valid(sbi->gid) ? ip->i_gid : jfs_ip->saved_gid,
3409+ ip->i_tag)));
2380c486 3410 jfs_get_inode_flags(jfs_ip);
d337f35e
JR
3411 /*
3412 * mode2 is only needed for storing the higher order bits.
3261cfd5
AM
3413diff -NurpP --minimal linux-4.9.207/fs/jfs/jfs_inode.c linux-4.9.207-vs2.3.9.11/fs/jfs/jfs_inode.c
3414--- linux-4.9.207/fs/jfs/jfs_inode.c 2016-12-11 19:17:54.000000000 +0000
3415+++ linux-4.9.207-vs2.3.9.11/fs/jfs/jfs_inode.c 2018-10-20 04:58:14.000000000 +0000
e22b5178
AM
3416@@ -18,6 +18,7 @@
3417
3418 #include <linux/fs.h>
3419 #include <linux/quotaops.h>
3420+#include <linux/vs_tag.h>
3421 #include "jfs_incore.h"
3422 #include "jfs_inode.h"
3423 #include "jfs_filsys.h"
cc23e853 3424@@ -33,6 +34,9 @@ void jfs_set_inode_flags(struct inode *i
d337f35e
JR
3425
3426 if (flags & JFS_IMMUTABLE_FL)
bb20add7 3427 new_fl |= S_IMMUTABLE;
2380c486 3428+ if (flags & JFS_IXUNLINK_FL)
cc23e853 3429+ new_fl |= S_IXUNLINK;
d337f35e 3430+
d337f35e 3431 if (flags & JFS_APPEND_FL)
bb20add7 3432 new_fl |= S_APPEND;
d337f35e 3433 if (flags & JFS_NOATIME_FL)
cc23e853 3434@@ -41,18 +45,35 @@ void jfs_set_inode_flags(struct inode *i
bb20add7 3435 new_fl |= S_DIRSYNC;
cc23e853
AM
3436 if (flags & JFS_SYNC_FL)
3437 new_fl |= S_SYNC;
bb20add7 3438- inode_set_flags(inode, new_fl, S_IMMUTABLE | S_APPEND | S_NOATIME |
cc23e853
AM
3439- S_DIRSYNC | S_SYNC);
3440+
3441+ inode_set_flags(inode, new_fl, S_IMMUTABLE | S_IXUNLINK |
3442+ S_APPEND | S_NOATIME | S_DIRSYNC | S_SYNC);
2380c486 3443+
bb20add7 3444+ new_fl = 0;
2380c486 3445+ if (flags & JFS_BARRIER_FL)
bb20add7 3446+ new_fl |= V_BARRIER;
2380c486 3447+ if (flags & JFS_COW_FL)
bb20add7
AM
3448+ new_fl |= V_COW;
3449+
3450+ set_mask_bits(&inode->i_vflags,
3451+ V_BARRIER | V_COW, new_fl);
2380c486
JR
3452 }
3453
3454 void jfs_get_inode_flags(struct jfs_inode_info *jfs_ip)
3455 {
3456 unsigned int flags = jfs_ip->vfs_inode.i_flags;
3457+ unsigned int vflags = jfs_ip->vfs_inode.i_vflags;
3458+
3459+ jfs_ip->mode2 &= ~(JFS_IMMUTABLE_FL | JFS_IXUNLINK_FL |
3460+ JFS_APPEND_FL | JFS_NOATIME_FL |
3461+ JFS_DIRSYNC_FL | JFS_SYNC_FL |
3462+ JFS_BARRIER_FL | JFS_COW_FL);
3463
3464- jfs_ip->mode2 &= ~(JFS_IMMUTABLE_FL | JFS_APPEND_FL | JFS_NOATIME_FL |
3465- JFS_DIRSYNC_FL | JFS_SYNC_FL);
3466 if (flags & S_IMMUTABLE)
3467 jfs_ip->mode2 |= JFS_IMMUTABLE_FL;
3468+ if (flags & S_IXUNLINK)
3469+ jfs_ip->mode2 |= JFS_IXUNLINK_FL;
3470+
3471 if (flags & S_APPEND)
3472 jfs_ip->mode2 |= JFS_APPEND_FL;
3473 if (flags & S_NOATIME)
cc23e853 3474@@ -61,6 +82,11 @@ void jfs_get_inode_flags(struct jfs_inod
2380c486
JR
3475 jfs_ip->mode2 |= JFS_DIRSYNC_FL;
3476 if (flags & S_SYNC)
3477 jfs_ip->mode2 |= JFS_SYNC_FL;
3478+
3479+ if (vflags & V_BARRIER)
3480+ jfs_ip->mode2 |= JFS_BARRIER_FL;
3481+ if (vflags & V_COW)
3482+ jfs_ip->mode2 |= JFS_COW_FL;
d337f35e
JR
3483 }
3484
3485 /*
3261cfd5
AM
3486diff -NurpP --minimal linux-4.9.207/fs/jfs/jfs_inode.h linux-4.9.207-vs2.3.9.11/fs/jfs/jfs_inode.h
3487--- linux-4.9.207/fs/jfs/jfs_inode.h 2016-12-11 19:17:54.000000000 +0000
3488+++ linux-4.9.207-vs2.3.9.11/fs/jfs/jfs_inode.h 2018-10-20 04:58:14.000000000 +0000
2380c486
JR
3489@@ -39,6 +39,7 @@ extern struct dentry *jfs_fh_to_dentry(s
3490 extern struct dentry *jfs_fh_to_parent(struct super_block *sb, struct fid *fid,
3491 int fh_len, int fh_type);
d337f35e 3492 extern void jfs_set_inode_flags(struct inode *);
d4263eb0 3493+extern int jfs_sync_flags(struct inode *, int, int);
d337f35e 3494 extern int jfs_get_block(struct inode *, sector_t, struct buffer_head *, int);
78865d5b 3495 extern int jfs_setattr(struct dentry *, struct iattr *);
d337f35e 3496
3261cfd5
AM
3497diff -NurpP --minimal linux-4.9.207/fs/jfs/namei.c linux-4.9.207-vs2.3.9.11/fs/jfs/namei.c
3498--- linux-4.9.207/fs/jfs/namei.c 2019-12-25 15:28:37.197318432 +0000
3499+++ linux-4.9.207-vs2.3.9.11/fs/jfs/namei.c 2018-10-20 04:58:14.000000000 +0000
d33d7b00 3500@@ -22,6 +22,7 @@
d337f35e
JR
3501 #include <linux/ctype.h>
3502 #include <linux/quotaops.h>
2380c486 3503 #include <linux/exportfs.h>
d337f35e
JR
3504+#include <linux/vs_tag.h>
3505 #include "jfs_incore.h"
3506 #include "jfs_superblock.h"
3507 #include "jfs_inode.h"
09a55596 3508@@ -1480,6 +1481,7 @@ static struct dentry *jfs_lookup(struct
a168f21d 3509 jfs_err("jfs_lookup: iget failed on inum %d", (uint)inum);
d337f35e
JR
3510 }
3511
3512+ dx_propagate_tag(nd, ip);
d33d7b00
AM
3513 return d_splice_alias(ip, dentry);
3514 }
d337f35e 3515
09a55596 3516@@ -1542,6 +1544,7 @@ const struct inode_operations jfs_dir_in
a168f21d 3517 .get_acl = jfs_get_acl,
bb20add7 3518 .set_acl = jfs_set_acl,
d337f35e
JR
3519 #endif
3520+ .sync_flags = jfs_sync_flags,
3521 };
3522
3523 const struct file_operations jfs_dir_operations = {
3261cfd5
AM
3524diff -NurpP --minimal linux-4.9.207/fs/jfs/super.c linux-4.9.207-vs2.3.9.11/fs/jfs/super.c
3525--- linux-4.9.207/fs/jfs/super.c 2019-12-25 15:28:37.197318432 +0000
3526+++ linux-4.9.207-vs2.3.9.11/fs/jfs/super.c 2018-10-20 04:58:14.000000000 +0000
cc23e853 3527@@ -206,7 +206,8 @@ enum {
d337f35e
JR
3528 Opt_integrity, Opt_nointegrity, Opt_iocharset, Opt_resize,
3529 Opt_resize_nosize, Opt_errors, Opt_ignore, Opt_err, Opt_quota,
537831f9
AM
3530 Opt_usrquota, Opt_grpquota, Opt_uid, Opt_gid, Opt_umask,
3531- Opt_discard, Opt_nodiscard, Opt_discard_minblk
3532+ Opt_discard, Opt_nodiscard, Opt_discard_minblk,
d337f35e
JR
3533+ Opt_tag, Opt_notag, Opt_tagid
3534 };
3535
ec22aa5c 3536 static const match_table_t tokens = {
cc23e853 3537@@ -216,6 +217,10 @@ static const match_table_t tokens = {
d337f35e
JR
3538 {Opt_resize, "resize=%u"},
3539 {Opt_resize_nosize, "resize"},
3540 {Opt_errors, "errors=%s"},
3541+ {Opt_tag, "tag"},
3542+ {Opt_notag, "notag"},
3543+ {Opt_tagid, "tagid=%u"},
3544+ {Opt_tag, "tagxid"},
3545 {Opt_ignore, "noquota"},
3546 {Opt_ignore, "quota"},
3547 {Opt_usrquota, "usrquota"},
cc23e853 3548@@ -405,7 +410,20 @@ static int parse_options(char *options,
bb20add7 3549 pr_err("JFS: discard option not supported on device\n");
d337f35e
JR
3550 break;
3551 }
537831f9 3552-
d337f35e
JR
3553+#ifndef CONFIG_TAGGING_NONE
3554+ case Opt_tag:
3555+ *flag |= JFS_TAGGED;
3556+ break;
3557+ case Opt_notag:
3558+ *flag &= JFS_TAGGED;
3559+ break;
3560+#endif
3561+#ifdef CONFIG_PROPAGATE
3562+ case Opt_tagid:
3563+ /* use args[0] */
3564+ *flag |= JFS_TAGGED;
3565+ break;
3566+#endif
3567 default:
bb20add7
AM
3568 printk("jfs: Unrecognized mount option \"%s\" or missing value\n",
3569 p);
cc23e853 3570@@ -437,6 +455,12 @@ static int jfs_remount(struct super_bloc
bb20add7 3571 if (!parse_options(data, sb, &newLVSize, &flag))
d337f35e 3572 return -EINVAL;
ab30d09f 3573
d337f35e
JR
3574+ if ((flag & JFS_TAGGED) && !(sb->s_flags & MS_TAGGED)) {
3575+ printk(KERN_ERR "JFS: %s: tagging not permitted on remount.\n",
3576+ sb->s_id);
3577+ return -EINVAL;
3578+ }
3579+
3580 if (newLVSize) {
3581 if (sb->s_flags & MS_RDONLY) {
bb20add7
AM
3582 pr_err("JFS: resize requires volume to be mounted read-write\n");
3583@@ -517,6 +541,9 @@ static int jfs_fill_super(struct super_b
d337f35e
JR
3584 #ifdef CONFIG_JFS_POSIX_ACL
3585 sb->s_flags |= MS_POSIXACL;
3586 #endif
3587+ /* map mount option tagxid */
3588+ if (sbi->flag & JFS_TAGGED)
3589+ sb->s_flags |= MS_TAGGED;
3590
3591 if (newLVSize) {
537831f9 3592 pr_err("resize option for remount only\n");
3261cfd5
AM
3593diff -NurpP --minimal linux-4.9.207/fs/libfs.c linux-4.9.207-vs2.3.9.11/fs/libfs.c
3594--- linux-4.9.207/fs/libfs.c 2019-12-25 15:28:37.237317786 +0000
3595+++ linux-4.9.207-vs2.3.9.11/fs/libfs.c 2019-10-22 13:49:06.407707139 +0000
cc23e853 3596@@ -180,7 +180,8 @@ static inline unsigned char dt_type(stru
d337f35e
JR
3597 * both impossible due to the lock on directory.
3598 */
3599
c2e5f7c8 3600-int dcache_readdir(struct file *file, struct dir_context *ctx)
cc23e853 3601+static inline int do_dcache_readdir_filter(struct file *file,
c2e5f7c8 3602+ struct dir_context *ctx, int (*filter)(struct dentry *dentry))
d337f35e 3603 {
cc23e853
AM
3604 struct dentry *dentry = file->f_path.dentry;
3605 struct dentry *cursor = file->private_data;
3261cfd5 3606@@ -197,9 +198,10 @@ int dcache_readdir(struct file *file, st
d12544d8
JR
3607 p = &cursor->d_child;
3608
3609 while ((p = scan_positives(cursor, p, 1, &next)) != anchor) {
cc23e853
AM
3610- if (!dir_emit(ctx, next->d_name.name, next->d_name.len,
3611+ if (!filter || filter(next))
3612+ if (!dir_emit(ctx, next->d_name.name, next->d_name.len,
3613 d_inode(next)->i_ino, dt_type(d_inode(next))))
3614- break;
3615+ break;
cc23e853 3616 ctx->pos++;
d12544d8
JR
3617 }
3618 spin_lock(&dentry->d_lock);
3261cfd5
AM
3619@@ -209,8 +211,22 @@ int dcache_readdir(struct file *file, st
3620
d337f35e
JR
3621 return 0;
3622 }
c2e5f7c8
JR
3623+
3624 EXPORT_SYMBOL(dcache_readdir);
d337f35e 3625
c2e5f7c8 3626+int dcache_readdir(struct file *filp, struct dir_context *ctx)
d337f35e 3627+{
c2e5f7c8 3628+ return do_dcache_readdir_filter(filp, ctx, NULL);
d337f35e
JR
3629+}
3630+
c2e5f7c8
JR
3631+EXPORT_SYMBOL(dcache_readdir_filter);
3632+
3633+int dcache_readdir_filter(struct file *filp, struct dir_context *ctx,
d337f35e
JR
3634+ int (*filter)(struct dentry *))
3635+{
c2e5f7c8 3636+ return do_dcache_readdir_filter(filp, ctx, filter);
d337f35e 3637+}
d337f35e
JR
3638+
3639 ssize_t generic_read_dir(struct file *filp, char __user *buf, size_t siz, loff_t *ppos)
3640 {
3641 return -EISDIR;
3261cfd5
AM
3642diff -NurpP --minimal linux-4.9.207/fs/locks.c linux-4.9.207-vs2.3.9.11/fs/locks.c
3643--- linux-4.9.207/fs/locks.c 2016-12-11 19:17:54.000000000 +0000
3644+++ linux-4.9.207-vs2.3.9.11/fs/locks.c 2018-10-20 04:58:14.000000000 +0000
cc23e853
AM
3645@@ -127,6 +127,8 @@
3646 #include <linux/pid_namespace.h>
c2e5f7c8
JR
3647 #include <linux/hashtable.h>
3648 #include <linux/percpu.h>
d337f35e
JR
3649+#include <linux/vs_base.h>
3650+#include <linux/vs_limit.h>
3651
bb20add7
AM
3652 #define CREATE_TRACE_POINTS
3653 #include <trace/events/filelock.h>
cc23e853 3654@@ -292,11 +294,15 @@ static void locks_init_lock_heads(struct
d337f35e 3655 /* Allocate an empty lock structure. */
ab30d09f 3656 struct file_lock *locks_alloc_lock(void)
d337f35e 3657 {
a168f21d 3658- struct file_lock *fl = kmem_cache_zalloc(filelock_cache, GFP_KERNEL);
a0a3e0cf 3659+ struct file_lock *fl;
a168f21d
AM
3660
3661- if (fl)
3662- locks_init_lock_heads(fl);
a168f21d 3663+ fl = kmem_cache_zalloc(filelock_cache, GFP_KERNEL);
cc23e853 3664
a168f21d
AM
3665+ if (fl) {
3666+ locks_init_lock_heads(fl);
cc23e853 3667+ vx_locks_inc(fl);
a168f21d
AM
3668+ fl->fl_xid = -1;
3669+ }
3670 return fl;
3671 }
3672 EXPORT_SYMBOL_GPL(locks_alloc_lock);
cc23e853 3673@@ -348,6 +354,7 @@ void locks_init_lock(struct file_lock *f
a168f21d
AM
3674 {
3675 memset(fl, 0, sizeof(struct file_lock));
3676 locks_init_lock_heads(fl);
3677+ fl->fl_xid = -1;
3678 }
3679
3680 EXPORT_SYMBOL(locks_init_lock);
cc23e853 3681@@ -365,6 +372,7 @@ void locks_copy_conflock(struct file_loc
bb20add7
AM
3682 new->fl_start = fl->fl_start;
3683 new->fl_end = fl->fl_end;
d337f35e
JR
3684 new->fl_lmops = fl->fl_lmops;
3685+ new->fl_xid = fl->fl_xid;
bb20add7 3686 new->fl_ops = NULL;
d337f35e 3687
bb20add7 3688 if (fl->fl_lmops) {
cc23e853 3689@@ -426,7 +434,10 @@ flock_make_lock(struct file *filp, unsig
d337f35e
JR
3690 fl->fl_flags = FL_FLOCK;
3691 fl->fl_type = type;
3692 fl->fl_end = OFFSET_MAX;
cc23e853 3693-
d337f35e
JR
3694+
3695+ vxd_assert(filp->f_xid == vx_current_xid(),
3696+ "f_xid(%d) == current(%d)", filp->f_xid, vx_current_xid());
3697+ fl->fl_xid = filp->f_xid;
bb20add7
AM
3698 return fl;
3699 }
cc23e853
AM
3700
3701@@ -548,6 +559,7 @@ static int lease_init(struct file *filp,
d337f35e 3702
bb20add7 3703 fl->fl_owner = filp;
d337f35e
JR
3704 fl->fl_pid = current->tgid;
3705+ fl->fl_xid = vx_current_xid();
3706
3707 fl->fl_file = filp;
3708 fl->fl_flags = FL_LEASE;
cc23e853 3709@@ -567,6 +579,10 @@ static struct file_lock *lease_alloc(str
d337f35e 3710 if (fl == NULL)
2380c486 3711 return ERR_PTR(error);
d337f35e
JR
3712
3713+ fl->fl_xid = vx_current_xid();
3714+ if (filp)
3715+ vxd_assert(filp->f_xid == fl->fl_xid,
3716+ "f_xid(%d) == fl_xid(%d)", filp->f_xid, fl->fl_xid);
d337f35e
JR
3717 error = lease_init(filp, type, fl);
3718 if (error) {
3719 locks_free_lock(fl);
cc23e853
AM
3720@@ -956,6 +972,7 @@ static int flock_lock_inode(struct inode
3721 goto out;
ab30d09f 3722 }
2380c486
JR
3723
3724+ new_fl->fl_xid = -1;
3725 find_conflict:
cc23e853
AM
3726 list_for_each_entry(fl, &ctx->flc_flock, fl_list) {
3727 if (!flock_locks_conflict(request, fl))
3728@@ -984,7 +1001,7 @@ out:
d337f35e
JR
3729 }
3730
cc23e853
AM
3731 static int posix_lock_inode(struct inode *inode, struct file_lock *request,
3732- struct file_lock *conflock)
3733+ struct file_lock *conflock, vxid_t xid)
d337f35e 3734 {
cc23e853 3735 struct file_lock *fl, *tmp;
d337f35e 3736 struct file_lock *new_fl = NULL;
cc23e853
AM
3737@@ -1000,6 +1017,9 @@ static int posix_lock_inode(struct inode
3738 if (!ctx)
3739 return (request->fl_type == F_UNLCK) ? 0 : -ENOMEM;
d337f35e 3740
cc23e853
AM
3741+ if (xid)
3742+ vxd_assert(xid == vx_current_xid(),
3743+ "xid(%d) == current(%d)", xid, vx_current_xid());
d337f35e
JR
3744 /*
3745 * We may need two file_lock structures for this operation,
3746 * so we get them in advance to avoid races.
cc23e853 3747@@ -1010,7 +1030,11 @@ static int posix_lock_inode(struct inode
d337f35e
JR
3748 (request->fl_type != F_UNLCK ||
3749 request->fl_start != 0 || request->fl_end != OFFSET_MAX)) {
3750 new_fl = locks_alloc_lock();
3751+ new_fl->fl_xid = xid;
cc23e853 3752+ // vx_locks_inc(new_fl);
d337f35e
JR
3753 new_fl2 = locks_alloc_lock();
3754+ new_fl2->fl_xid = xid;
cc23e853 3755+ // vx_locks_inc(new_fl2);
d337f35e
JR
3756 }
3757
cc23e853
AM
3758 percpu_down_read_preempt_disable(&file_rwsem);
3759@@ -1216,7 +1240,7 @@ static int posix_lock_inode(struct inode
2380c486 3760 int posix_lock_file(struct file *filp, struct file_lock *fl,
d337f35e
JR
3761 struct file_lock *conflock)
3762 {
cc23e853
AM
3763- return posix_lock_inode(locks_inode(filp), fl, conflock);
3764+ return posix_lock_inode(locks_inode(filp), fl, conflock, filp->f_xid);
d337f35e 3765 }
2380c486 3766 EXPORT_SYMBOL(posix_lock_file);
d337f35e 3767
cc23e853
AM
3768@@ -1232,7 +1256,7 @@ static int posix_lock_inode_wait(struct
3769 int error;
3770 might_sleep ();
3771 for (;;) {
3772- error = posix_lock_inode(inode, fl, NULL);
3773+ error = posix_lock_inode(inode, fl, NULL, 0);
3774 if (error != FILE_LOCK_DEFERRED)
3775 break;
3776 error = wait_event_interruptible(fl->fl_wait, !fl->fl_next);
3777@@ -1308,10 +1332,13 @@ int locks_mandatory_area(struct inode *i
3778 fl.fl_end = end;
3779
3780 for (;;) {
3781+ vxid_t f_xid = 0;
3782+
ca5d134c 3783 if (filp) {
bb20add7 3784 fl.fl_owner = filp;
ca5d134c 3785 fl.fl_flags &= ~FL_SLEEP;
cc23e853
AM
3786- error = posix_lock_inode(inode, &fl, NULL);
3787+ f_xid = filp->f_xid;
3788+ error = posix_lock_inode(inode, &fl, NULL, f_xid);
ca5d134c
JR
3789 if (!error)
3790 break;
3791 }
cc23e853 3792@@ -1319,7 +1346,7 @@ int locks_mandatory_area(struct inode *i
ca5d134c
JR
3793 if (sleep)
3794 fl.fl_flags |= FL_SLEEP;
3795 fl.fl_owner = current->files;
cc23e853
AM
3796- error = posix_lock_inode(inode, &fl, NULL);
3797+ error = posix_lock_inode(inode, &fl, NULL, f_xid);
2380c486 3798 if (error != FILE_LOCK_DEFERRED)
d337f35e 3799 break;
2380c486 3800 error = wait_event_interruptible(fl.fl_wait, !fl.fl_next);
cc23e853 3801@@ -2374,6 +2401,16 @@ int fcntl_setlk64(unsigned int fd, struc
d337f35e
JR
3802 if (file_lock == NULL)
3803 return -ENOLCK;
3804
3805+ vxd_assert(filp->f_xid == vx_current_xid(),
3806+ "f_xid(%d) == current(%d)", filp->f_xid, vx_current_xid());
3807+ file_lock->fl_xid = filp->f_xid;
cc23e853 3808+ // vx_locks_inc(file_lock);
d337f35e 3809+
d337f35e
JR
3810+ vxd_assert(filp->f_xid == vx_current_xid(),
3811+ "f_xid(%d) == current(%d)", filp->f_xid, vx_current_xid());
3812+ file_lock->fl_xid = filp->f_xid;
cc23e853 3813+ // vx_locks_inc(file_lock);
d337f35e
JR
3814+
3815 /*
3816 * This might block, so we do it before checking the inode.
3817 */
cc23e853 3818@@ -2710,8 +2747,11 @@ static int locks_show(struct seq_file *f
2380c486 3819
c2e5f7c8 3820 lock_get_status(f, fl, iter->li_pos, "");
2380c486
JR
3821
3822- list_for_each_entry(bfl, &fl->fl_block, fl_block)
3823+ list_for_each_entry(bfl, &fl->fl_block, fl_block) {
3824+ if (!vx_check(fl->fl_xid, VS_WATCH_P | VS_IDENT))
d337f35e 3825+ continue;
bb20add7 3826 lock_get_status(f, bfl, iter->li_pos, " ->");
2380c486 3827+ }
d337f35e 3828
2380c486 3829 return 0;
ab30d09f 3830 }
3261cfd5
AM
3831diff -NurpP --minimal linux-4.9.207/fs/mount.h linux-4.9.207-vs2.3.9.11/fs/mount.h
3832--- linux-4.9.207/fs/mount.h 2019-12-25 15:28:37.257317461 +0000
3833+++ linux-4.9.207-vs2.3.9.11/fs/mount.h 2018-10-20 04:58:14.000000000 +0000
cc23e853 3834@@ -69,6 +69,7 @@ struct mount {
bb20add7 3835 struct hlist_head mnt_pins;
cc23e853
AM
3836 struct fs_pin mnt_umount;
3837 struct dentry *mnt_ex_mountpoint;
61333608 3838+ vtag_t mnt_tag; /* tagging used for vfsmount */
db55b927
AM
3839 };
3840
92598135 3841 #define MNT_NS_INTERNAL ERR_PTR(-EINVAL) /* distinct from any mnt_namespace */
3261cfd5
AM
3842diff -NurpP --minimal linux-4.9.207/fs/namei.c linux-4.9.207-vs2.3.9.11/fs/namei.c
3843--- linux-4.9.207/fs/namei.c 2019-12-25 15:28:37.257317461 +0000
3844+++ linux-4.9.207-vs2.3.9.11/fs/namei.c 2019-02-22 08:37:55.023061290 +0000
cc23e853
AM
3845@@ -37,9 +37,19 @@
3846 #include <linux/hash.h>
3847 #include <linux/bitops.h>
3848 #include <linux/init_task.h>
d337f35e 3849+#include <linux/proc_fs.h>
09be7631 3850+#include <linux/magic.h>
d337f35e
JR
3851+#include <linux/vserver/inode.h>
3852+#include <linux/vs_base.h>
3853+#include <linux/vs_tag.h>
3854+#include <linux/vs_cowbl.h>
2380c486
JR
3855+#include <linux/vs_device.h>
3856+#include <linux/vs_context.h>
3857+#include <linux/pid_namespace.h>
d337f35e
JR
3858 #include <asm/uaccess.h>
3859
2bf5ad28 3860 #include "internal.h"
09be7631
JR
3861+#include "proc/internal.h"
3862 #include "mount.h"
3863
3864 /* [Feb-1997 T. Schoebel-Theuer]
09a55596 3865@@ -286,6 +296,93 @@ static int check_acl(struct inode *inode
a168f21d
AM
3866 return -EAGAIN;
3867 }
d337f35e 3868
7e46296a 3869+static inline int dx_barrier(const struct inode *inode)
d337f35e 3870+{
2380c486
JR
3871+ if (IS_BARRIER(inode) && !vx_check(0, VS_ADMIN | VS_WATCH)) {
3872+ vxwprintk_task(1, "did hit the barrier.");
d337f35e
JR
3873+ return 1;
3874+ }
3875+ return 0;
3876+}
3877+
7e46296a 3878+static int __dx_permission(const struct inode *inode, int mask)
d337f35e
JR
3879+{
3880+ if (dx_barrier(inode))
3881+ return -EACCES;
d337f35e 3882+
2380c486
JR
3883+ if (inode->i_sb->s_magic == DEVPTS_SUPER_MAGIC) {
3884+ /* devpts is xid tagged */
3885+ if (S_ISDIR(inode->i_mode) ||
61333608 3886+ vx_check((vxid_t)i_tag_read(inode), VS_IDENT | VS_WATCH_P))
2380c486 3887+ return 0;
ba86f833 3888+
adc1caaa 3889+ /* just pretend we didn't find anything */
ba86f833 3890+ return -ENOENT;
2380c486
JR
3891+ }
3892+ else if (inode->i_sb->s_magic == PROC_SUPER_MAGIC) {
3893+ struct proc_dir_entry *de = PDE(inode);
3894+
bb20add7
AM
3895+ if (de && !vx_hide_check(0, de->vx_flags)) {
3896+ vxdprintk(VXD_CBIT(misc, 9),
3897+ VS_Q("%*s") " hidden by _dx_permission",
3898+ de->namelen, de->name);
2380c486 3899+ goto out;
bb20add7 3900+ }
2380c486
JR
3901+
3902+ if ((mask & (MAY_WRITE | MAY_APPEND))) {
3903+ struct pid *pid;
3904+ struct task_struct *tsk;
3905+
3906+ if (vx_check(0, VS_ADMIN | VS_WATCH_P) ||
3907+ vx_flags(VXF_STATE_SETUP, 0))
3908+ return 0;
3909+
3910+ pid = PROC_I(inode)->pid;
3911+ if (!pid)
3912+ goto out;
3913+
c6ceaf95 3914+ rcu_read_lock();
2380c486
JR
3915+ tsk = pid_task(pid, PIDTYPE_PID);
3916+ vxdprintk(VXD_CBIT(tag, 0), "accessing %p[#%u]",
3917+ tsk, (tsk ? vx_task_xid(tsk) : 0));
c6ceaf95
AM
3918+ if (tsk &&
3919+ vx_check(vx_task_xid(tsk), VS_IDENT | VS_WATCH_P)) {
3920+ rcu_read_unlock();
2380c486 3921+ return 0;
c6ceaf95
AM
3922+ }
3923+ rcu_read_unlock();
2380c486
JR
3924+ }
3925+ else {
3926+ /* FIXME: Should we block some entries here? */
3927+ return 0;
3928+ }
3929+ }
3930+ else {
3931+ if (dx_notagcheck(inode->i_sb) ||
61333608 3932+ dx_check((vxid_t)i_tag_read(inode),
537831f9 3933+ DX_HOSTID | DX_ADMIN | DX_WATCH | DX_IDENT))
2380c486
JR
3934+ return 0;
3935+ }
3936+
3937+out:
d337f35e
JR
3938+ return -EACCES;
3939+}
3940+
7e46296a 3941+int dx_permission(const struct inode *inode, int mask)
2380c486
JR
3942+{
3943+ int ret = __dx_permission(inode, mask);
3944+ if (unlikely(ret)) {
ba86f833
AM
3945+#ifndef CONFIG_VSERVER_WARN_DEVPTS
3946+ if (inode->i_sb->s_magic != DEVPTS_SUPER_MAGIC)
3947+#endif
3948+ vxwprintk_task(1,
3949+ "denied [0x%x] access to inode %s:%p[#%d,%lu]",
8ce283e1
AM
3950+ mask, inode->i_sb->s_id, inode,
3951+ i_tag_read(inode), inode->i_ino);
2380c486
JR
3952+ }
3953+ return ret;
3954+}
3955+
7e46296a 3956 /*
f6c5ef8b 3957 * This does the basic permission checking
7e46296a 3958 */
09a55596 3959@@ -410,7 +507,7 @@ int __inode_permission(struct inode *ino
d337f35e
JR
3960 /*
3961 * Nobody gets write access to an immutable file.
3962 */
3963- if (IS_IMMUTABLE(inode))
3964+ if (IS_IMMUTABLE(inode) && !IS_COW(inode))
cc23e853
AM
3965 return -EPERM;
3966
3967 /*
09a55596 3968@@ -422,6 +519,10 @@ int __inode_permission(struct inode *ino
d337f35e
JR
3969 return -EACCES;
3970 }
3971
2380c486
JR
3972+ retval = dx_permission(inode, mask);
3973+ if (retval)
d337f35e 3974+ return retval;
2380c486 3975+
a168f21d
AM
3976 retval = do_inode_permission(inode, mask);
3977 if (retval)
3978 return retval;
3261cfd5 3979@@ -2824,7 +2925,7 @@ static int may_delete(struct inode *dir,
d337f35e 3980 return -EPERM;
c2e5f7c8
JR
3981
3982 if (check_sticky(dir, inode) || IS_APPEND(inode) ||
cc23e853
AM
3983- IS_IMMUTABLE(inode) || IS_SWAPFILE(inode) || HAS_UNMAPPED_ID(inode))
3984+ IS_IXORUNLINK(inode) || IS_SWAPFILE(inode) || HAS_UNMAPPED_ID(inode))
d337f35e
JR
3985 return -EPERM;
3986 if (isdir) {
bb20add7 3987 if (!d_is_dir(victim))
3261cfd5 3988@@ -2912,19 +3013,25 @@ int vfs_create(struct inode *dir, struct
92598135 3989 bool want_excl)
a168f21d
AM
3990 {
3991 int error = may_create(dir, dentry);
a168f21d
AM
3992- if (error)
3993+ if (error) {
3994+ vxdprintk(VXD_CBIT(misc, 3), "may_create failed with %d", error);
537831f9 3995 return error;
a168f21d
AM
3996+ }
3997
3998 if (!dir->i_op->create)
3999 return -EACCES; /* shouldn't it be ENOSYS? */
4000 mode &= S_IALLUGO;
4001 mode |= S_IFREG;
4002 error = security_inode_create(dir, dentry, mode);
4003- if (error)
4004+ if (error) {
4005+ vxdprintk(VXD_CBIT(misc, 3), "security_inode_create failed with %d", error);
537831f9 4006 return error;
a168f21d 4007+ }
92598135 4008 error = dir->i_op->create(dir, dentry, mode, want_excl);
a168f21d
AM
4009 if (!error)
4010 fsnotify_create(dir, dentry);
4011+ else
4012+ vxdprintk(VXD_CBIT(misc, 3), "i_op->create failed with %d", error);
4013 return error;
4014 }
bb20add7 4015 EXPORT_SYMBOL(vfs_create);
3261cfd5 4016@@ -2962,6 +3069,15 @@ static int may_open(struct path *path, i
ec22aa5c 4017 break;
2380c486 4018 }
d337f35e
JR
4019
4020+#ifdef CONFIG_VSERVER_COWBL
763640ca
JR
4021+ if (IS_COW(inode) &&
4022+ ((flag & O_ACCMODE) != O_RDONLY)) {
d337f35e
JR
4023+ if (IS_COW_LINK(inode))
4024+ return -EMLINK;
2380c486 4025+ inode->i_flags &= ~(S_IXUNLINK|S_IMMUTABLE);
d337f35e
JR
4026+ mark_inode_dirty(inode);
4027+ }
4028+#endif
cc23e853 4029 error = inode_permission(inode, MAY_OPEN | acc_mode);
d337f35e
JR
4030 if (error)
4031 return error;
3261cfd5 4032@@ -3420,6 +3536,16 @@ finish_open:
7b17263b 4033 }
92598135 4034 finish_open_created:
7b17263b
AM
4035 error = may_open(&nd->path, acc_mode, open_flag);
4036+#ifdef CONFIG_VSERVER_COWBL
4037+ if (error == -EMLINK) {
4038+ struct dentry *dentry;
cc23e853 4039+ dentry = cow_break_link(nd->name->name);
7b17263b
AM
4040+ if (IS_ERR(dentry))
4041+ error = PTR_ERR(dentry);
4042+ else
4043+ dput(dentry);
4044+ }
4045+#endif
4046 if (error)
92598135 4047 goto out;
cc23e853 4048 BUG_ON(*opened & FILE_OPENED); /* once it's opened, it's opened */
3261cfd5 4049@@ -3523,6 +3649,9 @@ static struct file *path_openat(struct n
92598135 4050 int opened = 0;
7b17263b
AM
4051 int error;
4052
cc23e853 4053+#ifdef CONFIG_VSERVER_COWBL
7b17263b 4054+restart:
cc23e853 4055+#endif
92598135 4056 file = get_empty_filp();
b00e13aa
AM
4057 if (IS_ERR(file))
4058 return file;
3261cfd5 4059@@ -3556,6 +3685,12 @@ static struct file *path_openat(struct n
cc23e853 4060 }
7b17263b 4061 }
cc23e853 4062 terminate_walk(nd);
7b17263b 4063+#ifdef CONFIG_VSERVER_COWBL
e915af4e 4064+ if (error == -EMLINK) {
cc23e853 4065+ // path_cleanup(nd);
7b17263b
AM
4066+ goto restart;
4067+ }
4068+#endif
cc23e853
AM
4069 out2:
4070 if (!(opened & FILE_OPENED)) {
4071 BUG_ON(!error);
3261cfd5 4072@@ -3676,6 +3811,11 @@ static struct dentry *filename_create(in
a168f21d
AM
4073 goto fail;
4074 }
cc23e853
AM
4075 putname(name);
4076+ vxdprintk(VXD_CBIT(misc, 3), "filename_create path.dentry = %p (%.*s), dentry = %p (%.*s), d_inode = %p",
a168f21d
AM
4077+ path->dentry, path->dentry->d_name.len,
4078+ path->dentry->d_name.name, dentry,
4079+ dentry->d_name.len, dentry->d_name.name,
4080+ path->dentry->d_inode);
4081 return dentry;
92598135 4082 fail:
a168f21d 4083 dput(dentry);
3261cfd5 4084@@ -3794,6 +3934,7 @@ retry:
cc23e853
AM
4085 error = vfs_mknod(path.dentry->d_inode,dentry,mode,0);
4086 break;
4087 }
4088+
4089 out:
4090 done_path_create(&path, dentry);
4091 if (retry_estale(error, lookup_flags)) {
3261cfd5 4092@@ -4215,7 +4356,7 @@ int vfs_link(struct dentry *old_dentry,
d337f35e
JR
4093 /*
4094 * A link to an append-only or immutable file cannot be created.
4095 */
4096- if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
4097+ if (IS_APPEND(inode) || IS_IXORUNLINK(inode))
4098 return -EPERM;
cc23e853
AM
4099 /*
4100 * Updating the link count will likely cause i_uid and i_gid to
3261cfd5 4101@@ -4745,6 +4886,326 @@ const char *vfs_get_link(struct dentry *
d337f35e 4102 }
cc23e853 4103 EXPORT_SYMBOL(vfs_get_link);
d337f35e
JR
4104
4105+
4106+#ifdef CONFIG_VSERVER_COWBL
4107+
2380c486 4108+static inline
cc23e853
AM
4109+void dump_path(const char *name, struct path *path)
4110+{
4111+ vxdprintk(VXD_CBIT(misc, 3),
4112+ "%s: path=%p mnt=%p dentry=%p", name, path,
4113+ path ? path->mnt : NULL,
4114+ path ? path->dentry : NULL);
4115+
4116+ if (path && path->mnt)
4117+ vxdprintk(VXD_CBIT(misc, 3),
4118+ "%s: path mnt_sb=%p[#%d,#%d] mnt_root=%p[#%d]", name,
4119+ path->mnt->mnt_sb,
4120+ path->mnt->mnt_sb ? path->mnt->mnt_sb->s_count : -1,
4121+ path->mnt->mnt_sb ? atomic_read(&path->mnt->mnt_sb->s_active) : -1,
4122+ path->mnt->mnt_root,
4123+ path->mnt->mnt_root ? path->mnt->mnt_root->d_lockref.count : -1);
4124+
4125+ if (path && path->dentry)
4126+ vxdprintk(VXD_CBIT(misc, 3),
4127+ "%s: path dentry=%p[#%d]", name,
4128+ path->dentry,
4129+ path->dentry ? path->dentry->d_lockref.count : -1);
4130+}
4131+
4132+static inline
2380c486
JR
4133+long do_cow_splice(struct file *in, struct file *out, size_t len)
4134+{
4135+ loff_t ppos = 0;
09be7631 4136+ loff_t opos = 0;
2380c486 4137+
09be7631 4138+ return do_splice_direct(in, &ppos, out, &opos, len, 0);
2380c486
JR
4139+}
4140+
d337f35e
JR
4141+struct dentry *cow_break_link(const char *pathname)
4142+{
b00e13aa 4143+ int ret, mode, pathlen, redo = 0, drop = 1;
cc23e853 4144+ struct path old_path = {}, par_path = {}, dir_path = {}, *new_path = NULL;
a168f21d 4145+ struct dentry *dir, *old_dentry, *new_dentry = NULL;
d337f35e
JR
4146+ struct file *old_file;
4147+ struct file *new_file;
cc23e853
AM
4148+ struct qstr new_qstr;
4149+ int new_type;
d337f35e
JR
4150+ char *to, *path, pad='\251';
4151+ loff_t size;
cc23e853
AM
4152+ struct filename *filename = getname_kernel(pathname);
4153+ struct filename *to_filename;
d337f35e 4154+
ba86f833
AM
4155+ vxdprintk(VXD_CBIT(misc, 1),
4156+ "cow_break_link(" VS_Q("%s") ")", pathname);
e915af4e 4157+
d337f35e 4158+ path = kmalloc(PATH_MAX, GFP_KERNEL);
2380c486 4159+ ret = -ENOMEM;
cc23e853 4160+ if (!path || IS_ERR(filename))
2380c486 4161+ goto out;
d337f35e 4162+
cc23e853
AM
4163+ /* old_path will have refs to dentry and mnt */
4164+ ret = filename_lookup(AT_FDCWD, filename, LOOKUP_FOLLOW, &old_path, NULL);
a168f21d 4165+ vxdprintk(VXD_CBIT(misc, 2),
e915af4e 4166+ "do_path_lookup(old): %d", ret);
2380c486
JR
4167+ if (ret < 0)
4168+ goto out_free_path;
d337f35e 4169+
cc23e853
AM
4170+ dump_path("cow (old)", &old_path);
4171+
e915af4e 4172+ /* no explicit reference for old_dentry here */
cc23e853 4173+ old_dentry = old_path.dentry;
2380c486 4174+
e915af4e 4175+ mode = old_dentry->d_inode->i_mode;
cc23e853 4176+ to = d_path(&old_path, path, PATH_MAX-2);
d337f35e 4177+ pathlen = strlen(to);
ba86f833 4178+ vxdprintk(VXD_CBIT(misc, 2),
a168f21d
AM
4179+ "old path " VS_Q("%s") " [%p:" VS_Q("%.*s") ":%d]", to,
4180+ old_dentry,
4181+ old_dentry->d_name.len, old_dentry->d_name.name,
4182+ old_dentry->d_name.len);
d337f35e 4183+
2380c486 4184+ to[pathlen + 1] = 0;
d337f35e 4185+retry:
a168f21d 4186+ new_dentry = NULL;
d337f35e 4187+ to[pathlen] = pad--;
a168f21d 4188+ ret = -ELOOP;
d337f35e
JR
4189+ if (pad <= '\240')
4190+ goto out_rel_old;
4191+
ba86f833 4192+ vxdprintk(VXD_CBIT(misc, 1), "temp copy " VS_Q("%s"), to);
e915af4e 4193+
cc23e853
AM
4194+ /* dir_path will have refs to dentry and mnt */
4195+ to_filename = getname_kernel(to);
4196+ to_filename = filename_parentat(AT_FDCWD, to_filename,
4197+ LOOKUP_PARENT | LOOKUP_OPEN | LOOKUP_CREATE, &par_path, &new_qstr, &new_type);
4198+ vxdprintk(VXD_CBIT(misc, 2), "filename_parentat(new): %p", to_filename);
4199+ dump_path("cow (par)", &par_path);
4200+ if (IS_ERR(to_filename))
2380c486
JR
4201+ goto retry;
4202+
cc23e853
AM
4203+ vxdprintk(VXD_CBIT(misc, 2), "to_filename refcnt=%d", to_filename->refcnt);
4204+
e915af4e
AM
4205+ /* this puppy downs the dir inode mutex if successful.
4206+ dir_path will hold refs to dentry and mnt and
b00e13aa 4207+ we'll have write access to the mnt */
cc23e853 4208+ new_dentry = filename_create(AT_FDCWD, to_filename, &dir_path, 0);
a168f21d 4209+ if (!new_dentry || IS_ERR(new_dentry)) {
cc23e853 4210+ path_put(&par_path);
a168f21d 4211+ vxdprintk(VXD_CBIT(misc, 2),
cc23e853 4212+ "filename_create(new) failed with %ld",
a168f21d 4213+ PTR_ERR(new_dentry));
d337f35e
JR
4214+ goto retry;
4215+ }
2380c486 4216+ vxdprintk(VXD_CBIT(misc, 2),
cc23e853 4217+ "filename_create(new): %p [" VS_Q("%.*s") ":%d]",
a168f21d
AM
4218+ new_dentry,
4219+ new_dentry->d_name.len, new_dentry->d_name.name,
4220+ new_dentry->d_name.len);
4221+
cc23e853
AM
4222+ dump_path("cow (dir)", &dir_path);
4223+
e915af4e
AM
4224+ /* take a reference on new_dentry */
4225+ dget(new_dentry);
4226+
4227+ /* dentry/mnt refs handed over to new_path */
4228+ new_path = &dir_path;
4229+
4230+ /* dentry for old/new dir */
cc23e853 4231+ dir = par_path.dentry;
d337f35e 4232+
e915af4e
AM
4233+ /* give up reference on dir */
4234+ dput(new_path->dentry);
4235+
4236+ /* new_dentry already has a reference */
4237+ new_path->dentry = new_dentry;
4238+
4239+ ret = vfs_create(dir->d_inode, new_dentry, mode, 1);
d337f35e
JR
4240+ vxdprintk(VXD_CBIT(misc, 2),
4241+ "vfs_create(new): %d", ret);
4242+ if (ret == -EEXIST) {
cc23e853
AM
4243+ path_put(&par_path);
4244+ inode_unlock(dir->d_inode);
e915af4e
AM
4245+ mnt_drop_write(new_path->mnt);
4246+ path_put(new_path);
4247+ new_dentry = NULL;
d337f35e
JR
4248+ goto retry;
4249+ }
2380c486
JR
4250+ else if (ret < 0)
4251+ goto out_unlock_new;
4252+
cc23e853 4253+ /* the old file went away */
2380c486 4254+ ret = -ENOENT;
a168f21d 4255+ if ((redo = d_unhashed(old_dentry)))
2380c486
JR
4256+ goto out_unlock_new;
4257+
e915af4e 4258+ /* doesn't change refs for old_path */
cc23e853 4259+ old_file = dentry_open(&old_path, O_RDONLY, current_cred());
d337f35e
JR
4260+ vxdprintk(VXD_CBIT(misc, 2),
4261+ "dentry_open(old): %p", old_file);
a168f21d
AM
4262+ if (IS_ERR(old_file)) {
4263+ ret = PTR_ERR(old_file);
2380c486
JR
4264+ goto out_unlock_new;
4265+ }
d337f35e 4266+
e915af4e
AM
4267+ /* doesn't change refs for new_path */
4268+ new_file = dentry_open(new_path, O_WRONLY, current_cred());
d337f35e
JR
4269+ vxdprintk(VXD_CBIT(misc, 2),
4270+ "dentry_open(new): %p", new_file);
a168f21d
AM
4271+ if (IS_ERR(new_file)) {
4272+ ret = PTR_ERR(new_file);
d337f35e 4273+ goto out_fput_old;
a168f21d 4274+ }
d337f35e 4275+
cc23e853
AM
4276+ /* unlock the inode from filename_create() */
4277+ inode_unlock(dir->d_inode);
b00e13aa
AM
4278+
4279+ /* drop write access to mnt */
4280+ mnt_drop_write(new_path->mnt);
4281+
4282+ drop = 0;
4283+
cc23e853 4284+ size = i_size_read(old_file->f_path.dentry->d_inode);
2380c486
JR
4285+ ret = do_cow_splice(old_file, new_file, size);
4286+ vxdprintk(VXD_CBIT(misc, 2), "do_splice_direct: %d", ret);
4287+ if (ret < 0) {
d337f35e 4288+ goto out_fput_both;
2380c486
JR
4289+ } else if (ret < size) {
4290+ ret = -ENOSPC;
4291+ goto out_fput_both;
4292+ } else {
a168f21d
AM
4293+ struct inode *old_inode = old_dentry->d_inode;
4294+ struct inode *new_inode = new_dentry->d_inode;
2380c486
JR
4295+ struct iattr attr = {
4296+ .ia_uid = old_inode->i_uid,
4297+ .ia_gid = old_inode->i_gid,
4298+ .ia_valid = ATTR_UID | ATTR_GID
4299+ };
4300+
93de0823
AM
4301+ setattr_copy(new_inode, &attr);
4302+ mark_inode_dirty(new_inode);
2380c486 4303+ }
d337f35e 4304+
e915af4e 4305+ /* lock rename mutex */
a168f21d 4306+ mutex_lock(&old_dentry->d_inode->i_sb->s_vfs_rename_mutex);
2380c486
JR
4307+
4308+ /* drop out late */
4309+ ret = -ENOENT;
a168f21d 4310+ if ((redo = d_unhashed(old_dentry)))
2380c486
JR
4311+ goto out_unlock;
4312+
4313+ vxdprintk(VXD_CBIT(misc, 2),
ba86f833 4314+ "vfs_rename: [" VS_Q("%*s") ":%d] -> [" VS_Q("%*s") ":%d]",
a168f21d
AM
4315+ new_dentry->d_name.len, new_dentry->d_name.name,
4316+ new_dentry->d_name.len,
4317+ old_dentry->d_name.len, old_dentry->d_name.name,
4318+ old_dentry->d_name.len);
cc23e853 4319+ ret = vfs_rename(par_path.dentry->d_inode, new_dentry,
eafa5b1d 4320+ old_dentry->d_parent->d_inode, old_dentry, NULL, 0);
d337f35e 4321+ vxdprintk(VXD_CBIT(misc, 2), "vfs_rename: %d", ret);
2380c486
JR
4322+
4323+out_unlock:
a168f21d 4324+ mutex_unlock(&old_dentry->d_inode->i_sb->s_vfs_rename_mutex);
d337f35e
JR
4325+
4326+out_fput_both:
4327+ vxdprintk(VXD_CBIT(misc, 3),
2380c486 4328+ "fput(new_file=%p[#%ld])", new_file,
4a036bed 4329+ atomic_long_read(&new_file->f_count));
d337f35e
JR
4330+ fput(new_file);
4331+
4332+out_fput_old:
4333+ vxdprintk(VXD_CBIT(misc, 3),
2380c486 4334+ "fput(old_file=%p[#%ld])", old_file,
4a036bed 4335+ atomic_long_read(&old_file->f_count));
d337f35e
JR
4336+ fput(old_file);
4337+
2380c486 4338+out_unlock_new:
cc23e853
AM
4339+ /* drop references from par_path */
4340+ path_put(&par_path);
e915af4e 4341+
b00e13aa 4342+ if (drop) {
cc23e853
AM
4343+ /* unlock the inode from filename_create() */
4344+ inode_unlock(dir->d_inode);
b00e13aa
AM
4345+
4346+ /* drop write access to mnt */
4347+ mnt_drop_write(new_path->mnt);
4348+ }
e915af4e 4349+
2380c486
JR
4350+ if (!ret)
4351+ goto out_redo;
4352+
4353+ /* error path cleanup */
c2e5f7c8 4354+ vfs_unlink(dir->d_inode, new_dentry, NULL);
2380c486
JR
4355+
4356+out_redo:
4357+ if (!redo)
4358+ goto out_rel_both;
e915af4e
AM
4359+
4360+ /* lookup dentry once again
cc23e853
AM
4361+ old_path will be freed as old_path in out_rel_old */
4362+ ret = filename_lookup(AT_FDCWD, filename, LOOKUP_FOLLOW, &old_path, NULL);
2380c486
JR
4363+ if (ret)
4364+ goto out_rel_both;
d337f35e 4365+
e915af4e 4366+ /* drop reference on new_dentry */
a168f21d 4367+ dput(new_dentry);
cc23e853 4368+ new_dentry = old_path.dentry;
e915af4e 4369+ dget(new_dentry);
2380c486 4370+ vxdprintk(VXD_CBIT(misc, 2),
763640ca 4371+ "do_path_lookup(redo): %p [" VS_Q("%.*s") ":%d]",
a168f21d
AM
4372+ new_dentry,
4373+ new_dentry->d_name.len, new_dentry->d_name.name,
4374+ new_dentry->d_name.len);
2380c486
JR
4375+
4376+out_rel_both:
cc23e853 4377+ dump_path("put (new)", new_path);
e915af4e
AM
4378+ if (new_path)
4379+ path_put(new_path);
d337f35e 4380+out_rel_old:
cc23e853
AM
4381+ dump_path("put (old)", &old_path);
4382+ path_put(&old_path);
2380c486 4383+out_free_path:
d337f35e 4384+ kfree(path);
2380c486 4385+out:
a168f21d
AM
4386+ if (ret) {
4387+ dput(new_dentry);
4388+ new_dentry = ERR_PTR(ret);
4389+ }
cc23e853
AM
4390+ // if (!IS_ERR(filename))
4391+ // putname(filename);
a168f21d 4392+ vxdprintk(VXD_CBIT(misc, 3),
e915af4e 4393+ "cow_break_link returning with %p", new_dentry);
a168f21d 4394+ return new_dentry;
d337f35e
JR
4395+}
4396+
4397+#endif
1e8b8f9b
AM
4398+
4399+int vx_info_mnt_namespace(struct mnt_namespace *ns, char *buffer)
4400+{
4401+ struct path path;
4402+ struct vfsmount *vmnt;
4403+ char *pstr, *root;
4404+ int length = 0;
4405+
4406+ pstr = kmalloc(PATH_MAX, GFP_KERNEL);
4407+ if (!pstr)
4408+ return 0;
4409+
4410+ vmnt = &ns->root->mnt;
4411+ path.mnt = vmnt;
4412+ path.dentry = vmnt->mnt_root;
4413+ root = d_path(&path, pstr, PATH_MAX - 2);
4414+ length = sprintf(buffer + length,
4415+ "Namespace:\t%p [#%u]\n"
4416+ "RootPath:\t%s\n",
4417+ ns, atomic_read(&ns->count),
4418+ root);
4419+ kfree(pstr);
4420+ return length;
4421+}
bb20add7 4422+
265de2f7 4423+EXPORT_SYMBOL(vx_info_mnt_namespace);
d337f35e
JR
4424+
4425 /* get the link contents into pagecache */
cc23e853
AM
4426 const char *page_get_link(struct dentry *dentry, struct inode *inode,
4427 struct delayed_call *callback)
3261cfd5
AM
4428diff -NurpP --minimal linux-4.9.207/fs/namespace.c linux-4.9.207-vs2.3.9.11/fs/namespace.c
4429--- linux-4.9.207/fs/namespace.c 2019-12-25 15:28:37.257317461 +0000
4430+++ linux-4.9.207-vs2.3.9.11/fs/namespace.c 2019-02-22 08:37:55.023061290 +0000
978063ce 4431@@ -24,6 +24,11 @@
09be7631 4432 #include <linux/magic.h>
52afa9bd 4433 #include <linux/bootmem.h>
bb20add7 4434 #include <linux/task_work.h>
d337f35e 4435+#include <linux/vs_base.h>
d337f35e
JR
4436+#include <linux/vs_context.h>
4437+#include <linux/vs_tag.h>
2380c486
JR
4438+#include <linux/vserver/space.h>
4439+#include <linux/vserver/global.h>
d337f35e 4440 #include "pnode.h"
db55b927
AM
4441 #include "internal.h"
4442
09a55596 4443@@ -980,6 +985,10 @@ vfs_kern_mount(struct file_system_type *
be261992
AM
4444 if (!type)
4445 return ERR_PTR(-ENODEV);
4446
4447+ if ((type->fs_flags & FS_BINARY_MOUNTDATA) &&
4448+ !vx_capable(CAP_SYS_ADMIN, VXC_BINARY_MOUNT))
4449+ return ERR_PTR(-EPERM);
4450+
4451 mnt = alloc_vfsmnt(name);
4452 if (!mnt)
4453 return ERR_PTR(-ENOMEM);
09a55596 4454@@ -1071,6 +1080,7 @@ static struct mount *clone_mnt(struct mo
92598135
AM
4455 mnt->mnt.mnt_root = dget(root);
4456 mnt->mnt_mountpoint = mnt->mnt.mnt_root;
4457 mnt->mnt_parent = mnt;
c2e5f7c8
JR
4458+ mnt->mnt_tag = old->mnt_tag;
4459 lock_mount_hash();
92598135 4460 list_add_tail(&mnt->mnt_instance, &sb->s_mounts);
c2e5f7c8 4461 unlock_mount_hash();
3261cfd5 4462@@ -1666,7 +1676,8 @@ out_unlock:
c2e5f7c8
JR
4463 */
4464 static inline bool may_mount(void)
4465 {
4466- return ns_capable(current->nsproxy->mnt_ns->user_ns, CAP_SYS_ADMIN);
4467+ return vx_ns_capable(current->nsproxy->mnt_ns->user_ns,
4468+ CAP_SYS_ADMIN, VXC_SECURE_MOUNT);
4469 }
4470
cc23e853 4471 static inline bool may_mandlock(void)
3261cfd5 4472@@ -2181,6 +2192,7 @@ static int do_change_type(struct path *p
763640ca
JR
4473 if (err)
4474 goto out_unlock;
4475 }
4476+ // mnt->mnt_flags = mnt_flags;
4477
c2e5f7c8 4478 lock_mount_hash();
763640ca 4479 for (m = mnt; m; m = (recurse ? next_mnt(m, mnt) : NULL))
3261cfd5 4480@@ -2209,12 +2221,14 @@ static bool has_locked_children(struct m
ec22aa5c 4481 * do loopback mount.
d337f35e 4482 */
537831f9 4483 static int do_loopback(struct path *path, const char *old_name,
2380c486 4484- int recurse)
61333608 4485+ vtag_t tag, unsigned long flags, int mnt_flags)
d337f35e 4486 {
ec22aa5c 4487 struct path old_path;
09be7631
JR
4488 struct mount *mnt = NULL, *old, *parent;
4489 struct mountpoint *mp;
d337f35e 4490+ int recurse = flags & MS_REC;
b00e13aa 4491 int err;
2380c486 4492+
d337f35e 4493 if (!old_name || !*old_name)
b00e13aa
AM
4494 return -EINVAL;
4495 err = kern_path(old_name, LOOKUP_FOLLOW|LOOKUP_AUTOMOUNT, &old_path);
3261cfd5 4496@@ -2294,7 +2308,7 @@ static int change_mount_flags(struct vfs
ec22aa5c 4497 * on it - tough luck.
d337f35e 4498 */
ec22aa5c 4499 static int do_remount(struct path *path, int flags, int mnt_flags,
d337f35e 4500- void *data)
61333608 4501+ void *data, vxid_t xid)
d337f35e
JR
4502 {
4503 int err;
ec22aa5c 4504 struct super_block *sb = path->mnt->mnt_sb;
3261cfd5 4505@@ -2779,6 +2793,7 @@ long do_mount(const char *dev_name, cons
ec22aa5c 4506 struct path path;
d337f35e
JR
4507 int retval = 0;
4508 int mnt_flags = 0;
61333608 4509+ vtag_t tag = 0;
d337f35e
JR
4510
4511 /* Discard magic */
4512 if ((flags & MS_MGC_MSK) == MS_MGC_VAL)
3261cfd5 4513@@ -2806,6 +2821,12 @@ long do_mount(const char *dev_name, cons
ec22aa5c
AM
4514 if (!(flags & MS_NOATIME))
4515 mnt_flags |= MNT_RELATIME;
d337f35e 4516
2380c486
JR
4517+ if (dx_parse_tag(data_page, &tag, 1, &mnt_flags, &flags)) {
4518+ /* FIXME: bind and re-mounts get the tag flag? */
d337f35e
JR
4519+ if (flags & (MS_BIND|MS_REMOUNT))
4520+ flags |= MS_TAGID;
4521+ }
d337f35e
JR
4522+
4523 /* Separate the per-mountpoint flags */
d337f35e
JR
4524 if (flags & MS_NOSUID)
4525 mnt_flags |= MNT_NOSUID;
3261cfd5 4526@@ -2830,15 +2851,18 @@ long do_mount(const char *dev_name, cons
bb20add7
AM
4527 mnt_flags |= path.mnt->mnt_flags & MNT_ATIME_MASK;
4528 }
d337f35e 4529
b00e13aa 4530+ if (!vx_capable(CAP_SYS_ADMIN, VXC_DEV_MOUNT))
d337f35e 4531+ mnt_flags |= MNT_NODEV;
cc23e853 4532+
c146dd73 4533 flags &= ~(MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_ACTIVE | MS_BORN |
ec22aa5c 4534 MS_NOATIME | MS_NODIRATIME | MS_RELATIME| MS_KERNMOUNT |
cc23e853 4535 MS_STRICTATIME | MS_NOREMOTELOCK | MS_SUBMOUNT);
d337f35e
JR
4536
4537 if (flags & MS_REMOUNT)
ec22aa5c 4538 retval = do_remount(&path, flags & ~MS_REMOUNT, mnt_flags,
d337f35e
JR
4539- data_page);
4540+ data_page, tag);
4541 else if (flags & MS_BIND)
ec22aa5c
AM
4542- retval = do_loopback(&path, dev_name, flags & MS_REC);
4543+ retval = do_loopback(&path, dev_name, tag, flags, mnt_flags);
d337f35e 4544 else if (flags & (MS_SHARED | MS_PRIVATE | MS_SLAVE | MS_UNBINDABLE))
ec22aa5c 4545 retval = do_change_type(&path, flags);
d337f35e 4546 else if (flags & MS_MOVE)
3261cfd5 4547@@ -2979,6 +3003,7 @@ struct mnt_namespace *copy_mnt_ns(unsign
c2e5f7c8 4548 p = next_mnt(p, old);
d337f35e 4549 }
09be7631 4550 namespace_unlock();
2380c486
JR
4551+ atomic_inc(&vs_global_mnt_ns);
4552
4553 if (rootmnt)
4554 mntput(rootmnt);
3261cfd5 4555@@ -3154,9 +3179,10 @@ SYSCALL_DEFINE2(pivot_root, const char _
db55b927
AM
4556 new_mnt = real_mount(new.mnt);
4557 root_mnt = real_mount(root.mnt);
09be7631
JR
4558 old_mnt = real_mount(old.mnt);
4559- if (IS_MNT_SHARED(old_mnt) ||
4560+ if ((IS_MNT_SHARED(old_mnt) ||
db55b927
AM
4561 IS_MNT_SHARED(new_mnt->mnt_parent) ||
4562- IS_MNT_SHARED(root_mnt->mnt_parent))
4563+ IS_MNT_SHARED(root_mnt->mnt_parent)) &&
50e68740 4564+ !vx_flags(VXF_STATE_SETUP, 0))
763640ca 4565 goto out4;
db55b927 4566 if (!check_mnt(root_mnt) || !check_mnt(new_mnt))
763640ca 4567 goto out4;
3261cfd5 4568@@ -3294,6 +3320,7 @@ void put_mnt_ns(struct mnt_namespace *ns
c2e5f7c8
JR
4569 if (!atomic_dec_and_test(&ns->count))
4570 return;
4571 drop_collected_mounts(&ns->root->mnt);
2380c486 4572+ atomic_dec(&vs_global_mnt_ns);
b00e13aa 4573 free_mnt_ns(ns);
2380c486 4574 }
db55b927 4575
3261cfd5
AM
4576diff -NurpP --minimal linux-4.9.207/fs/nfs/client.c linux-4.9.207-vs2.3.9.11/fs/nfs/client.c
4577--- linux-4.9.207/fs/nfs/client.c 2019-12-25 15:28:37.347316006 +0000
4578+++ linux-4.9.207-vs2.3.9.11/fs/nfs/client.c 2019-10-05 14:58:45.410311711 +0000
cc23e853 4579@@ -586,6 +586,9 @@ int nfs_init_server_rpcclient(struct nfs
2380c486
JR
4580 if (server->flags & NFS_MOUNT_SOFT)
4581 server->client->cl_softrtry = 1;
d337f35e
JR
4582
4583+ server->client->cl_tag = 0;
4584+ if (server->flags & NFS_MOUNT_TAGGED)
4585+ server->client->cl_tag = 1;
4586 return 0;
4587 }
92598135 4588 EXPORT_SYMBOL_GPL(nfs_init_server_rpcclient);
cc23e853 4589@@ -762,6 +765,10 @@ static void nfs_server_set_fsinfo(struct
d337f35e
JR
4590 server->acdirmin = server->acdirmax = 0;
4591 }
4592
4593+ /* FIXME: needs fsinfo
4594+ if (server->flags & NFS_MOUNT_TAGGED)
4595+ sb->s_flags |= MS_TAGGED; */
4596+
4597 server->maxfilesize = fsinfo->maxfilesize;
4598
ab30d09f 4599 server->time_delta = fsinfo->time_delta;
3261cfd5
AM
4600diff -NurpP --minimal linux-4.9.207/fs/nfs/dir.c linux-4.9.207-vs2.3.9.11/fs/nfs/dir.c
4601--- linux-4.9.207/fs/nfs/dir.c 2019-12-25 15:28:37.357315845 +0000
4602+++ linux-4.9.207-vs2.3.9.11/fs/nfs/dir.c 2018-10-20 04:58:14.000000000 +0000
c2e5f7c8 4603@@ -37,6 +37,7 @@
2380c486 4604 #include <linux/sched.h>
ab30d09f 4605 #include <linux/kmemleak.h>
d33d7b00 4606 #include <linux/xattr.h>
d337f35e
JR
4607+#include <linux/vs_tag.h>
4608
d337f35e 4609 #include "delegation.h"
ab30d09f 4610 #include "iostat.h"
cc23e853 4611@@ -1420,6 +1421,7 @@ struct dentry *nfs_lookup(struct inode *
42bc425c
AM
4612 /* Success: notify readdir to use READDIRPLUS */
4613 nfs_advise_use_readdirplus(dir);
d337f35e
JR
4614
4615+ dx_propagate_tag(nd, inode);
4616 no_entry:
cc23e853 4617 res = d_splice_alias(inode, dentry);
d337f35e 4618 if (res != NULL) {
3261cfd5
AM
4619diff -NurpP --minimal linux-4.9.207/fs/nfs/inode.c linux-4.9.207-vs2.3.9.11/fs/nfs/inode.c
4620--- linux-4.9.207/fs/nfs/inode.c 2019-12-25 15:28:37.417314874 +0000
4621+++ linux-4.9.207-vs2.3.9.11/fs/nfs/inode.c 2019-10-05 14:58:45.430311390 +0000
c2e5f7c8
JR
4622@@ -38,6 +38,7 @@
4623 #include <linux/slab.h>
d33d7b00 4624 #include <linux/compat.h>
db55b927 4625 #include <linux/freezer.h>
d337f35e
JR
4626+#include <linux/vs_tag.h>
4627
d337f35e 4628 #include <asm/uaccess.h>
1e8b8f9b 4629
cc23e853 4630@@ -383,6 +384,8 @@ nfs_fhget(struct super_block *sb, struct
ec22aa5c
AM
4631 if (inode->i_state & I_NEW) {
4632 struct nfs_inode *nfsi = NFS_I(inode);
4633 unsigned long now = jiffies;
a4a22af8
AM
4634+ kuid_t kuid;
4635+ kgid_t kgid;
ec22aa5c
AM
4636
4637 /* We set i_ino for the few things that still rely on it,
4638 * such as stat(2) */
cc23e853 4639@@ -427,8 +430,8 @@ nfs_fhget(struct super_block *sb, struct
f6c5ef8b 4640 inode->i_version = 0;
ec22aa5c 4641 inode->i_size = 0;
f6c5ef8b 4642 clear_nlink(inode);
b00e13aa
AM
4643- inode->i_uid = make_kuid(&init_user_ns, -2);
4644- inode->i_gid = make_kgid(&init_user_ns, -2);
a4a22af8
AM
4645+ kuid = make_kuid(&init_user_ns, -2);
4646+ kgid = make_kgid(&init_user_ns, -2);
ec22aa5c
AM
4647 inode->i_blocks = 0;
4648 memset(nfsi->cookieverf, 0, sizeof(nfsi->cookieverf));
42bc425c 4649 nfsi->write_io = 0;
cc23e853 4650@@ -463,11 +466,11 @@ nfs_fhget(struct super_block *sb, struct
7e46296a 4651 else if (nfs_server_capable(inode, NFS_CAP_NLINK))
bb20add7 4652 nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR);
ec22aa5c
AM
4653 if (fattr->valid & NFS_ATTR_FATTR_OWNER)
4654- inode->i_uid = fattr->uid;
a4a22af8 4655+ kuid = fattr->uid;
7e46296a 4656 else if (nfs_server_capable(inode, NFS_CAP_OWNER))
bb20add7 4657 nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR);
ec22aa5c
AM
4658 if (fattr->valid & NFS_ATTR_FATTR_GROUP)
4659- inode->i_gid = fattr->gid;
a4a22af8 4660+ kgid = fattr->gid;
7e46296a 4661 else if (nfs_server_capable(inode, NFS_CAP_OWNER_GROUP))
bb20add7 4662 nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR);
42bc425c 4663 if (fattr->valid & NFS_ATTR_FATTR_BLOCKS_USED)
cc23e853 4664@@ -478,6 +481,10 @@ nfs_fhget(struct super_block *sb, struct
ec22aa5c
AM
4665 */
4666 inode->i_blocks = nfs_calc_block_size(fattr->du.nfs3.used);
4667 }
a4a22af8
AM
4668+ inode->i_uid = INOTAG_KUID(DX_TAG(inode), kuid, kgid);
4669+ inode->i_gid = INOTAG_KGID(DX_TAG(inode), kuid, kgid);
4670+ inode->i_tag = INOTAG_KTAG(DX_TAG(inode), kuid, kgid, GLOBAL_ROOT_TAG);
ec22aa5c 4671+ /* maybe fattr->xid someday */
c2e5f7c8
JR
4672
4673 nfs_setsecurity(inode, fattr, label);
4674
cc23e853 4675@@ -619,6 +626,8 @@ void nfs_setattr_update_inode(struct ino
d337f35e
JR
4676 inode->i_uid = attr->ia_uid;
4677 if ((attr->ia_valid & ATTR_GID) != 0)
4678 inode->i_gid = attr->ia_gid;
4679+ if ((attr->ia_valid & ATTR_TAG) && IS_TAGGED(inode))
4680+ inode->i_tag = attr->ia_tag;
bb20add7
AM
4681 nfs_set_cache_invalid(inode, NFS_INO_INVALID_ACCESS
4682 | NFS_INO_INVALID_ACL);
cc23e853 4683 }
3261cfd5 4684@@ -1273,7 +1282,9 @@ static int nfs_check_inode_attributes(st
d337f35e
JR
4685 struct nfs_inode *nfsi = NFS_I(inode);
4686 loff_t cur_size, new_isize;
2380c486 4687 unsigned long invalid = 0;
a4a22af8 4688-
b00e13aa
AM
4689+ kuid_t kuid;
4690+ kgid_t kgid;
4691+ ktag_t ktag;
d337f35e 4692
42bc425c 4693 if (nfs_have_delegated_attributes(inode))
a4a22af8 4694 return 0;
3261cfd5 4695@@ -1302,13 +1313,18 @@ static int nfs_check_inode_attributes(st
cc23e853 4696 }
ec22aa5c 4697 }
d337f35e 4698
a4a22af8
AM
4699+ kuid = INOTAG_KUID(DX_TAG(inode), fattr->uid, fattr->gid);
4700+ kgid = INOTAG_KGID(DX_TAG(inode), fattr->uid, fattr->gid);
4701+ ktag = INOTAG_KTAG(DX_TAG(inode), fattr->uid, fattr->gid, GLOBAL_ROOT_TAG);
d337f35e
JR
4702+
4703 /* Have any file permissions changed? */
ec22aa5c 4704 if ((fattr->valid & NFS_ATTR_FATTR_MODE) && (inode->i_mode & S_IALLUGO) != (fattr->mode & S_IALLUGO))
9474138d 4705 invalid |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS | NFS_INO_INVALID_ACL;
b00e13aa
AM
4706- if ((fattr->valid & NFS_ATTR_FATTR_OWNER) && !uid_eq(inode->i_uid, fattr->uid))
4707+ if ((fattr->valid & NFS_ATTR_FATTR_OWNER) && !uid_eq(inode->i_uid, kuid))
ec22aa5c 4708 invalid |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS | NFS_INO_INVALID_ACL;
b00e13aa
AM
4709- if ((fattr->valid & NFS_ATTR_FATTR_GROUP) && !gid_eq(inode->i_gid, fattr->gid))
4710+ if ((fattr->valid & NFS_ATTR_FATTR_GROUP) && !gid_eq(inode->i_gid, kgid))
ec22aa5c
AM
4711 invalid |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS | NFS_INO_INVALID_ACL;
4712+ /* maybe check for tag too? */
d337f35e
JR
4713
4714 /* Has the link count changed? */
ec22aa5c 4715 if ((fattr->valid & NFS_ATTR_FATTR_NLINK) && inode->i_nlink != fattr->nlink)
3261cfd5 4716@@ -1667,6 +1683,9 @@ static int nfs_update_inode(struct inode
7e46296a 4717 unsigned long save_cache_validity;
cc23e853
AM
4718 bool have_writers = nfs_file_has_buffered_writers(nfsi);
4719 bool cache_revalidated = true;
a4a22af8
AM
4720+ kuid_t kuid;
4721+ kgid_t kgid;
4722+ ktag_t ktag;
d337f35e 4723
bb20add7 4724 dfprintk(VFS, "NFS: %s(%s/%lu fh_crc=0x%08x ct=%d info=0x%x)\n",
2380c486 4725 __func__, inode->i_sb->s_id, inode->i_ino,
3261cfd5 4726@@ -1786,6 +1805,9 @@ static int nfs_update_inode(struct inode
cc23e853
AM
4727 cache_revalidated = false;
4728 }
d337f35e 4729
a4a22af8
AM
4730+ kuid = TAGINO_KUID(DX_TAG(inode), inode->i_uid, inode->i_tag);
4731+ kgid = TAGINO_KGID(DX_TAG(inode), inode->i_gid, inode->i_tag);
4732+ ktag = TAGINO_KTAG(DX_TAG(inode), inode->i_tag);
ec22aa5c
AM
4733
4734 if (fattr->valid & NFS_ATTR_FATTR_ATIME)
4735 memcpy(&inode->i_atime, &fattr->atime, sizeof(inode->i_atime));
3261cfd5 4736@@ -1840,6 +1862,10 @@ static int nfs_update_inode(struct inode
cc23e853
AM
4737 cache_revalidated = false;
4738 }
ec22aa5c 4739
a4a22af8
AM
4740+ inode->i_uid = INOTAG_KUID(DX_TAG(inode), kuid, kgid);
4741+ inode->i_gid = INOTAG_KGID(DX_TAG(inode), kuid, kgid);
4742+ inode->i_tag = INOTAG_KTAG(DX_TAG(inode), kuid, kgid, ktag);
ec22aa5c
AM
4743+
4744 if (fattr->valid & NFS_ATTR_FATTR_NLINK) {
4745 if (inode->i_nlink != fattr->nlink) {
4746 invalid |= NFS_INO_INVALID_ATTR;
3261cfd5
AM
4747diff -NurpP --minimal linux-4.9.207/fs/nfs/nfs3xdr.c linux-4.9.207-vs2.3.9.11/fs/nfs/nfs3xdr.c
4748--- linux-4.9.207/fs/nfs/nfs3xdr.c 2016-12-11 19:17:54.000000000 +0000
4749+++ linux-4.9.207-vs2.3.9.11/fs/nfs/nfs3xdr.c 2018-10-20 04:58:14.000000000 +0000
78865d5b 4750@@ -20,6 +20,7 @@
d337f35e
JR
4751 #include <linux/nfs3.h>
4752 #include <linux/nfs_fs.h>
4753 #include <linux/nfsacl.h>
4754+#include <linux/vs_tag.h>
4755 #include "internal.h"
4756
4757 #define NFSDBG_FACILITY NFSDBG_XDR
b00e13aa 4758@@ -558,7 +559,8 @@ static __be32 *xdr_decode_nfstime3(__be3
d33d7b00
AM
4759 * set_mtime mtime;
4760 * };
4761 */
4762-static void encode_sattr3(struct xdr_stream *xdr, const struct iattr *attr)
4763+static void encode_sattr3(struct xdr_stream *xdr,
4764+ const struct iattr *attr, int tag)
d337f35e 4765 {
d33d7b00
AM
4766 u32 nbytes;
4767 __be32 *p;
b00e13aa 4768@@ -590,15 +592,19 @@ static void encode_sattr3(struct xdr_str
d33d7b00 4769 } else
d337f35e 4770 *p++ = xdr_zero;
d33d7b00 4771
d337f35e
JR
4772- if (attr->ia_valid & ATTR_UID) {
4773+ if (attr->ia_valid & ATTR_UID ||
4774+ (tag && (attr->ia_valid & ATTR_TAG))) {
4775 *p++ = xdr_one;
b00e13aa 4776- *p++ = cpu_to_be32(from_kuid(&init_user_ns, attr->ia_uid));
a4a22af8
AM
4777+ *p++ = cpu_to_be32(from_kuid(&init_user_ns,
4778+ TAGINO_KUID(tag, attr->ia_uid, attr->ia_tag)));
d33d7b00 4779 } else
d337f35e 4780 *p++ = xdr_zero;
d33d7b00 4781
d337f35e
JR
4782- if (attr->ia_valid & ATTR_GID) {
4783+ if (attr->ia_valid & ATTR_GID ||
4784+ (tag && (attr->ia_valid & ATTR_TAG))) {
4785 *p++ = xdr_one;
b00e13aa 4786- *p++ = cpu_to_be32(from_kgid(&init_user_ns, attr->ia_gid));
a4a22af8
AM
4787+ *p++ = cpu_to_be32(from_kgid(&init_user_ns,
4788+ TAGINO_KGID(tag, attr->ia_gid, attr->ia_tag)));
d33d7b00 4789 } else
d337f35e 4790 *p++ = xdr_zero;
d33d7b00 4791
b00e13aa 4792@@ -887,7 +893,7 @@ static void nfs3_xdr_enc_setattr3args(st
d33d7b00 4793 const struct nfs3_sattrargs *args)
d337f35e 4794 {
d33d7b00
AM
4795 encode_nfs_fh3(xdr, args->fh);
4796- encode_sattr3(xdr, args->sattr);
4797+ encode_sattr3(xdr, args->sattr, req->rq_task->tk_client->cl_tag);
4798 encode_sattrguard3(xdr, args);
4799 }
d337f35e 4800
b00e13aa 4801@@ -1037,13 +1043,13 @@ static void nfs3_xdr_enc_write3args(stru
d33d7b00
AM
4802 * };
4803 */
4804 static void encode_createhow3(struct xdr_stream *xdr,
4805- const struct nfs3_createargs *args)
4806+ const struct nfs3_createargs *args, int tag)
d337f35e 4807 {
d33d7b00
AM
4808 encode_uint32(xdr, args->createmode);
4809 switch (args->createmode) {
4810 case NFS3_CREATE_UNCHECKED:
4811 case NFS3_CREATE_GUARDED:
4812- encode_sattr3(xdr, args->sattr);
4813+ encode_sattr3(xdr, args->sattr, tag);
4814 break;
4815 case NFS3_CREATE_EXCLUSIVE:
4816 encode_createverf3(xdr, args->verifier);
b00e13aa 4817@@ -1058,7 +1064,7 @@ static void nfs3_xdr_enc_create3args(str
d33d7b00
AM
4818 const struct nfs3_createargs *args)
4819 {
4820 encode_diropargs3(xdr, args->fh, args->name, args->len);
4821- encode_createhow3(xdr, args);
4822+ encode_createhow3(xdr, args, req->rq_task->tk_client->cl_tag);
4823 }
4824
4825 /*
b00e13aa 4826@@ -1074,7 +1080,7 @@ static void nfs3_xdr_enc_mkdir3args(stru
d33d7b00
AM
4827 const struct nfs3_mkdirargs *args)
4828 {
4829 encode_diropargs3(xdr, args->fh, args->name, args->len);
4830- encode_sattr3(xdr, args->sattr);
4831+ encode_sattr3(xdr, args->sattr, req->rq_task->tk_client->cl_tag);
d337f35e 4832 }
d33d7b00
AM
4833
4834 /*
b00e13aa 4835@@ -1091,9 +1097,9 @@ static void nfs3_xdr_enc_mkdir3args(stru
d33d7b00
AM
4836 * };
4837 */
4838 static void encode_symlinkdata3(struct xdr_stream *xdr,
4839- const struct nfs3_symlinkargs *args)
4840+ const struct nfs3_symlinkargs *args, int tag)
4841 {
4842- encode_sattr3(xdr, args->sattr);
4843+ encode_sattr3(xdr, args->sattr, tag);
4844 encode_nfspath3(xdr, args->pages, args->pathlen);
4845 }
4846
b00e13aa 4847@@ -1102,7 +1108,7 @@ static void nfs3_xdr_enc_symlink3args(st
d33d7b00
AM
4848 const struct nfs3_symlinkargs *args)
4849 {
4850 encode_diropargs3(xdr, args->fromfh, args->fromname, args->fromlen);
4851- encode_symlinkdata3(xdr, args);
4852+ encode_symlinkdata3(xdr, args, req->rq_task->tk_client->cl_tag);
cc23e853 4853 xdr->buf->flags |= XDRBUF_WRITE;
d33d7b00
AM
4854 }
4855
cc23e853 4856@@ -1131,24 +1137,24 @@ static void nfs3_xdr_enc_symlink3args(st
d33d7b00
AM
4857 * };
4858 */
4859 static void encode_devicedata3(struct xdr_stream *xdr,
4860- const struct nfs3_mknodargs *args)
4861+ const struct nfs3_mknodargs *args, int tag)
4862 {
4863- encode_sattr3(xdr, args->sattr);
4864+ encode_sattr3(xdr, args->sattr, tag);
4865 encode_specdata3(xdr, args->rdev);
4866 }
4867
4868 static void encode_mknoddata3(struct xdr_stream *xdr,
4869- const struct nfs3_mknodargs *args)
4870+ const struct nfs3_mknodargs *args, int tag)
4871 {
4872 encode_ftype3(xdr, args->type);
4873 switch (args->type) {
4874 case NF3CHR:
4875 case NF3BLK:
4876- encode_devicedata3(xdr, args);
4877+ encode_devicedata3(xdr, args, tag);
4878 break;
4879 case NF3SOCK:
4880 case NF3FIFO:
4881- encode_sattr3(xdr, args->sattr);
4882+ encode_sattr3(xdr, args->sattr, tag);
4883 break;
4884 case NF3REG:
4885 case NF3DIR:
cc23e853 4886@@ -1163,7 +1169,7 @@ static void nfs3_xdr_enc_mknod3args(stru
d33d7b00 4887 const struct nfs3_mknodargs *args)
d337f35e 4888 {
d33d7b00
AM
4889 encode_diropargs3(xdr, args->fh, args->name, args->len);
4890- encode_mknoddata3(xdr, args);
4891+ encode_mknoddata3(xdr, args, req->rq_task->tk_client->cl_tag);
4892 }
4893
4894 /*
3261cfd5
AM
4895diff -NurpP --minimal linux-4.9.207/fs/nfs/super.c linux-4.9.207-vs2.3.9.11/fs/nfs/super.c
4896--- linux-4.9.207/fs/nfs/super.c 2019-12-25 15:28:37.507313419 +0000
4897+++ linux-4.9.207-vs2.3.9.11/fs/nfs/super.c 2019-10-05 14:58:45.430311390 +0000
cc23e853 4898@@ -54,6 +54,7 @@
b00e13aa 4899 #include <linux/parser.h>
1e8b8f9b
AM
4900 #include <linux/nsproxy.h>
4901 #include <linux/rcupdate.h>
d337f35e
JR
4902+#include <linux/vs_tag.h>
4903
d337f35e 4904 #include <asm/uaccess.h>
1e8b8f9b 4905
cc23e853 4906@@ -102,6 +103,7 @@ enum {
1e8b8f9b 4907 Opt_mountport,
ab30d09f 4908 Opt_mountvers,
ab30d09f
AM
4909 Opt_minorversion,
4910+ Opt_tagid,
4911
4912 /* Mount options that take string arguments */
1e8b8f9b 4913 Opt_nfsvers,
cc23e853 4914@@ -114,6 +116,9 @@ enum {
537831f9
AM
4915 /* Special mount options */
4916 Opt_userspace, Opt_deprecated, Opt_sloppy,
4917
4918+ /* Linux-VServer tagging options */
4919+ Opt_tag, Opt_notag,
4920+
4921 Opt_err
4922 };
4923
cc23e853 4924@@ -183,6 +188,10 @@ static const match_table_t nfs_mount_opt
537831f9
AM
4925 { Opt_fscache_uniq, "fsc=%s" },
4926 { Opt_local_lock, "local_lock=%s" },
ab30d09f
AM
4927
4928+ { Opt_tag, "tag" },
4929+ { Opt_notag, "notag" },
4930+ { Opt_tagid, "tagid=%u" },
4931+
537831f9
AM
4932 /* The following needs to be listed after all other options */
4933 { Opt_nfsvers, "v%s" },
ab30d09f 4934
cc23e853 4935@@ -644,6 +653,7 @@ static void nfs_show_mount_options(struc
2380c486 4936 { NFS_MOUNT_NORDIRPLUS, ",nordirplus", "" },
ec22aa5c
AM
4937 { NFS_MOUNT_UNSHARED, ",nosharecache", "" },
4938 { NFS_MOUNT_NORESVPORT, ",noresvport", "" },
d337f35e
JR
4939+ { NFS_MOUNT_TAGGED, ",tag", "" },
4940 { 0, NULL, NULL }
4941 };
4942 const struct proc_nfs_info *nfs_infop;
cc23e853 4943@@ -1341,6 +1351,14 @@ static int nfs_parse_mount_options(char
537831f9 4944 case Opt_nomigration:
cc23e853 4945 mnt->options &= ~NFS_OPTION_MIGRATION;
ab30d09f
AM
4946 break;
4947+#ifndef CONFIG_TAGGING_NONE
4948+ case Opt_tag:
4949+ mnt->flags |= NFS_MOUNT_TAGGED;
4950+ break;
4951+ case Opt_notag:
4952+ mnt->flags &= ~NFS_MOUNT_TAGGED;
4953+ break;
4954+#endif
4955
4956 /*
4957 * options that take numeric values
cc23e853 4958@@ -1427,6 +1445,12 @@ static int nfs_parse_mount_options(char
ab30d09f
AM
4959 goto out_invalid_value;
4960 mnt->minorversion = option;
4961 break;
4962+#ifdef CONFIG_PROPAGATE
4963+ case Opt_tagid:
4964+ /* use args[0] */
4965+ nfs_data.flags |= NFS_MOUNT_TAGGED;
4966+ break;
4967+#endif
4968
4969 /*
4970 * options that take text values
3261cfd5
AM
4971diff -NurpP --minimal linux-4.9.207/fs/nfsd/auth.c linux-4.9.207-vs2.3.9.11/fs/nfsd/auth.c
4972--- linux-4.9.207/fs/nfsd/auth.c 2019-12-25 15:28:37.537312933 +0000
4973+++ linux-4.9.207-vs2.3.9.11/fs/nfsd/auth.c 2018-10-20 04:58:14.000000000 +0000
bb20add7
AM
4974@@ -1,6 +1,7 @@
4975 /* Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de> */
2bf5ad28
AM
4976
4977 #include <linux/sched.h>
d337f35e 4978+#include <linux/vs_tag.h>
2bf5ad28 4979 #include "nfsd.h"
2380c486 4980 #include "auth.h"
d337f35e 4981
bb20add7 4982@@ -35,6 +36,9 @@ int nfsd_setuser(struct svc_rqst *rqstp,
d337f35e 4983
ec22aa5c
AM
4984 new->fsuid = rqstp->rq_cred.cr_uid;
4985 new->fsgid = rqstp->rq_cred.cr_gid;
4986+ /* FIXME: this desperately needs a tag :)
61333608 4987+ new->xid = (vxid_t)INOTAG_TAG(DX_TAG_NFSD, cred.cr_uid, cred.cr_gid, 0);
ec22aa5c 4988+ */
d337f35e 4989
ec22aa5c
AM
4990 rqgi = rqstp->rq_cred.cr_group_info;
4991
3261cfd5
AM
4992diff -NurpP --minimal linux-4.9.207/fs/nfsd/nfs3xdr.c linux-4.9.207-vs2.3.9.11/fs/nfsd/nfs3xdr.c
4993--- linux-4.9.207/fs/nfsd/nfs3xdr.c 2019-12-25 15:28:37.557312612 +0000
4994+++ linux-4.9.207-vs2.3.9.11/fs/nfsd/nfs3xdr.c 2019-10-05 14:58:45.440311232 +0000
b00e13aa 4995@@ -8,6 +8,7 @@
2bf5ad28
AM
4996
4997 #include <linux/namei.h>
b00e13aa 4998 #include <linux/sunrpc/svc_xprt.h>
d337f35e 4999+#include <linux/vs_tag.h>
2bf5ad28 5000 #include "xdr3.h"
2380c486 5001 #include "auth.h"
b00e13aa
AM
5002 #include "netns.h"
5003@@ -98,6 +99,8 @@ static __be32 *
d337f35e
JR
5004 decode_sattr3(__be32 *p, struct iattr *iap)
5005 {
5006 u32 tmp;
a4a22af8
AM
5007+ kuid_t kuid = GLOBAL_ROOT_UID;
5008+ kgid_t kgid = GLOBAL_ROOT_GID;
d337f35e
JR
5009
5010 iap->ia_valid = 0;
5011
b00e13aa
AM
5012@@ -106,15 +109,18 @@ decode_sattr3(__be32 *p, struct iattr *i
5013 iap->ia_mode = ntohl(*p++);
d337f35e
JR
5014 }
5015 if (*p++) {
b00e13aa 5016- iap->ia_uid = make_kuid(&init_user_ns, ntohl(*p++));
a4a22af8 5017+ kuid = make_kuid(&init_user_ns, ntohl(*p++));
b00e13aa
AM
5018 if (uid_valid(iap->ia_uid))
5019 iap->ia_valid |= ATTR_UID;
d337f35e
JR
5020 }
5021 if (*p++) {
b00e13aa 5022- iap->ia_gid = make_kgid(&init_user_ns, ntohl(*p++));
a4a22af8 5023+ kgid = make_kgid(&init_user_ns, ntohl(*p++));
b00e13aa
AM
5024 if (gid_valid(iap->ia_gid))
5025 iap->ia_valid |= ATTR_GID;
d337f35e 5026 }
a4a22af8
AM
5027+ iap->ia_uid = INOTAG_KUID(DX_TAG_NFSD, kuid, kgid);
5028+ iap->ia_gid = INOTAG_KGID(DX_TAG_NFSD, kuid, kgid);
5029+ iap->ia_tag = INOTAG_KTAG(DX_TAG_NFSD, kuid, kgid, GLOBAL_ROOT_TAG);
d337f35e
JR
5030 if (*p++) {
5031 u64 newsize;
5032
bb20add7 5033@@ -167,8 +173,12 @@ encode_fattr3(struct svc_rqst *rqstp, __
d337f35e 5034 *p++ = htonl(nfs3_ftypes[(stat->mode & S_IFMT) >> 12]);
bb20add7 5035 *p++ = htonl((u32) (stat->mode & S_IALLUGO));
d337f35e 5036 *p++ = htonl((u32) stat->nlink);
b00e13aa
AM
5037- *p++ = htonl((u32) from_kuid(&init_user_ns, stat->uid));
5038- *p++ = htonl((u32) from_kgid(&init_user_ns, stat->gid));
5039+ *p++ = htonl((u32) from_kuid(&init_user_ns,
a4a22af8 5040+ TAGINO_KUID(0 /* FIXME: DX_TAG(dentry->d_inode) */,
2380c486 5041+ stat->uid, stat->tag)));
b00e13aa 5042+ *p++ = htonl((u32) from_kgid(&init_user_ns,
a4a22af8 5043+ TAGINO_KGID(0 /* FIXME: DX_TAG(dentry->d_inode) */,
2380c486 5044+ stat->gid, stat->tag)));
d337f35e
JR
5045 if (S_ISLNK(stat->mode) && stat->size > NFS3_MAXPATHLEN) {
5046 p = xdr_encode_hyper(p, (u64) NFS3_MAXPATHLEN);
5047 } else {
3261cfd5
AM
5048diff -NurpP --minimal linux-4.9.207/fs/nfsd/nfs4xdr.c linux-4.9.207-vs2.3.9.11/fs/nfsd/nfs4xdr.c
5049--- linux-4.9.207/fs/nfsd/nfs4xdr.c 2019-12-25 15:28:37.557312612 +0000
5050+++ linux-4.9.207-vs2.3.9.11/fs/nfsd/nfs4xdr.c 2018-10-20 05:55:43.000000000 +0000
cc23e853 5051@@ -40,6 +40,7 @@
d33d7b00 5052 #include <linux/utsname.h>
a168f21d 5053 #include <linux/pagemap.h>
2380c486 5054 #include <linux/sunrpc/svcauth_gss.h>
d337f35e
JR
5055+#include <linux/vs_tag.h>
5056
d33d7b00
AM
5057 #include "idmap.h"
5058 #include "acl.h"
09a55596 5059@@ -2679,12 +2680,16 @@ out_acl:
bb20add7 5060 *p++ = cpu_to_be32(stat.nlink);
d337f35e
JR
5061 }
5062 if (bmval1 & FATTR4_WORD1_OWNER) {
bb20add7
AM
5063- status = nfsd4_encode_user(xdr, rqstp, stat.uid);
5064+ status = nfsd4_encode_user(xdr, rqstp,
a4a22af8 5065+ TAGINO_KUID(DX_TAG(dentry->d_inode),
bb20add7 5066+ stat.uid, stat.tag));
d337f35e
JR
5067 if (status)
5068 goto out;
5069 }
5070 if (bmval1 & FATTR4_WORD1_OWNER_GROUP) {
bb20add7
AM
5071- status = nfsd4_encode_group(xdr, rqstp, stat.gid);
5072+ status = nfsd4_encode_group(xdr, rqstp,
a4a22af8 5073+ TAGINO_KGID(DX_TAG(dentry->d_inode),
bb20add7 5074+ stat.gid, stat.tag));
d337f35e 5075 if (status)
f15949f2
JR
5076 goto out;
5077 }
3261cfd5
AM
5078diff -NurpP --minimal linux-4.9.207/fs/nfsd/nfsxdr.c linux-4.9.207-vs2.3.9.11/fs/nfsd/nfsxdr.c
5079--- linux-4.9.207/fs/nfsd/nfsxdr.c 2019-12-25 15:28:37.567312448 +0000
5080+++ linux-4.9.207-vs2.3.9.11/fs/nfsd/nfsxdr.c 2018-10-20 04:58:14.000000000 +0000
b00e13aa
AM
5081@@ -7,6 +7,7 @@
5082 #include "vfs.h"
2bf5ad28 5083 #include "xdr.h"
2380c486 5084 #include "auth.h"
2bf5ad28 5085+#include <linux/vs_tag.h>
d337f35e
JR
5086
5087 #define NFSDDBG_FACILITY NFSDDBG_XDR
2bf5ad28 5088
b00e13aa 5089@@ -89,6 +90,8 @@ static __be32 *
d337f35e
JR
5090 decode_sattr(__be32 *p, struct iattr *iap)
5091 {
5092 u32 tmp, tmp1;
a4a22af8
AM
5093+ kuid_t kuid = GLOBAL_ROOT_UID;
5094+ kgid_t kgid = GLOBAL_ROOT_GID;
d337f35e
JR
5095
5096 iap->ia_valid = 0;
5097
b00e13aa
AM
5098@@ -101,15 +104,18 @@ decode_sattr(__be32 *p, struct iattr *ia
5099 iap->ia_mode = tmp;
d337f35e
JR
5100 }
5101 if ((tmp = ntohl(*p++)) != (u32)-1) {
b00e13aa 5102- iap->ia_uid = make_kuid(&init_user_ns, tmp);
a4a22af8 5103+ kuid = make_kuid(&init_user_ns, tmp);
b00e13aa
AM
5104 if (uid_valid(iap->ia_uid))
5105 iap->ia_valid |= ATTR_UID;
d337f35e
JR
5106 }
5107 if ((tmp = ntohl(*p++)) != (u32)-1) {
b00e13aa 5108- iap->ia_gid = make_kgid(&init_user_ns, tmp);
a4a22af8 5109+ kgid = make_kgid(&init_user_ns, tmp);
b00e13aa
AM
5110 if (gid_valid(iap->ia_gid))
5111 iap->ia_valid |= ATTR_GID;
d337f35e 5112 }
a4a22af8
AM
5113+ iap->ia_uid = INOTAG_KUID(DX_TAG_NFSD, kuid, kgid);
5114+ iap->ia_gid = INOTAG_KGID(DX_TAG_NFSD, kuid, kgid);
5115+ iap->ia_tag = INOTAG_KTAG(DX_TAG_NFSD, kuid, kgid, GLOBAL_ROOT_TAG);
d337f35e
JR
5116 if ((tmp = ntohl(*p++)) != (u32)-1) {
5117 iap->ia_valid |= ATTR_SIZE;
5118 iap->ia_size = tmp;
b00e13aa 5119@@ -154,8 +160,10 @@ encode_fattr(struct svc_rqst *rqstp, __b
d337f35e
JR
5120 *p++ = htonl(nfs_ftypes[type >> 12]);
5121 *p++ = htonl((u32) stat->mode);
5122 *p++ = htonl((u32) stat->nlink);
b00e13aa
AM
5123- *p++ = htonl((u32) from_kuid(&init_user_ns, stat->uid));
5124- *p++ = htonl((u32) from_kgid(&init_user_ns, stat->gid));
5125+ *p++ = htonl((u32) from_kuid(&init_user_ns,
a4a22af8 5126+ TAGINO_KUID(DX_TAG(dentry->d_inode), stat->uid, stat->tag)));
b00e13aa 5127+ *p++ = htonl((u32) from_kgid(&init_user_ns,
a4a22af8 5128+ TAGINO_KGID(DX_TAG(dentry->d_inode), stat->gid, stat->tag)));
d337f35e
JR
5129
5130 if (S_ISLNK(type) && stat->size > NFS_MAXPATHLEN) {
5131 *p++ = htonl(NFS_MAXPATHLEN);
3261cfd5
AM
5132diff -NurpP --minimal linux-4.9.207/fs/ocfs2/dlmglue.c linux-4.9.207-vs2.3.9.11/fs/ocfs2/dlmglue.c
5133--- linux-4.9.207/fs/ocfs2/dlmglue.c 2019-12-25 15:28:37.857307760 +0000
5134+++ linux-4.9.207-vs2.3.9.11/fs/ocfs2/dlmglue.c 2019-12-25 15:37:51.918430506 +0000
cc23e853 5135@@ -2120,6 +2120,7 @@ static void __ocfs2_stuff_meta_lvb(struc
d337f35e 5136 lvb->lvb_iclusters = cpu_to_be32(oi->ip_clusters);
b00e13aa
AM
5137 lvb->lvb_iuid = cpu_to_be32(i_uid_read(inode));
5138 lvb->lvb_igid = cpu_to_be32(i_gid_read(inode));
a4a22af8 5139+ lvb->lvb_itag = cpu_to_be16(i_tag_read(inode));
d337f35e
JR
5140 lvb->lvb_imode = cpu_to_be16(inode->i_mode);
5141 lvb->lvb_inlink = cpu_to_be16(inode->i_nlink);
5142 lvb->lvb_iatime_packed =
cc23e853 5143@@ -2170,6 +2171,7 @@ static void ocfs2_refresh_inode_from_lvb
d337f35e 5144
b00e13aa
AM
5145 i_uid_write(inode, be32_to_cpu(lvb->lvb_iuid));
5146 i_gid_write(inode, be32_to_cpu(lvb->lvb_igid));
5147+ i_tag_write(inode, be16_to_cpu(lvb->lvb_itag));
d337f35e 5148 inode->i_mode = be16_to_cpu(lvb->lvb_imode);
f6c5ef8b 5149 set_nlink(inode, be16_to_cpu(lvb->lvb_inlink));
d337f35e 5150 ocfs2_unpack_timespec(&inode->i_atime,
3261cfd5
AM
5151diff -NurpP --minimal linux-4.9.207/fs/ocfs2/dlmglue.h linux-4.9.207-vs2.3.9.11/fs/ocfs2/dlmglue.h
5152--- linux-4.9.207/fs/ocfs2/dlmglue.h 2019-12-25 15:28:37.857307760 +0000
5153+++ linux-4.9.207-vs2.3.9.11/fs/ocfs2/dlmglue.h 2018-10-20 04:58:14.000000000 +0000
2380c486
JR
5154@@ -46,7 +46,8 @@ struct ocfs2_meta_lvb {
5155 __be16 lvb_inlink;
5156 __be32 lvb_iattr;
5157 __be32 lvb_igeneration;
5158- __be32 lvb_reserved2;
d337f35e 5159+ __be16 lvb_itag;
2380c486
JR
5160+ __be16 lvb_reserved2;
5161 };
5162
ec22aa5c 5163 #define OCFS2_QINFO_LVB_VERSION 1
3261cfd5
AM
5164diff -NurpP --minimal linux-4.9.207/fs/ocfs2/file.c linux-4.9.207-vs2.3.9.11/fs/ocfs2/file.c
5165--- linux-4.9.207/fs/ocfs2/file.c 2019-12-25 15:28:37.877307439 +0000
5166+++ linux-4.9.207-vs2.3.9.11/fs/ocfs2/file.c 2018-10-20 04:58:14.000000000 +0000
cc23e853 5167@@ -1151,7 +1151,7 @@ int ocfs2_setattr(struct dentry *dentry,
763640ca 5168 attr->ia_valid &= ~ATTR_SIZE;
d337f35e
JR
5169
5170 #define OCFS2_VALID_ATTRS (ATTR_ATIME | ATTR_MTIME | ATTR_CTIME | ATTR_SIZE \
5171- | ATTR_GID | ATTR_UID | ATTR_MODE)
5172+ | ATTR_GID | ATTR_UID | ATTR_TAG | ATTR_MODE)
763640ca 5173 if (!(attr->ia_valid & OCFS2_VALID_ATTRS))
d337f35e 5174 return 0;
763640ca 5175
3261cfd5
AM
5176diff -NurpP --minimal linux-4.9.207/fs/ocfs2/inode.c linux-4.9.207-vs2.3.9.11/fs/ocfs2/inode.c
5177--- linux-4.9.207/fs/ocfs2/inode.c 2016-12-11 19:17:54.000000000 +0000
5178+++ linux-4.9.207-vs2.3.9.11/fs/ocfs2/inode.c 2018-10-20 04:58:14.000000000 +0000
78865d5b 5179@@ -28,6 +28,7 @@
d337f35e
JR
5180 #include <linux/highmem.h>
5181 #include <linux/pagemap.h>
ec22aa5c 5182 #include <linux/quotaops.h>
d337f35e
JR
5183+#include <linux/vs_tag.h>
5184
5185 #include <asm/byteorder.h>
5186
cc23e853 5187@@ -87,11 +88,13 @@ void ocfs2_set_inode_flags(struct inode
2380c486
JR
5188 {
5189 unsigned int flags = OCFS2_I(inode)->ip_attr;
5190
5191- inode->i_flags &= ~(S_IMMUTABLE |
5192+ inode->i_flags &= ~(S_IMMUTABLE | S_IXUNLINK |
5193 S_SYNC | S_APPEND | S_NOATIME | S_DIRSYNC);
d337f35e
JR
5194
5195 if (flags & OCFS2_IMMUTABLE_FL)
5196 inode->i_flags |= S_IMMUTABLE;
2380c486
JR
5197+ if (flags & OCFS2_IXUNLINK_FL)
5198+ inode->i_flags |= S_IXUNLINK;
d337f35e
JR
5199
5200 if (flags & OCFS2_SYNC_FL)
5201 inode->i_flags |= S_SYNC;
cc23e853 5202@@ -101,25 +104,44 @@ void ocfs2_set_inode_flags(struct inode
2380c486
JR
5203 inode->i_flags |= S_NOATIME;
5204 if (flags & OCFS2_DIRSYNC_FL)
d337f35e 5205 inode->i_flags |= S_DIRSYNC;
2380c486
JR
5206+
5207+ inode->i_vflags &= ~(V_BARRIER | V_COW);
5208+
5209+ if (flags & OCFS2_BARRIER_FL)
5210+ inode->i_vflags |= V_BARRIER;
5211+ if (flags & OCFS2_COW_FL)
5212+ inode->i_vflags |= V_COW;
d337f35e
JR
5213 }
5214
2380c486
JR
5215 /* Propagate flags from i_flags to OCFS2_I(inode)->ip_attr */
5216 void ocfs2_get_inode_flags(struct ocfs2_inode_info *oi)
5217 {
5218 unsigned int flags = oi->vfs_inode.i_flags;
5219+ unsigned int vflags = oi->vfs_inode.i_vflags;
5220+
5221+ oi->ip_attr &= ~(OCFS2_SYNC_FL | OCFS2_APPEND_FL |
5222+ OCFS2_IMMUTABLE_FL | OCFS2_IXUNLINK_FL |
5223+ OCFS2_NOATIME_FL | OCFS2_DIRSYNC_FL |
5224+ OCFS2_BARRIER_FL | OCFS2_COW_FL);
5225+
5226+ if (flags & S_IMMUTABLE)
5227+ oi->ip_attr |= OCFS2_IMMUTABLE_FL;
5228+ if (flags & S_IXUNLINK)
5229+ oi->ip_attr |= OCFS2_IXUNLINK_FL;
5230
5231- oi->ip_attr &= ~(OCFS2_SYNC_FL|OCFS2_APPEND_FL|
5232- OCFS2_IMMUTABLE_FL|OCFS2_NOATIME_FL|OCFS2_DIRSYNC_FL);
5233 if (flags & S_SYNC)
5234 oi->ip_attr |= OCFS2_SYNC_FL;
5235 if (flags & S_APPEND)
5236 oi->ip_attr |= OCFS2_APPEND_FL;
5237- if (flags & S_IMMUTABLE)
5238- oi->ip_attr |= OCFS2_IMMUTABLE_FL;
5239 if (flags & S_NOATIME)
5240 oi->ip_attr |= OCFS2_NOATIME_FL;
5241 if (flags & S_DIRSYNC)
5242 oi->ip_attr |= OCFS2_DIRSYNC_FL;
5243+
5244+ if (vflags & V_BARRIER)
5245+ oi->ip_attr |= OCFS2_BARRIER_FL;
5246+ if (vflags & V_COW)
5247+ oi->ip_attr |= OCFS2_COW_FL;
2380c486
JR
5248 }
5249
ec22aa5c 5250 struct inode *ocfs2_ilookup(struct super_block *sb, u64 blkno)
cc23e853 5251@@ -278,6 +300,8 @@ void ocfs2_populate_inode(struct inode *
d337f35e
JR
5252 struct super_block *sb;
5253 struct ocfs2_super *osb;
ec22aa5c 5254 int use_plocks = 1;
d337f35e
JR
5255+ uid_t uid;
5256+ gid_t gid;
5257
763640ca
JR
5258 sb = inode->i_sb;
5259 osb = OCFS2_SB(sb);
cc23e853 5260@@ -306,8 +330,12 @@ void ocfs2_populate_inode(struct inode *
d337f35e
JR
5261 inode->i_generation = le32_to_cpu(fe->i_generation);
5262 inode->i_rdev = huge_decode_dev(le64_to_cpu(fe->id1.dev1.i_rdev));
5263 inode->i_mode = le16_to_cpu(fe->i_mode);
b00e13aa
AM
5264- i_uid_write(inode, le32_to_cpu(fe->i_uid));
5265- i_gid_write(inode, le32_to_cpu(fe->i_gid));
d337f35e
JR
5266+ uid = le32_to_cpu(fe->i_uid);
5267+ gid = le32_to_cpu(fe->i_gid);
b00e13aa
AM
5268+ i_uid_write(inode, INOTAG_UID(DX_TAG(inode), uid, gid));
5269+ i_gid_write(inode, INOTAG_GID(DX_TAG(inode), uid, gid));
5270+ i_tag_write(inode, INOTAG_TAG(DX_TAG(inode), uid, gid,
5271+ /* le16_to_cpu(raw_inode->i_raw_tag) */ 0));
d337f35e
JR
5272
5273 /* Fast symlinks will have i_size but no allocated clusters. */
42bc425c 5274 if (S_ISLNK(inode->i_mode) && !fe->i_clusters) {
3261cfd5
AM
5275diff -NurpP --minimal linux-4.9.207/fs/ocfs2/inode.h linux-4.9.207-vs2.3.9.11/fs/ocfs2/inode.h
5276--- linux-4.9.207/fs/ocfs2/inode.h 2016-12-11 19:17:54.000000000 +0000
5277+++ linux-4.9.207-vs2.3.9.11/fs/ocfs2/inode.h 2018-10-20 04:58:14.000000000 +0000
cc23e853 5278@@ -155,6 +155,7 @@ int ocfs2_mark_inode_dirty(handle_t *han
d337f35e
JR
5279
5280 void ocfs2_set_inode_flags(struct inode *inode);
2380c486 5281 void ocfs2_get_inode_flags(struct ocfs2_inode_info *oi);
d4263eb0 5282+int ocfs2_sync_flags(struct inode *inode, int, int);
d337f35e 5283
2380c486
JR
5284 static inline blkcnt_t ocfs2_inode_sector_count(struct inode *inode)
5285 {
3261cfd5
AM
5286diff -NurpP --minimal linux-4.9.207/fs/ocfs2/ioctl.c linux-4.9.207-vs2.3.9.11/fs/ocfs2/ioctl.c
5287--- linux-4.9.207/fs/ocfs2/ioctl.c 2019-12-25 15:28:37.887307275 +0000
5288+++ linux-4.9.207-vs2.3.9.11/fs/ocfs2/ioctl.c 2019-12-25 15:37:51.918430506 +0000
1e8b8f9b 5289@@ -76,7 +76,41 @@ static int ocfs2_get_inode_attr(struct i
d337f35e
JR
5290 return status;
5291 }
5292
5293-static int ocfs2_set_inode_attr(struct inode *inode, unsigned flags,
d4263eb0
JR
5294+int ocfs2_sync_flags(struct inode *inode, int flags, int vflags)
5295+{
5296+ struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
5297+ struct buffer_head *bh = NULL;
5298+ handle_t *handle = NULL;
5299+ int status;
5300+
5301+ status = ocfs2_inode_lock(inode, &bh, 1);
5302+ if (status < 0) {
5303+ mlog_errno(status);
5304+ return status;
5305+ }
5306+ handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS);
5307+ if (IS_ERR(handle)) {
5308+ status = PTR_ERR(handle);
5309+ mlog_errno(status);
5310+ goto bail_unlock;
5311+ }
5312+
5313+ inode->i_flags = flags;
5314+ inode->i_vflags = vflags;
5315+ ocfs2_get_inode_flags(OCFS2_I(inode));
5316+
5317+ status = ocfs2_mark_inode_dirty(handle, inode, bh);
5318+ if (status < 0)
5319+ mlog_errno(status);
5320+
5321+ ocfs2_commit_trans(osb, handle);
5322+bail_unlock:
5323+ ocfs2_inode_unlock(inode, 1);
5324+ brelse(bh);
5325+ return status;
5326+}
5327+
d337f35e
JR
5328+int ocfs2_set_inode_attr(struct inode *inode, unsigned flags,
5329 unsigned mask)
5330 {
5331 struct ocfs2_inode_info *ocfs2_inode = OCFS2_I(inode);
09be7631
JR
5332@@ -116,6 +150,11 @@ static int ocfs2_set_inode_attr(struct i
5333 goto bail_unlock;
5334 }
2380c486
JR
5335
5336+ if (IS_BARRIER(inode)) {
5337+ vxwprintk_task(1, "messing with the barrier.");
5338+ goto bail_unlock;
5339+ }
5340+
5341 handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS);
5342 if (IS_ERR(handle)) {
5343 status = PTR_ERR(handle);
cc23e853 5344@@ -839,6 +878,7 @@ bail:
d4263eb0
JR
5345 return status;
5346 }
d337f35e 5347
d337f35e 5348+
d4263eb0
JR
5349 long ocfs2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
5350 {
b00e13aa 5351 struct inode *inode = file_inode(filp);
3261cfd5
AM
5352diff -NurpP --minimal linux-4.9.207/fs/ocfs2/namei.c linux-4.9.207-vs2.3.9.11/fs/ocfs2/namei.c
5353--- linux-4.9.207/fs/ocfs2/namei.c 2016-12-11 19:17:54.000000000 +0000
5354+++ linux-4.9.207-vs2.3.9.11/fs/ocfs2/namei.c 2018-10-20 04:58:14.000000000 +0000
ec22aa5c 5355@@ -41,6 +41,7 @@
d337f35e
JR
5356 #include <linux/slab.h>
5357 #include <linux/highmem.h>
ec22aa5c 5358 #include <linux/quotaops.h>
d337f35e
JR
5359+#include <linux/vs_tag.h>
5360
d337f35e 5361 #include <cluster/masklog.h>
763640ca 5362
cc23e853 5363@@ -516,6 +517,7 @@ static int __ocfs2_mknod_locked(struct i
93de0823 5364 struct ocfs2_extent_list *fel;
ec22aa5c 5365 u16 feat;
265de2f7 5366 struct ocfs2_inode_info *oi = OCFS2_I(inode);
a4a22af8 5367+ ktag_t ktag;
d337f35e 5368
7e46296a
AM
5369 *new_fe_bh = NULL;
5370
cc23e853 5371@@ -553,8 +555,13 @@ static int __ocfs2_mknod_locked(struct i
76514441 5372 fe->i_suballoc_loc = cpu_to_le64(suballoc_loc);
d337f35e 5373 fe->i_suballoc_bit = cpu_to_le16(suballoc_bit);
2380c486 5374 fe->i_suballoc_slot = cpu_to_le16(inode_ac->ac_alloc_slot);
b00e13aa
AM
5375- fe->i_uid = cpu_to_le32(i_uid_read(inode));
5376- fe->i_gid = cpu_to_le32(i_gid_read(inode));
d337f35e 5377+
a4a22af8
AM
5378+ ktag = make_ktag(&init_user_ns, dx_current_fstag(osb->sb));
5379+ fe->i_uid = cpu_to_le32(from_kuid(&init_user_ns,
5380+ TAGINO_KUID(DX_TAG(inode), inode->i_uid, ktag)));
5381+ fe->i_gid = cpu_to_le32(from_kgid(&init_user_ns,
5382+ TAGINO_KGID(DX_TAG(inode), inode->i_gid, ktag)));
5383+ inode->i_tag = ktag; /* is this correct? */
ec22aa5c
AM
5384 fe->i_mode = cpu_to_le16(inode->i_mode);
5385 if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
d337f35e 5386 fe->id1.dev1.i_rdev = cpu_to_le64(huge_encode_dev(dev));
3261cfd5
AM
5387diff -NurpP --minimal linux-4.9.207/fs/ocfs2/ocfs2_fs.h linux-4.9.207-vs2.3.9.11/fs/ocfs2/ocfs2_fs.h
5388--- linux-4.9.207/fs/ocfs2/ocfs2_fs.h 2016-12-11 19:17:54.000000000 +0000
5389+++ linux-4.9.207-vs2.3.9.11/fs/ocfs2/ocfs2_fs.h 2018-10-20 04:58:14.000000000 +0000
cc23e853 5390@@ -275,6 +275,11 @@
93de0823
AM
5391 #define OCFS2_TOPDIR_FL FS_TOPDIR_FL /* Top of directory hierarchies*/
5392 #define OCFS2_RESERVED_FL FS_RESERVED_FL /* reserved for ext2 lib */
2380c486 5393
93de0823
AM
5394+#define OCFS2_IXUNLINK_FL FS_IXUNLINK_FL /* Immutable invert on unlink */
5395+
5396+#define OCFS2_BARRIER_FL FS_BARRIER_FL /* Barrier for chroot() */
5397+#define OCFS2_COW_FL FS_COW_FL /* Copy on Write marker */
5398+
5399 #define OCFS2_FL_VISIBLE FS_FL_USER_VISIBLE /* User visible flags */
5400 #define OCFS2_FL_MODIFIABLE FS_FL_USER_MODIFIABLE /* User modifiable flags */
5401
3261cfd5
AM
5402diff -NurpP --minimal linux-4.9.207/fs/ocfs2/ocfs2.h linux-4.9.207-vs2.3.9.11/fs/ocfs2/ocfs2.h
5403--- linux-4.9.207/fs/ocfs2/ocfs2.h 2019-12-25 15:28:37.907306953 +0000
5404+++ linux-4.9.207-vs2.3.9.11/fs/ocfs2/ocfs2.h 2018-10-20 04:58:14.000000000 +0000
5405@@ -289,6 +289,7 @@ enum ocfs2_mount_options
5406 OCFS2_MOUNT_JOURNAL_ASYNC_COMMIT = 1 << 15, /* Journal Async Commit */
5407 OCFS2_MOUNT_ERRORS_CONT = 1 << 16, /* Return EIO to the calling process on error */
5408 OCFS2_MOUNT_ERRORS_ROFS = 1 << 17, /* Change filesystem to read-only on error */
5409+ OCFS2_MOUNT_TAGGED = 1 << 18, /* use tagging */
5410 };
5411
5412 #define OCFS2_OSB_SOFT_RO 0x0001
5413diff -NurpP --minimal linux-4.9.207/fs/ocfs2/super.c linux-4.9.207-vs2.3.9.11/fs/ocfs2/super.c
5414--- linux-4.9.207/fs/ocfs2/super.c 2019-12-25 15:28:37.927306628 +0000
5415+++ linux-4.9.207-vs2.3.9.11/fs/ocfs2/super.c 2018-10-20 04:58:14.000000000 +0000
cc23e853 5416@@ -188,6 +188,7 @@ enum {
76514441 5417 Opt_dir_resv_level,
cc23e853
AM
5418 Opt_journal_async_commit,
5419 Opt_err_cont,
d337f35e
JR
5420+ Opt_tag, Opt_notag, Opt_tagid,
5421 Opt_err,
5422 };
5423
cc23e853 5424@@ -221,6 +222,9 @@ static const match_table_t tokens = {
76514441 5425 {Opt_dir_resv_level, "dir_resv_level=%u"},
cc23e853
AM
5426 {Opt_journal_async_commit, "journal_async_commit"},
5427 {Opt_err_cont, "errors=continue"},
d337f35e 5428+ {Opt_tag, "tag"},
d337f35e
JR
5429+ {Opt_notag, "notag"},
5430+ {Opt_tagid, "tagid=%u"},
5431 {Opt_err, NULL}
5432 };
5433
09a55596 5434@@ -672,6 +676,13 @@ static int ocfs2_remount(struct super_bl
d337f35e
JR
5435 goto out;
5436 }
5437
d4263eb0
JR
5438+ if ((osb->s_mount_opt & OCFS2_MOUNT_TAGGED) !=
5439+ (parsed_options.mount_opt & OCFS2_MOUNT_TAGGED)) {
d337f35e
JR
5440+ ret = -EINVAL;
5441+ mlog(ML_ERROR, "Cannot change tagging on remount\n");
5442+ goto out;
5443+ }
5444+
ab30d09f
AM
5445 /* We're going to/from readonly mode. */
5446 if ((*flags & MS_RDONLY) != (sb->s_flags & MS_RDONLY)) {
5447 /* Disable quota accounting before remounting RO */
09a55596 5448@@ -1161,6 +1172,9 @@ static int ocfs2_fill_super(struct super
d337f35e
JR
5449
5450 ocfs2_complete_mount_recovery(osb);
5451
5452+ if (osb->s_mount_opt & OCFS2_MOUNT_TAGGED)
5453+ sb->s_flags |= MS_TAGGED;
5454+
2380c486
JR
5455 if (ocfs2_mount_local(osb))
5456 snprintf(nodestr, sizeof(nodestr), "local");
5457 else
09a55596 5458@@ -1480,6 +1494,20 @@ static int ocfs2_parse_options(struct su
cc23e853
AM
5459 case Opt_journal_async_commit:
5460 mopt->mount_opt |= OCFS2_MOUNT_JOURNAL_ASYNC_COMMIT;
d337f35e
JR
5461 break;
5462+#ifndef CONFIG_TAGGING_NONE
5463+ case Opt_tag:
2380c486 5464+ mopt->mount_opt |= OCFS2_MOUNT_TAGGED;
d337f35e
JR
5465+ break;
5466+ case Opt_notag:
2380c486 5467+ mopt->mount_opt &= ~OCFS2_MOUNT_TAGGED;
d337f35e
JR
5468+ break;
5469+#endif
5470+#ifdef CONFIG_PROPAGATE
5471+ case Opt_tagid:
5472+ /* use args[0] */
2380c486 5473+ mopt->mount_opt |= OCFS2_MOUNT_TAGGED;
d337f35e
JR
5474+ break;
5475+#endif
5476 default:
5477 mlog(ML_ERROR,
5478 "Unrecognized mount option \"%s\" "
3261cfd5
AM
5479diff -NurpP --minimal linux-4.9.207/fs/open.c linux-4.9.207-vs2.3.9.11/fs/open.c
5480--- linux-4.9.207/fs/open.c 2019-12-25 15:28:37.947306307 +0000
5481+++ linux-4.9.207-vs2.3.9.11/fs/open.c 2019-10-05 14:58:45.460310912 +0000
b00e13aa 5482@@ -31,6 +31,11 @@
2bf5ad28 5483 #include <linux/ima.h>
93de0823 5484 #include <linux/dnotify.h>
b00e13aa 5485 #include <linux/compat.h>
d337f35e
JR
5486+#include <linux/vs_base.h>
5487+#include <linux/vs_limit.h>
d337f35e
JR
5488+#include <linux/vs_tag.h>
5489+#include <linux/vs_cowbl.h>
78865d5b 5490+#include <linux/vserver/dlimit.h>
d337f35e 5491
2bf5ad28
AM
5492 #include "internal.h"
5493
cc23e853
AM
5494@@ -65,12 +70,17 @@ int do_truncate(struct dentry *dentry, l
5495 return ret;
5496 }
5497
5498-long vfs_truncate(const struct path *path, loff_t length)
5499+long vfs_truncate(struct path *path, loff_t length)
5500 {
b00e13aa 5501 struct inode *inode;
cc23e853 5502 struct dentry *upperdentry;
b00e13aa
AM
5503 long error;
5504
76514441 5505+#ifdef CONFIG_VSERVER_COWBL
b00e13aa 5506+ error = cow_check_and_break(path);
d337f35e 5507+ if (error)
b00e13aa 5508+ goto out;
76514441 5509+#endif
b00e13aa 5510 inode = path->dentry->d_inode;
d337f35e 5511
a168f21d 5512 /* For directories it's -EISDIR, for other non-regulars - -EINVAL */
3261cfd5 5513@@ -584,6 +594,13 @@ SYSCALL_DEFINE3(fchmodat, int, dfd, cons
b00e13aa
AM
5514 unsigned int lookup_flags = LOOKUP_FOLLOW;
5515 retry:
5516 error = user_path_at(dfd, filename, lookup_flags, &path);
a168f21d 5517+#ifdef CONFIG_VSERVER_COWBL
b00e13aa 5518+ if (!error) {
a168f21d 5519+ error = cow_check_and_break(&path);
b00e13aa
AM
5520+ if (error)
5521+ path_put(&path);
5522+ }
a168f21d 5523+#endif
b00e13aa 5524 if (!error) {
a168f21d
AM
5525 error = chmod_common(&path, mode);
5526 path_put(&path);
3261cfd5 5527@@ -618,13 +635,15 @@ retry_deleg:
42bc425c
AM
5528 if (!uid_valid(uid))
5529 return -EINVAL;
d337f35e 5530 newattrs.ia_valid |= ATTR_UID;
42bc425c 5531- newattrs.ia_uid = uid;
8ce283e1
AM
5532+ newattrs.ia_uid = make_kuid(&init_user_ns,
5533+ dx_map_uid(user));
d337f35e
JR
5534 }
5535 if (group != (gid_t) -1) {
42bc425c
AM
5536 if (!gid_valid(gid))
5537 return -EINVAL;
d337f35e 5538 newattrs.ia_valid |= ATTR_GID;
42bc425c 5539- newattrs.ia_gid = gid;
8ce283e1
AM
5540+ newattrs.ia_gid = make_kgid(&init_user_ns,
5541+ dx_map_gid(group));
d337f35e
JR
5542 }
5543 if (!S_ISDIR(inode->i_mode))
2380c486 5544 newattrs.ia_valid |=
3261cfd5 5545@@ -662,6 +681,10 @@ retry:
2380c486 5546 error = mnt_want_write(path.mnt);
d337f35e 5547 if (error)
2380c486 5548 goto out_release;
d337f35e 5549+#ifdef CONFIG_VSERVER_COWBL
2380c486 5550+ error = cow_check_and_break(&path);
d337f35e 5551+ if (!error)
d337f35e 5552+#endif
2bf5ad28 5553 error = chown_common(&path, user, group);
2380c486
JR
5554 mnt_drop_write(path.mnt);
5555 out_release:
3261cfd5
AM
5556diff -NurpP --minimal linux-4.9.207/fs/proc/array.c linux-4.9.207-vs2.3.9.11/fs/proc/array.c
5557--- linux-4.9.207/fs/proc/array.c 2019-12-25 15:28:37.987305658 +0000
5558+++ linux-4.9.207-vs2.3.9.11/fs/proc/array.c 2019-10-05 14:58:45.660307716 +0000
09a55596 5559@@ -86,6 +86,8 @@
cc23e853 5560 #include <linux/string_helpers.h>
42bc425c 5561 #include <linux/user_namespace.h>
cc23e853 5562 #include <linux/fs_struct.h>
d337f35e
JR
5563+#include <linux/vs_context.h>
5564+#include <linux/vs_network.h>
5565
d337f35e 5566 #include <asm/pgtable.h>
2380c486 5567 #include <asm/processor.h>
09a55596 5568@@ -170,6 +172,9 @@ static inline void task_state(struct seq
2380c486
JR
5569 ppid = pid_alive(p) ?
5570 task_tgid_nr_ns(rcu_dereference(p->real_parent), ns) : 0;
cc23e853 5571
2380c486
JR
5572+ if (unlikely(vx_current_initpid(p->pid)))
5573+ ppid = 0;
5574+
cc23e853
AM
5575 tracer = ptrace_parent(p);
5576 if (tracer)
5577 tpid = task_pid_nr_ns(tracer, ns);
09a55596 5578@@ -307,8 +312,8 @@ static inline void task_sig(struct seq_f
bb20add7 5579 render_sigset_t(m, "SigCgt:\t", &caught);
2380c486
JR
5580 }
5581
bb20add7 5582-static void render_cap_t(struct seq_file *m, const char *header,
2380c486 5583- kernel_cap_t *a)
bb20add7 5584+void render_cap_t(struct seq_file *m, const char *header,
2380c486 5585+ struct vx_info *vxi, kernel_cap_t *a)
d337f35e 5586 {
2380c486
JR
5587 unsigned __capi;
5588
09a55596 5589@@ -335,11 +340,12 @@ static inline void task_cap(struct seq_f
cc23e853 5590 cap_ambient = cred->cap_ambient;
bb20add7 5591 rcu_read_unlock();
2380c486 5592
ec22aa5c
AM
5593- render_cap_t(m, "CapInh:\t", &cap_inheritable);
5594- render_cap_t(m, "CapPrm:\t", &cap_permitted);
5595- render_cap_t(m, "CapEff:\t", &cap_effective);
5596- render_cap_t(m, "CapBnd:\t", &cap_bset);
cc23e853 5597- render_cap_t(m, "CapAmb:\t", &cap_ambient);
ec22aa5c
AM
5598+ /* FIXME: maybe move the p->vx_info masking to __task_cred() ? */
5599+ render_cap_t(m, "CapInh:\t", p->vx_info, &cap_inheritable);
5600+ render_cap_t(m, "CapPrm:\t", p->vx_info, &cap_permitted);
5601+ render_cap_t(m, "CapEff:\t", p->vx_info, &cap_effective);
5602+ render_cap_t(m, "CapBnd:\t", p->vx_info, &cap_bset);
cc23e853 5603+ render_cap_t(m, "CapAmb:\t", p->vx_info, &cap_ambient);
d337f35e
JR
5604 }
5605
b00e13aa 5606 static inline void task_seccomp(struct seq_file *m, struct task_struct *p)
3261cfd5 5607@@ -391,6 +397,43 @@ static void task_cpus_allowed(struct seq
cc23e853 5608 cpumask_pr_args(&task->cpus_allowed));
2380c486
JR
5609 }
5610
5611+int proc_pid_nsproxy(struct seq_file *m, struct pid_namespace *ns,
5612+ struct pid *pid, struct task_struct *task)
5613+{
5614+ seq_printf(m, "Proxy:\t%p(%c)\n"
5615+ "Count:\t%u\n"
5616+ "uts:\t%p(%c)\n"
5617+ "ipc:\t%p(%c)\n"
5618+ "mnt:\t%p(%c)\n"
5619+ "pid:\t%p(%c)\n"
5620+ "net:\t%p(%c)\n",
5621+ task->nsproxy,
5622+ (task->nsproxy == init_task.nsproxy ? 'I' : '-'),
5623+ atomic_read(&task->nsproxy->count),
5624+ task->nsproxy->uts_ns,
5625+ (task->nsproxy->uts_ns == init_task.nsproxy->uts_ns ? 'I' : '-'),
5626+ task->nsproxy->ipc_ns,
5627+ (task->nsproxy->ipc_ns == init_task.nsproxy->ipc_ns ? 'I' : '-'),
5628+ task->nsproxy->mnt_ns,
5629+ (task->nsproxy->mnt_ns == init_task.nsproxy->mnt_ns ? 'I' : '-'),
c2e5f7c8
JR
5630+ task->nsproxy->pid_ns_for_children,
5631+ (task->nsproxy->pid_ns_for_children ==
5632+ init_task.nsproxy->pid_ns_for_children ? 'I' : '-'),
2380c486
JR
5633+ task->nsproxy->net_ns,
5634+ (task->nsproxy->net_ns == init_task.nsproxy->net_ns ? 'I' : '-'));
5635+ return 0;
5636+}
d337f35e 5637+
2380c486
JR
5638+void task_vs_id(struct seq_file *m, struct task_struct *task)
5639+{
d337f35e 5640+ if (task_vx_flags(task, VXF_HIDE_VINFO, 0))
2380c486
JR
5641+ return;
5642+
bb20add7
AM
5643+ seq_printf(m, "VxID:\t%d\n", vx_task_xid(task));
5644+ seq_printf(m, "NxID:\t%d\n", nx_task_nid(task));
2380c486
JR
5645+}
5646+
5647+
5648 int proc_pid_status(struct seq_file *m, struct pid_namespace *ns,
5649 struct pid *pid, struct task_struct *task)
5650 {
3261cfd5 5651@@ -408,6 +451,7 @@ int proc_pid_status(struct seq_file *m,
b00e13aa 5652 task_seccomp(m, task);
2bf5ad28 5653 task_cpus_allowed(m, task);
2380c486
JR
5654 cpuset_task_status_allowed(m, task);
5655+ task_vs_id(m, task);
152aeb71
JR
5656 task_context_switch_counts(m, task);
5657 return 0;
5658 }
3261cfd5 5659@@ -523,6 +567,17 @@ static int do_task_stat(struct seq_file
d337f35e 5660 /* convert nsec -> ticks */
bb20add7 5661 start_time = nsec_to_clock_t(task->real_start_time);
d337f35e
JR
5662
5663+ /* fixup start time for virt uptime */
5664+ if (vx_flags(VXF_VIRT_UPTIME, 0)) {
5665+ unsigned long long bias =
5666+ current->vx_info->cvirt.bias_clock;
5667+
5668+ if (start_time > bias)
5669+ start_time -= bias;
5670+ else
5671+ start_time = 0;
5672+ }
5673+
1e8b8f9b 5674 seq_printf(m, "%d (%s) %c", pid_nr_ns(pid, ns), tcomm, state);
cc23e853
AM
5675 seq_put_decimal_ll(m, " ", ppid);
5676 seq_put_decimal_ll(m, " ", pgid);
3261cfd5
AM
5677diff -NurpP --minimal linux-4.9.207/fs/proc/base.c linux-4.9.207-vs2.3.9.11/fs/proc/base.c
5678--- linux-4.9.207/fs/proc/base.c 2019-12-25 15:28:37.987305658 +0000
5679+++ linux-4.9.207-vs2.3.9.11/fs/proc/base.c 2019-10-05 14:58:45.660307716 +0000
09be7631 5680@@ -87,6 +87,8 @@
78865d5b 5681 #include <linux/slab.h>
db55b927 5682 #include <linux/flex_array.h>
09be7631 5683 #include <linux/posix-timers.h>
d337f35e
JR
5684+#include <linux/vs_context.h>
5685+#include <linux/vs_network.h>
763640ca
JR
5686 #ifdef CONFIG_HARDWALL
5687 #include <asm/hardwall.h>
5688 #endif
09a55596 5689@@ -1079,10 +1081,15 @@ static int __set_oom_adj(struct file *fi
cc23e853
AM
5690 mutex_lock(&oom_adj_mutex);
5691 if (legacy) {
5692 if (oom_adj < task->signal->oom_score_adj &&
5693- !capable(CAP_SYS_RESOURCE)) {
5694+ !vx_capable(CAP_SYS_RESOURCE, VXC_OOM_ADJUST)) {
5695 err = -EACCES;
5696 goto err_unlock;
5697 }
7e46296a 5698+
cc23e853
AM
5699+ /* prevent guest processes from circumventing the oom killer */
5700+ if (vx_current_xid() && (oom_adj == OOM_DISABLE))
5701+ oom_adj = OOM_ADJUST_MIN;
5702+
5703 /*
5704 * /proc/pid/oom_adj is provided for legacy purposes, ask users to use
5705 * /proc/pid/oom_score_adj instead.
3261cfd5 5706@@ -1708,6 +1715,8 @@ struct inode *proc_pid_make_inode(struct
ec22aa5c
AM
5707 inode->i_gid = cred->egid;
5708 rcu_read_unlock();
d337f35e
JR
5709 }
5710+ /* procfs is xid tagged */
61333608 5711+ i_tag_write(inode, (vtag_t)vx_task_xid(task));
d337f35e
JR
5712 security_task_to_inode(task, inode);
5713
5714 out:
3261cfd5 5715@@ -1753,6 +1762,8 @@ int pid_getattr(struct vfsmount *mnt, st
d33d7b00
AM
5716
5717 /* dentry stuff */
5718
bb20add7 5719+// static unsigned name_to_int(struct dentry *dentry);
d33d7b00
AM
5720+
5721 /*
5722 * Exceptional case: normally we are not allowed to unhash a busy
5723 * directory. In this case, however, we can do it - no aliasing problems
3261cfd5 5724@@ -1781,6 +1792,19 @@ int pid_revalidate(struct dentry *dentry
d33d7b00
AM
5725 task = get_proc_task(inode);
5726
5727 if (task) {
bb20add7
AM
5728+ unsigned pid = name_to_int(&dentry->d_name);
5729+
5730+ if (pid != ~0U && pid != vx_map_pid(task->pid) &&
5731+ pid != __task_pid_nr_ns(task, PIDTYPE_PID,
5732+ task_active_pid_ns(task))) {
5733+ vxdprintk(VXD_CBIT(misc, 10),
5734+ VS_Q("%*s") " dropped by pid_revalidate(%d!=%d)",
5735+ dentry->d_name.len, dentry->d_name.name,
5736+ pid, vx_map_pid(task->pid));
d33d7b00 5737+ put_task_struct(task);
bb20add7
AM
5738+ d_drop(dentry);
5739+ return 0;
d33d7b00
AM
5740+ }
5741 if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) ||
5742 task_dumpable(task)) {
5743 rcu_read_lock();
3261cfd5 5744@@ -2445,6 +2469,13 @@ static struct dentry *proc_pident_lookup
d337f35e
JR
5745 if (!task)
5746 goto out_no_task;
5747
2380c486 5748+ /* TODO: maybe we can come up with a generic approach? */
d337f35e
JR
5749+ if (task_vx_flags(task, VXF_HIDE_VINFO, 0) &&
5750+ (dentry->d_name.len == 5) &&
5751+ (!memcmp(dentry->d_name.name, "vinfo", 5) ||
5752+ !memcmp(dentry->d_name.name, "ninfo", 5)))
5753+ goto out;
5754+
5755 /*
5756 * Yes, it does not scale. And it should not. Don't add
5757 * new entries into /proc/<tgid>/ without very good reasons.
3261cfd5 5758@@ -2884,6 +2915,11 @@ static int proc_pid_personality(struct s
2380c486
JR
5759 static const struct file_operations proc_task_operations;
5760 static const struct inode_operations proc_task_inode_operations;
d337f35e 5761
bb20add7
AM
5762+extern int proc_pid_vx_info(struct seq_file *,
5763+ struct pid_namespace *, struct pid *, struct task_struct *);
5764+extern int proc_pid_nx_info(struct seq_file *,
5765+ struct pid_namespace *, struct pid *, struct task_struct *);
d337f35e 5766+
2380c486 5767 static const struct pid_entry tgid_base_stuff[] = {
ec22aa5c
AM
5768 DIR("task", S_IRUGO|S_IXUGO, proc_task_inode_operations, proc_task_operations),
5769 DIR("fd", S_IRUSR|S_IXUSR, proc_fd_inode_operations, proc_fd_operations),
3261cfd5 5770@@ -2948,6 +2984,8 @@ static const struct pid_entry tgid_base_
2380c486 5771 #ifdef CONFIG_CGROUPS
bb20add7 5772 ONE("cgroup", S_IRUGO, proc_cgroup_show),
d337f35e 5773 #endif
bb20add7
AM
5774+ ONE("vinfo", S_IRUGO, proc_pid_vx_info),
5775+ ONE("ninfo", S_IRUGO, proc_pid_nx_info),
5776 ONE("oom_score", S_IRUGO, proc_oom_score),
537831f9 5777 REG("oom_adj", S_IRUGO|S_IWUSR, proc_oom_adj_operations),
93de0823 5778 REG("oom_score_adj", S_IRUGO|S_IWUSR, proc_oom_score_adj_operations),
3261cfd5 5779@@ -3163,7 +3201,7 @@ retry:
2380c486
JR
5780 iter.task = NULL;
5781 pid = find_ge_pid(iter.tgid, ns);
5782 if (pid) {
5783- iter.tgid = pid_nr_ns(pid, ns);
5784+ iter.tgid = pid_unmapped_nr_ns(pid, ns);
5785 iter.task = pid_task(pid, PIDTYPE_PID);
5786 /* What we to know is if the pid we have find is the
5787 * pid of a thread_group_leader. Testing for task
3261cfd5 5788@@ -3223,8 +3261,10 @@ int proc_pid_readdir(struct file *file,
c2e5f7c8
JR
5789 if (!has_pid_permissions(ns, iter.task, 2))
5790 continue;
db55b927 5791
c2e5f7c8
JR
5792- len = snprintf(name, sizeof(name), "%d", iter.tgid);
5793+ len = snprintf(name, sizeof(name), "%d", vx_map_tgid(iter.tgid));
5794 ctx->pos = iter.tgid + TGID_OFFSET;
2380c486 5795+ if (!vx_proc_task_visible(iter.task))
d337f35e 5796+ continue;
c2e5f7c8
JR
5797 if (!proc_fill_cache(file, ctx, name, len,
5798 proc_pid_instantiate, iter.task, NULL)) {
2380c486 5799 put_task_struct(iter.task);
3261cfd5 5800@@ -3361,6 +3401,7 @@ static const struct pid_entry tid_base_s
09be7631 5801 REG("projid_map", S_IRUGO|S_IWUSR, proc_projid_map_operations),
bb20add7 5802 REG("setgroups", S_IRUGO|S_IWUSR, proc_setgroups_operations),
09be7631
JR
5803 #endif
5804+ ONE("nsproxy", S_IRUGO, proc_pid_nsproxy),
5805 };
5806
c2e5f7c8 5807 static int proc_tid_base_readdir(struct file *file, struct dir_context *ctx)
3261cfd5 5808@@ -3427,6 +3468,8 @@ static struct dentry *proc_task_lookup(s
bb20add7 5809 tid = name_to_int(&dentry->d_name);
d337f35e
JR
5810 if (tid == ~0U)
5811 goto out;
5812+ if (vx_current_initpid(tid))
5813+ goto out;
5814
2380c486 5815 ns = dentry->d_sb->s_fs_info;
d337f35e 5816 rcu_read_lock();
3261cfd5
AM
5817diff -NurpP --minimal linux-4.9.207/fs/proc/generic.c linux-4.9.207-vs2.3.9.11/fs/proc/generic.c
5818--- linux-4.9.207/fs/proc/generic.c 2019-12-25 15:28:37.987305658 +0000
5819+++ linux-4.9.207-vs2.3.9.11/fs/proc/generic.c 2018-10-20 04:58:14.000000000 +0000
cc23e853 5820@@ -22,6 +22,7 @@
d337f35e
JR
5821 #include <linux/bitops.h>
5822 #include <linux/spinlock.h>
2380c486 5823 #include <linux/completion.h>
d337f35e
JR
5824+#include <linux/vserver/inode.h>
5825 #include <asm/uaccess.h>
5826
5827 #include "internal.h"
cc23e853
AM
5828@@ -66,8 +67,16 @@ static struct proc_dir_entry *pde_subdir
5829 node = node->rb_left;
5830 else if (result > 0)
5831 node = node->rb_right;
5832- else
5833+ else {
5834+ if (!vx_hide_check(0, de->vx_flags)) {
5835+ vxdprintk(VXD_CBIT(misc, 9),
5836+ VS_Q("%*s")
5837+ " hidden in pde_subdir_find()",
5838+ de->namelen, de->name);
5839+ return 0;
5840+ }
5841 return de;
bb20add7 5842+ }
cc23e853
AM
5843 }
5844 return NULL;
5845 }
5846@@ -241,6 +250,8 @@ struct dentry *proc_lookup_de(struct pro
5847 return ERR_PTR(-ENOMEM);
5848 d_set_d_op(dentry, &simple_dentry_operations);
5849 d_add(dentry, inode);
ba86f833 5850+ /* generic proc entries belong to the host */
537831f9 5851+ i_tag_write(inode, 0);
cc23e853 5852 return NULL;
2380c486 5853 }
cc23e853
AM
5854 read_unlock(&proc_subdir_lock);
5855@@ -287,6 +298,12 @@ int proc_readdir_de(struct proc_dir_entr
c2e5f7c8
JR
5856 do {
5857 struct proc_dir_entry *next;
5858 pde_get(de);
bb20add7
AM
5859+ if (!vx_hide_check(0, de->vx_flags)) {
5860+ vxdprintk(VXD_CBIT(misc, 9),
5861+ VS_Q("%*s") " hidden in proc_readdir_de()",
5862+ de->namelen, de->name);
c2e5f7c8 5863+ goto skip;
bb20add7 5864+ }
cc23e853 5865 read_unlock(&proc_subdir_lock);
c2e5f7c8
JR
5866 if (!dir_emit(ctx, de->name, de->namelen,
5867 de->low_ino, de->mode >> 12)) {
cc23e853 5868@@ -294,6 +311,7 @@ int proc_readdir_de(struct proc_dir_entr
c2e5f7c8
JR
5869 return 0;
5870 }
cc23e853 5871 read_lock(&proc_subdir_lock);
c2e5f7c8
JR
5872+ skip:
5873 ctx->pos++;
cc23e853 5874 next = pde_subdir_next(de);
c2e5f7c8 5875 pde_put(de);
cc23e853 5876@@ -387,6 +405,7 @@ static struct proc_dir_entry *__proc_cre
537831f9 5877 ent->mode = mode;
d337f35e 5878 ent->nlink = nlink;
cc23e853 5879 ent->subdir = RB_ROOT;
d337f35e 5880+ ent->vx_flags = IATTR_PROC_DEFAULT;
537831f9 5881 atomic_set(&ent->count, 1);
2380c486 5882 spin_lock_init(&ent->pde_unload_lock);
2380c486 5883 INIT_LIST_HEAD(&ent->pde_openers);
cc23e853 5884@@ -413,7 +432,8 @@ struct proc_dir_entry *proc_symlink(cons
d337f35e
JR
5885 kfree(ent->data);
5886 kfree(ent);
5887 ent = NULL;
5888- }
5889+ } else
5890+ ent->vx_flags = IATTR_PROC_SYMLINK;
5891 } else {
5892 kfree(ent);
5893 ent = NULL;
3261cfd5
AM
5894diff -NurpP --minimal linux-4.9.207/fs/proc/inode.c linux-4.9.207-vs2.3.9.11/fs/proc/inode.c
5895--- linux-4.9.207/fs/proc/inode.c 2019-12-25 15:28:37.997305497 +0000
5896+++ linux-4.9.207-vs2.3.9.11/fs/proc/inode.c 2018-10-20 05:55:43.000000000 +0000
09a55596 5897@@ -433,6 +433,8 @@ struct inode *proc_get_inode(struct supe
d337f35e
JR
5898 inode->i_uid = de->uid;
5899 inode->i_gid = de->gid;
5900 }
5901+ if (de->vx_flags)
5902+ PROC_I(inode)->vx_flags = de->vx_flags;
5903 if (de->size)
5904 inode->i_size = de->size;
5905 if (de->nlink)
3261cfd5
AM
5906diff -NurpP --minimal linux-4.9.207/fs/proc/internal.h linux-4.9.207-vs2.3.9.11/fs/proc/internal.h
5907--- linux-4.9.207/fs/proc/internal.h 2019-12-25 15:28:38.017305173 +0000
5908+++ linux-4.9.207-vs2.3.9.11/fs/proc/internal.h 2018-10-20 05:55:43.000000000 +0000
09be7631
JR
5909@@ -14,6 +14,7 @@
5910 #include <linux/spinlock.h>
5911 #include <linux/atomic.h>
b00e13aa 5912 #include <linux/binfmts.h>
d337f35e
JR
5913+#include <linux/vs_pid.h>
5914
09be7631
JR
5915 struct ctl_table_header;
5916 struct mempolicy;
cc23e853 5917@@ -34,6 +35,7 @@ struct proc_dir_entry {
09be7631
JR
5918 nlink_t nlink;
5919 kuid_t uid;
5920 kgid_t gid;
5921+ int vx_flags;
5922 loff_t size;
5923 const struct inode_operations *proc_iops;
5924 const struct file_operations *proc_fops;
cc23e853 5925@@ -51,15 +53,22 @@ struct proc_dir_entry {
09be7631
JR
5926 char name[];
5927 };
5928
5929+struct vx_info;
5930+struct nx_info;
2380c486 5931+
09be7631
JR
5932 union proc_op {
5933 int (*proc_get_link)(struct dentry *, struct path *);
09be7631
JR
5934 int (*proc_show)(struct seq_file *m,
5935 struct pid_namespace *ns, struct pid *pid,
5936 struct task_struct *task);
5937+ int (*proc_vs_read)(char *page);
5938+ int (*proc_vxi_read)(struct vx_info *vxi, char *page);
5939+ int (*proc_nxi_read)(struct nx_info *nxi, char *page);
5940 };
2380c486 5941
09be7631
JR
5942 struct proc_inode {
5943 struct pid *pid;
5944+ int vx_flags;
cc23e853 5945 unsigned int fd;
09be7631
JR
5946 union proc_op op;
5947 struct proc_dir_entry *pde;
09a55596 5948@@ -93,11 +102,16 @@ static inline struct pid *proc_pid(struc
d337f35e
JR
5949 return PROC_I(inode)->pid;
5950 }
5951
5952-static inline struct task_struct *get_proc_task(struct inode *inode)
5953+static inline struct task_struct *get_proc_task_real(struct inode *inode)
5954 {
5955 return get_pid_task(proc_pid(inode), PIDTYPE_PID);
5956 }
5957
5958+static inline struct task_struct *get_proc_task(struct inode *inode)
5959+{
5960+ return vx_get_proc_task(inode, proc_pid(inode));
5961+}
5962+
09be7631 5963 static inline int task_dumpable(struct task_struct *task)
d337f35e 5964 {
09be7631 5965 int dumpable = 0;
09a55596 5966@@ -156,6 +170,8 @@ extern int proc_pid_status(struct seq_fi
09be7631
JR
5967 struct pid *, struct task_struct *);
5968 extern int proc_pid_statm(struct seq_file *, struct pid_namespace *,
5969 struct pid *, struct task_struct *);
5970+extern int proc_pid_nsproxy(struct seq_file *m, struct pid_namespace *ns,
5971+ struct pid *pid, struct task_struct *task);
5972
5973 /*
5974 * base.c
3261cfd5
AM
5975diff -NurpP --minimal linux-4.9.207/fs/proc/loadavg.c linux-4.9.207-vs2.3.9.11/fs/proc/loadavg.c
5976--- linux-4.9.207/fs/proc/loadavg.c 2016-12-11 19:17:54.000000000 +0000
5977+++ linux-4.9.207-vs2.3.9.11/fs/proc/loadavg.c 2018-10-20 04:58:14.000000000 +0000
ec22aa5c 5978@@ -12,15 +12,27 @@
1bc743c0 5979
ec22aa5c 5980 static int loadavg_proc_show(struct seq_file *m, void *v)
1bc743c0
JR
5981 {
5982+ unsigned long running;
5983+ unsigned int threads;
ec22aa5c 5984 unsigned long avnrun[3];
1bc743c0 5985
ec22aa5c 5986 get_avenrun(avnrun, FIXED_1/200, 0);
bd427b06 5987
ec22aa5c 5988+ if (vx_flags(VXF_VIRT_LOAD, 0)) {
eab5a9a6 5989+ struct vx_info *vxi = current_vx_info();
ec22aa5c
AM
5990+
5991+ running = atomic_read(&vxi->cvirt.nr_running);
5992+ threads = atomic_read(&vxi->cvirt.nr_threads);
5993+ } else {
5994+ running = nr_running();
5995+ threads = nr_threads;
5996+ }
5997+
5998 seq_printf(m, "%lu.%02lu %lu.%02lu %lu.%02lu %ld/%d %d\n",
5999 LOAD_INT(avnrun[0]), LOAD_FRAC(avnrun[0]),
6000 LOAD_INT(avnrun[1]), LOAD_FRAC(avnrun[1]),
6001 LOAD_INT(avnrun[2]), LOAD_FRAC(avnrun[2]),
1bc743c0
JR
6002- nr_running(), nr_threads,
6003+ running, threads,
6004 task_active_pid_ns(current)->last_pid);
ec22aa5c 6005 return 0;
1bc743c0 6006 }
3261cfd5
AM
6007diff -NurpP --minimal linux-4.9.207/fs/proc/meminfo.c linux-4.9.207-vs2.3.9.11/fs/proc/meminfo.c
6008--- linux-4.9.207/fs/proc/meminfo.c 2016-12-11 19:17:54.000000000 +0000
6009+++ linux-4.9.207-vs2.3.9.11/fs/proc/meminfo.c 2018-10-20 04:58:14.000000000 +0000
cc23e853 6010@@ -55,7 +55,8 @@ static int meminfo_proc_show(struct seq_
c2e5f7c8
JR
6011 si_swapinfo(&i);
6012 committed = percpu_counter_read_positive(&vm_committed_as);
e3afe727 6013
cc23e853 6014- cached = global_node_page_state(NR_FILE_PAGES) -
e3afe727 6015+ cached = vx_flags(VXF_VIRT_MEM, 0) ?
cc23e853 6016+ vx_vsi_cached(&i) : global_node_page_state(NR_FILE_PAGES) -
b00e13aa 6017 total_swapcache_pages() - i.bufferram;
e3afe727 6018 if (cached < 0)
d337f35e 6019 cached = 0;
3261cfd5
AM
6020diff -NurpP --minimal linux-4.9.207/fs/proc/root.c linux-4.9.207-vs2.3.9.11/fs/proc/root.c
6021--- linux-4.9.207/fs/proc/root.c 2016-12-11 19:17:54.000000000 +0000
6022+++ linux-4.9.207-vs2.3.9.11/fs/proc/root.c 2018-10-20 04:58:14.000000000 +0000
b00e13aa 6023@@ -20,9 +20,14 @@
2380c486
JR
6024 #include <linux/mount.h>
6025 #include <linux/pid_namespace.h>
db55b927 6026 #include <linux/parser.h>
2380c486 6027+#include <linux/vserver/inode.h>
d337f35e 6028
2380c486 6029 #include "internal.h"
d337f35e 6030
d337f35e
JR
6031+struct proc_dir_entry *proc_virtual;
6032+
6033+extern void proc_vx_init(void);
2380c486 6034+
cc23e853
AM
6035 enum {
6036 Opt_gid, Opt_hidepid, Opt_err,
6037 };
6038@@ -145,6 +150,7 @@ void __init proc_root_init(void)
bb20add7 6039 proc_tty_init();
2380c486
JR
6040 proc_mkdir("bus", NULL);
6041 proc_sys_init();
d337f35e
JR
6042+ proc_vx_init();
6043 }
6044
6045 static int proc_root_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat
cc23e853 6046@@ -206,6 +212,7 @@ struct proc_dir_entry proc_root = {
2380c486
JR
6047 .proc_iops = &proc_root_inode_operations,
6048 .proc_fops = &proc_root_operations,
6049 .parent = &proc_root,
6050+ .vx_flags = IATTR_ADMIN | IATTR_WATCH,
cc23e853 6051 .subdir = RB_ROOT,
a168f21d 6052 .name = "/proc",
2380c486 6053 };
3261cfd5
AM
6054diff -NurpP --minimal linux-4.9.207/fs/proc/self.c linux-4.9.207-vs2.3.9.11/fs/proc/self.c
6055--- linux-4.9.207/fs/proc/self.c 2016-12-11 19:17:54.000000000 +0000
6056+++ linux-4.9.207-vs2.3.9.11/fs/proc/self.c 2018-10-20 04:58:14.000000000 +0000
cc23e853
AM
6057@@ -1,6 +1,7 @@
6058 #include <linux/sched.h>
09be7631
JR
6059 #include <linux/slab.h>
6060 #include <linux/pid_namespace.h>
b00e13aa 6061+#include <linux/vserver/inode.h>
09be7631 6062 #include "internal.h"
b00e13aa
AM
6063
6064 /*
c2e5f7c8 6065@@ -54,6 +55,8 @@ int proc_setup_self(struct super_block *
09be7631
JR
6066 self = d_alloc_name(s->s_root, "self");
6067 if (self) {
6068 struct inode *inode = new_inode_pseudo(s);
6069+
6070+ // self->vx_flags = IATTR_PROC_SYMLINK;
6071 if (inode) {
6072 inode->i_ino = self_inum;
cc23e853 6073 inode->i_mtime = inode->i_atime = inode->i_ctime = current_time(inode);
3261cfd5
AM
6074diff -NurpP --minimal linux-4.9.207/fs/proc/stat.c linux-4.9.207-vs2.3.9.11/fs/proc/stat.c
6075--- linux-4.9.207/fs/proc/stat.c 2019-12-25 15:28:38.017305173 +0000
6076+++ linux-4.9.207-vs2.3.9.11/fs/proc/stat.c 2019-10-13 15:58:54.758080005 +0000
537831f9 6077@@ -9,8 +9,10 @@
1e8b8f9b
AM
6078 #include <linux/slab.h>
6079 #include <linux/time.h>
6080 #include <linux/irqnr.h>
6081+#include <linux/vserver/cvirt.h>
265de2f7 6082 #include <linux/cputime.h>
1e8b8f9b 6083 #include <linux/tick.h>
537831f9
AM
6084+#include <linux/cpuset.h>
6085
6086 #ifndef arch_irq_stat_cpu
6087 #define arch_irq_stat_cpu(cpu) 0
3261cfd5 6088@@ -86,13 +88,21 @@ static int show_stat(struct seq_file *p,
537831f9
AM
6089 u64 sum_softirq = 0;
6090 unsigned int per_softirq_sums[NR_SOFTIRQS] = {0};
cc23e853 6091 struct timespec64 boottime;
537831f9
AM
6092+ cpumask_var_t cpus_allowed;
6093+ bool virt_cpu = vx_flags(VXF_VIRT_CPU, 0);
6094
6095 user = nice = system = idle = iowait =
1e8b8f9b
AM
6096 irq = softirq = steal = 0;
6097 guest = guest_nice = 0;
cc23e853
AM
6098 getboottime64(&boottime);
6099
537831f9
AM
6100+ if (virt_cpu)
6101+ cpuset_cpus_allowed(current, cpus_allowed);
1e8b8f9b 6102+
1e8b8f9b 6103 for_each_possible_cpu(i) {
537831f9
AM
6104+ if (virt_cpu && !cpumask_test_cpu(i, cpus_allowed))
6105+ continue;
6106+
6107 user += kcpustat_cpu(i).cpustat[CPUTIME_USER];
6108 nice += kcpustat_cpu(i).cpustat[CPUTIME_NICE];
6109 system += kcpustat_cpu(i).cpustat[CPUTIME_SYSTEM];
3261cfd5 6110@@ -128,6 +138,9 @@ static int show_stat(struct seq_file *p,
537831f9
AM
6111 seq_putc(p, '\n');
6112
6113 for_each_online_cpu(i) {
6114+ if (virt_cpu && !cpumask_test_cpu(i, cpus_allowed))
6115+ continue;
6116+
6117 /* Copy values here to work around gcc-2.95.3, gcc-2.96 */
6118 user = kcpustat_cpu(i).cpustat[CPUTIME_USER];
6119 nice = kcpustat_cpu(i).cpustat[CPUTIME_NICE];
3261cfd5
AM
6120diff -NurpP --minimal linux-4.9.207/fs/proc/uptime.c linux-4.9.207-vs2.3.9.11/fs/proc/uptime.c
6121--- linux-4.9.207/fs/proc/uptime.c 2019-12-25 15:28:38.017305173 +0000
6122+++ linux-4.9.207-vs2.3.9.11/fs/proc/uptime.c 2019-10-13 16:02:19.324763467 +0000
f6c5ef8b 6123@@ -5,6 +5,7 @@
ec22aa5c
AM
6124 #include <linux/seq_file.h>
6125 #include <linux/time.h>
f6c5ef8b 6126 #include <linux/kernel_stat.h>
ec22aa5c 6127+#include <linux/vserver/cvirt.h>
ec22aa5c
AM
6128
6129 static int uptime_proc_show(struct seq_file *m, void *v)
627cd95b 6130 {
3261cfd5 6131@@ -21,6 +22,7 @@ static int uptime_proc_show(struct seq_f
09a55596 6132 get_monotonic_boottime(&uptime);
f6c5ef8b
AM
6133 idle.tv_sec = div_u64_rem(nsec, NSEC_PER_SEC, &rem);
6134 idle.tv_nsec = rem;
ec22aa5c
AM
6135+
6136 seq_printf(m, "%lu.%02lu %lu.%02lu\n",
6137 (unsigned long) uptime.tv_sec,
6138 (uptime.tv_nsec / (NSEC_PER_SEC / 100)),
3261cfd5
AM
6139diff -NurpP --minimal linux-4.9.207/fs/proc_namespace.c linux-4.9.207-vs2.3.9.11/fs/proc_namespace.c
6140--- linux-4.9.207/fs/proc_namespace.c 2016-12-11 19:17:54.000000000 +0000
6141+++ linux-4.9.207-vs2.3.9.11/fs/proc_namespace.c 2018-10-20 04:58:14.000000000 +0000
cc23e853 6142@@ -46,6 +46,8 @@ static int show_sb_opts(struct seq_file
db55b927
AM
6143 { MS_DIRSYNC, ",dirsync" },
6144 { MS_MANDLOCK, ",mand" },
cc23e853 6145 { MS_LAZYTIME, ",lazytime" },
db55b927
AM
6146+ { MS_TAGGED, ",tag" },
6147+ { MS_NOTAGCHECK, ",notagcheck" },
6148 { 0, NULL }
6149 };
6150 const struct proc_fs_info *fs_infop;
cc23e853 6151@@ -82,6 +84,38 @@ static inline void mangle(struct seq_fil
db55b927
AM
6152 seq_escape(m, s, " \t\n\\");
6153 }
6154
61b0c03f
JR
6155+#ifdef CONFIG_VSERVER_EXTRA_MNT_CHECK
6156+
db55b927
AM
6157+static int mnt_is_reachable(struct vfsmount *vfsmnt)
6158+{
6159+ struct path root;
6160+ struct dentry *point;
6161+ struct mount *mnt = real_mount(vfsmnt);
6162+ struct mount *root_mnt;
6163+ int ret;
6164+
6165+ if (mnt == mnt->mnt_ns->root)
6166+ return 1;
6167+
98d9a5b1 6168+ rcu_read_lock();
db55b927
AM
6169+ root = current->fs->root;
6170+ root_mnt = real_mount(root.mnt);
6171+ point = root.dentry;
6172+
6173+ while ((mnt != mnt->mnt_parent) && (mnt != root_mnt)) {
6174+ point = mnt->mnt_mountpoint;
6175+ mnt = mnt->mnt_parent;
6176+ }
98d9a5b1 6177+ rcu_read_unlock();
db55b927
AM
6178+
6179+ ret = (mnt == root_mnt) && is_subdir(point, root.dentry);
db55b927
AM
6180+ return ret;
6181+}
61b0c03f
JR
6182+
6183+#else
6184+#define mnt_is_reachable(v) (1)
6185+#endif
db55b927
AM
6186+
6187 static void show_type(struct seq_file *m, struct super_block *sb)
6188 {
6189 mangle(m, sb->s_type->name);
cc23e853 6190@@ -99,6 +133,17 @@ static int show_vfsmnt(struct seq_file *
db55b927 6191 struct super_block *sb = mnt_path.dentry->d_sb;
cc23e853 6192 int err;
db55b927
AM
6193
6194+ if (vx_flags(VXF_HIDE_MOUNT, 0))
6195+ return SEQ_SKIP;
6196+ if (!mnt_is_reachable(mnt) && !vx_check(0, VS_WATCH_P))
6197+ return SEQ_SKIP;
6198+
6199+ if (!vx_check(0, VS_ADMIN|VS_WATCH) &&
6200+ mnt == current->fs->root.mnt) {
6201+ seq_puts(m, "/dev/root / ");
6202+ goto type;
6203+ }
6204+
6205 if (sb->s_op->show_devname) {
6206 err = sb->s_op->show_devname(m, mnt_path.dentry);
6207 if (err)
cc23e853
AM
6208@@ -112,6 +157,7 @@ static int show_vfsmnt(struct seq_file *
6209 if (err)
6210 goto out;
db55b927
AM
6211 seq_putc(m, ' ');
6212+type:
6213 show_type(m, sb);
6214 seq_puts(m, __mnt_is_readonly(mnt) ? " ro" : " rw");
6215 err = show_sb_opts(m, sb);
cc23e853
AM
6216@@ -133,6 +179,11 @@ static int show_mountinfo(struct seq_fil
6217 struct path mnt_path = { .dentry = mnt->mnt_root, .mnt = mnt };
6218 int err;
db55b927
AM
6219
6220+ if (vx_flags(VXF_HIDE_MOUNT, 0))
6221+ return SEQ_SKIP;
6222+ if (!mnt_is_reachable(mnt) && !vx_check(0, VS_WATCH_P))
6223+ return SEQ_SKIP;
6224+
6225 seq_printf(m, "%i %i %u:%u ", r->mnt_id, r->mnt_parent->mnt_id,
6226 MAJOR(sb->s_dev), MINOR(sb->s_dev));
cc23e853
AM
6227 if (sb->s_op->show_path) {
6228@@ -195,6 +246,17 @@ static int show_vfsstat(struct seq_file
db55b927 6229 struct super_block *sb = mnt_path.dentry->d_sb;
cc23e853 6230 int err;
db55b927
AM
6231
6232+ if (vx_flags(VXF_HIDE_MOUNT, 0))
6233+ return SEQ_SKIP;
6234+ if (!mnt_is_reachable(mnt) && !vx_check(0, VS_WATCH_P))
6235+ return SEQ_SKIP;
6236+
6237+ if (!vx_check(0, VS_ADMIN|VS_WATCH) &&
6238+ mnt == current->fs->root.mnt) {
6239+ seq_puts(m, "device /dev/root mounted on / ");
6240+ goto type;
6241+ }
6242+
6243 /* device */
6244 if (sb->s_op->show_devname) {
6245 seq_puts(m, "device ");
cc23e853
AM
6246@@ -216,7 +278,7 @@ static int show_vfsstat(struct seq_file
6247 if (err)
6248 goto out;
db55b927
AM
6249 seq_putc(m, ' ');
6250-
6251+type:
6252 /* file system type */
6253 seq_puts(m, "with fstype ");
6254 show_type(m, sb);
3261cfd5
AM
6255diff -NurpP --minimal linux-4.9.207/fs/quota/dquot.c linux-4.9.207-vs2.3.9.11/fs/quota/dquot.c
6256--- linux-4.9.207/fs/quota/dquot.c 2019-12-25 15:28:38.017305173 +0000
6257+++ linux-4.9.207-vs2.3.9.11/fs/quota/dquot.c 2019-12-25 15:37:52.028428731 +0000
6258@@ -1659,6 +1659,9 @@ int __dquot_alloc_space(struct inode *in
76514441 6259 int reserve = flags & DQUOT_SPACE_RESERVE;
cc23e853 6260 struct dquot **dquots;
76514441
AM
6261
6262+ if ((ret = dl_alloc_space(inode, number)))
6263+ return ret;
6264+
bb20add7
AM
6265 if (!dquot_active(inode)) {
6266 inode_incr_space(inode, number, reserve);
6267 goto out;
3261cfd5 6268@@ -1711,6 +1714,9 @@ int dquot_alloc_inode(struct inode *inod
1e8b8f9b 6269 struct dquot_warn warn[MAXQUOTAS];
cc23e853 6270 struct dquot * const *dquots;
76514441
AM
6271
6272+ if ((ret = dl_alloc_inode(inode)))
6273+ return ret;
6274+
93de0823 6275 if (!dquot_active(inode))
bb20add7
AM
6276 return 0;
6277 for (cnt = 0; cnt < MAXQUOTAS; cnt++)
3261cfd5 6278@@ -1813,6 +1819,8 @@ void __dquot_free_space(struct inode *in
cc23e853 6279 struct dquot **dquots;
bb20add7 6280 int reserve = flags & DQUOT_SPACE_RESERVE, index;
76514441
AM
6281
6282+ dl_free_space(inode, number);
6283+
93de0823 6284 if (!dquot_active(inode)) {
bb20add7
AM
6285 inode_decr_space(inode, number, reserve);
6286 return;
3261cfd5 6287@@ -1857,6 +1865,8 @@ void dquot_free_inode(struct inode *inod
cc23e853 6288 struct dquot * const *dquots;
bb20add7 6289 int index;
76514441
AM
6290
6291+ dl_free_inode(inode);
6292+
93de0823 6293 if (!dquot_active(inode))
bb20add7
AM
6294 return;
6295
3261cfd5
AM
6296diff -NurpP --minimal linux-4.9.207/fs/quota/quota.c linux-4.9.207-vs2.3.9.11/fs/quota/quota.c
6297--- linux-4.9.207/fs/quota/quota.c 2019-12-25 15:28:38.027305012 +0000
6298+++ linux-4.9.207-vs2.3.9.11/fs/quota/quota.c 2018-10-20 05:55:43.000000000 +0000
78865d5b
AM
6299@@ -8,6 +8,7 @@
6300 #include <linux/fs.h>
6301 #include <linux/namei.h>
6302 #include <linux/slab.h>
d337f35e 6303+#include <linux/vs_context.h>
78865d5b 6304 #include <asm/current.h>
92598135 6305 #include <linux/uaccess.h>
78865d5b 6306 #include <linux/kernel.h>
09a55596 6307@@ -39,7 +40,7 @@ static int check_quotactl_permission(str
78865d5b
AM
6308 break;
6309 /*FALLTHROUGH*/
6310 default:
d337f35e
JR
6311- if (!capable(CAP_SYS_ADMIN))
6312+ if (!vx_capable(CAP_SYS_ADMIN, VXC_QUOTA_CTL))
6313 return -EPERM;
6314 }
6315
09a55596 6316@@ -770,6 +771,46 @@ static int do_quotactl(struct super_bloc
b00e13aa
AM
6317
6318 #ifdef CONFIG_BLOCK
d337f35e 6319
d337f35e
JR
6320+#if defined(CONFIG_BLK_DEV_VROOT) || defined(CONFIG_BLK_DEV_VROOT_MODULE)
6321+
6322+#include <linux/vroot.h>
2380c486
JR
6323+#include <linux/major.h>
6324+#include <linux/module.h>
d337f35e 6325+#include <linux/kallsyms.h>
2380c486 6326+#include <linux/vserver/debug.h>
d337f35e
JR
6327+
6328+static vroot_grb_func *vroot_get_real_bdev = NULL;
6329+
763640ca 6330+static DEFINE_SPINLOCK(vroot_grb_lock);
d337f35e
JR
6331+
6332+int register_vroot_grb(vroot_grb_func *func) {
6333+ int ret = -EBUSY;
6334+
6335+ spin_lock(&vroot_grb_lock);
6336+ if (!vroot_get_real_bdev) {
6337+ vroot_get_real_bdev = func;
6338+ ret = 0;
6339+ }
6340+ spin_unlock(&vroot_grb_lock);
6341+ return ret;
6342+}
6343+EXPORT_SYMBOL(register_vroot_grb);
6344+
6345+int unregister_vroot_grb(vroot_grb_func *func) {
6346+ int ret = -EINVAL;
6347+
6348+ spin_lock(&vroot_grb_lock);
6349+ if (vroot_get_real_bdev) {
6350+ vroot_get_real_bdev = NULL;
6351+ ret = 0;
6352+ }
6353+ spin_unlock(&vroot_grb_lock);
6354+ return ret;
6355+}
6356+EXPORT_SYMBOL(unregister_vroot_grb);
6357+
6358+#endif
6359+
db55b927
AM
6360 /* Return 1 if 'cmd' will block on frozen filesystem */
6361 static int quotactl_cmd_write(int cmd)
6362 {
09a55596 6363@@ -811,6 +852,22 @@ static struct super_block *quotactl_bloc
2380c486
JR
6364 putname(tmp);
6365 if (IS_ERR(bdev))
6366 return ERR_CAST(bdev);
6367+#if defined(CONFIG_BLK_DEV_VROOT) || defined(CONFIG_BLK_DEV_VROOT_MODULE)
6368+ if (bdev && bdev->bd_inode &&
537831f9 6369+ imajor(bdev->bd_inode) == VROOT_MAJOR) {
2380c486
JR
6370+ struct block_device *bdnew = (void *)-EINVAL;
6371+
6372+ if (vroot_get_real_bdev)
6373+ bdnew = vroot_get_real_bdev(bdev);
6374+ else
6375+ vxdprintk(VXD_CBIT(misc, 0),
6376+ "vroot_get_real_bdev not set");
6377+ bdput(bdev);
6378+ if (IS_ERR(bdnew))
6379+ return ERR_PTR(PTR_ERR(bdnew));
6380+ bdev = bdnew;
6381+ }
6382+#endif
db55b927
AM
6383 if (quotactl_cmd_write(cmd))
6384 sb = get_super_thawed(bdev);
6385 else
3261cfd5
AM
6386diff -NurpP --minimal linux-4.9.207/fs/stat.c linux-4.9.207-vs2.3.9.11/fs/stat.c
6387--- linux-4.9.207/fs/stat.c 2019-12-25 15:28:38.087304041 +0000
6388+++ linux-4.9.207-vs2.3.9.11/fs/stat.c 2018-10-20 04:58:14.000000000 +0000
2380c486 6389@@ -26,6 +26,7 @@ void generic_fillattr(struct inode *inod
d337f35e
JR
6390 stat->nlink = inode->i_nlink;
6391 stat->uid = inode->i_uid;
6392 stat->gid = inode->i_gid;
6393+ stat->tag = inode->i_tag;
6394 stat->rdev = inode->i_rdev;
a168f21d 6395 stat->size = i_size_read(inode);
d337f35e 6396 stat->atime = inode->i_atime;
3261cfd5
AM
6397diff -NurpP --minimal linux-4.9.207/fs/statfs.c linux-4.9.207-vs2.3.9.11/fs/statfs.c
6398--- linux-4.9.207/fs/statfs.c 2016-12-11 19:17:54.000000000 +0000
6399+++ linux-4.9.207-vs2.3.9.11/fs/statfs.c 2018-10-20 04:58:14.000000000 +0000
93de0823 6400@@ -7,6 +7,8 @@
76514441
AM
6401 #include <linux/statfs.h>
6402 #include <linux/security.h>
6403 #include <linux/uaccess.h>
6404+#include <linux/vs_base.h>
6405+#include <linux/vs_dlimit.h>
db55b927 6406 #include "internal.h"
76514441 6407
93de0823 6408 static int flags_by_mnt(int mnt_flags)
db55b927 6409@@ -60,6 +62,8 @@ static int statfs_by_dentry(struct dentr
93de0823
AM
6410 retval = dentry->d_sb->s_op->statfs(dentry, buf);
6411 if (retval == 0 && buf->f_frsize == 0)
6412 buf->f_frsize = buf->f_bsize;
6413+ if (!vx_check(0, VS_ADMIN|VS_WATCH))
6414+ vx_vsi_statfs(dentry->d_sb, buf);
76514441
AM
6415 return retval;
6416 }
93de0823 6417
3261cfd5
AM
6418diff -NurpP --minimal linux-4.9.207/fs/super.c linux-4.9.207-vs2.3.9.11/fs/super.c
6419--- linux-4.9.207/fs/super.c 2019-12-25 15:28:38.087304041 +0000
6420+++ linux-4.9.207-vs2.3.9.11/fs/super.c 2019-10-13 10:11:07.125382902 +0000
cc23e853 6421@@ -34,6 +34,8 @@
1e8b8f9b 6422 #include <linux/fsnotify.h>
92598135 6423 #include <linux/lockdep.h>
cc23e853 6424 #include <linux/user_namespace.h>
1e8b8f9b 6425+#include <linux/magic.h>
be261992
AM
6426+#include <linux/vs_context.h>
6427 #include "internal.h"
6428
6429
3261cfd5
AM
6430@@ -482,7 +484,7 @@ struct super_block *sget_userns(struct f
6431
6432 if (!(flags & (MS_KERNMOUNT|MS_SUBMOUNT)) &&
6433 !(type->fs_flags & FS_USERNS_MOUNT) &&
6434- !capable(CAP_SYS_ADMIN))
6435+ !vx_capable(CAP_SYS_ADMIN, VXC_SECURE_MOUNT))
6436 return ERR_PTR(-EPERM);
6437 retry:
6438 spin_lock(&sb_lock);
6439@@ -563,7 +565,8 @@ struct super_block *sget(struct file_sys
6440 user_ns = &init_user_ns;
6441
6442 /* Ensure the requestor has permissions over the target filesystem */
6443- if (!(flags & (MS_KERNMOUNT|MS_SUBMOUNT)) && !ns_capable(user_ns, CAP_SYS_ADMIN))
6444+ if (!(flags & (MS_KERNMOUNT|MS_SUBMOUNT)) &&
6445+ !vx_ns_capable(user_ns, CAP_SYS_ADMIN, VXC_SECURE_MOUNT))
6446 return ERR_PTR(-EPERM);
6447
6448 return sget_userns(type, test, set, flags, user_ns, data);
6449@@ -995,7 +998,8 @@ struct dentry *mount_ns(struct file_syst
cc23e853
AM
6450 /* Don't allow mounting unless the caller has CAP_SYS_ADMIN
6451 * over the namespace.
6452 */
6453- if (!(flags & MS_KERNMOUNT) && !ns_capable(user_ns, CAP_SYS_ADMIN))
6454+ if (!(flags & MS_KERNMOUNT) &&
6455+ !vx_ns_capable(user_ns, CAP_SYS_ADMIN, VXC_SECURE_MOUNT))
6456 return ERR_PTR(-EPERM);
6457
6458 sb = sget_userns(fs_type, ns_test_super, ns_set_super, flags,
3261cfd5
AM
6459@@ -1213,6 +1217,13 @@ mount_fs(struct file_system_type *type,
6460 smp_wmb();
be261992
AM
6461 sb->s_flags |= MS_BORN;
6462
6463+ error = -EPERM;
6464+ if (!vx_capable(CAP_SYS_ADMIN, VXC_BINARY_MOUNT) &&
6465+ !sb->s_bdev &&
6466+ (sb->s_magic != PROC_SUPER_MAGIC) &&
6467+ (sb->s_magic != DEVPTS_SUPER_MAGIC))
6468+ goto out_sb;
6469+
6470 error = security_sb_kern_mount(sb, flags, secdata);
6471 if (error)
6472 goto out_sb;
3261cfd5
AM
6473diff -NurpP --minimal linux-4.9.207/fs/utimes.c linux-4.9.207-vs2.3.9.11/fs/utimes.c
6474--- linux-4.9.207/fs/utimes.c 2016-12-11 19:17:54.000000000 +0000
6475+++ linux-4.9.207-vs2.3.9.11/fs/utimes.c 2018-10-20 04:58:14.000000000 +0000
2380c486
JR
6476@@ -8,6 +8,8 @@
6477 #include <linux/stat.h>
d337f35e 6478 #include <linux/utime.h>
2380c486 6479 #include <linux/syscalls.h>
d337f35e
JR
6480+#include <linux/mount.h>
6481+#include <linux/vs_cowbl.h>
6482 #include <asm/uaccess.h>
6483 #include <asm/unistd.h>
6484
c2e5f7c8 6485@@ -52,13 +54,19 @@ static int utimes_common(struct path *pa
76514441
AM
6486 {
6487 int error;
6488 struct iattr newattrs;
6489- struct inode *inode = path->dentry->d_inode;
c2e5f7c8 6490 struct inode *delegated_inode = NULL;
76514441 6491+ struct inode *inode;
b00e13aa
AM
6492+
6493+ error = cow_check_and_break(path);
6494+ if (error)
6495+ goto out;
76514441
AM
6496
6497 error = mnt_want_write(path->mnt);
6498 if (error)
6499 goto out;
6500
76514441
AM
6501+ inode = path->dentry->d_inode;
6502+
6503 if (times && times[0].tv_nsec == UTIME_NOW &&
6504 times[1].tv_nsec == UTIME_NOW)
6505 times = NULL;
3261cfd5
AM
6506diff -NurpP --minimal linux-4.9.207/fs/xattr.c linux-4.9.207-vs2.3.9.11/fs/xattr.c
6507--- linux-4.9.207/fs/xattr.c 2019-12-25 15:28:38.177302586 +0000
6508+++ linux-4.9.207-vs2.3.9.11/fs/xattr.c 2018-10-20 05:55:43.000000000 +0000
537831f9 6509@@ -21,6 +21,7 @@
d337f35e 6510 #include <linux/audit.h>
1e8b8f9b 6511 #include <linux/vmalloc.h>
537831f9 6512 #include <linux/posix_acl_xattr.h>
d337f35e 6513+#include <linux/mount.h>
d337f35e 6514
1e8b8f9b 6515 #include <asm/uaccess.h>
d337f35e 6516
cc23e853 6517@@ -112,7 +113,7 @@ xattr_permission(struct inode *inode, co
763640ca 6518 * The trusted.* namespace can only be accessed by privileged users.
e03b8c3c 6519 */
763640ca
JR
6520 if (!strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN)) {
6521- if (!capable(CAP_SYS_ADMIN))
a168f21d
AM
6522+ if (!vx_capable(CAP_SYS_ADMIN, VXC_FS_TRUSTED))
6523 return (mask & MAY_WRITE) ? -EPERM : -ENODATA;
6524 return 0;
6525 }
3261cfd5
AM
6526diff -NurpP --minimal linux-4.9.207/include/linux/capability.h linux-4.9.207-vs2.3.9.11/include/linux/capability.h
6527--- linux-4.9.207/include/linux/capability.h 2019-12-25 15:28:38.667294664 +0000
6528+++ linux-4.9.207-vs2.3.9.11/include/linux/capability.h 2018-10-20 04:58:14.000000000 +0000
cc23e853 6529@@ -78,7 +78,8 @@ extern const kernel_cap_t __cap_init_eff
bb20add7
AM
6530 #else /* HAND-CODED capability initializers */
6531
6532 #define CAP_LAST_U32 ((_KERNEL_CAPABILITY_U32S) - 1)
6533-#define CAP_LAST_U32_VALID_MASK (CAP_TO_MASK(CAP_LAST_CAP + 1) -1)
6534+#define CAP_LAST_U32_VALID_MASK ((CAP_TO_MASK(CAP_LAST_CAP + 1) -1) \
6535+ | CAP_TO_MASK(CAP_CONTEXT))
6536
6537 # define CAP_EMPTY_SET ((kernel_cap_t){{ 0, 0 }})
6538 # define CAP_FULL_SET ((kernel_cap_t){{ ~0, CAP_LAST_U32_VALID_MASK }})
3261cfd5
AM
6539diff -NurpP --minimal linux-4.9.207/include/linux/cred.h linux-4.9.207-vs2.3.9.11/include/linux/cred.h
6540--- linux-4.9.207/include/linux/cred.h 2019-12-25 15:28:38.737293533 +0000
6541+++ linux-4.9.207-vs2.3.9.11/include/linux/cred.h 2019-10-05 14:58:45.680307395 +0000
6542@@ -156,6 +156,7 @@ extern void exit_creds(struct task_struc
1163e6ab
AM
6543 extern int copy_creds(struct task_struct *, unsigned long);
6544 extern const struct cred *get_task_cred(struct task_struct *);
6545 extern struct cred *cred_alloc_blank(void);
6546+extern struct cred *__prepare_creds(const struct cred *);
6547 extern struct cred *prepare_creds(void);
6548 extern struct cred *prepare_exec_creds(void);
6549 extern int commit_creds(struct cred *);
3261cfd5 6550@@ -216,6 +217,31 @@ static inline bool cap_ambient_invariant
cc23e853 6551 cred->cap_inheritable));
3bac966d 6552 }
3bac966d
AM
6553
6554+static inline void set_cred_subscribers(struct cred *cred, int n)
6555+{
6556+#ifdef CONFIG_DEBUG_CREDENTIALS
6557+ atomic_set(&cred->subscribers, n);
6558+#endif
6559+}
6560+
6561+static inline int read_cred_subscribers(const struct cred *cred)
6562+{
6563+#ifdef CONFIG_DEBUG_CREDENTIALS
6564+ return atomic_read(&cred->subscribers);
6565+#else
6566+ return 0;
6567+#endif
6568+}
6569+
6570+static inline void alter_cred_subscribers(const struct cred *_cred, int n)
6571+{
6572+#ifdef CONFIG_DEBUG_CREDENTIALS
6573+ struct cred *cred = (struct cred *) _cred;
6574+
6575+ atomic_add(n, &cred->subscribers);
6576+#endif
6577+}
6578+
6579 /**
6580 * get_new_cred - Get a reference on a new set of credentials
6581 * @cred: The new credentials to reference
3261cfd5
AM
6582diff -NurpP --minimal linux-4.9.207/include/linux/dcache.h linux-4.9.207-vs2.3.9.11/include/linux/dcache.h
6583--- linux-4.9.207/include/linux/dcache.h 2019-12-25 15:28:38.737293533 +0000
6584+++ linux-4.9.207-vs2.3.9.11/include/linux/dcache.h 2018-10-20 04:58:14.000000000 +0000
09a55596 6585@@ -308,8 +308,10 @@ extern char *dentry_path(struct dentry *
cc23e853
AM
6586 */
6587 static inline struct dentry *dget_dlock(struct dentry *dentry)
6588 {
6589- if (dentry)
6590+ if (dentry) {
6591 dentry->d_lockref.count++;
6592+ // vx_dentry_inc(dentry);
6593+ }
6594 return dentry;
6595 }
6596
3261cfd5
AM
6597diff -NurpP --minimal linux-4.9.207/include/linux/devpts_fs.h linux-4.9.207-vs2.3.9.11/include/linux/devpts_fs.h
6598--- linux-4.9.207/include/linux/devpts_fs.h 2016-12-11 19:17:54.000000000 +0000
6599+++ linux-4.9.207-vs2.3.9.11/include/linux/devpts_fs.h 2018-10-20 04:58:14.000000000 +0000
cc23e853 6600@@ -34,5 +34,4 @@ void devpts_pty_kill(struct dentry *);
2380c486
JR
6601
6602 #endif
d337f35e 6603
2380c486 6604-
d337f35e 6605 #endif /* _LINUX_DEVPTS_FS_H */
3261cfd5
AM
6606diff -NurpP --minimal linux-4.9.207/include/linux/fs.h linux-4.9.207-vs2.3.9.11/include/linux/fs.h
6607--- linux-4.9.207/include/linux/fs.h 2019-12-25 15:28:38.777292887 +0000
6608+++ linux-4.9.207-vs2.3.9.11/include/linux/fs.h 2019-10-05 14:58:45.690307237 +0000
6609@@ -231,6 +231,7 @@ typedef int (dio_iodone_t)(struct kiocb
2380c486
JR
6610 #define ATTR_OPEN (1 << 15) /* Truncating from open(O_TRUNC) */
6611 #define ATTR_TIMES_SET (1 << 16)
cc23e853
AM
6612 #define ATTR_TOUCH (1 << 17)
6613+#define ATTR_TAG (1 << 18)
d337f35e
JR
6614
6615 /*
bb20add7 6616 * Whiteout is represented by a char device. The following constants define the
3261cfd5 6617@@ -253,6 +254,7 @@ struct iattr {
d337f35e 6618 umode_t ia_mode;
42bc425c
AM
6619 kuid_t ia_uid;
6620 kgid_t ia_gid;
537831f9 6621+ ktag_t ia_tag;
d337f35e
JR
6622 loff_t ia_size;
6623 struct timespec ia_atime;
6624 struct timespec ia_mtime;
3261cfd5 6625@@ -612,7 +614,9 @@ struct inode {
a168f21d 6626 unsigned short i_opflags;
42bc425c
AM
6627 kuid_t i_uid;
6628 kgid_t i_gid;
2380c486 6629- unsigned int i_flags;
537831f9 6630+ ktag_t i_tag;
2380c486
JR
6631+ unsigned short i_flags;
6632+ unsigned short i_vflags;
a168f21d
AM
6633
6634 #ifdef CONFIG_FS_POSIX_ACL
6635 struct posix_acl *i_acl;
3261cfd5 6636@@ -641,6 +645,7 @@ struct inode {
f6c5ef8b
AM
6637 unsigned int __i_nlink;
6638 };
d33d7b00
AM
6639 dev_t i_rdev;
6640+ dev_t i_mdev;
42bc425c 6641 loff_t i_size;
a168f21d
AM
6642 struct timespec i_atime;
6643 struct timespec i_mtime;
3261cfd5 6644@@ -845,14 +850,19 @@ static inline void i_size_write(struct i
cc23e853 6645 #endif
537831f9 6646 }
2380c486 6647
61333608 6648+static inline void i_tag_write(struct inode *inode, vtag_t tag)
537831f9
AM
6649+{
6650+ inode->i_tag = make_ktag(&init_user_ns, tag);
6651+}
6652+
2380c486
JR
6653 static inline unsigned iminor(const struct inode *inode)
6654 {
6655- return MINOR(inode->i_rdev);
6656+ return MINOR(inode->i_mdev);
6657 }
6658
6659 static inline unsigned imajor(const struct inode *inode)
6660 {
6661- return MAJOR(inode->i_rdev);
6662+ return MAJOR(inode->i_mdev);
6663 }
6664
6665 extern struct block_device *I_BDEV(struct inode *inode);
3261cfd5 6666@@ -909,6 +919,7 @@ struct file {
d337f35e
JR
6667 loff_t f_pos;
6668 struct fown_struct f_owner;
ec22aa5c 6669 const struct cred *f_cred;
61333608 6670+ vxid_t f_xid;
d337f35e
JR
6671 struct file_ra_state f_ra;
6672
2380c486 6673 u64 f_version;
3261cfd5 6674@@ -1043,6 +1054,7 @@ struct file_lock {
2380c486 6675 struct file *fl_file;
d337f35e
JR
6676 loff_t fl_start;
6677 loff_t fl_end;
61333608 6678+ vxid_t fl_xid;
d337f35e
JR
6679
6680 struct fasync_struct * fl_fasync; /* for lease break notifications */
f6c5ef8b 6681 /* for lease breaks: */
3261cfd5 6682@@ -1476,6 +1488,11 @@ static inline gid_t i_gid_read(const str
cc23e853
AM
6683 return from_kgid(inode->i_sb->s_user_ns, inode->i_gid);
6684 }
6685
6686+static inline vtag_t i_tag_read(const struct inode *inode)
6687+{
6688+ return from_ktag(&init_user_ns, inode->i_tag);
6689+}
6690+
6691 static inline void i_uid_write(struct inode *inode, uid_t uid)
6692 {
6693 inode->i_uid = make_kuid(inode->i_sb->s_user_ns, uid);
3261cfd5 6694@@ -1765,6 +1782,7 @@ struct inode_operations {
cc23e853
AM
6695 int (*setattr) (struct dentry *, struct iattr *);
6696 int (*getattr) (struct vfsmount *mnt, struct dentry *, struct kstat *);
d4263eb0 6697 ssize_t (*listxattr) (struct dentry *, char *, size_t);
d4263eb0 6698+ int (*sync_flags) (struct inode *, int, int);
d33d7b00
AM
6699 int (*fiemap)(struct inode *, struct fiemap_extent_info *, u64 start,
6700 u64 len);
42bc425c 6701 int (*update_time)(struct inode *, struct timespec *, int);
3261cfd5 6702@@ -1779,6 +1797,7 @@ ssize_t rw_copy_check_uvector(int type,
537831f9
AM
6703 unsigned long nr_segs, unsigned long fast_segs,
6704 struct iovec *fast_pointer,
6705 struct iovec **ret_pointer);
d337f35e
JR
6706+ssize_t vfs_sendfile(struct file *, struct file *, loff_t *, size_t, loff_t);
6707
cc23e853
AM
6708 extern ssize_t __vfs_read(struct file *, char __user *, size_t, loff_t *);
6709 extern ssize_t __vfs_write(struct file *, const char __user *, size_t, loff_t *);
3261cfd5 6710@@ -1850,6 +1869,14 @@ struct super_operations {
cc23e853
AM
6711 #else
6712 #define S_DAX 0 /* Make all the DAX code disappear */
6713 #endif
6714+#define S_IXUNLINK 16384 /* Immutable Invert on unlink */
537831f9
AM
6715+
6716+/* Linux-VServer related Inode flags */
6717+
6718+#define V_VALID 1
6719+#define V_XATTR 2
6720+#define V_BARRIER 4 /* Barrier for chroot() */
6721+#define V_COW 8 /* Copy on Write */
6722
6723 /*
6724 * Note that nosuid etc flags are inode-specific: setting some file-system
3261cfd5 6725@@ -1874,10 +1901,13 @@ struct super_operations {
537831f9
AM
6726 #define IS_MANDLOCK(inode) __IS_FLG(inode, MS_MANDLOCK)
6727 #define IS_NOATIME(inode) __IS_FLG(inode, MS_RDONLY|MS_NOATIME)
6728 #define IS_I_VERSION(inode) __IS_FLG(inode, MS_I_VERSION)
6729+#define IS_TAGGED(inode) __IS_FLG(inode, MS_TAGGED)
6730
6731 #define IS_NOQUOTA(inode) ((inode)->i_flags & S_NOQUOTA)
6732 #define IS_APPEND(inode) ((inode)->i_flags & S_APPEND)
6733 #define IS_IMMUTABLE(inode) ((inode)->i_flags & S_IMMUTABLE)
6734+#define IS_IXUNLINK(inode) ((inode)->i_flags & S_IXUNLINK)
6735+#define IS_IXORUNLINK(inode) ((IS_IXUNLINK(inode) ? S_IMMUTABLE : 0) ^ IS_IMMUTABLE(inode))
6736 #define IS_POSIXACL(inode) __IS_FLG(inode, MS_POSIXACL)
6737
6738 #define IS_DEADDIR(inode) ((inode)->i_flags & S_DEAD)
3261cfd5 6739@@ -1897,6 +1927,16 @@ static inline bool HAS_UNMAPPED_ID(struc
cc23e853
AM
6740 return !uid_valid(inode->i_uid) || !gid_valid(inode->i_gid);
6741 }
537831f9
AM
6742
6743+#define IS_BARRIER(inode) (S_ISDIR((inode)->i_mode) && ((inode)->i_vflags & V_BARRIER))
6744+
6745+#ifdef CONFIG_VSERVER_COWBL
6746+# define IS_COW(inode) (IS_IXUNLINK(inode) && IS_IMMUTABLE(inode))
6747+# define IS_COW_LINK(inode) (S_ISREG((inode)->i_mode) && ((inode)->i_nlink > 1))
6748+#else
6749+# define IS_COW(inode) (0)
6750+# define IS_COW_LINK(inode) (0)
6751+#endif
6752+
6753 /*
6754 * Inode state bits. Protected by inode->i_lock
6755 *
3261cfd5 6756@@ -2162,6 +2202,9 @@ extern struct kobject *fs_kobj;
bb20add7 6757 extern int locks_mandatory_locked(struct file *);
cc23e853 6758 extern int locks_mandatory_area(struct inode *, struct file *, loff_t, loff_t, unsigned char);
537831f9
AM
6759
6760+#define ATTR_FLAG_BARRIER 512 /* Barrier for chroot() */
6761+#define ATTR_FLAG_IXUNLINK 1024 /* Immutable invert on unlink */
6762+
6763 /*
6764 * Candidates for mandatory locking have the setgid bit set
6765 * but no group execute bit - an otherwise meaningless combination.
3261cfd5 6766@@ -2342,7 +2385,7 @@ struct filename {
cc23e853
AM
6767 const char iname[];
6768 };
6769
6770-extern long vfs_truncate(const struct path *, loff_t);
6771+extern long vfs_truncate(struct path *, loff_t);
6772 extern int do_truncate(struct dentry *, loff_t start, unsigned int time_attrs,
6773 struct file *filp);
6774 extern int vfs_fallocate(struct file *file, int mode, loff_t offset,
3261cfd5 6775@@ -2973,6 +3016,7 @@ extern int dcache_dir_open(struct inode
d337f35e
JR
6776 extern int dcache_dir_close(struct inode *, struct file *);
6777 extern loff_t dcache_dir_lseek(struct file *, loff_t, int);
c2e5f7c8
JR
6778 extern int dcache_readdir(struct file *, struct dir_context *);
6779+extern int dcache_readdir_filter(struct file *, struct dir_context *, int (*)(struct dentry *));
76514441 6780 extern int simple_setattr(struct dentry *, struct iattr *);
d337f35e
JR
6781 extern int simple_getattr(struct vfsmount *, struct dentry *, struct kstat *);
6782 extern int simple_statfs(struct dentry *, struct kstatfs *);
3261cfd5
AM
6783diff -NurpP --minimal linux-4.9.207/include/linux/init_task.h linux-4.9.207-vs2.3.9.11/include/linux/init_task.h
6784--- linux-4.9.207/include/linux/init_task.h 2016-12-11 19:17:54.000000000 +0000
6785+++ linux-4.9.207-vs2.3.9.11/include/linux/init_task.h 2018-10-20 04:58:14.000000000 +0000
cc23e853 6786@@ -271,6 +271,10 @@ extern struct task_group root_task_group
b00e13aa 6787 INIT_VTIME(tsk) \
cc23e853
AM
6788 INIT_NUMA_BALANCING(tsk) \
6789 INIT_KASAN(tsk) \
d337f35e
JR
6790+ .xid = 0, \
6791+ .vx_info = NULL, \
6792+ .nid = 0, \
6793+ .nx_info = NULL, \
6794 }
6795
6796
3261cfd5
AM
6797diff -NurpP --minimal linux-4.9.207/include/linux/ipc.h linux-4.9.207-vs2.3.9.11/include/linux/ipc.h
6798--- linux-4.9.207/include/linux/ipc.h 2016-12-11 19:17:54.000000000 +0000
6799+++ linux-4.9.207-vs2.3.9.11/include/linux/ipc.h 2018-10-20 04:58:14.000000000 +0000
537831f9 6800@@ -16,6 +16,7 @@ struct kern_ipc_perm
d337f35e 6801 key_t key;
537831f9
AM
6802 kuid_t uid;
6803 kgid_t gid;
61333608 6804+ vxid_t xid;
537831f9
AM
6805 kuid_t cuid;
6806 kgid_t cgid;
db55b927 6807 umode_t mode;
3261cfd5
AM
6808diff -NurpP --minimal linux-4.9.207/include/linux/memcontrol.h linux-4.9.207-vs2.3.9.11/include/linux/memcontrol.h
6809--- linux-4.9.207/include/linux/memcontrol.h 2019-12-25 15:28:39.087287874 +0000
6810+++ linux-4.9.207-vs2.3.9.11/include/linux/memcontrol.h 2018-10-20 04:58:14.000000000 +0000
cc23e853
AM
6811@@ -92,6 +92,7 @@ enum mem_cgroup_events_target {
6812 MEM_CGROUP_NTARGETS,
6813 };
6814
6815+
6816 #ifdef CONFIG_MEMCG
6817
6818 #define MEM_CGROUP_ID_SHIFT 16
369dbd59 6819@@ -402,6 +403,12 @@ static inline bool mem_cgroup_is_descend
cc23e853
AM
6820 return cgroup_is_descendant(memcg->css.cgroup, root->css.cgroup);
6821 }
6822
369dbd59
AM
6823+extern unsigned long mem_cgroup_mem_usage_pages(struct mem_cgroup *memcg);
6824+extern unsigned long mem_cgroup_mem_limit_pages(struct mem_cgroup *memcg);
6825+extern unsigned long mem_cgroup_memsw_usage_pages(struct mem_cgroup *memcg);
6826+extern unsigned long mem_cgroup_memsw_limit_pages(struct mem_cgroup *memcg);
6827+extern void dump_mem_cgroup(struct mem_cgroup *memcg);
cc23e853
AM
6828+
6829 static inline bool mm_match_cgroup(struct mm_struct *mm,
6830 struct mem_cgroup *memcg)
e3afe727 6831 {
3261cfd5
AM
6832diff -NurpP --minimal linux-4.9.207/include/linux/mount.h linux-4.9.207-vs2.3.9.11/include/linux/mount.h
6833--- linux-4.9.207/include/linux/mount.h 2019-12-25 15:28:39.377283185 +0000
6834+++ linux-4.9.207-vs2.3.9.11/include/linux/mount.h 2018-10-20 04:58:14.000000000 +0000
cc23e853 6835@@ -63,6 +63,9 @@ struct mnt_namespace;
bb20add7 6836 #define MNT_MARKED 0x4000000
cc23e853 6837 #define MNT_UMOUNT 0x8000000
d337f35e 6838
2380c486
JR
6839+#define MNT_TAGID 0x10000
6840+#define MNT_NOTAG 0x20000
6841+
d337f35e 6842 struct vfsmount {
db55b927
AM
6843 struct dentry *mnt_root; /* root of the mounted tree */
6844 struct super_block *mnt_sb; /* pointer to superblock */
3261cfd5
AM
6845diff -NurpP --minimal linux-4.9.207/include/linux/netdevice.h linux-4.9.207-vs2.3.9.11/include/linux/netdevice.h
6846--- linux-4.9.207/include/linux/netdevice.h 2019-12-25 15:28:39.397282861 +0000
6847+++ linux-4.9.207-vs2.3.9.11/include/linux/netdevice.h 2019-12-25 15:37:52.148426794 +0000
6848@@ -2489,6 +2489,7 @@ static inline int dev_recursion_level(vo
6849
6850 struct net_device *dev_get_by_index(struct net *net, int ifindex);
6851 struct net_device *__dev_get_by_index(struct net *net, int ifindex);
6852+struct net_device *dev_get_by_index_real_rcu(struct net *net, int ifindex);
6853 struct net_device *dev_get_by_index_rcu(struct net *net, int ifindex);
6854 int netdev_get_name(struct net *net, char *name, int ifindex);
6855 int dev_restart(struct net_device *dev);
6856diff -NurpP --minimal linux-4.9.207/include/linux/net.h linux-4.9.207-vs2.3.9.11/include/linux/net.h
6857--- linux-4.9.207/include/linux/net.h 2016-12-11 19:17:54.000000000 +0000
6858+++ linux-4.9.207-vs2.3.9.11/include/linux/net.h 2018-10-20 04:58:14.000000000 +0000
cc23e853
AM
6859@@ -44,6 +44,7 @@ struct net;
6860 #define SOCK_NOSPACE 2
d337f35e
JR
6861 #define SOCK_PASSCRED 3
6862 #define SOCK_PASSSEC 4
cc23e853 6863+#define SOCK_USER_SOCKET 5
d337f35e
JR
6864
6865 #ifndef ARCH_HAS_SOCKET_TYPES
6866 /**
3261cfd5
AM
6867diff -NurpP --minimal linux-4.9.207/include/linux/nsproxy.h linux-4.9.207-vs2.3.9.11/include/linux/nsproxy.h
6868--- linux-4.9.207/include/linux/nsproxy.h 2016-12-11 19:17:54.000000000 +0000
6869+++ linux-4.9.207-vs2.3.9.11/include/linux/nsproxy.h 2018-10-20 04:58:14.000000000 +0000
2380c486 6870@@ -3,6 +3,7 @@
d337f35e 6871
2380c486
JR
6872 #include <linux/spinlock.h>
6873 #include <linux/sched.h>
6874+#include <linux/vserver/debug.h>
6875
6876 struct mnt_namespace;
6877 struct uts_namespace;
cc23e853 6878@@ -65,6 +66,7 @@ extern struct nsproxy init_nsproxy;
bb20add7 6879 */
2380c486
JR
6880
6881 int copy_namespaces(unsigned long flags, struct task_struct *tsk);
6882+struct nsproxy *copy_nsproxy(struct nsproxy *orig);
6883 void exit_task_namespaces(struct task_struct *tsk);
6884 void switch_task_namespaces(struct task_struct *tsk, struct nsproxy *new);
6885 void free_nsproxy(struct nsproxy *ns);
cc23e853 6886@@ -72,16 +74,26 @@ int unshare_nsproxy_namespaces(unsigned
b00e13aa 6887 struct cred *, struct fs_struct *);
a168f21d 6888 int __init nsproxy_cache_init(void);
2380c486
JR
6889
6890-static inline void put_nsproxy(struct nsproxy *ns)
6891+#define get_nsproxy(n) __get_nsproxy(n, __FILE__, __LINE__)
d337f35e 6892+
2380c486
JR
6893+static inline void __get_nsproxy(struct nsproxy *ns,
6894+ const char *_file, int _line)
6895 {
6896- if (atomic_dec_and_test(&ns->count)) {
6897- free_nsproxy(ns);
6898- }
6899+ vxlprintk(VXD_CBIT(space, 0), "get_nsproxy(%p[%u])",
6900+ ns, atomic_read(&ns->count), _file, _line);
d337f35e 6901+ atomic_inc(&ns->count);
2380c486
JR
6902 }
6903
6904-static inline void get_nsproxy(struct nsproxy *ns)
6905+#define put_nsproxy(n) __put_nsproxy(n, __FILE__, __LINE__)
d337f35e 6906+
2380c486
JR
6907+static inline void __put_nsproxy(struct nsproxy *ns,
6908+ const char *_file, int _line)
6909 {
6910- atomic_inc(&ns->count);
6911+ vxlprintk(VXD_CBIT(space, 0), "put_nsproxy(%p[%u])",
6912+ ns, atomic_read(&ns->count), _file, _line);
6913+ if (atomic_dec_and_test(&ns->count)) {
6914+ free_nsproxy(ns);
6915+ }
6916 }
d337f35e 6917
763640ca 6918 #endif
3261cfd5
AM
6919diff -NurpP --minimal linux-4.9.207/include/linux/pid.h linux-4.9.207-vs2.3.9.11/include/linux/pid.h
6920--- linux-4.9.207/include/linux/pid.h 2019-12-25 15:28:39.507281083 +0000
6921+++ linux-4.9.207-vs2.3.9.11/include/linux/pid.h 2018-10-20 04:58:14.000000000 +0000
cc23e853 6922@@ -10,7 +10,8 @@ enum pid_type
d337f35e 6923 PIDTYPE_SID,
cc23e853
AM
6924 PIDTYPE_MAX,
6925 /* only valid to __task_pid_nr_ns() */
6926- __PIDTYPE_TGID
6927+ __PIDTYPE_TGID,
6928+ __PIDTYPE_REALPID
d337f35e
JR
6929 };
6930
6931 /*
cc23e853 6932@@ -172,6 +173,7 @@ static inline pid_t pid_nr(struct pid *p
2380c486
JR
6933 }
6934
6935 pid_t pid_nr_ns(struct pid *pid, struct pid_namespace *ns);
6936+pid_t pid_unmapped_nr_ns(struct pid *pid, struct pid_namespace *ns);
6937 pid_t pid_vnr(struct pid *pid);
6938
6939 #define do_each_pid_task(pid, type, task) \
3261cfd5
AM
6940diff -NurpP --minimal linux-4.9.207/include/linux/quotaops.h linux-4.9.207-vs2.3.9.11/include/linux/quotaops.h
6941--- linux-4.9.207/include/linux/quotaops.h 2019-12-25 15:28:39.587279789 +0000
6942+++ linux-4.9.207-vs2.3.9.11/include/linux/quotaops.h 2019-12-25 15:37:52.158426633 +0000
e22b5178
AM
6943@@ -8,6 +8,7 @@
6944 #define _LINUX_QUOTAOPS_
6945
6946 #include <linux/fs.h>
6947+#include <linux/vs_dlimit.h>
6948
76514441
AM
6949 #define DQUOT_SPACE_WARN 0x1
6950 #define DQUOT_SPACE_RESERVE 0x2
3261cfd5 6951@@ -224,11 +225,12 @@ static inline void dquot_drop(struct ino
76514441 6952
cc23e853 6953 static inline int dquot_alloc_inode(struct inode *inode)
76514441
AM
6954 {
6955- return 0;
6956+ return dl_alloc_inode(inode);
6957 }
6958
cc23e853 6959 static inline void dquot_free_inode(struct inode *inode)
e22b5178 6960 {
76514441
AM
6961+ dl_free_inode(inode);
6962 }
6963
6964 static inline int dquot_transfer(struct inode *inode, struct iattr *iattr)
3261cfd5 6965@@ -239,6 +241,10 @@ static inline int dquot_transfer(struct
76514441
AM
6966 static inline int __dquot_alloc_space(struct inode *inode, qsize_t number,
6967 int flags)
6968 {
6969+ int ret = 0;
6970+
6971+ if ((ret = dl_alloc_space(inode, number)))
6972+ return ret;
6973 if (!(flags & DQUOT_SPACE_RESERVE))
6974 inode_add_bytes(inode, number);
6975 return 0;
3261cfd5 6976@@ -249,6 +255,7 @@ static inline void __dquot_free_space(st
76514441
AM
6977 {
6978 if (!(flags & DQUOT_SPACE_RESERVE))
6979 inode_sub_bytes(inode, number);
6980+ dl_free_space(inode, number);
6981 }
6982
6983 static inline int dquot_claim_space_nodirty(struct inode *inode, qsize_t number)
3261cfd5
AM
6984diff -NurpP --minimal linux-4.9.207/include/linux/sched.h linux-4.9.207-vs2.3.9.11/include/linux/sched.h
6985--- linux-4.9.207/include/linux/sched.h 2019-12-25 15:28:39.727277526 +0000
6986+++ linux-4.9.207-vs2.3.9.11/include/linux/sched.h 2019-10-05 14:58:45.710306917 +0000
6987@@ -1719,6 +1719,14 @@ struct task_struct {
2380c486 6988 #endif
42bc425c 6989 struct seccomp seccomp;
2380c486
JR
6990
6991+/* vserver context data */
6992+ struct vx_info *vx_info;
6993+ struct nx_info *nx_info;
d337f35e 6994+
61333608
AM
6995+ vxid_t xid;
6996+ vnid_t nid;
6997+ vtag_t tag;
2380c486
JR
6998+
6999 /* Thread group tracking */
7000 u32 parent_exec_id;
7001 u32 self_exec_id;
3261cfd5 7002@@ -2112,6 +2120,11 @@ struct pid_namespace;
ec22aa5c
AM
7003 pid_t __task_pid_nr_ns(struct task_struct *task, enum pid_type type,
7004 struct pid_namespace *ns);
d337f35e 7005
2380c486
JR
7006+#include <linux/vserver/base.h>
7007+#include <linux/vserver/context.h>
7008+#include <linux/vserver/debug.h>
7009+#include <linux/vserver/pid.h>
7010+
7011 static inline pid_t task_pid_nr(struct task_struct *tsk)
7012 {
7013 return tsk->pid;
3261cfd5 7014@@ -2125,7 +2138,8 @@ static inline pid_t task_pid_nr_ns(struc
d337f35e 7015
2380c486
JR
7016 static inline pid_t task_pid_vnr(struct task_struct *tsk)
7017 {
ec22aa5c
AM
7018- return __task_pid_nr_ns(tsk, PIDTYPE_PID, NULL);
7019+ // return __task_pid_nr_ns(tsk, PIDTYPE_PID, NULL);
7020+ return vx_map_pid(__task_pid_nr_ns(tsk, PIDTYPE_PID, NULL));
2380c486 7021 }
d337f35e 7022
d337f35e 7023
3261cfd5
AM
7024diff -NurpP --minimal linux-4.9.207/include/linux/shmem_fs.h linux-4.9.207-vs2.3.9.11/include/linux/shmem_fs.h
7025--- linux-4.9.207/include/linux/shmem_fs.h 2016-12-11 19:17:54.000000000 +0000
7026+++ linux-4.9.207-vs2.3.9.11/include/linux/shmem_fs.h 2018-10-20 04:58:14.000000000 +0000
bb20add7 7027@@ -10,6 +10,9 @@
2380c486 7028
a168f21d 7029 /* inode in-kernel data */
2380c486
JR
7030
7031+#define TMPFS_SUPER_MAGIC 0x01021994
7032+
7033+
7034 struct shmem_inode_info {
7035 spinlock_t lock;
bb20add7 7036 unsigned int seals; /* shmem seals */
3261cfd5
AM
7037diff -NurpP --minimal linux-4.9.207/include/linux/stat.h linux-4.9.207-vs2.3.9.11/include/linux/stat.h
7038--- linux-4.9.207/include/linux/stat.h 2016-12-11 19:17:54.000000000 +0000
7039+++ linux-4.9.207-vs2.3.9.11/include/linux/stat.h 2018-10-20 04:58:14.000000000 +0000
537831f9 7040@@ -25,6 +25,7 @@ struct kstat {
2380c486 7041 unsigned int nlink;
42bc425c
AM
7042 kuid_t uid;
7043 kgid_t gid;
8ce283e1 7044+ ktag_t tag;
2380c486
JR
7045 dev_t rdev;
7046 loff_t size;
7047 struct timespec atime;
3261cfd5
AM
7048diff -NurpP --minimal linux-4.9.207/include/linux/sunrpc/auth.h linux-4.9.207-vs2.3.9.11/include/linux/sunrpc/auth.h
7049--- linux-4.9.207/include/linux/sunrpc/auth.h 2016-12-11 19:17:54.000000000 +0000
7050+++ linux-4.9.207-vs2.3.9.11/include/linux/sunrpc/auth.h 2018-10-20 04:58:14.000000000 +0000
cc23e853 7051@@ -46,6 +46,7 @@ enum {
2380c486 7052 struct auth_cred {
b00e13aa
AM
7053 kuid_t uid;
7054 kgid_t gid;
7055+ ktag_t tag;
2380c486 7056 struct group_info *group_info;
db55b927 7057 const char *principal;
c2e5f7c8 7058 unsigned long ac_flags;
3261cfd5
AM
7059diff -NurpP --minimal linux-4.9.207/include/linux/sunrpc/clnt.h linux-4.9.207-vs2.3.9.11/include/linux/sunrpc/clnt.h
7060--- linux-4.9.207/include/linux/sunrpc/clnt.h 2019-12-25 15:28:39.857275424 +0000
7061+++ linux-4.9.207-vs2.3.9.11/include/linux/sunrpc/clnt.h 2018-10-20 05:55:43.000000000 +0000
cc23e853 7062@@ -52,7 +52,8 @@ struct rpc_clnt {
2380c486 7063 cl_discrtry : 1,/* disconnect before retry */
c2e5f7c8 7064 cl_noretranstimeo: 1,/* No retransmit timeouts */
2380c486
JR
7065 cl_autobind : 1,/* use getport() */
7066- cl_chatty : 1;/* be verbose */
7067+ cl_chatty : 1,/* be verbose */
7068+ cl_tag : 1;/* context tagging */
d337f35e 7069
2380c486
JR
7070 struct rpc_rtt * cl_rtt; /* RTO estimator data */
7071 const struct rpc_timeout *cl_timeout; /* Timeout strategy */
3261cfd5
AM
7072diff -NurpP --minimal linux-4.9.207/include/linux/types.h linux-4.9.207-vs2.3.9.11/include/linux/types.h
7073--- linux-4.9.207/include/linux/types.h 2016-12-11 19:17:54.000000000 +0000
7074+++ linux-4.9.207-vs2.3.9.11/include/linux/types.h 2018-10-20 04:58:14.000000000 +0000
537831f9 7075@@ -32,6 +32,9 @@ typedef __kernel_uid32_t uid_t;
2380c486
JR
7076 typedef __kernel_gid32_t gid_t;
7077 typedef __kernel_uid16_t uid16_t;
7078 typedef __kernel_gid16_t gid16_t;
61333608
AM
7079+typedef unsigned int vxid_t;
7080+typedef unsigned int vnid_t;
7081+typedef unsigned int vtag_t;
2380c486
JR
7082
7083 typedef unsigned long uintptr_t;
7084
3261cfd5
AM
7085diff -NurpP --minimal linux-4.9.207/include/linux/uidgid.h linux-4.9.207-vs2.3.9.11/include/linux/uidgid.h
7086--- linux-4.9.207/include/linux/uidgid.h 2016-12-11 19:17:54.000000000 +0000
7087+++ linux-4.9.207-vs2.3.9.11/include/linux/uidgid.h 2018-10-20 04:58:14.000000000 +0000
bb20add7 7088@@ -21,13 +21,17 @@ typedef struct {
537831f9
AM
7089 uid_t val;
7090 } kuid_t;
7091
7092-
7093 typedef struct {
7094 gid_t val;
7095 } kgid_t;
7096
7097+typedef struct {
61333608 7098+ vtag_t val;
537831f9
AM
7099+} ktag_t;
7100+
7101 #define KUIDT_INIT(value) (kuid_t){ value }
7102 #define KGIDT_INIT(value) (kgid_t){ value }
7103+#define KTAGT_INIT(value) (ktag_t){ value }
7104
cc23e853 7105 #ifdef CONFIG_MULTIUSER
537831f9 7106 static inline uid_t __kuid_val(kuid_t uid)
cc23e853 7107@@ -51,11 +55,18 @@ static inline gid_t __kgid_val(kgid_t gi
537831f9 7108 }
cc23e853 7109 #endif
537831f9 7110
61333608 7111+static inline vtag_t __ktag_val(ktag_t tag)
537831f9
AM
7112+{
7113+ return tag.val;
7114+}
7115+
537831f9
AM
7116 #define GLOBAL_ROOT_UID KUIDT_INIT(0)
7117 #define GLOBAL_ROOT_GID KGIDT_INIT(0)
7118+#define GLOBAL_ROOT_TAG KTAGT_INIT(0)
7119
7120 #define INVALID_UID KUIDT_INIT(-1)
7121 #define INVALID_GID KGIDT_INIT(-1)
7122+#define INVALID_TAG KTAGT_INIT(-1)
7123
7124 static inline bool uid_eq(kuid_t left, kuid_t right)
7125 {
cc23e853 7126@@ -67,6 +78,11 @@ static inline bool gid_eq(kgid_t left, k
537831f9
AM
7127 return __kgid_val(left) == __kgid_val(right);
7128 }
7129
7130+static inline bool tag_eq(ktag_t left, ktag_t right)
7131+{
7132+ return __ktag_val(left) == __ktag_val(right);
7133+}
7134+
7135 static inline bool uid_gt(kuid_t left, kuid_t right)
7136 {
7137 return __kuid_val(left) > __kuid_val(right);
cc23e853
AM
7138@@ -117,13 +133,21 @@ static inline bool gid_valid(kgid_t gid)
7139 return __kgid_val(gid) != (gid_t) -1;
537831f9
AM
7140 }
7141
7142+static inline bool tag_valid(ktag_t tag)
7143+{
7144+ return !tag_eq(tag, INVALID_TAG);
7145+}
7146+
7147 #ifdef CONFIG_USER_NS
7148
7149 extern kuid_t make_kuid(struct user_namespace *from, uid_t uid);
7150 extern kgid_t make_kgid(struct user_namespace *from, gid_t gid);
c90fe048 7151+extern ktag_t make_ktag(struct user_namespace *from, gid_t gid);
537831f9
AM
7152
7153 extern uid_t from_kuid(struct user_namespace *to, kuid_t uid);
7154 extern gid_t from_kgid(struct user_namespace *to, kgid_t gid);
61333608 7155+extern vtag_t from_ktag(struct user_namespace *to, ktag_t tag);
537831f9
AM
7156+
7157 extern uid_t from_kuid_munged(struct user_namespace *to, kuid_t uid);
7158 extern gid_t from_kgid_munged(struct user_namespace *to, kgid_t gid);
7159
cc23e853 7160@@ -149,6 +173,11 @@ static inline kgid_t make_kgid(struct us
537831f9
AM
7161 return KGIDT_INIT(gid);
7162 }
7163
61333608 7164+static inline ktag_t make_ktag(struct user_namespace *from, vtag_t tag)
537831f9
AM
7165+{
7166+ return KTAGT_INIT(tag);
7167+}
7168+
7169 static inline uid_t from_kuid(struct user_namespace *to, kuid_t kuid)
7170 {
7171 return __kuid_val(kuid);
cc23e853 7172@@ -159,6 +188,11 @@ static inline gid_t from_kgid(struct use
537831f9
AM
7173 return __kgid_val(kgid);
7174 }
7175
61333608 7176+static inline vtag_t from_ktag(struct user_namespace *to, ktag_t ktag)
537831f9
AM
7177+{
7178+ return __ktag_val(ktag);
7179+}
7180+
7181 static inline uid_t from_kuid_munged(struct user_namespace *to, kuid_t kuid)
7182 {
7183 uid_t uid = from_kuid(to, kuid);
3261cfd5
AM
7184diff -NurpP --minimal linux-4.9.207/include/linux/vroot.h linux-4.9.207-vs2.3.9.11/include/linux/vroot.h
7185--- linux-4.9.207/include/linux/vroot.h 1970-01-01 00:00:00.000000000 +0000
7186+++ linux-4.9.207-vs2.3.9.11/include/linux/vroot.h 2018-10-20 04:58:14.000000000 +0000
2380c486
JR
7187@@ -0,0 +1,51 @@
7188+
7189+/*
7190+ * include/linux/vroot.h
7191+ *
cc23e853
AM
7192+ * written by Herbert P?tzl, 9/11/2002
7193+ * ported to 2.6 by Herbert P?tzl, 30/12/2004
2380c486 7194+ *
cc23e853 7195+ * Copyright (C) 2002-2007 by Herbert P?tzl.
2380c486
JR
7196+ * Redistribution of this file is permitted under the
7197+ * GNU General Public License.
7198+ */
7199+
7200+#ifndef _LINUX_VROOT_H
7201+#define _LINUX_VROOT_H
7202+
7203+
7204+#ifdef __KERNEL__
7205+
7206+/* Possible states of device */
7207+enum {
7208+ Vr_unbound,
7209+ Vr_bound,
7210+};
7211+
7212+struct vroot_device {
7213+ int vr_number;
7214+ int vr_refcnt;
7215+
7216+ struct semaphore vr_ctl_mutex;
7217+ struct block_device *vr_device;
7218+ int vr_state;
7219+};
7220+
7221+
7222+typedef struct block_device *(vroot_grb_func)(struct block_device *);
7223+
7224+extern int register_vroot_grb(vroot_grb_func *);
7225+extern int unregister_vroot_grb(vroot_grb_func *);
7226+
7227+#endif /* __KERNEL__ */
7228+
7229+#define MAX_VROOT_DEFAULT 8
7230+
7231+/*
7232+ * IOCTL commands --- we will commandeer 0x56 ('V')
7233+ */
7234+
7235+#define VROOT_SET_DEV 0x5600
7236+#define VROOT_CLR_DEV 0x5601
7237+
7238+#endif /* _LINUX_VROOT_H */
3261cfd5
AM
7239diff -NurpP --minimal linux-4.9.207/include/linux/vs_base.h linux-4.9.207-vs2.3.9.11/include/linux/vs_base.h
7240--- linux-4.9.207/include/linux/vs_base.h 1970-01-01 00:00:00.000000000 +0000
7241+++ linux-4.9.207-vs2.3.9.11/include/linux/vs_base.h 2018-10-20 04:58:14.000000000 +0000
2380c486
JR
7242@@ -0,0 +1,10 @@
7243+#ifndef _VS_BASE_H
7244+#define _VS_BASE_H
7245+
7246+#include "vserver/base.h"
7247+#include "vserver/check.h"
7248+#include "vserver/debug.h"
7249+
7250+#else
7251+#warning duplicate inclusion
7252+#endif
3261cfd5
AM
7253diff -NurpP --minimal linux-4.9.207/include/linux/vs_context.h linux-4.9.207-vs2.3.9.11/include/linux/vs_context.h
7254--- linux-4.9.207/include/linux/vs_context.h 1970-01-01 00:00:00.000000000 +0000
7255+++ linux-4.9.207-vs2.3.9.11/include/linux/vs_context.h 2018-10-20 04:58:14.000000000 +0000
4a036bed 7256@@ -0,0 +1,242 @@
2380c486
JR
7257+#ifndef _VS_CONTEXT_H
7258+#define _VS_CONTEXT_H
7259+
7260+#include "vserver/base.h"
7261+#include "vserver/check.h"
7262+#include "vserver/context.h"
7263+#include "vserver/history.h"
7264+#include "vserver/debug.h"
7265+
7266+#include <linux/sched.h>
7267+
7268+
7269+#define get_vx_info(i) __get_vx_info(i, __FILE__, __LINE__, __HERE__)
7270+
7271+static inline struct vx_info *__get_vx_info(struct vx_info *vxi,
7272+ const char *_file, int _line, void *_here)
7273+{
7274+ if (!vxi)
7275+ return NULL;
7276+
7277+ vxlprintk(VXD_CBIT(xid, 2), "get_vx_info(%p[#%d.%d])",
7278+ vxi, vxi ? vxi->vx_id : 0,
7279+ vxi ? atomic_read(&vxi->vx_usecnt) : 0,
7280+ _file, _line);
7281+ __vxh_get_vx_info(vxi, _here);
7282+
7283+ atomic_inc(&vxi->vx_usecnt);
7284+ return vxi;
7285+}
7286+
7287+
7288+extern void free_vx_info(struct vx_info *);
7289+
7290+#define put_vx_info(i) __put_vx_info(i, __FILE__, __LINE__, __HERE__)
7291+
7292+static inline void __put_vx_info(struct vx_info *vxi,
7293+ const char *_file, int _line, void *_here)
7294+{
7295+ if (!vxi)
7296+ return;
7297+
7298+ vxlprintk(VXD_CBIT(xid, 2), "put_vx_info(%p[#%d.%d])",
7299+ vxi, vxi ? vxi->vx_id : 0,
7300+ vxi ? atomic_read(&vxi->vx_usecnt) : 0,
7301+ _file, _line);
7302+ __vxh_put_vx_info(vxi, _here);
7303+
7304+ if (atomic_dec_and_test(&vxi->vx_usecnt))
7305+ free_vx_info(vxi);
7306+}
7307+
7308+
7309+#define init_vx_info(p, i) \
7310+ __init_vx_info(p, i, __FILE__, __LINE__, __HERE__)
7311+
7312+static inline void __init_vx_info(struct vx_info **vxp, struct vx_info *vxi,
7313+ const char *_file, int _line, void *_here)
7314+{
7315+ if (vxi) {
7316+ vxlprintk(VXD_CBIT(xid, 3),
7317+ "init_vx_info(%p[#%d.%d])",
7318+ vxi, vxi ? vxi->vx_id : 0,
7319+ vxi ? atomic_read(&vxi->vx_usecnt) : 0,
7320+ _file, _line);
7321+ __vxh_init_vx_info(vxi, vxp, _here);
7322+
7323+ atomic_inc(&vxi->vx_usecnt);
7324+ }
7325+ *vxp = vxi;
7326+}
7327+
7328+
7329+#define set_vx_info(p, i) \
7330+ __set_vx_info(p, i, __FILE__, __LINE__, __HERE__)
7331+
7332+static inline void __set_vx_info(struct vx_info **vxp, struct vx_info *vxi,
7333+ const char *_file, int _line, void *_here)
7334+{
7335+ struct vx_info *vxo;
7336+
7337+ if (!vxi)
7338+ return;
7339+
7340+ vxlprintk(VXD_CBIT(xid, 3), "set_vx_info(%p[#%d.%d])",
7341+ vxi, vxi ? vxi->vx_id : 0,
7342+ vxi ? atomic_read(&vxi->vx_usecnt) : 0,
7343+ _file, _line);
7344+ __vxh_set_vx_info(vxi, vxp, _here);
7345+
7346+ atomic_inc(&vxi->vx_usecnt);
7347+ vxo = xchg(vxp, vxi);
7348+ BUG_ON(vxo);
7349+}
7350+
7351+
7352+#define clr_vx_info(p) __clr_vx_info(p, __FILE__, __LINE__, __HERE__)
7353+
7354+static inline void __clr_vx_info(struct vx_info **vxp,
7355+ const char *_file, int _line, void *_here)
7356+{
7357+ struct vx_info *vxo;
7358+
7359+ vxo = xchg(vxp, NULL);
7360+ if (!vxo)
7361+ return;
7362+
7363+ vxlprintk(VXD_CBIT(xid, 3), "clr_vx_info(%p[#%d.%d])",
7364+ vxo, vxo ? vxo->vx_id : 0,
7365+ vxo ? atomic_read(&vxo->vx_usecnt) : 0,
7366+ _file, _line);
7367+ __vxh_clr_vx_info(vxo, vxp, _here);
7368+
7369+ if (atomic_dec_and_test(&vxo->vx_usecnt))
7370+ free_vx_info(vxo);
7371+}
7372+
7373+
7374+#define claim_vx_info(v, p) \
7375+ __claim_vx_info(v, p, __FILE__, __LINE__, __HERE__)
7376+
7377+static inline void __claim_vx_info(struct vx_info *vxi,
7378+ struct task_struct *task,
7379+ const char *_file, int _line, void *_here)
7380+{
7381+ vxlprintk(VXD_CBIT(xid, 3), "claim_vx_info(%p[#%d.%d.%d]) %p",
7382+ vxi, vxi ? vxi->vx_id : 0,
7383+ vxi ? atomic_read(&vxi->vx_usecnt) : 0,
7384+ vxi ? atomic_read(&vxi->vx_tasks) : 0,
7385+ task, _file, _line);
7386+ __vxh_claim_vx_info(vxi, task, _here);
7387+
7388+ atomic_inc(&vxi->vx_tasks);
7389+}
7390+
7391+
7392+extern void unhash_vx_info(struct vx_info *);
7393+
7394+#define release_vx_info(v, p) \
7395+ __release_vx_info(v, p, __FILE__, __LINE__, __HERE__)
7396+
7397+static inline void __release_vx_info(struct vx_info *vxi,
7398+ struct task_struct *task,
7399+ const char *_file, int _line, void *_here)
7400+{
7401+ vxlprintk(VXD_CBIT(xid, 3), "release_vx_info(%p[#%d.%d.%d]) %p",
7402+ vxi, vxi ? vxi->vx_id : 0,
7403+ vxi ? atomic_read(&vxi->vx_usecnt) : 0,
7404+ vxi ? atomic_read(&vxi->vx_tasks) : 0,
7405+ task, _file, _line);
7406+ __vxh_release_vx_info(vxi, task, _here);
7407+
7408+ might_sleep();
7409+
7410+ if (atomic_dec_and_test(&vxi->vx_tasks))
7411+ unhash_vx_info(vxi);
7412+}
7413+
7414+
7415+#define task_get_vx_info(p) \
7416+ __task_get_vx_info(p, __FILE__, __LINE__, __HERE__)
7417+
7418+static inline struct vx_info *__task_get_vx_info(struct task_struct *p,
7419+ const char *_file, int _line, void *_here)
7420+{
7421+ struct vx_info *vxi;
7422+
7423+ task_lock(p);
7424+ vxlprintk(VXD_CBIT(xid, 5), "task_get_vx_info(%p)",
7425+ p, _file, _line);
7426+ vxi = __get_vx_info(p->vx_info, _file, _line, _here);
7427+ task_unlock(p);
7428+ return vxi;
7429+}
7430+
7431+
7432+static inline void __wakeup_vx_info(struct vx_info *vxi)
7433+{
7434+ if (waitqueue_active(&vxi->vx_wait))
7435+ wake_up_interruptible(&vxi->vx_wait);
7436+}
7437+
7438+
7439+#define enter_vx_info(v, s) __enter_vx_info(v, s, __FILE__, __LINE__)
7440+
7441+static inline void __enter_vx_info(struct vx_info *vxi,
7442+ struct vx_info_save *vxis, const char *_file, int _line)
7443+{
7444+ vxlprintk(VXD_CBIT(xid, 5), "enter_vx_info(%p[#%d],%p) %p[#%d,%p]",
7445+ vxi, vxi ? vxi->vx_id : 0, vxis, current,
7446+ current->xid, current->vx_info, _file, _line);
7447+ vxis->vxi = xchg(&current->vx_info, vxi);
7448+ vxis->xid = current->xid;
7449+ current->xid = vxi ? vxi->vx_id : 0;
7450+}
7451+
7452+#define leave_vx_info(s) __leave_vx_info(s, __FILE__, __LINE__)
7453+
7454+static inline void __leave_vx_info(struct vx_info_save *vxis,
7455+ const char *_file, int _line)
7456+{
7457+ vxlprintk(VXD_CBIT(xid, 5), "leave_vx_info(%p[#%d,%p]) %p[#%d,%p]",
7458+ vxis, vxis->xid, vxis->vxi, current,
7459+ current->xid, current->vx_info, _file, _line);
7460+ (void)xchg(&current->vx_info, vxis->vxi);
7461+ current->xid = vxis->xid;
7462+}
7463+
7464+
7465+static inline void __enter_vx_admin(struct vx_info_save *vxis)
7466+{
7467+ vxis->vxi = xchg(&current->vx_info, NULL);
61333608 7468+ vxis->xid = xchg(&current->xid, (vxid_t)0);
2380c486
JR
7469+}
7470+
7471+static inline void __leave_vx_admin(struct vx_info_save *vxis)
7472+{
7473+ (void)xchg(&current->xid, vxis->xid);
7474+ (void)xchg(&current->vx_info, vxis->vxi);
7475+}
7476+
4a036bed
AM
7477+#define task_is_init(p) \
7478+ __task_is_init(p, __FILE__, __LINE__, __HERE__)
7479+
7480+static inline int __task_is_init(struct task_struct *p,
7481+ const char *_file, int _line, void *_here)
7482+{
7483+ int is_init = is_global_init(p);
7484+
7485+ task_lock(p);
7486+ if (p->vx_info)
7487+ is_init = p->vx_info->vx_initpid == p->pid;
7488+ task_unlock(p);
7489+ return is_init;
7490+}
7491+
2380c486
JR
7492+extern void exit_vx_info(struct task_struct *, int);
7493+extern void exit_vx_info_early(struct task_struct *, int);
7494+
7495+
7496+#else
7497+#warning duplicate inclusion
7498+#endif
3261cfd5
AM
7499diff -NurpP --minimal linux-4.9.207/include/linux/vs_cowbl.h linux-4.9.207-vs2.3.9.11/include/linux/vs_cowbl.h
7500--- linux-4.9.207/include/linux/vs_cowbl.h 1970-01-01 00:00:00.000000000 +0000
7501+++ linux-4.9.207-vs2.3.9.11/include/linux/vs_cowbl.h 2018-10-20 04:58:14.000000000 +0000
78865d5b 7502@@ -0,0 +1,48 @@
2380c486
JR
7503+#ifndef _VS_COWBL_H
7504+#define _VS_COWBL_H
7505+
7506+#include <linux/fs.h>
7507+#include <linux/dcache.h>
7508+#include <linux/namei.h>
78865d5b 7509+#include <linux/slab.h>
2380c486
JR
7510+
7511+extern struct dentry *cow_break_link(const char *pathname);
7512+
7513+static inline int cow_check_and_break(struct path *path)
7514+{
7515+ struct inode *inode = path->dentry->d_inode;
7516+ int error = 0;
7517+
7518+ /* do we need this check? */
7519+ if (IS_RDONLY(inode))
7520+ return -EROFS;
7521+
7522+ if (IS_COW(inode)) {
7523+ if (IS_COW_LINK(inode)) {
7524+ struct dentry *new_dentry, *old_dentry = path->dentry;
7525+ char *pp, *buf;
7526+
7527+ buf = kmalloc(PATH_MAX, GFP_KERNEL);
7528+ if (!buf) {
7529+ return -ENOMEM;
7530+ }
7531+ pp = d_path(path, buf, PATH_MAX);
7532+ new_dentry = cow_break_link(pp);
7533+ kfree(buf);
7534+ if (!IS_ERR(new_dentry)) {
7535+ path->dentry = new_dentry;
7536+ dput(old_dentry);
7537+ } else
7538+ error = PTR_ERR(new_dentry);
7539+ } else {
7540+ inode->i_flags &= ~(S_IXUNLINK | S_IMMUTABLE);
7541+ inode->i_ctime = CURRENT_TIME;
7542+ mark_inode_dirty(inode);
7543+ }
7544+ }
7545+ return error;
7546+}
7547+
7548+#else
7549+#warning duplicate inclusion
7550+#endif
3261cfd5
AM
7551diff -NurpP --minimal linux-4.9.207/include/linux/vs_cvirt.h linux-4.9.207-vs2.3.9.11/include/linux/vs_cvirt.h
7552--- linux-4.9.207/include/linux/vs_cvirt.h 1970-01-01 00:00:00.000000000 +0000
7553+++ linux-4.9.207-vs2.3.9.11/include/linux/vs_cvirt.h 2018-10-20 04:58:14.000000000 +0000
2380c486
JR
7554@@ -0,0 +1,50 @@
7555+#ifndef _VS_CVIRT_H
7556+#define _VS_CVIRT_H
7557+
7558+#include "vserver/cvirt.h"
7559+#include "vserver/context.h"
7560+#include "vserver/base.h"
7561+#include "vserver/check.h"
7562+#include "vserver/debug.h"
7563+
7564+
7565+static inline void vx_activate_task(struct task_struct *p)
7566+{
7567+ struct vx_info *vxi;
7568+
7569+ if ((vxi = p->vx_info)) {
7570+ vx_update_load(vxi);
7571+ atomic_inc(&vxi->cvirt.nr_running);
7572+ }
7573+}
7574+
7575+static inline void vx_deactivate_task(struct task_struct *p)
7576+{
7577+ struct vx_info *vxi;
7578+
7579+ if ((vxi = p->vx_info)) {
7580+ vx_update_load(vxi);
7581+ atomic_dec(&vxi->cvirt.nr_running);
7582+ }
7583+}
7584+
7585+static inline void vx_uninterruptible_inc(struct task_struct *p)
7586+{
7587+ struct vx_info *vxi;
7588+
7589+ if ((vxi = p->vx_info))
7590+ atomic_inc(&vxi->cvirt.nr_uninterruptible);
7591+}
7592+
7593+static inline void vx_uninterruptible_dec(struct task_struct *p)
7594+{
7595+ struct vx_info *vxi;
7596+
7597+ if ((vxi = p->vx_info))
7598+ atomic_dec(&vxi->cvirt.nr_uninterruptible);
7599+}
7600+
7601+
7602+#else
7603+#warning duplicate inclusion
7604+#endif
3261cfd5
AM
7605diff -NurpP --minimal linux-4.9.207/include/linux/vs_device.h linux-4.9.207-vs2.3.9.11/include/linux/vs_device.h
7606--- linux-4.9.207/include/linux/vs_device.h 1970-01-01 00:00:00.000000000 +0000
7607+++ linux-4.9.207-vs2.3.9.11/include/linux/vs_device.h 2018-10-20 04:58:14.000000000 +0000
2380c486
JR
7608@@ -0,0 +1,45 @@
7609+#ifndef _VS_DEVICE_H
7610+#define _VS_DEVICE_H
7611+
7612+#include "vserver/base.h"
7613+#include "vserver/device.h"
7614+#include "vserver/debug.h"
7615+
7616+
7617+#ifdef CONFIG_VSERVER_DEVICE
7618+
7619+int vs_map_device(struct vx_info *, dev_t, dev_t *, umode_t);
7620+
7621+#define vs_device_perm(v, d, m, p) \
7622+ ((vs_map_device(current_vx_info(), d, NULL, m) & (p)) == (p))
7623+
7624+#else
7625+
7626+static inline
7627+int vs_map_device(struct vx_info *vxi,
7628+ dev_t device, dev_t *target, umode_t mode)
7629+{
7630+ if (target)
7631+ *target = device;
7632+ return ~0;
7633+}
7634+
7635+#define vs_device_perm(v, d, m, p) ((p) == (p))
7636+
7637+#endif
7638+
7639+
7640+#define vs_map_chrdev(d, t, p) \
7641+ ((vs_map_device(current_vx_info(), d, t, S_IFCHR) & (p)) == (p))
7642+#define vs_map_blkdev(d, t, p) \
7643+ ((vs_map_device(current_vx_info(), d, t, S_IFBLK) & (p)) == (p))
7644+
7645+#define vs_chrdev_perm(d, p) \
7646+ vs_device_perm(current_vx_info(), d, S_IFCHR, p)
7647+#define vs_blkdev_perm(d, p) \
7648+ vs_device_perm(current_vx_info(), d, S_IFBLK, p)
7649+
7650+
7651+#else
7652+#warning duplicate inclusion
7653+#endif
3261cfd5
AM
7654diff -NurpP --minimal linux-4.9.207/include/linux/vs_dlimit.h linux-4.9.207-vs2.3.9.11/include/linux/vs_dlimit.h
7655--- linux-4.9.207/include/linux/vs_dlimit.h 1970-01-01 00:00:00.000000000 +0000
7656+++ linux-4.9.207-vs2.3.9.11/include/linux/vs_dlimit.h 2018-10-20 04:58:14.000000000 +0000
2c8c5bc5 7657@@ -0,0 +1,215 @@
2380c486
JR
7658+#ifndef _VS_DLIMIT_H
7659+#define _VS_DLIMIT_H
7660+
7661+#include <linux/fs.h>
7662+
7663+#include "vserver/dlimit.h"
7664+#include "vserver/base.h"
7665+#include "vserver/debug.h"
7666+
7667+
7668+#define get_dl_info(i) __get_dl_info(i, __FILE__, __LINE__)
7669+
7670+static inline struct dl_info *__get_dl_info(struct dl_info *dli,
7671+ const char *_file, int _line)
7672+{
7673+ if (!dli)
7674+ return NULL;
7675+ vxlprintk(VXD_CBIT(dlim, 4), "get_dl_info(%p[#%d.%d])",
7676+ dli, dli ? dli->dl_tag : 0,
7677+ dli ? atomic_read(&dli->dl_usecnt) : 0,
7678+ _file, _line);
7679+ atomic_inc(&dli->dl_usecnt);
7680+ return dli;
7681+}
7682+
7683+
7684+#define free_dl_info(i) \
7685+ call_rcu(&(i)->dl_rcu, rcu_free_dl_info)
7686+
7687+#define put_dl_info(i) __put_dl_info(i, __FILE__, __LINE__)
7688+
7689+static inline void __put_dl_info(struct dl_info *dli,
7690+ const char *_file, int _line)
7691+{
7692+ if (!dli)
7693+ return;
7694+ vxlprintk(VXD_CBIT(dlim, 4), "put_dl_info(%p[#%d.%d])",
7695+ dli, dli ? dli->dl_tag : 0,
7696+ dli ? atomic_read(&dli->dl_usecnt) : 0,
7697+ _file, _line);
7698+ if (atomic_dec_and_test(&dli->dl_usecnt))
7699+ free_dl_info(dli);
7700+}
7701+
7702+
7703+#define __dlimit_char(d) ((d) ? '*' : ' ')
7704+
7705+static inline int __dl_alloc_space(struct super_block *sb,
61333608 7706+ vtag_t tag, dlsize_t nr, const char *file, int line)
2380c486
JR
7707+{
7708+ struct dl_info *dli = NULL;
7709+ int ret = 0;
7710+
7711+ if (nr == 0)
7712+ goto out;
7713+ dli = locate_dl_info(sb, tag);
7714+ if (!dli)
7715+ goto out;
7716+
7717+ spin_lock(&dli->dl_lock);
7718+ ret = (dli->dl_space_used + nr > dli->dl_space_total);
7719+ if (!ret)
7720+ dli->dl_space_used += nr;
7721+ spin_unlock(&dli->dl_lock);
7722+ put_dl_info(dli);
7723+out:
7724+ vxlprintk(VXD_CBIT(dlim, 1),
7725+ "ALLOC (%p,#%d)%c %lld bytes (%d)",
7726+ sb, tag, __dlimit_char(dli), (long long)nr,
7727+ ret, file, line);
76514441 7728+ return ret ? -ENOSPC : 0;
2380c486
JR
7729+}
7730+
7731+static inline void __dl_free_space(struct super_block *sb,
61333608 7732+ vtag_t tag, dlsize_t nr, const char *_file, int _line)
2380c486
JR
7733+{
7734+ struct dl_info *dli = NULL;
7735+
7736+ if (nr == 0)
7737+ goto out;
7738+ dli = locate_dl_info(sb, tag);
7739+ if (!dli)
7740+ goto out;
7741+
7742+ spin_lock(&dli->dl_lock);
7743+ if (dli->dl_space_used > nr)
7744+ dli->dl_space_used -= nr;
7745+ else
7746+ dli->dl_space_used = 0;
7747+ spin_unlock(&dli->dl_lock);
7748+ put_dl_info(dli);
7749+out:
7750+ vxlprintk(VXD_CBIT(dlim, 1),
7751+ "FREE (%p,#%d)%c %lld bytes",
7752+ sb, tag, __dlimit_char(dli), (long long)nr,
7753+ _file, _line);
7754+}
7755+
7756+static inline int __dl_alloc_inode(struct super_block *sb,
61333608 7757+ vtag_t tag, const char *_file, int _line)
2380c486
JR
7758+{
7759+ struct dl_info *dli;
7760+ int ret = 0;
d337f35e 7761+
2380c486
JR
7762+ dli = locate_dl_info(sb, tag);
7763+ if (!dli)
7764+ goto out;
d337f35e 7765+
2380c486 7766+ spin_lock(&dli->dl_lock);
2c8c5bc5
AM
7767+ dli->dl_inodes_used++;
7768+ ret = (dli->dl_inodes_used > dli->dl_inodes_total);
2380c486
JR
7769+ spin_unlock(&dli->dl_lock);
7770+ put_dl_info(dli);
7771+out:
7772+ vxlprintk(VXD_CBIT(dlim, 0),
7773+ "ALLOC (%p,#%d)%c inode (%d)",
7774+ sb, tag, __dlimit_char(dli), ret, _file, _line);
76514441 7775+ return ret ? -ENOSPC : 0;
2380c486 7776+}
d337f35e 7777+
2380c486 7778+static inline void __dl_free_inode(struct super_block *sb,
61333608 7779+ vtag_t tag, const char *_file, int _line)
d337f35e 7780+{
2380c486
JR
7781+ struct dl_info *dli;
7782+
7783+ dli = locate_dl_info(sb, tag);
7784+ if (!dli)
7785+ goto out;
7786+
7787+ spin_lock(&dli->dl_lock);
7788+ if (dli->dl_inodes_used > 1)
7789+ dli->dl_inodes_used--;
7790+ else
7791+ dli->dl_inodes_used = 0;
7792+ spin_unlock(&dli->dl_lock);
7793+ put_dl_info(dli);
7794+out:
7795+ vxlprintk(VXD_CBIT(dlim, 0),
7796+ "FREE (%p,#%d)%c inode",
7797+ sb, tag, __dlimit_char(dli), _file, _line);
d337f35e
JR
7798+}
7799+
61333608 7800+static inline void __dl_adjust_block(struct super_block *sb, vtag_t tag,
2380c486
JR
7801+ unsigned long long *free_blocks, unsigned long long *root_blocks,
7802+ const char *_file, int _line)
d337f35e 7803+{
2380c486
JR
7804+ struct dl_info *dli;
7805+ uint64_t broot, bfree;
7806+
7807+ dli = locate_dl_info(sb, tag);
7808+ if (!dli)
7809+ return;
7810+
7811+ spin_lock(&dli->dl_lock);
7812+ broot = (dli->dl_space_total -
7813+ (dli->dl_space_total >> 10) * dli->dl_nrlmult)
7814+ >> sb->s_blocksize_bits;
7815+ bfree = (dli->dl_space_total - dli->dl_space_used)
7816+ >> sb->s_blocksize_bits;
7817+ spin_unlock(&dli->dl_lock);
7818+
7819+ vxlprintk(VXD_CBIT(dlim, 2),
7820+ "ADJUST: %lld,%lld on %lld,%lld [mult=%d]",
7821+ (long long)bfree, (long long)broot,
7822+ *free_blocks, *root_blocks, dli->dl_nrlmult,
7823+ _file, _line);
7824+ if (free_blocks) {
7825+ if (*free_blocks > bfree)
7826+ *free_blocks = bfree;
7827+ }
7828+ if (root_blocks) {
7829+ if (*root_blocks > broot)
7830+ *root_blocks = broot;
7831+ }
7832+ put_dl_info(dli);
d337f35e
JR
7833+}
7834+
e22b5178 7835+#define dl_prealloc_space(in, bytes) \
537831f9 7836+ __dl_alloc_space((in)->i_sb, i_tag_read(in), (dlsize_t)(bytes), \
2380c486 7837+ __FILE__, __LINE__ )
d337f35e 7838+
e22b5178 7839+#define dl_alloc_space(in, bytes) \
537831f9 7840+ __dl_alloc_space((in)->i_sb, i_tag_read(in), (dlsize_t)(bytes), \
2380c486 7841+ __FILE__, __LINE__ )
d337f35e 7842+
e22b5178 7843+#define dl_reserve_space(in, bytes) \
537831f9 7844+ __dl_alloc_space((in)->i_sb, i_tag_read(in), (dlsize_t)(bytes), \
2380c486 7845+ __FILE__, __LINE__ )
d337f35e 7846+
e22b5178
AM
7847+#define dl_claim_space(in, bytes) (0)
7848+
7849+#define dl_release_space(in, bytes) \
537831f9 7850+ __dl_free_space((in)->i_sb, i_tag_read(in), (dlsize_t)(bytes), \
2380c486 7851+ __FILE__, __LINE__ )
d337f35e 7852+
e22b5178 7853+#define dl_free_space(in, bytes) \
537831f9 7854+ __dl_free_space((in)->i_sb, i_tag_read(in), (dlsize_t)(bytes), \
e22b5178
AM
7855+ __FILE__, __LINE__ )
7856+
7857+
d337f35e 7858+
e22b5178 7859+#define dl_alloc_inode(in) \
537831f9 7860+ __dl_alloc_inode((in)->i_sb, i_tag_read(in), __FILE__, __LINE__ )
d337f35e 7861+
e22b5178 7862+#define dl_free_inode(in) \
537831f9 7863+ __dl_free_inode((in)->i_sb, i_tag_read(in), __FILE__, __LINE__ )
d337f35e 7864+
d337f35e 7865+
e22b5178 7866+#define dl_adjust_block(sb, tag, fb, rb) \
2380c486 7867+ __dl_adjust_block(sb, tag, fb, rb, __FILE__, __LINE__ )
d337f35e 7868+
d337f35e 7869+
2380c486
JR
7870+#else
7871+#warning duplicate inclusion
7872+#endif
3261cfd5
AM
7873diff -NurpP --minimal linux-4.9.207/include/linux/vserver/base.h linux-4.9.207-vs2.3.9.11/include/linux/vserver/base.h
7874--- linux-4.9.207/include/linux/vserver/base.h 1970-01-01 00:00:00.000000000 +0000
7875+++ linux-4.9.207-vs2.3.9.11/include/linux/vserver/base.h 2018-10-20 04:58:14.000000000 +0000
7876@@ -0,0 +1,184 @@
7877+#ifndef _VSERVER_BASE_H
7878+#define _VSERVER_BASE_H
d337f35e
JR
7879+
7880+
3261cfd5 7881+/* context state changes */
d337f35e 7882+
3261cfd5
AM
7883+enum {
7884+ VSC_STARTUP = 1,
7885+ VSC_SHUTDOWN,
d337f35e 7886+
3261cfd5
AM
7887+ VSC_NETUP,
7888+ VSC_NETDOWN,
7889+};
d337f35e
JR
7890+
7891+
d337f35e 7892+
3261cfd5 7893+#define vx_task_xid(t) ((t)->xid)
d337f35e 7894+
3261cfd5 7895+#define vx_current_xid() vx_task_xid(current)
d337f35e 7896+
3261cfd5 7897+#define current_vx_info() (current->vx_info)
d337f35e
JR
7898+
7899+
3261cfd5 7900+#define nx_task_nid(t) ((t)->nid)
d337f35e 7901+
3261cfd5 7902+#define nx_current_nid() nx_task_nid(current)
4bf69007 7903+
3261cfd5 7904+#define current_nx_info() (current->nx_info)
d337f35e 7905+
d337f35e 7906+
3261cfd5 7907+/* generic flag merging */
d337f35e 7908+
3261cfd5 7909+#define vs_check_flags(v, m, f) (((v) & (m)) ^ (f))
d337f35e 7910+
3261cfd5 7911+#define vs_mask_flags(v, f, m) (((v) & ~(m)) | ((f) & (m)))
d337f35e 7912+
3261cfd5 7913+#define vs_mask_mask(v, f, m) (((v) & ~(m)) | ((v) & (f) & (m)))
d337f35e 7914+
3261cfd5 7915+#define vs_check_bit(v, n) ((v) & (1LL << (n)))
d337f35e 7916+
d337f35e 7917+
3261cfd5 7918+/* context flags */
d337f35e 7919+
3261cfd5 7920+#define __vx_flags(v) ((v) ? (v)->vx_flags : 0)
d337f35e 7921+
3261cfd5 7922+#define vx_current_flags() __vx_flags(current_vx_info())
d337f35e 7923+
3261cfd5
AM
7924+#define vx_info_flags(v, m, f) \
7925+ vs_check_flags(__vx_flags(v), m, f)
d337f35e 7926+
3261cfd5
AM
7927+#define task_vx_flags(t, m, f) \
7928+ ((t) && vx_info_flags((t)->vx_info, m, f))
d337f35e 7929+
3261cfd5 7930+#define vx_flags(m, f) vx_info_flags(current_vx_info(), m, f)
d337f35e
JR
7931+
7932+
3261cfd5 7933+/* context caps */
d337f35e 7934+
3261cfd5 7935+#define __vx_ccaps(v) ((v) ? (v)->vx_ccaps : 0)
d337f35e 7936+
3261cfd5 7937+#define vx_current_ccaps() __vx_ccaps(current_vx_info())
d337f35e 7938+
3261cfd5 7939+#define vx_info_ccaps(v, c) (__vx_ccaps(v) & (c))
d337f35e 7940+
3261cfd5 7941+#define vx_ccaps(c) vx_info_ccaps(current_vx_info(), (c))
d337f35e
JR
7942+
7943+
d337f35e 7944+
3261cfd5 7945+/* network flags */
d337f35e 7946+
3261cfd5 7947+#define __nx_flags(n) ((n) ? (n)->nx_flags : 0)
d337f35e 7948+
3261cfd5 7949+#define nx_current_flags() __nx_flags(current_nx_info())
d337f35e 7950+
3261cfd5
AM
7951+#define nx_info_flags(n, m, f) \
7952+ vs_check_flags(__nx_flags(n), m, f)
d337f35e 7953+
3261cfd5
AM
7954+#define task_nx_flags(t, m, f) \
7955+ ((t) && nx_info_flags((t)->nx_info, m, f))
d337f35e 7956+
3261cfd5 7957+#define nx_flags(m, f) nx_info_flags(current_nx_info(), m, f)
d337f35e 7958+
d337f35e 7959+
3261cfd5 7960+/* network caps */
d337f35e 7961+
3261cfd5 7962+#define __nx_ncaps(n) ((n) ? (n)->nx_ncaps : 0)
d337f35e 7963+
3261cfd5 7964+#define nx_current_ncaps() __nx_ncaps(current_nx_info())
d337f35e 7965+
3261cfd5 7966+#define nx_info_ncaps(n, c) (__nx_ncaps(n) & (c))
d337f35e 7967+
3261cfd5 7968+#define nx_ncaps(c) nx_info_ncaps(current_nx_info(), c)
d337f35e
JR
7969+
7970+
3261cfd5 7971+/* context mask capabilities */
d337f35e 7972+
3261cfd5 7973+#define __vx_mcaps(v) ((v) ? (v)->vx_ccaps >> 32UL : ~0 )
d337f35e 7974+
3261cfd5 7975+#define vx_info_mcaps(v, c) (__vx_mcaps(v) & (c))
d337f35e 7976+
3261cfd5 7977+#define vx_mcaps(c) vx_info_mcaps(current_vx_info(), c)
d337f35e 7978+
d337f35e 7979+
3261cfd5 7980+/* context bcap mask */
d337f35e 7981+
3261cfd5 7982+#define __vx_bcaps(v) ((v)->vx_bcaps)
d337f35e 7983+
3261cfd5 7984+#define vx_current_bcaps() __vx_bcaps(current_vx_info())
d337f35e 7985+
d337f35e 7986+
3261cfd5 7987+/* mask given bcaps */
d337f35e 7988+
3261cfd5 7989+#define vx_info_mbcaps(v, c) ((v) ? cap_intersect(__vx_bcaps(v), c) : c)
d337f35e 7990+
3261cfd5 7991+#define vx_mbcaps(c) vx_info_mbcaps(current_vx_info(), c)
d337f35e 7992+
4a036bed 7993+
3261cfd5 7994+/* masked cap_bset */
d337f35e 7995+
3261cfd5 7996+#define vx_info_cap_bset(v) vx_info_mbcaps(v, current->cap_bset)
d337f35e 7997+
3261cfd5 7998+#define vx_current_cap_bset() vx_info_cap_bset(current_vx_info())
7e46296a 7999+
3261cfd5
AM
8000+#if 0
8001+#define vx_info_mbcap(v, b) \
8002+ (!vx_info_flags(v, VXF_STATE_SETUP, 0) ? \
8003+ vx_info_bcaps(v, b) : (b))
7e46296a 8004+
3261cfd5
AM
8005+#define task_vx_mbcap(t, b) \
8006+ vx_info_mbcap((t)->vx_info, (t)->b)
7e46296a 8007+
3261cfd5
AM
8008+#define vx_mbcap(b) task_vx_mbcap(current, b)
8009+#endif
7e46296a 8010+
3261cfd5 8011+#define vx_cap_raised(v, c, f) cap_raised(vx_info_mbcaps(v, c), f)
7e46296a 8012+
3261cfd5
AM
8013+#define vx_capable(b, c) (capable(b) || \
8014+ (cap_raised(current_cap(), b) && vx_ccaps(c)))
d337f35e 8015+
3261cfd5
AM
8016+#define vx_ns_capable(n, b, c) (ns_capable(n, b) || \
8017+ (cap_raised(current_cap(), b) && vx_ccaps(c)))
4bf69007 8018+
3261cfd5
AM
8019+#define nx_capable(b, c) (capable(b) || \
8020+ (cap_raised(current_cap(), b) && nx_ncaps(c)))
d337f35e 8021+
3261cfd5
AM
8022+#define nx_ns_capable(n, b, c) (ns_capable(n, b) || \
8023+ (cap_raised(current_cap(), b) && nx_ncaps(c)))
d337f35e 8024+
3261cfd5
AM
8025+#define vx_task_initpid(t, n) \
8026+ ((t)->vx_info && \
8027+ ((t)->vx_info->vx_initpid == (n)))
d337f35e 8028+
3261cfd5 8029+#define vx_current_initpid(n) vx_task_initpid(current, n)
d337f35e 8030+
d337f35e 8031+
3261cfd5 8032+/* context unshare mask */
d337f35e 8033+
3261cfd5 8034+#define __vx_umask(v) ((v)->vx_umask)
d337f35e 8035+
3261cfd5 8036+#define vx_current_umask() __vx_umask(current_vx_info())
d337f35e 8037+
3261cfd5
AM
8038+#define vx_can_unshare(b, f) (capable(b) || \
8039+ (cap_raised(current_cap(), b) && \
8040+ !((f) & ~vx_current_umask())))
d337f35e 8041+
3261cfd5
AM
8042+#define vx_ns_can_unshare(n, b, f) (ns_capable(n, b) || \
8043+ (cap_raised(current_cap(), b) && \
8044+ !((f) & ~vx_current_umask())))
d337f35e 8045+
3261cfd5 8046+#define __vx_wmask(v) ((v)->vx_wmask)
d337f35e 8047+
3261cfd5 8048+#define vx_current_wmask() __vx_wmask(current_vx_info())
d337f35e 8049+
d337f35e 8050+
3261cfd5 8051+#define __vx_state(v) ((v) ? ((v)->vx_state) : 0)
d337f35e 8052+
3261cfd5 8053+#define vx_info_state(v, m) (__vx_state(v) & (m))
d337f35e
JR
8054+
8055+
3261cfd5 8056+#define __nx_state(n) ((n) ? ((n)->nx_state) : 0)
d337f35e 8057+
3261cfd5 8058+#define nx_info_state(n, m) (__nx_state(n) & (m))
d337f35e 8059+
3261cfd5
AM
8060+#endif
8061diff -NurpP --minimal linux-4.9.207/include/linux/vserver/cacct_cmd.h linux-4.9.207-vs2.3.9.11/include/linux/vserver/cacct_cmd.h
8062--- linux-4.9.207/include/linux/vserver/cacct_cmd.h 1970-01-01 00:00:00.000000000 +0000
8063+++ linux-4.9.207-vs2.3.9.11/include/linux/vserver/cacct_cmd.h 2018-10-20 04:58:14.000000000 +0000
8064@@ -0,0 +1,10 @@
8065+#ifndef _VSERVER_CACCT_CMD_H
8066+#define _VSERVER_CACCT_CMD_H
d337f35e
JR
8067+
8068+
3261cfd5
AM
8069+#include <linux/compiler.h>
8070+#include <uapi/vserver/cacct_cmd.h>
3bac966d 8071+
3261cfd5 8072+extern int vc_sock_stat(struct vx_info *, void __user *);
d337f35e 8073+
3261cfd5
AM
8074+#endif /* _VSERVER_CACCT_CMD_H */
8075diff -NurpP --minimal linux-4.9.207/include/linux/vserver/cacct_def.h linux-4.9.207-vs2.3.9.11/include/linux/vserver/cacct_def.h
8076--- linux-4.9.207/include/linux/vserver/cacct_def.h 1970-01-01 00:00:00.000000000 +0000
8077+++ linux-4.9.207-vs2.3.9.11/include/linux/vserver/cacct_def.h 2018-10-20 04:58:14.000000000 +0000
8078@@ -0,0 +1,43 @@
8079+#ifndef _VSERVER_CACCT_DEF_H
8080+#define _VSERVER_CACCT_DEF_H
d337f35e 8081+
3261cfd5
AM
8082+#include <asm/atomic.h>
8083+#include <linux/vserver/cacct.h>
d337f35e 8084+
d337f35e 8085+
3261cfd5
AM
8086+struct _vx_sock_acc {
8087+ atomic_long_t count;
8088+ atomic_long_t total;
d33d7b00
AM
8089+};
8090+
3261cfd5 8091+/* context sub struct */
3bac966d 8092+
3261cfd5
AM
8093+struct _vx_cacct {
8094+ struct _vx_sock_acc sock[VXA_SOCK_SIZE][3];
8095+ atomic_t slab[8];
8096+ atomic_t page[6][8];
8097+};
3bac966d 8098+
3261cfd5
AM
8099+#ifdef CONFIG_VSERVER_DEBUG
8100+
8101+static inline void __dump_vx_cacct(struct _vx_cacct *cacct)
d33d7b00 8102+{
3261cfd5 8103+ int i, j;
3bac966d 8104+
3261cfd5
AM
8105+ printk("\t_vx_cacct:");
8106+ for (i = 0; i < 6; i++) {
8107+ struct _vx_sock_acc *ptr = cacct->sock[i];
3bac966d 8108+
3261cfd5
AM
8109+ printk("\t [%d] =", i);
8110+ for (j = 0; j < 3; j++) {
8111+ printk(" [%d] = %8lu, %8lu", j,
8112+ atomic_long_read(&ptr[j].count),
8113+ atomic_long_read(&ptr[j].total));
8114+ }
8115+ printk("\n");
8116+ }
d33d7b00 8117+}
3bac966d 8118+
3261cfd5 8119+#endif
d337f35e 8120+
3261cfd5
AM
8121+#endif /* _VSERVER_CACCT_DEF_H */
8122diff -NurpP --minimal linux-4.9.207/include/linux/vserver/cacct.h linux-4.9.207-vs2.3.9.11/include/linux/vserver/cacct.h
8123--- linux-4.9.207/include/linux/vserver/cacct.h 1970-01-01 00:00:00.000000000 +0000
8124+++ linux-4.9.207-vs2.3.9.11/include/linux/vserver/cacct.h 2018-10-20 04:58:14.000000000 +0000
8125@@ -0,0 +1,15 @@
8126+#ifndef _VSERVER_CACCT_H
8127+#define _VSERVER_CACCT_H
d337f35e 8128+
3bac966d 8129+
3261cfd5
AM
8130+enum sock_acc_field {
8131+ VXA_SOCK_UNSPEC = 0,
8132+ VXA_SOCK_UNIX,
8133+ VXA_SOCK_INET,
8134+ VXA_SOCK_INET6,
8135+ VXA_SOCK_PACKET,
8136+ VXA_SOCK_OTHER,
8137+ VXA_SOCK_SIZE /* array size */
8138+};
2380c486 8139+
3261cfd5
AM
8140+#endif /* _VSERVER_CACCT_H */
8141diff -NurpP --minimal linux-4.9.207/include/linux/vserver/cacct_int.h linux-4.9.207-vs2.3.9.11/include/linux/vserver/cacct_int.h
8142--- linux-4.9.207/include/linux/vserver/cacct_int.h 1970-01-01 00:00:00.000000000 +0000
8143+++ linux-4.9.207-vs2.3.9.11/include/linux/vserver/cacct_int.h 2018-10-20 04:58:14.000000000 +0000
8144@@ -0,0 +1,17 @@
8145+#ifndef _VSERVER_CACCT_INT_H
8146+#define _VSERVER_CACCT_INT_H
d33d7b00
AM
8147+
8148+static inline
3261cfd5 8149+unsigned long vx_sock_count(struct _vx_cacct *cacct, int type, int pos)
d33d7b00 8150+{
3261cfd5 8151+ return atomic_long_read(&cacct->sock[type][pos].count);
d33d7b00 8152+}
2380c486 8153+
3261cfd5 8154+
369dbd59 8155+static inline
3261cfd5 8156+unsigned long vx_sock_total(struct _vx_cacct *cacct, int type, int pos)
369dbd59 8157+{
3261cfd5 8158+ return atomic_long_read(&cacct->sock[type][pos].total);
369dbd59
AM
8159+}
8160+
3261cfd5
AM
8161+#endif /* _VSERVER_CACCT_INT_H */
8162diff -NurpP --minimal linux-4.9.207/include/linux/vserver/check.h linux-4.9.207-vs2.3.9.11/include/linux/vserver/check.h
8163--- linux-4.9.207/include/linux/vserver/check.h 1970-01-01 00:00:00.000000000 +0000
8164+++ linux-4.9.207-vs2.3.9.11/include/linux/vserver/check.h 2018-10-20 04:58:14.000000000 +0000
8165@@ -0,0 +1,89 @@
8166+#ifndef _VSERVER_CHECK_H
8167+#define _VSERVER_CHECK_H
d337f35e 8168+
3bac966d 8169+
3261cfd5
AM
8170+#define MAX_S_CONTEXT 65535 /* Arbitrary limit */
8171+
8172+#ifdef CONFIG_VSERVER_DYNAMIC_IDS
8173+#define MIN_D_CONTEXT 49152 /* dynamic contexts start here */
d337f35e 8174+#else
3261cfd5 8175+#define MIN_D_CONTEXT 65536
d337f35e 8176+#endif
d337f35e 8177+
3261cfd5 8178+/* check conditions */
d337f35e 8179+
3261cfd5
AM
8180+#define VS_ADMIN 0x0001
8181+#define VS_WATCH 0x0002
8182+#define VS_HIDE 0x0004
8183+#define VS_HOSTID 0x0008
d337f35e 8184+
3261cfd5
AM
8185+#define VS_IDENT 0x0010
8186+#define VS_EQUIV 0x0020
8187+#define VS_PARENT 0x0040
8188+#define VS_CHILD 0x0080
d337f35e 8189+
3261cfd5 8190+#define VS_ARG_MASK 0x00F0
d337f35e 8191+
3261cfd5
AM
8192+#define VS_DYNAMIC 0x0100
8193+#define VS_STATIC 0x0200
d337f35e 8194+
3261cfd5 8195+#define VS_ATR_MASK 0x0F00
d337f35e 8196+
3261cfd5
AM
8197+#ifdef CONFIG_VSERVER_PRIVACY
8198+#define VS_ADMIN_P (0)
8199+#define VS_WATCH_P (0)
8200+#else
8201+#define VS_ADMIN_P VS_ADMIN
8202+#define VS_WATCH_P VS_WATCH
8203+#endif
d337f35e 8204+
3261cfd5
AM
8205+#define VS_HARDIRQ 0x1000
8206+#define VS_SOFTIRQ 0x2000
8207+#define VS_IRQ 0x4000
d337f35e 8208+
3261cfd5 8209+#define VS_IRQ_MASK 0xF000
d337f35e 8210+
3261cfd5 8211+#include <linux/hardirq.h>
d337f35e 8212+
3261cfd5
AM
8213+/*
8214+ * check current context for ADMIN/WATCH and
8215+ * optionally against supplied argument
8216+ */
8217+static inline int __vs_check(int cid, int id, unsigned int mode)
8218+{
8219+ if (mode & VS_ARG_MASK) {
8220+ if ((mode & VS_IDENT) && (id == cid))
8221+ return 1;
8222+ }
8223+ if (mode & VS_ATR_MASK) {
8224+ if ((mode & VS_DYNAMIC) &&
8225+ (id >= MIN_D_CONTEXT) &&
8226+ (id <= MAX_S_CONTEXT))
8227+ return 1;
8228+ if ((mode & VS_STATIC) &&
8229+ (id > 1) && (id < MIN_D_CONTEXT))
8230+ return 1;
8231+ }
8232+ if (mode & VS_IRQ_MASK) {
8233+ if ((mode & VS_IRQ) && unlikely(in_interrupt()))
8234+ return 1;
8235+ if ((mode & VS_HARDIRQ) && unlikely(in_irq()))
8236+ return 1;
8237+ if ((mode & VS_SOFTIRQ) && unlikely(in_softirq()))
8238+ return 1;
8239+ }
8240+ return (((mode & VS_ADMIN) && (cid == 0)) ||
8241+ ((mode & VS_WATCH) && (cid == 1)) ||
8242+ ((mode & VS_HOSTID) && (id == 0)));
8243+}
d337f35e 8244+
3261cfd5 8245+#define vx_check(c, m) __vs_check(vx_current_xid(), c, (m) | VS_IRQ)
d337f35e 8246+
3261cfd5 8247+#define vx_weak_check(c, m) ((m) ? vx_check(c, m) : 1)
d337f35e 8248+
d337f35e 8249+
3261cfd5 8250+#define nx_check(c, m) __vs_check(nx_current_nid(), c, m)
d337f35e 8251+
3261cfd5 8252+#define nx_weak_check(c, m) ((m) ? nx_check(c, m) : 1)
d337f35e 8253+
3261cfd5
AM
8254+#endif
8255diff -NurpP --minimal linux-4.9.207/include/linux/vserver/context_cmd.h linux-4.9.207-vs2.3.9.11/include/linux/vserver/context_cmd.h
8256--- linux-4.9.207/include/linux/vserver/context_cmd.h 1970-01-01 00:00:00.000000000 +0000
8257+++ linux-4.9.207-vs2.3.9.11/include/linux/vserver/context_cmd.h 2018-10-20 04:58:14.000000000 +0000
8258@@ -0,0 +1,33 @@
8259+#ifndef _VSERVER_CONTEXT_CMD_H
8260+#define _VSERVER_CONTEXT_CMD_H
d337f35e 8261+
3261cfd5 8262+#include <uapi/vserver/context_cmd.h>
d337f35e 8263+
3261cfd5 8264+extern int vc_task_xid(uint32_t);
d337f35e 8265+
3261cfd5 8266+extern int vc_vx_info(struct vx_info *, void __user *);
d337f35e 8267+
3261cfd5 8268+extern int vc_ctx_stat(struct vx_info *, void __user *);
d337f35e 8269+
3261cfd5
AM
8270+extern int vc_ctx_create(uint32_t, void __user *);
8271+extern int vc_ctx_migrate(struct vx_info *, void __user *);
d337f35e 8272+
3261cfd5
AM
8273+extern int vc_get_cflags(struct vx_info *, void __user *);
8274+extern int vc_set_cflags(struct vx_info *, void __user *);
d337f35e 8275+
3261cfd5
AM
8276+extern int vc_get_ccaps(struct vx_info *, void __user *);
8277+extern int vc_set_ccaps(struct vx_info *, void __user *);
d337f35e 8278+
3261cfd5
AM
8279+extern int vc_get_bcaps(struct vx_info *, void __user *);
8280+extern int vc_set_bcaps(struct vx_info *, void __user *);
d337f35e 8281+
3261cfd5
AM
8282+extern int vc_get_umask(struct vx_info *, void __user *);
8283+extern int vc_set_umask(struct vx_info *, void __user *);
d337f35e 8284+
3261cfd5
AM
8285+extern int vc_get_wmask(struct vx_info *, void __user *);
8286+extern int vc_set_wmask(struct vx_info *, void __user *);
d337f35e 8287+
3261cfd5
AM
8288+extern int vc_get_badness(struct vx_info *, void __user *);
8289+extern int vc_set_badness(struct vx_info *, void __user *);
d337f35e 8290+
3261cfd5
AM
8291+#endif /* _VSERVER_CONTEXT_CMD_H */
8292diff -NurpP --minimal linux-4.9.207/include/linux/vserver/context.h linux-4.9.207-vs2.3.9.11/include/linux/vserver/context.h
8293--- linux-4.9.207/include/linux/vserver/context.h 1970-01-01 00:00:00.000000000 +0000
8294+++ linux-4.9.207-vs2.3.9.11/include/linux/vserver/context.h 2018-10-20 04:58:14.000000000 +0000
8295@@ -0,0 +1,110 @@
8296+#ifndef _VSERVER_CONTEXT_H
8297+#define _VSERVER_CONTEXT_H
d337f35e 8298+
d337f35e 8299+
3261cfd5
AM
8300+#include <linux/list.h>
8301+#include <linux/spinlock.h>
8302+#include <linux/rcupdate.h>
8303+#include <uapi/vserver/context.h>
d337f35e 8304+
3261cfd5
AM
8305+#include "limit_def.h"
8306+#include "sched_def.h"
8307+#include "cvirt_def.h"
8308+#include "cacct_def.h"
8309+#include "device_def.h"
d337f35e 8310+
3261cfd5 8311+#define VX_SPACES 2
d337f35e 8312+
3261cfd5
AM
8313+struct _vx_info_pc {
8314+ struct _vx_sched_pc sched_pc;
8315+ struct _vx_cvirt_pc cvirt_pc;
8316+};
d337f35e 8317+
3261cfd5
AM
8318+struct _vx_space {
8319+ unsigned long vx_nsmask; /* assignment mask */
8320+ struct nsproxy *vx_nsproxy; /* private namespaces */
8321+ struct fs_struct *vx_fs; /* private namespace fs */
8322+ const struct cred *vx_cred; /* task credentials */
8323+};
d337f35e 8324+
3261cfd5
AM
8325+struct vx_info {
8326+ struct hlist_node vx_hlist; /* linked list of contexts */
8327+ vxid_t vx_id; /* context id */
8328+ atomic_t vx_usecnt; /* usage count */
8329+ atomic_t vx_tasks; /* tasks count */
8330+ struct vx_info *vx_parent; /* parent context */
8331+ int vx_state; /* context state */
d337f35e 8332+
3261cfd5 8333+ struct _vx_space space[VX_SPACES]; /* namespace store */
d337f35e 8334+
3261cfd5
AM
8335+ uint64_t vx_flags; /* context flags */
8336+ uint64_t vx_ccaps; /* context caps (vserver) */
8337+ uint64_t vx_umask; /* unshare mask (guest) */
8338+ uint64_t vx_wmask; /* warn mask (guest) */
8339+ kernel_cap_t vx_bcaps; /* bounding caps (system) */
d337f35e 8340+
3261cfd5
AM
8341+ struct task_struct *vx_reaper; /* guest reaper process */
8342+ pid_t vx_initpid; /* PID of guest init */
8343+ int64_t vx_badness_bias; /* OOM points bias */
d337f35e 8344+
3261cfd5
AM
8345+ struct _vx_limit limit; /* vserver limits */
8346+ struct _vx_sched sched; /* vserver scheduler */
8347+ struct _vx_cvirt cvirt; /* virtual/bias stuff */
8348+ struct _vx_cacct cacct; /* context accounting */
d337f35e 8349+
3261cfd5 8350+ struct _vx_device dmap; /* default device map targets */
d337f35e 8351+
3261cfd5
AM
8352+#ifndef CONFIG_SMP
8353+ struct _vx_info_pc info_pc; /* per cpu data */
8354+#else
8355+ struct _vx_info_pc *ptr_pc; /* per cpu array */
8356+#endif
d337f35e 8357+
3261cfd5
AM
8358+ wait_queue_head_t vx_wait; /* context exit waitqueue */
8359+ int reboot_cmd; /* last sys_reboot() cmd */
8360+ int exit_code; /* last process exit code */
d337f35e 8361+
3261cfd5
AM
8362+ char vx_name[65]; /* vserver name */
8363+};
d337f35e 8364+
3261cfd5
AM
8365+#ifndef CONFIG_SMP
8366+#define vx_ptr_pc(vxi) (&(vxi)->info_pc)
8367+#define vx_per_cpu(vxi, v, id) vx_ptr_pc(vxi)->v
8368+#else
8369+#define vx_ptr_pc(vxi) ((vxi)->ptr_pc)
8370+#define vx_per_cpu(vxi, v, id) per_cpu_ptr(vx_ptr_pc(vxi), id)->v
8371+#endif
d337f35e 8372+
3261cfd5 8373+#define vx_cpu(vxi, v) vx_per_cpu(vxi, v, smp_processor_id())
d337f35e 8374+
d337f35e 8375+
3261cfd5
AM
8376+struct vx_info_save {
8377+ struct vx_info *vxi;
8378+ vxid_t xid;
8379+};
d337f35e 8380+
d337f35e 8381+
3261cfd5 8382+/* status flags */
d337f35e 8383+
3261cfd5
AM
8384+#define VXS_HASHED 0x0001
8385+#define VXS_PAUSED 0x0010
8386+#define VXS_SHUTDOWN 0x0100
8387+#define VXS_HELPER 0x1000
8388+#define VXS_RELEASED 0x8000
7e46296a 8389+
2380c486 8390+
3261cfd5
AM
8391+extern void claim_vx_info(struct vx_info *, struct task_struct *);
8392+extern void release_vx_info(struct vx_info *, struct task_struct *);
2380c486 8393+
3261cfd5
AM
8394+extern struct vx_info *lookup_vx_info(int);
8395+extern struct vx_info *lookup_or_create_vx_info(int);
2380c486 8396+
3261cfd5
AM
8397+extern int get_xid_list(int, unsigned int *, int);
8398+extern int xid_is_hashed(vxid_t);
2380c486 8399+
3261cfd5 8400+extern int vx_migrate_task(struct task_struct *, struct vx_info *, int);
d337f35e 8401+
3261cfd5 8402+extern long vs_state_change(struct vx_info *, unsigned int);
d337f35e 8403+
d337f35e 8404+
3261cfd5
AM
8405+#endif /* _VSERVER_CONTEXT_H */
8406diff -NurpP --minimal linux-4.9.207/include/linux/vserver/cvirt_cmd.h linux-4.9.207-vs2.3.9.11/include/linux/vserver/cvirt_cmd.h
8407--- linux-4.9.207/include/linux/vserver/cvirt_cmd.h 1970-01-01 00:00:00.000000000 +0000
8408+++ linux-4.9.207-vs2.3.9.11/include/linux/vserver/cvirt_cmd.h 2018-10-20 04:58:14.000000000 +0000
8409@@ -0,0 +1,13 @@
8410+#ifndef _VSERVER_CVIRT_CMD_H
8411+#define _VSERVER_CVIRT_CMD_H
d337f35e
JR
8412+
8413+
3261cfd5
AM
8414+#include <linux/compiler.h>
8415+#include <uapi/vserver/cvirt_cmd.h>
d337f35e 8416+
3261cfd5
AM
8417+extern int vc_set_vhi_name(struct vx_info *, void __user *);
8418+extern int vc_get_vhi_name(struct vx_info *, void __user *);
d337f35e 8419+
3261cfd5 8420+extern int vc_virt_stat(struct vx_info *, void __user *);
d337f35e 8421+
3261cfd5
AM
8422+#endif /* _VSERVER_CVIRT_CMD_H */
8423diff -NurpP --minimal linux-4.9.207/include/linux/vserver/cvirt_def.h linux-4.9.207-vs2.3.9.11/include/linux/vserver/cvirt_def.h
8424--- linux-4.9.207/include/linux/vserver/cvirt_def.h 1970-01-01 00:00:00.000000000 +0000
8425+++ linux-4.9.207-vs2.3.9.11/include/linux/vserver/cvirt_def.h 2018-10-20 04:58:14.000000000 +0000
8426@@ -0,0 +1,80 @@
8427+#ifndef _VSERVER_CVIRT_DEF_H
8428+#define _VSERVER_CVIRT_DEF_H
d337f35e 8429+
3261cfd5
AM
8430+#include <linux/jiffies.h>
8431+#include <linux/spinlock.h>
8432+#include <linux/wait.h>
8433+#include <linux/time.h>
8434+#include <asm/atomic.h>
d337f35e 8435+
d337f35e 8436+
3261cfd5
AM
8437+struct _vx_usage_stat {
8438+ uint64_t user;
8439+ uint64_t nice;
8440+ uint64_t system;
8441+ uint64_t softirq;
8442+ uint64_t irq;
8443+ uint64_t idle;
8444+ uint64_t iowait;
8445+};
d337f35e 8446+
3261cfd5
AM
8447+struct _vx_syslog {
8448+ wait_queue_head_t log_wait;
8449+ spinlock_t logbuf_lock; /* lock for the log buffer */
d337f35e 8450+
3261cfd5
AM
8451+ unsigned long log_start; /* next char to be read by syslog() */
8452+ unsigned long con_start; /* next char to be sent to consoles */
8453+ unsigned long log_end; /* most-recently-written-char + 1 */
8454+ unsigned long logged_chars; /* #chars since last read+clear operation */
d337f35e 8455+
3261cfd5
AM
8456+ char log_buf[1024];
8457+};
d337f35e
JR
8458+
8459+
3261cfd5 8460+/* context sub struct */
d337f35e 8461+
3261cfd5
AM
8462+struct _vx_cvirt {
8463+ atomic_t nr_threads; /* number of current threads */
8464+ atomic_t nr_running; /* number of running threads */
8465+ atomic_t nr_uninterruptible; /* number of uninterruptible threads */
d337f35e 8466+
3261cfd5
AM
8467+ atomic_t nr_onhold; /* processes on hold */
8468+ uint32_t onhold_last; /* jiffies when put on hold */
d337f35e 8469+
3261cfd5
AM
8470+ struct timespec64 bias_ts; /* time offset to the host */
8471+ struct timespec64 bias_idle;
8472+ struct timespec64 bias_uptime; /* context creation point */
8473+ uint64_t bias_clock; /* offset in clock_t */
d337f35e 8474+
3261cfd5
AM
8475+ spinlock_t load_lock; /* lock for the load averages */
8476+ atomic_t load_updates; /* nr of load updates done so far */
8477+ uint32_t load_last; /* last time load was calculated */
8478+ uint32_t load[3]; /* load averages 1,5,15 */
d337f35e 8479+
3261cfd5 8480+ atomic_t total_forks; /* number of forks so far */
d337f35e 8481+
3261cfd5
AM
8482+ struct _vx_syslog syslog;
8483+};
d337f35e 8484+
3261cfd5
AM
8485+struct _vx_cvirt_pc {
8486+ struct _vx_usage_stat cpustat;
8487+};
d337f35e
JR
8488+
8489+
3261cfd5 8490+#ifdef CONFIG_VSERVER_DEBUG
d337f35e 8491+
3261cfd5 8492+static inline void __dump_vx_cvirt(struct _vx_cvirt *cvirt)
d33d7b00 8493+{
3261cfd5
AM
8494+ printk("\t_vx_cvirt:\n");
8495+ printk("\t threads: %4d, %4d, %4d, %4d\n",
8496+ atomic_read(&cvirt->nr_threads),
8497+ atomic_read(&cvirt->nr_running),
8498+ atomic_read(&cvirt->nr_uninterruptible),
8499+ atomic_read(&cvirt->nr_onhold));
8500+ /* add rest here */
8501+ printk("\t total_forks = %d\n", atomic_read(&cvirt->total_forks));
d33d7b00 8502+}
d337f35e 8503+
3261cfd5 8504+#endif
d337f35e 8505+
3261cfd5
AM
8506+#endif /* _VSERVER_CVIRT_DEF_H */
8507diff -NurpP --minimal linux-4.9.207/include/linux/vserver/cvirt.h linux-4.9.207-vs2.3.9.11/include/linux/vserver/cvirt.h
8508--- linux-4.9.207/include/linux/vserver/cvirt.h 1970-01-01 00:00:00.000000000 +0000
8509+++ linux-4.9.207-vs2.3.9.11/include/linux/vserver/cvirt.h 2019-10-13 16:04:08.203030205 +0000
8510@@ -0,0 +1,11 @@
8511+#ifndef _VSERVER_CVIRT_H
8512+#define _VSERVER_CVIRT_H
d337f35e 8513+
3261cfd5 8514+struct vx_info;
d337f35e 8515+
3261cfd5 8516+void vx_update_load(struct vx_info *);
ab30d09f 8517+
d337f35e 8518+
3261cfd5 8519+int vx_do_syslog(int, char __user *, int);
d337f35e 8520+
3261cfd5
AM
8521+#endif /* _VSERVER_CVIRT_H */
8522diff -NurpP --minimal linux-4.9.207/include/linux/vserver/debug_cmd.h linux-4.9.207-vs2.3.9.11/include/linux/vserver/debug_cmd.h
8523--- linux-4.9.207/include/linux/vserver/debug_cmd.h 1970-01-01 00:00:00.000000000 +0000
8524+++ linux-4.9.207-vs2.3.9.11/include/linux/vserver/debug_cmd.h 2018-10-20 04:58:14.000000000 +0000
8525@@ -0,0 +1,37 @@
8526+#ifndef _VSERVER_DEBUG_CMD_H
8527+#define _VSERVER_DEBUG_CMD_H
d337f35e 8528+
3261cfd5 8529+#include <uapi/vserver/debug_cmd.h>
d337f35e
JR
8530+
8531+
3261cfd5 8532+#ifdef CONFIG_COMPAT
d337f35e 8533+
3261cfd5 8534+#include <asm/compat.h>
d337f35e 8535+
3261cfd5
AM
8536+struct vcmd_read_history_v0_x32 {
8537+ uint32_t index;
8538+ uint32_t count;
8539+ compat_uptr_t data_ptr;
8540+};
adc1caaa 8541+
3261cfd5
AM
8542+struct vcmd_read_monitor_v0_x32 {
8543+ uint32_t index;
8544+ uint32_t count;
8545+ compat_uptr_t data_ptr;
8546+};
d337f35e 8547+
3261cfd5 8548+#endif /* CONFIG_COMPAT */
d337f35e 8549+
3261cfd5 8550+extern int vc_dump_history(uint32_t);
d337f35e 8551+
3261cfd5
AM
8552+extern int vc_read_history(uint32_t, void __user *);
8553+extern int vc_read_monitor(uint32_t, void __user *);
d337f35e 8554+
3261cfd5 8555+#ifdef CONFIG_COMPAT
d337f35e 8556+
3261cfd5
AM
8557+extern int vc_read_history_x32(uint32_t, void __user *);
8558+extern int vc_read_monitor_x32(uint32_t, void __user *);
d337f35e 8559+
3261cfd5 8560+#endif /* CONFIG_COMPAT */
d337f35e 8561+
3261cfd5
AM
8562+#endif /* _VSERVER_DEBUG_CMD_H */
8563diff -NurpP --minimal linux-4.9.207/include/linux/vserver/debug.h linux-4.9.207-vs2.3.9.11/include/linux/vserver/debug.h
8564--- linux-4.9.207/include/linux/vserver/debug.h 1970-01-01 00:00:00.000000000 +0000
8565+++ linux-4.9.207-vs2.3.9.11/include/linux/vserver/debug.h 2018-10-20 04:58:14.000000000 +0000
8566@@ -0,0 +1,146 @@
8567+#ifndef _VSERVER_DEBUG_H
8568+#define _VSERVER_DEBUG_H
d337f35e
JR
8569+
8570+
3261cfd5
AM
8571+#define VXD_CBIT(n, m) (vs_debug_ ## n & (1 << (m)))
8572+#define VXD_CMIN(n, m) (vs_debug_ ## n > (m))
8573+#define VXD_MASK(n, m) (vs_debug_ ## n & (m))
d337f35e 8574+
3261cfd5
AM
8575+#define VXD_DEV(d) (d), (d)->bd_inode->i_ino, \
8576+ imajor((d)->bd_inode), iminor((d)->bd_inode)
8577+#define VXF_DEV "%p[%lu,%d:%d]"
d337f35e 8578+
3261cfd5
AM
8579+#if defined(CONFIG_QUOTES_UTF8)
8580+#define VS_Q_LQM "\xc2\xbb"
8581+#define VS_Q_RQM "\xc2\xab"
8582+#elif defined(CONFIG_QUOTES_ASCII)
8583+#define VS_Q_LQM "\x27"
8584+#define VS_Q_RQM "\x27"
d33d7b00 8585+#else
3261cfd5
AM
8586+#define VS_Q_LQM "\xbb"
8587+#define VS_Q_RQM "\xab"
d33d7b00 8588+#endif
d337f35e 8589+
3261cfd5 8590+#define VS_Q(f) VS_Q_LQM f VS_Q_RQM
d337f35e
JR
8591+
8592+
3261cfd5
AM
8593+#define vxd_path(p) \
8594+ ({ static char _buffer[PATH_MAX]; \
8595+ d_path(p, _buffer, sizeof(_buffer)); })
d337f35e 8596+
3261cfd5
AM
8597+#define vxd_cond_path(n) \
8598+ ((n) ? vxd_path(&(n)->path) : "<null>" )
d337f35e
JR
8599+
8600+
3261cfd5 8601+#ifdef CONFIG_VSERVER_DEBUG
d337f35e 8602+
3261cfd5
AM
8603+extern unsigned int vs_debug_switch;
8604+extern unsigned int vs_debug_xid;
8605+extern unsigned int vs_debug_nid;
8606+extern unsigned int vs_debug_tag;
8607+extern unsigned int vs_debug_net;
8608+extern unsigned int vs_debug_limit;
8609+extern unsigned int vs_debug_cres;
8610+extern unsigned int vs_debug_dlim;
8611+extern unsigned int vs_debug_quota;
8612+extern unsigned int vs_debug_cvirt;
8613+extern unsigned int vs_debug_space;
8614+extern unsigned int vs_debug_perm;
8615+extern unsigned int vs_debug_misc;
d337f35e 8616+
d337f35e 8617+
3261cfd5
AM
8618+#define VX_LOGLEVEL "vxD: "
8619+#define VX_PROC_FMT "%p: "
8620+#define VX_PROCESS current
d337f35e 8621+
3261cfd5
AM
8622+#define vxdprintk(c, f, x...) \
8623+ do { \
8624+ if (c) \
8625+ printk(VX_LOGLEVEL VX_PROC_FMT f "\n", \
8626+ VX_PROCESS , ##x); \
8627+ } while (0)
d337f35e 8628+
3261cfd5
AM
8629+#define vxlprintk(c, f, x...) \
8630+ do { \
8631+ if (c) \
8632+ printk(VX_LOGLEVEL f " @%s:%d\n", x); \
8633+ } while (0)
d337f35e 8634+
3261cfd5
AM
8635+#define vxfprintk(c, f, x...) \
8636+ do { \
8637+ if (c) \
8638+ printk(VX_LOGLEVEL f " %s@%s:%d\n", x); \
8639+ } while (0)
d337f35e 8640+
d337f35e 8641+
3261cfd5 8642+struct vx_info;
d337f35e 8643+
3261cfd5
AM
8644+void dump_vx_info(struct vx_info *, int);
8645+void dump_vx_info_inactive(int);
d337f35e 8646+
3261cfd5 8647+#else /* CONFIG_VSERVER_DEBUG */
d337f35e 8648+
3261cfd5
AM
8649+#define vs_debug_switch 0
8650+#define vs_debug_xid 0
8651+#define vs_debug_nid 0
8652+#define vs_debug_tag 0
8653+#define vs_debug_net 0
8654+#define vs_debug_limit 0
8655+#define vs_debug_cres 0
8656+#define vs_debug_dlim 0
8657+#define vs_debug_quota 0
8658+#define vs_debug_cvirt 0
8659+#define vs_debug_space 0
8660+#define vs_debug_perm 0
8661+#define vs_debug_misc 0
d337f35e 8662+
3261cfd5
AM
8663+#define vxdprintk(x...) do { } while (0)
8664+#define vxlprintk(x...) do { } while (0)
8665+#define vxfprintk(x...) do { } while (0)
d337f35e 8666+
3261cfd5 8667+#endif /* CONFIG_VSERVER_DEBUG */
d337f35e 8668+
d337f35e 8669+
3261cfd5 8670+#ifdef CONFIG_VSERVER_WARN
d337f35e 8671+
3261cfd5
AM
8672+#define VX_WARNLEVEL KERN_WARNING "vxW: "
8673+#define VX_WARN_TASK "[" VS_Q("%s") ",%u:#%u|%u|%u] "
8674+#define VX_WARN_XID "[xid #%u] "
8675+#define VX_WARN_NID "[nid #%u] "
8676+#define VX_WARN_TAG "[tag #%u] "
d337f35e 8677+
3261cfd5
AM
8678+#define vxwprintk(c, f, x...) \
8679+ do { \
8680+ if (c) \
8681+ printk(VX_WARNLEVEL f "\n", ##x); \
8682+ } while (0)
d337f35e 8683+
3261cfd5 8684+#else /* CONFIG_VSERVER_WARN */
d337f35e 8685+
3261cfd5 8686+#define vxwprintk(x...) do { } while (0)
d337f35e 8687+
3261cfd5 8688+#endif /* CONFIG_VSERVER_WARN */
d337f35e 8689+
3261cfd5
AM
8690+#define vxwprintk_task(c, f, x...) \
8691+ vxwprintk(c, VX_WARN_TASK f, \
8692+ current->comm, current->pid, \
8693+ current->xid, current->nid, \
8694+ current->tag, ##x)
8695+#define vxwprintk_xid(c, f, x...) \
8696+ vxwprintk(c, VX_WARN_XID f, current->xid, x)
8697+#define vxwprintk_nid(c, f, x...) \
8698+ vxwprintk(c, VX_WARN_NID f, current->nid, x)
8699+#define vxwprintk_tag(c, f, x...) \
8700+ vxwprintk(c, VX_WARN_TAG f, current->tag, x)
d337f35e 8701+
3261cfd5
AM
8702+#ifdef CONFIG_VSERVER_DEBUG
8703+#define vxd_assert_lock(l) assert_spin_locked(l)
8704+#define vxd_assert(c, f, x...) vxlprintk(!(c), \
8705+ "assertion [" f "] failed.", ##x, __FILE__, __LINE__)
8706+#else
8707+#define vxd_assert_lock(l) do { } while (0)
8708+#define vxd_assert(c, f, x...) do { } while (0)
8709+#endif
d337f35e 8710+
d337f35e 8711+
3261cfd5
AM
8712+#endif /* _VSERVER_DEBUG_H */
8713diff -NurpP --minimal linux-4.9.207/include/linux/vserver/device_cmd.h linux-4.9.207-vs2.3.9.11/include/linux/vserver/device_cmd.h
8714--- linux-4.9.207/include/linux/vserver/device_cmd.h 1970-01-01 00:00:00.000000000 +0000
8715+++ linux-4.9.207-vs2.3.9.11/include/linux/vserver/device_cmd.h 2018-10-20 04:58:14.000000000 +0000
8716@@ -0,0 +1,31 @@
8717+#ifndef _VSERVER_DEVICE_CMD_H
8718+#define _VSERVER_DEVICE_CMD_H
d337f35e 8719+
3261cfd5 8720+#include <uapi/vserver/device_cmd.h>
d337f35e 8721+
d337f35e 8722+
3261cfd5 8723+#ifdef CONFIG_COMPAT
d337f35e 8724+
3261cfd5 8725+#include <asm/compat.h>
d337f35e 8726+
3261cfd5
AM
8727+struct vcmd_set_mapping_v0_x32 {
8728+ compat_uptr_t device_ptr;
8729+ compat_uptr_t target_ptr;
8730+ uint32_t flags;
8731+};
d337f35e 8732+
3261cfd5 8733+#endif /* CONFIG_COMPAT */
d337f35e 8734+
3261cfd5 8735+#include <linux/compiler.h>
d337f35e 8736+
3261cfd5
AM
8737+extern int vc_set_mapping(struct vx_info *, void __user *);
8738+extern int vc_unset_mapping(struct vx_info *, void __user *);
d337f35e 8739+
3261cfd5 8740+#ifdef CONFIG_COMPAT
d337f35e 8741+
3261cfd5
AM
8742+extern int vc_set_mapping_x32(struct vx_info *, void __user *);
8743+extern int vc_unset_mapping_x32(struct vx_info *, void __user *);
d337f35e 8744+
3261cfd5 8745+#endif /* CONFIG_COMPAT */
d337f35e 8746+
3261cfd5
AM
8747+#endif /* _VSERVER_DEVICE_CMD_H */
8748diff -NurpP --minimal linux-4.9.207/include/linux/vserver/device_def.h linux-4.9.207-vs2.3.9.11/include/linux/vserver/device_def.h
8749--- linux-4.9.207/include/linux/vserver/device_def.h 1970-01-01 00:00:00.000000000 +0000
8750+++ linux-4.9.207-vs2.3.9.11/include/linux/vserver/device_def.h 2018-10-20 04:58:14.000000000 +0000
8751@@ -0,0 +1,17 @@
8752+#ifndef _VSERVER_DEVICE_DEF_H
8753+#define _VSERVER_DEVICE_DEF_H
d337f35e 8754+
3261cfd5 8755+#include <linux/types.h>
d337f35e 8756+
3261cfd5
AM
8757+struct vx_dmap_target {
8758+ dev_t target;
8759+ uint32_t flags;
3bac966d 8760+};
d337f35e 8761+
3261cfd5
AM
8762+struct _vx_device {
8763+#ifdef CONFIG_VSERVER_DEVICE
8764+ struct vx_dmap_target targets[2];
8765+#endif
8766+};
d337f35e 8767+
3261cfd5
AM
8768+#endif /* _VSERVER_DEVICE_DEF_H */
8769diff -NurpP --minimal linux-4.9.207/include/linux/vserver/device.h linux-4.9.207-vs2.3.9.11/include/linux/vserver/device.h
8770--- linux-4.9.207/include/linux/vserver/device.h 1970-01-01 00:00:00.000000000 +0000
8771+++ linux-4.9.207-vs2.3.9.11/include/linux/vserver/device.h 2018-10-20 04:58:14.000000000 +0000
8772@@ -0,0 +1,9 @@
8773+#ifndef _VSERVER_DEVICE_H
8774+#define _VSERVER_DEVICE_H
d337f35e 8775+
d337f35e 8776+
3261cfd5 8777+#include <uapi/vserver/device.h>
d337f35e 8778+
3261cfd5
AM
8779+#else /* _VSERVER_DEVICE_H */
8780+#warning duplicate inclusion
8781+#endif /* _VSERVER_DEVICE_H */
8782diff -NurpP --minimal linux-4.9.207/include/linux/vserver/dlimit_cmd.h linux-4.9.207-vs2.3.9.11/include/linux/vserver/dlimit_cmd.h
8783--- linux-4.9.207/include/linux/vserver/dlimit_cmd.h 1970-01-01 00:00:00.000000000 +0000
8784+++ linux-4.9.207-vs2.3.9.11/include/linux/vserver/dlimit_cmd.h 2018-10-20 04:58:14.000000000 +0000
8785@@ -0,0 +1,46 @@
8786+#ifndef _VSERVER_DLIMIT_CMD_H
8787+#define _VSERVER_DLIMIT_CMD_H
ba86f833 8788+
3261cfd5 8789+#include <uapi/vserver/dlimit_cmd.h>
ba86f833 8790+
d337f35e 8791+
3261cfd5 8792+#ifdef CONFIG_COMPAT
d337f35e 8793+
3261cfd5 8794+#include <asm/compat.h>
d337f35e 8795+
3261cfd5
AM
8796+struct vcmd_ctx_dlimit_base_v0_x32 {
8797+ compat_uptr_t name_ptr;
8798+ uint32_t flags;
8799+};
d337f35e 8800+
3261cfd5
AM
8801+struct vcmd_ctx_dlimit_v0_x32 {
8802+ compat_uptr_t name_ptr;
8803+ uint32_t space_used; /* used space in kbytes */
8804+ uint32_t space_total; /* maximum space in kbytes */
8805+ uint32_t inodes_used; /* used inodes */
8806+ uint32_t inodes_total; /* maximum inodes */
8807+ uint32_t reserved; /* reserved for root in % */
8808+ uint32_t flags;
8809+};
d337f35e 8810+
3261cfd5 8811+#endif /* CONFIG_COMPAT */
d337f35e 8812+
3261cfd5 8813+#include <linux/compiler.h>
d337f35e 8814+
3261cfd5
AM
8815+extern int vc_add_dlimit(uint32_t, void __user *);
8816+extern int vc_rem_dlimit(uint32_t, void __user *);
d337f35e 8817+
3261cfd5
AM
8818+extern int vc_set_dlimit(uint32_t, void __user *);
8819+extern int vc_get_dlimit(uint32_t, void __user *);
d337f35e 8820+
3261cfd5 8821+#ifdef CONFIG_COMPAT
d337f35e 8822+
3261cfd5
AM
8823+extern int vc_add_dlimit_x32(uint32_t, void __user *);
8824+extern int vc_rem_dlimit_x32(uint32_t, void __user *);
d337f35e 8825+
3261cfd5
AM
8826+extern int vc_set_dlimit_x32(uint32_t, void __user *);
8827+extern int vc_get_dlimit_x32(uint32_t, void __user *);
d337f35e 8828+
3261cfd5 8829+#endif /* CONFIG_COMPAT */
d337f35e 8830+
3261cfd5
AM
8831+#endif /* _VSERVER_DLIMIT_CMD_H */
8832diff -NurpP --minimal linux-4.9.207/include/linux/vserver/dlimit.h linux-4.9.207-vs2.3.9.11/include/linux/vserver/dlimit.h
8833--- linux-4.9.207/include/linux/vserver/dlimit.h 1970-01-01 00:00:00.000000000 +0000
8834+++ linux-4.9.207-vs2.3.9.11/include/linux/vserver/dlimit.h 2018-10-20 04:58:14.000000000 +0000
8835@@ -0,0 +1,54 @@
8836+#ifndef _VSERVER_DLIMIT_H
8837+#define _VSERVER_DLIMIT_H
d337f35e 8838+
3261cfd5 8839+#include "switch.h"
d337f35e
JR
8840+
8841+
3261cfd5 8842+#ifdef __KERNEL__
d337f35e 8843+
3261cfd5 8844+/* keep in sync with CDLIM_INFINITY */
d337f35e 8845+
3261cfd5 8846+#define DLIM_INFINITY (~0ULL)
d337f35e 8847+
3261cfd5
AM
8848+#include <linux/spinlock.h>
8849+#include <linux/rcupdate.h>
d337f35e 8850+
3261cfd5 8851+struct super_block;
d337f35e 8852+
3261cfd5
AM
8853+struct dl_info {
8854+ struct hlist_node dl_hlist; /* linked list of contexts */
8855+ struct rcu_head dl_rcu; /* the rcu head */
8856+ vtag_t dl_tag; /* context tag */
8857+ atomic_t dl_usecnt; /* usage count */
8858+ atomic_t dl_refcnt; /* reference count */
d337f35e 8859+
3261cfd5 8860+ struct super_block *dl_sb; /* associated superblock */
d337f35e 8861+
3261cfd5 8862+ spinlock_t dl_lock; /* protect the values */
2380c486 8863+
3261cfd5
AM
8864+ unsigned long long dl_space_used; /* used space in bytes */
8865+ unsigned long long dl_space_total; /* maximum space in bytes */
8866+ unsigned long dl_inodes_used; /* used inodes */
8867+ unsigned long dl_inodes_total; /* maximum inodes */
d337f35e 8868+
3261cfd5
AM
8869+ unsigned int dl_nrlmult; /* non root limit mult */
8870+};
d337f35e 8871+
3261cfd5 8872+struct rcu_head;
d337f35e 8873+
3261cfd5
AM
8874+extern void rcu_free_dl_info(struct rcu_head *);
8875+extern void unhash_dl_info(struct dl_info *);
d337f35e 8876+
3261cfd5 8877+extern struct dl_info *locate_dl_info(struct super_block *, vtag_t);
d337f35e 8878+
d337f35e 8879+
3261cfd5 8880+struct kstatfs;
d337f35e 8881+
3261cfd5 8882+extern void vx_vsi_statfs(struct super_block *, struct kstatfs *);
d337f35e 8883+
3261cfd5 8884+typedef uint64_t dlsize_t;
d337f35e 8885+
3261cfd5
AM
8886+#endif /* __KERNEL__ */
8887+#else /* _VSERVER_DLIMIT_H */
8888+#warning duplicate inclusion
8889+#endif /* _VSERVER_DLIMIT_H */
8890diff -NurpP --minimal linux-4.9.207/include/linux/vserver/global.h linux-4.9.207-vs2.3.9.11/include/linux/vserver/global.h
8891--- linux-4.9.207/include/linux/vserver/global.h 1970-01-01 00:00:00.000000000 +0000
8892+++ linux-4.9.207-vs2.3.9.11/include/linux/vserver/global.h 2018-10-20 04:58:14.000000000 +0000
8893@@ -0,0 +1,20 @@
8894+#ifndef _VSERVER_GLOBAL_H
8895+#define _VSERVER_GLOBAL_H
d337f35e 8896+
d337f35e 8897+
3261cfd5
AM
8898+extern atomic_t vx_global_ctotal;
8899+extern atomic_t vx_global_cactive;
d337f35e 8900+
3261cfd5
AM
8901+extern atomic_t nx_global_ctotal;
8902+extern atomic_t nx_global_cactive;
d337f35e 8903+
3261cfd5
AM
8904+extern atomic_t vs_global_nsproxy;
8905+extern atomic_t vs_global_fs;
8906+extern atomic_t vs_global_mnt_ns;
8907+extern atomic_t vs_global_uts_ns;
8908+extern atomic_t vs_global_ipc_ns;
8909+extern atomic_t vs_global_user_ns;
8910+extern atomic_t vs_global_pid_ns;
d337f35e 8911+
d337f35e 8912+
3261cfd5
AM
8913+#endif /* _VSERVER_GLOBAL_H */
8914diff -NurpP --minimal linux-4.9.207/include/linux/vserver/history.h linux-4.9.207-vs2.3.9.11/include/linux/vserver/history.h
8915--- linux-4.9.207/include/linux/vserver/history.h 1970-01-01 00:00:00.000000000 +0000
8916+++ linux-4.9.207-vs2.3.9.11/include/linux/vserver/history.h 2018-10-20 04:58:14.000000000 +0000
8917@@ -0,0 +1,197 @@
8918+#ifndef _VSERVER_HISTORY_H
8919+#define _VSERVER_HISTORY_H
d337f35e
JR
8920+
8921+
3261cfd5
AM
8922+enum {
8923+ VXH_UNUSED = 0,
8924+ VXH_THROW_OOPS = 1,
d337f35e 8925+
3261cfd5
AM
8926+ VXH_GET_VX_INFO,
8927+ VXH_PUT_VX_INFO,
8928+ VXH_INIT_VX_INFO,
8929+ VXH_SET_VX_INFO,
8930+ VXH_CLR_VX_INFO,
8931+ VXH_CLAIM_VX_INFO,
8932+ VXH_RELEASE_VX_INFO,
8933+ VXH_ALLOC_VX_INFO,
8934+ VXH_DEALLOC_VX_INFO,
8935+ VXH_HASH_VX_INFO,
8936+ VXH_UNHASH_VX_INFO,
8937+ VXH_LOC_VX_INFO,
8938+ VXH_LOOKUP_VX_INFO,
8939+ VXH_CREATE_VX_INFO,
8940+};
d337f35e 8941+
3261cfd5
AM
8942+struct _vxhe_vxi {
8943+ struct vx_info *ptr;
8944+ unsigned xid;
8945+ unsigned usecnt;
8946+ unsigned tasks;
8947+};
d337f35e 8948+
3261cfd5
AM
8949+struct _vxhe_set_clr {
8950+ void *data;
8951+};
d337f35e 8952+
3261cfd5
AM
8953+struct _vxhe_loc_lookup {
8954+ unsigned arg;
8955+};
adc1caaa 8956+
3261cfd5
AM
8957+struct _vx_hist_entry {
8958+ void *loc;
8959+ unsigned short seq;
8960+ unsigned short type;
8961+ struct _vxhe_vxi vxi;
8962+ union {
8963+ struct _vxhe_set_clr sc;
8964+ struct _vxhe_loc_lookup ll;
8965+ };
8966+};
2380c486 8967+
3261cfd5 8968+#ifdef CONFIG_VSERVER_HISTORY
d337f35e 8969+
3261cfd5 8970+extern unsigned volatile int vxh_active;
d337f35e 8971+
3261cfd5 8972+struct _vx_hist_entry *vxh_advance(void *loc);
2380c486 8973+
2380c486 8974+
3261cfd5
AM
8975+static inline
8976+void __vxh_copy_vxi(struct _vx_hist_entry *entry, struct vx_info *vxi)
8977+{
8978+ entry->vxi.ptr = vxi;
8979+ if (vxi) {
8980+ entry->vxi.usecnt = atomic_read(&vxi->vx_usecnt);
8981+ entry->vxi.tasks = atomic_read(&vxi->vx_tasks);
8982+ entry->vxi.xid = vxi->vx_id;
8983+ }
8984+}
d337f35e 8985+
d337f35e 8986+
3261cfd5 8987+#define __HERE__ current_text_addr()
d33d7b00 8988+
3261cfd5
AM
8989+#define __VXH_BODY(__type, __data, __here) \
8990+ struct _vx_hist_entry *entry; \
8991+ \
8992+ preempt_disable(); \
8993+ entry = vxh_advance(__here); \
8994+ __data; \
8995+ entry->type = __type; \
8996+ preempt_enable();
d337f35e
JR
8997+
8998+
3261cfd5 8999+ /* pass vxi only */
d337f35e 9000+
3261cfd5
AM
9001+#define __VXH_SMPL \
9002+ __vxh_copy_vxi(entry, vxi)
763640ca 9003+
3261cfd5
AM
9004+static inline
9005+void __vxh_smpl(struct vx_info *vxi, int __type, void *__here)
9006+{
9007+ __VXH_BODY(__type, __VXH_SMPL, __here)
9008+}
d337f35e 9009+
3261cfd5 9010+ /* pass vxi and data (void *) */
c2e5f7c8 9011+
3261cfd5
AM
9012+#define __VXH_DATA \
9013+ __vxh_copy_vxi(entry, vxi); \
9014+ entry->sc.data = data
d337f35e 9015+
3261cfd5
AM
9016+static inline
9017+void __vxh_data(struct vx_info *vxi, void *data,
9018+ int __type, void *__here)
9019+{
9020+ __VXH_BODY(__type, __VXH_DATA, __here)
9021+}
d337f35e 9022+
3261cfd5 9023+ /* pass vxi and arg (long) */
d337f35e 9024+
3261cfd5
AM
9025+#define __VXH_LONG \
9026+ __vxh_copy_vxi(entry, vxi); \
9027+ entry->ll.arg = arg
d337f35e 9028+
3261cfd5
AM
9029+static inline
9030+void __vxh_long(struct vx_info *vxi, long arg,
9031+ int __type, void *__here)
9032+{
9033+ __VXH_BODY(__type, __VXH_LONG, __here)
9034+}
7e46296a 9035+
7e46296a 9036+
3261cfd5
AM
9037+static inline
9038+void __vxh_throw_oops(void *__here)
9039+{
9040+ __VXH_BODY(VXH_THROW_OOPS, {}, __here);
9041+ /* prevent further acquisition */
9042+ vxh_active = 0;
9043+}
7e46296a 9044+
7e46296a 9045+
3261cfd5 9046+#define vxh_throw_oops() __vxh_throw_oops(__HERE__);
265d6dcc 9047+
3261cfd5
AM
9048+#define __vxh_get_vx_info(v, h) __vxh_smpl(v, VXH_GET_VX_INFO, h);
9049+#define __vxh_put_vx_info(v, h) __vxh_smpl(v, VXH_PUT_VX_INFO, h);
265d6dcc 9050+
3261cfd5
AM
9051+#define __vxh_init_vx_info(v, d, h) \
9052+ __vxh_data(v, d, VXH_INIT_VX_INFO, h);
9053+#define __vxh_set_vx_info(v, d, h) \
9054+ __vxh_data(v, d, VXH_SET_VX_INFO, h);
9055+#define __vxh_clr_vx_info(v, d, h) \
9056+ __vxh_data(v, d, VXH_CLR_VX_INFO, h);
265d6dcc 9057+
3261cfd5
AM
9058+#define __vxh_claim_vx_info(v, d, h) \
9059+ __vxh_data(v, d, VXH_CLAIM_VX_INFO, h);
9060+#define __vxh_release_vx_info(v, d, h) \
9061+ __vxh_data(v, d, VXH_RELEASE_VX_INFO, h);
7e46296a 9062+
3261cfd5
AM
9063+#define vxh_alloc_vx_info(v) \
9064+ __vxh_smpl(v, VXH_ALLOC_VX_INFO, __HERE__);
9065+#define vxh_dealloc_vx_info(v) \
9066+ __vxh_smpl(v, VXH_DEALLOC_VX_INFO, __HERE__);
d337f35e 9067+
3261cfd5
AM
9068+#define vxh_hash_vx_info(v) \
9069+ __vxh_smpl(v, VXH_HASH_VX_INFO, __HERE__);
9070+#define vxh_unhash_vx_info(v) \
9071+ __vxh_smpl(v, VXH_UNHASH_VX_INFO, __HERE__);
d337f35e 9072+
3261cfd5
AM
9073+#define vxh_loc_vx_info(v, l) \
9074+ __vxh_long(v, l, VXH_LOC_VX_INFO, __HERE__);
9075+#define vxh_lookup_vx_info(v, l) \
9076+ __vxh_long(v, l, VXH_LOOKUP_VX_INFO, __HERE__);
9077+#define vxh_create_vx_info(v, l) \
9078+ __vxh_long(v, l, VXH_CREATE_VX_INFO, __HERE__);
d337f35e 9079+
3261cfd5 9080+extern void vxh_dump_history(void);
d337f35e 9081+
d337f35e 9082+
3261cfd5 9083+#else /* CONFIG_VSERVER_HISTORY */
d337f35e 9084+
3261cfd5 9085+#define __HERE__ 0
d337f35e 9086+
3261cfd5 9087+#define vxh_throw_oops() do { } while (0)
d337f35e 9088+
3261cfd5
AM
9089+#define __vxh_get_vx_info(v, h) do { } while (0)
9090+#define __vxh_put_vx_info(v, h) do { } while (0)
d337f35e 9091+
3261cfd5
AM
9092+#define __vxh_init_vx_info(v, d, h) do { } while (0)
9093+#define __vxh_set_vx_info(v, d, h) do { } while (0)
9094+#define __vxh_clr_vx_info(v, d, h) do { } while (0)
d337f35e 9095+
3261cfd5
AM
9096+#define __vxh_claim_vx_info(v, d, h) do { } while (0)
9097+#define __vxh_release_vx_info(v, d, h) do { } while (0)
d337f35e 9098+
3261cfd5
AM
9099+#define vxh_alloc_vx_info(v) do { } while (0)
9100+#define vxh_dealloc_vx_info(v) do { } while (0)
d337f35e 9101+
3261cfd5
AM
9102+#define vxh_hash_vx_info(v) do { } while (0)
9103+#define vxh_unhash_vx_info(v) do { } while (0)
d337f35e 9104+
3261cfd5
AM
9105+#define vxh_loc_vx_info(v, l) do { } while (0)
9106+#define vxh_lookup_vx_info(v, l) do { } while (0)
9107+#define vxh_create_vx_info(v, l) do { } while (0)
d337f35e 9108+
3261cfd5 9109+#define vxh_dump_history() do { } while (0)
d337f35e 9110+
d337f35e 9111+
3261cfd5 9112+#endif /* CONFIG_VSERVER_HISTORY */
d337f35e 9113+
3261cfd5
AM
9114+#endif /* _VSERVER_HISTORY_H */
9115diff -NurpP --minimal linux-4.9.207/include/linux/vserver/inode_cmd.h linux-4.9.207-vs2.3.9.11/include/linux/vserver/inode_cmd.h
9116--- linux-4.9.207/include/linux/vserver/inode_cmd.h 1970-01-01 00:00:00.000000000 +0000
9117+++ linux-4.9.207-vs2.3.9.11/include/linux/vserver/inode_cmd.h 2018-10-20 04:58:14.000000000 +0000
9118@@ -0,0 +1,36 @@
9119+#ifndef _VSERVER_INODE_CMD_H
9120+#define _VSERVER_INODE_CMD_H
d337f35e 9121+
3261cfd5 9122+#include <uapi/vserver/inode_cmd.h>
d337f35e 9123+
d337f35e 9124+
d337f35e 9125+
3261cfd5 9126+#ifdef CONFIG_COMPAT
d337f35e 9127+
3261cfd5 9128+#include <asm/compat.h>
d337f35e 9129+
3261cfd5
AM
9130+struct vcmd_ctx_iattr_v1_x32 {
9131+ compat_uptr_t name_ptr;
9132+ uint32_t tag;
9133+ uint32_t flags;
9134+ uint32_t mask;
9135+};
d337f35e 9136+
3261cfd5 9137+#endif /* CONFIG_COMPAT */
d337f35e 9138+
3261cfd5 9139+#include <linux/compiler.h>
d337f35e 9140+
3261cfd5
AM
9141+extern int vc_get_iattr(void __user *);
9142+extern int vc_set_iattr(void __user *);
d337f35e 9143+
3261cfd5
AM
9144+extern int vc_fget_iattr(uint32_t, void __user *);
9145+extern int vc_fset_iattr(uint32_t, void __user *);
d337f35e 9146+
3261cfd5 9147+#ifdef CONFIG_COMPAT
d337f35e 9148+
3261cfd5
AM
9149+extern int vc_get_iattr_x32(void __user *);
9150+extern int vc_set_iattr_x32(void __user *);
d337f35e 9151+
3261cfd5 9152+#endif /* CONFIG_COMPAT */
d337f35e 9153+
3261cfd5
AM
9154+#endif /* _VSERVER_INODE_CMD_H */
9155diff -NurpP --minimal linux-4.9.207/include/linux/vserver/inode.h linux-4.9.207-vs2.3.9.11/include/linux/vserver/inode.h
9156--- linux-4.9.207/include/linux/vserver/inode.h 1970-01-01 00:00:00.000000000 +0000
9157+++ linux-4.9.207-vs2.3.9.11/include/linux/vserver/inode.h 2018-10-20 04:58:14.000000000 +0000
9158@@ -0,0 +1,19 @@
9159+#ifndef _VSERVER_INODE_H
9160+#define _VSERVER_INODE_H
d337f35e 9161+
3261cfd5 9162+#include <uapi/vserver/inode.h>
d337f35e 9163+
d337f35e 9164+
3261cfd5
AM
9165+#ifdef CONFIG_VSERVER_PROC_SECURE
9166+#define IATTR_PROC_DEFAULT ( IATTR_ADMIN | IATTR_HIDE )
9167+#define IATTR_PROC_SYMLINK ( IATTR_ADMIN )
d33d7b00 9168+#else
3261cfd5
AM
9169+#define IATTR_PROC_DEFAULT ( IATTR_ADMIN )
9170+#define IATTR_PROC_SYMLINK ( IATTR_ADMIN )
d33d7b00 9171+#endif
d337f35e 9172+
3261cfd5 9173+#define vx_hide_check(c, m) (((m) & IATTR_HIDE) ? vx_check(c, m) : 1)
d337f35e 9174+
3261cfd5
AM
9175+#else /* _VSERVER_INODE_H */
9176+#warning duplicate inclusion
9177+#endif /* _VSERVER_INODE_H */
9178diff -NurpP --minimal linux-4.9.207/include/linux/vserver/limit_cmd.h linux-4.9.207-vs2.3.9.11/include/linux/vserver/limit_cmd.h
9179--- linux-4.9.207/include/linux/vserver/limit_cmd.h 1970-01-01 00:00:00.000000000 +0000
9180+++ linux-4.9.207-vs2.3.9.11/include/linux/vserver/limit_cmd.h 2018-10-20 04:58:14.000000000 +0000
9181@@ -0,0 +1,35 @@
9182+#ifndef _VSERVER_LIMIT_CMD_H
9183+#define _VSERVER_LIMIT_CMD_H
d337f35e 9184+
3261cfd5 9185+#include <uapi/vserver/limit_cmd.h>
d337f35e 9186+
d337f35e 9187+
3261cfd5 9188+#ifdef CONFIG_IA32_EMULATION
d337f35e 9189+
3261cfd5
AM
9190+struct vcmd_ctx_rlimit_v0_x32 {
9191+ uint32_t id;
9192+ uint64_t minimum;
9193+ uint64_t softlimit;
9194+ uint64_t maximum;
9195+} __attribute__ ((packed));
2380c486 9196+
3261cfd5 9197+#endif /* CONFIG_IA32_EMULATION */
d337f35e 9198+
3261cfd5 9199+#include <linux/compiler.h>
d337f35e 9200+
3261cfd5
AM
9201+extern int vc_get_rlimit_mask(uint32_t, void __user *);
9202+extern int vc_get_rlimit(struct vx_info *, void __user *);
9203+extern int vc_set_rlimit(struct vx_info *, void __user *);
9204+extern int vc_reset_hits(struct vx_info *, void __user *);
9205+extern int vc_reset_minmax(struct vx_info *, void __user *);
d337f35e 9206+
3261cfd5 9207+extern int vc_rlimit_stat(struct vx_info *, void __user *);
d337f35e 9208+
3261cfd5 9209+#ifdef CONFIG_IA32_EMULATION
d337f35e 9210+
3261cfd5
AM
9211+extern int vc_get_rlimit_x32(struct vx_info *, void __user *);
9212+extern int vc_set_rlimit_x32(struct vx_info *, void __user *);
d337f35e 9213+
3261cfd5 9214+#endif /* CONFIG_IA32_EMULATION */
d337f35e 9215+
3261cfd5
AM
9216+#endif /* _VSERVER_LIMIT_CMD_H */
9217diff -NurpP --minimal linux-4.9.207/include/linux/vserver/limit_def.h linux-4.9.207-vs2.3.9.11/include/linux/vserver/limit_def.h
9218--- linux-4.9.207/include/linux/vserver/limit_def.h 1970-01-01 00:00:00.000000000 +0000
9219+++ linux-4.9.207-vs2.3.9.11/include/linux/vserver/limit_def.h 2018-10-20 04:58:14.000000000 +0000
9220@@ -0,0 +1,47 @@
9221+#ifndef _VSERVER_LIMIT_DEF_H
9222+#define _VSERVER_LIMIT_DEF_H
d337f35e 9223+
3261cfd5
AM
9224+#include <asm/atomic.h>
9225+#include <asm/resource.h>
d337f35e 9226+
3261cfd5 9227+#include "limit.h"
d337f35e 9228+
d337f35e 9229+
3261cfd5
AM
9230+struct _vx_res_limit {
9231+ rlim_t soft; /* Context soft limit */
9232+ rlim_t hard; /* Context hard limit */
d337f35e 9233+
3261cfd5
AM
9234+ rlim_atomic_t rcur; /* Current value */
9235+ rlim_t rmin; /* Context minimum */
9236+ rlim_t rmax; /* Context maximum */
d337f35e 9237+
3261cfd5
AM
9238+ atomic_t lhit; /* Limit hits */
9239+};
d337f35e 9240+
3261cfd5 9241+/* context sub struct */
d337f35e 9242+
3261cfd5
AM
9243+struct _vx_limit {
9244+ struct _vx_res_limit res[NUM_LIMITS];
9245+};
d337f35e 9246+
3261cfd5 9247+#ifdef CONFIG_VSERVER_DEBUG
d337f35e 9248+
3261cfd5
AM
9249+static inline void __dump_vx_limit(struct _vx_limit *limit)
9250+{
9251+ int i;
d337f35e 9252+
3261cfd5
AM
9253+ printk("\t_vx_limit:");
9254+ for (i = 0; i < NUM_LIMITS; i++) {
9255+ printk("\t [%2d] = %8lu %8lu/%8lu, %8ld/%8ld, %8d\n",
9256+ i, (unsigned long)__rlim_get(limit, i),
9257+ (unsigned long)__rlim_rmin(limit, i),
9258+ (unsigned long)__rlim_rmax(limit, i),
9259+ (long)__rlim_soft(limit, i),
9260+ (long)__rlim_hard(limit, i),
9261+ atomic_read(&__rlim_lhit(limit, i)));
9262+ }
9263+}
d337f35e 9264+
d33d7b00 9265+#endif
d337f35e 9266+
3261cfd5
AM
9267+#endif /* _VSERVER_LIMIT_DEF_H */
9268diff -NurpP --minimal linux-4.9.207/include/linux/vserver/limit.h linux-4.9.207-vs2.3.9.11/include/linux/vserver/limit.h
9269--- linux-4.9.207/include/linux/vserver/limit.h 1970-01-01 00:00:00.000000000 +0000
9270+++ linux-4.9.207-vs2.3.9.11/include/linux/vserver/limit.h 2018-10-20 04:58:14.000000000 +0000
9271@@ -0,0 +1,67 @@
9272+#ifndef _VSERVER_LIMIT_H
9273+#define _VSERVER_LIMIT_H
d337f35e 9274+
3261cfd5 9275+#include <uapi/vserver/limit.h>
d337f35e 9276+
d337f35e 9277+
3261cfd5 9278+#define VLIM_NOCHECK ((1L << VLIMIT_DENTRY) | (1L << RLIMIT_RSS))
d337f35e 9279+
3261cfd5 9280+/* keep in sync with CRLIM_INFINITY */
d337f35e 9281+
3261cfd5 9282+#define VLIM_INFINITY (~0ULL)
d337f35e 9283+
3261cfd5
AM
9284+#include <asm/atomic.h>
9285+#include <asm/resource.h>
d337f35e 9286+
3261cfd5
AM
9287+#ifndef RLIM_INFINITY
9288+#warning RLIM_INFINITY is undefined
9289+#endif
adc1caaa 9290+
3261cfd5 9291+#define __rlim_val(l, r, v) ((l)->res[r].v)
d337f35e 9292+
3261cfd5
AM
9293+#define __rlim_soft(l, r) __rlim_val(l, r, soft)
9294+#define __rlim_hard(l, r) __rlim_val(l, r, hard)
d337f35e 9295+
3261cfd5
AM
9296+#define __rlim_rcur(l, r) __rlim_val(l, r, rcur)
9297+#define __rlim_rmin(l, r) __rlim_val(l, r, rmin)
9298+#define __rlim_rmax(l, r) __rlim_val(l, r, rmax)
d337f35e 9299+
3261cfd5
AM
9300+#define __rlim_lhit(l, r) __rlim_val(l, r, lhit)
9301+#define __rlim_hit(l, r) atomic_inc(&__rlim_lhit(l, r))
d337f35e 9302+
3261cfd5
AM
9303+typedef atomic_long_t rlim_atomic_t;
9304+typedef unsigned long rlim_t;
d337f35e 9305+
3261cfd5
AM
9306+#define __rlim_get(l, r) atomic_long_read(&__rlim_rcur(l, r))
9307+#define __rlim_set(l, r, v) atomic_long_set(&__rlim_rcur(l, r), v)
9308+#define __rlim_inc(l, r) atomic_long_inc(&__rlim_rcur(l, r))
9309+#define __rlim_dec(l, r) atomic_long_dec(&__rlim_rcur(l, r))
9310+#define __rlim_add(l, r, v) atomic_long_add(v, &__rlim_rcur(l, r))
9311+#define __rlim_sub(l, r, v) atomic_long_sub(v, &__rlim_rcur(l, r))
d337f35e
JR
9312+
9313+
3261cfd5
AM
9314+#if (RLIM_INFINITY == VLIM_INFINITY)
9315+#define VX_VLIM(r) ((long long)(long)(r))
9316+#define VX_RLIM(v) ((rlim_t)(v))
9317+#else
9318+#define VX_VLIM(r) (((r) == RLIM_INFINITY) \
9319+ ? VLIM_INFINITY : (long long)(r))
9320+#define VX_RLIM(v) (((v) == VLIM_INFINITY) \
9321+ ? RLIM_INFINITY : (rlim_t)(v))
9322+#endif
d337f35e 9323+
3261cfd5 9324+struct sysinfo;
d337f35e 9325+
3261cfd5
AM
9326+#ifdef CONFIG_MEMCG
9327+void vx_vsi_meminfo(struct sysinfo *);
9328+void vx_vsi_swapinfo(struct sysinfo *);
9329+long vx_vsi_cached(struct sysinfo *);
9330+#else /* !CONFIG_MEMCG */
9331+#define vx_vsi_meminfo(s) do { } while (0)
9332+#define vx_vsi_swapinfo(s) do { } while (0)
9333+#define vx_vsi_cached(s) (0L)
9334+#endif /* !CONFIG_MEMCG */
d337f35e 9335+
3261cfd5 9336+#define NUM_LIMITS 24
d337f35e 9337+
3261cfd5
AM
9338+#endif /* _VSERVER_LIMIT_H */
9339diff -NurpP --minimal linux-4.9.207/include/linux/vserver/limit_int.h linux-4.9.207-vs2.3.9.11/include/linux/vserver/limit_int.h
9340--- linux-4.9.207/include/linux/vserver/limit_int.h 1970-01-01 00:00:00.000000000 +0000
9341+++ linux-4.9.207-vs2.3.9.11/include/linux/vserver/limit_int.h 2018-10-20 04:58:14.000000000 +0000
9342@@ -0,0 +1,193 @@
9343+#ifndef _VSERVER_LIMIT_INT_H
9344+#define _VSERVER_LIMIT_INT_H
d337f35e 9345+
3261cfd5
AM
9346+#define VXD_RCRES_COND(r) VXD_CBIT(cres, r)
9347+#define VXD_RLIMIT_COND(r) VXD_CBIT(limit, r)
d337f35e 9348+
3261cfd5 9349+extern const char *vlimit_name[NUM_LIMITS];
d337f35e 9350+
3261cfd5
AM
9351+static inline void __vx_acc_cres(struct vx_info *vxi,
9352+ int res, int dir, void *_data, char *_file, int _line)
9353+{
9354+ if (VXD_RCRES_COND(res))
9355+ vxlprintk(1, "vx_acc_cres[%5d,%s,%2d]: %5ld%s (%p)",
9356+ (vxi ? vxi->vx_id : -1), vlimit_name[res], res,
9357+ (vxi ? (long)__rlim_get(&vxi->limit, res) : 0),
9358+ (dir > 0) ? "++" : "--", _data, _file, _line);
9359+ if (!vxi)
9360+ return;
d33d7b00 9361+
3261cfd5
AM
9362+ if (dir > 0)
9363+ __rlim_inc(&vxi->limit, res);
9364+ else
9365+ __rlim_dec(&vxi->limit, res);
9366+}
d33d7b00 9367+
3261cfd5
AM
9368+static inline void __vx_add_cres(struct vx_info *vxi,
9369+ int res, int amount, void *_data, char *_file, int _line)
9370+{
9371+ if (VXD_RCRES_COND(res))
9372+ vxlprintk(1, "vx_add_cres[%5d,%s,%2d]: %5ld += %5d (%p)",
9373+ (vxi ? vxi->vx_id : -1), vlimit_name[res], res,
9374+ (vxi ? (long)__rlim_get(&vxi->limit, res) : 0),
9375+ amount, _data, _file, _line);
9376+ if (amount == 0)
9377+ return;
9378+ if (!vxi)
9379+ return;
9380+ __rlim_add(&vxi->limit, res, amount);
9381+}
d337f35e 9382+
3261cfd5
AM
9383+static inline
9384+int __vx_cres_adjust_max(struct _vx_limit *limit, int res, rlim_t value)
9385+{
9386+ int cond = (value > __rlim_rmax(limit, res));
d337f35e 9387+
3261cfd5
AM
9388+ if (cond)
9389+ __rlim_rmax(limit, res) = value;
9390+ return cond;
9391+}
d337f35e 9392+
3261cfd5
AM
9393+static inline
9394+int __vx_cres_adjust_min(struct _vx_limit *limit, int res, rlim_t value)
9395+{
9396+ int cond = (value < __rlim_rmin(limit, res));
d337f35e 9397+
3261cfd5
AM
9398+ if (cond)
9399+ __rlim_rmin(limit, res) = value;
9400+ return cond;
9401+}
d337f35e 9402+
3261cfd5
AM
9403+static inline
9404+void __vx_cres_fixup(struct _vx_limit *limit, int res, rlim_t value)
9405+{
9406+ if (!__vx_cres_adjust_max(limit, res, value))
9407+ __vx_cres_adjust_min(limit, res, value);
9408+}
d337f35e 9409+
d337f35e 9410+
3261cfd5
AM
9411+/* return values:
9412+ +1 ... no limit hit
9413+ -1 ... over soft limit
9414+ 0 ... over hard limit */
d337f35e 9415+
3261cfd5
AM
9416+static inline int __vx_cres_avail(struct vx_info *vxi,
9417+ int res, int num, char *_file, int _line)
9418+{
9419+ struct _vx_limit *limit;
9420+ rlim_t value;
d337f35e 9421+
3261cfd5
AM
9422+ if (VXD_RLIMIT_COND(res))
9423+ vxlprintk(1, "vx_cres_avail[%5d,%s,%2d]: %5ld/%5ld > %5ld + %5d",
9424+ (vxi ? vxi->vx_id : -1), vlimit_name[res], res,
9425+ (vxi ? (long)__rlim_soft(&vxi->limit, res) : -1),
9426+ (vxi ? (long)__rlim_hard(&vxi->limit, res) : -1),
9427+ (vxi ? (long)__rlim_get(&vxi->limit, res) : 0),
9428+ num, _file, _line);
9429+ if (!vxi)
9430+ return 1;
d337f35e 9431+
3261cfd5
AM
9432+ limit = &vxi->limit;
9433+ value = __rlim_get(limit, res);
d337f35e 9434+
3261cfd5
AM
9435+ if (!__vx_cres_adjust_max(limit, res, value))
9436+ __vx_cres_adjust_min(limit, res, value);
d337f35e 9437+
3261cfd5
AM
9438+ if (num == 0)
9439+ return 1;
d337f35e 9440+
3261cfd5
AM
9441+ if (__rlim_soft(limit, res) == RLIM_INFINITY)
9442+ return -1;
9443+ if (value + num <= __rlim_soft(limit, res))
9444+ return -1;
d337f35e 9445+
3261cfd5
AM
9446+ if (__rlim_hard(limit, res) == RLIM_INFINITY)
9447+ return 1;
9448+ if (value + num <= __rlim_hard(limit, res))
9449+ return 1;
d337f35e 9450+
3261cfd5
AM
9451+ __rlim_hit(limit, res);
9452+ return 0;
9453+}
d337f35e 9454+
d337f35e 9455+
3261cfd5 9456+static const int VLA_RSS[] = { RLIMIT_RSS, VLIMIT_ANON, VLIMIT_MAPPED, 0 };
d337f35e 9457+
3261cfd5
AM
9458+static inline
9459+rlim_t __vx_cres_array_sum(struct _vx_limit *limit, const int *array)
9460+{
9461+ rlim_t value, sum = 0;
9462+ int res;
d337f35e 9463+
3261cfd5
AM
9464+ while ((res = *array++)) {
9465+ value = __rlim_get(limit, res);
9466+ __vx_cres_fixup(limit, res, value);
9467+ sum += value;
9468+ }
9469+ return sum;
9470+}
d337f35e 9471+
3261cfd5
AM
9472+static inline
9473+rlim_t __vx_cres_array_fixup(struct _vx_limit *limit, const int *array)
9474+{
9475+ rlim_t value = __vx_cres_array_sum(limit, array + 1);
9476+ int res = *array;
d337f35e 9477+
3261cfd5
AM
9478+ if (value == __rlim_get(limit, res))
9479+ return value;
d337f35e 9480+
3261cfd5
AM
9481+ __rlim_set(limit, res, value);
9482+ /* now adjust min/max */
9483+ if (!__vx_cres_adjust_max(limit, res, value))
9484+ __vx_cres_adjust_min(limit, res, value);
d337f35e 9485+
3261cfd5
AM
9486+ return value;
9487+}
d337f35e 9488+
3261cfd5
AM
9489+static inline int __vx_cres_array_avail(struct vx_info *vxi,
9490+ const int *array, int num, char *_file, int _line)
9491+{
9492+ struct _vx_limit *limit;
9493+ rlim_t value = 0;
9494+ int res;
d337f35e 9495+
3261cfd5
AM
9496+ if (num == 0)
9497+ return 1;
9498+ if (!vxi)
9499+ return 1;
d337f35e 9500+
3261cfd5
AM
9501+ limit = &vxi->limit;
9502+ res = *array;
9503+ value = __vx_cres_array_sum(limit, array + 1);
3bac966d 9504+
3261cfd5
AM
9505+ __rlim_set(limit, res, value);
9506+ __vx_cres_fixup(limit, res, value);
d337f35e 9507+
3261cfd5
AM
9508+ return __vx_cres_avail(vxi, res, num, _file, _line);
9509+}
d337f35e 9510+
d337f35e 9511+
3261cfd5
AM
9512+static inline void vx_limit_fixup(struct _vx_limit *limit, int id)
9513+{
9514+ rlim_t value;
9515+ int res;
3bac966d 9516+
3261cfd5
AM
9517+ /* complex resources first */
9518+ if ((id < 0) || (id == RLIMIT_RSS))
9519+ __vx_cres_array_fixup(limit, VLA_RSS);
d337f35e 9520+
3261cfd5
AM
9521+ for (res = 0; res < NUM_LIMITS; res++) {
9522+ if ((id > 0) && (res != id))
9523+ continue;
d337f35e 9524+
3261cfd5
AM
9525+ value = __rlim_get(limit, res);
9526+ __vx_cres_fixup(limit, res, value);
9527+
9528+ /* not supposed to happen, maybe warn? */
9529+ if (__rlim_rmax(limit, res) > __rlim_hard(limit, res))
9530+ __rlim_rmax(limit, res) = __rlim_hard(limit, res);
9531+ }
3bac966d 9532+}
d337f35e 9533+
d337f35e 9534+
3261cfd5
AM
9535+#endif /* _VSERVER_LIMIT_INT_H */
9536diff -NurpP --minimal linux-4.9.207/include/linux/vserver/monitor.h linux-4.9.207-vs2.3.9.11/include/linux/vserver/monitor.h
9537--- linux-4.9.207/include/linux/vserver/monitor.h 1970-01-01 00:00:00.000000000 +0000
9538+++ linux-4.9.207-vs2.3.9.11/include/linux/vserver/monitor.h 2018-10-20 04:58:14.000000000 +0000
9539@@ -0,0 +1,6 @@
9540+#ifndef _VSERVER_MONITOR_H
9541+#define _VSERVER_MONITOR_H
d337f35e 9542+
3261cfd5 9543+#include <uapi/vserver/monitor.h>
d337f35e 9544+
3261cfd5
AM
9545+#endif /* _VSERVER_MONITOR_H */
9546diff -NurpP --minimal linux-4.9.207/include/linux/vserver/network_cmd.h linux-4.9.207-vs2.3.9.11/include/linux/vserver/network_cmd.h
9547--- linux-4.9.207/include/linux/vserver/network_cmd.h 1970-01-01 00:00:00.000000000 +0000
9548+++ linux-4.9.207-vs2.3.9.11/include/linux/vserver/network_cmd.h 2018-10-20 04:58:14.000000000 +0000
9549@@ -0,0 +1,37 @@
9550+#ifndef _VSERVER_NETWORK_CMD_H
9551+#define _VSERVER_NETWORK_CMD_H
d337f35e 9552+
3261cfd5 9553+#include <uapi/vserver/network_cmd.h>
d337f35e 9554+
3261cfd5 9555+extern int vc_task_nid(uint32_t);
d337f35e 9556+
3261cfd5 9557+extern int vc_nx_info(struct nx_info *, void __user *);
d337f35e 9558+
3261cfd5
AM
9559+extern int vc_net_create(uint32_t, void __user *);
9560+extern int vc_net_migrate(struct nx_info *, void __user *);
d337f35e 9561+
3261cfd5
AM
9562+extern int vc_net_add(struct nx_info *, void __user *);
9563+extern int vc_net_remove(struct nx_info *, void __user *);
d337f35e 9564+
3261cfd5
AM
9565+extern int vc_net_add_ipv4_v1(struct nx_info *, void __user *);
9566+extern int vc_net_add_ipv4(struct nx_info *, void __user *);
d337f35e 9567+
3261cfd5
AM
9568+extern int vc_net_rem_ipv4_v1(struct nx_info *, void __user *);
9569+extern int vc_net_rem_ipv4(struct nx_info *, void __user *);
d337f35e 9570+
3261cfd5
AM
9571+extern int vc_net_add_ipv6(struct nx_info *, void __user *);
9572+extern int vc_net_remove_ipv6(struct nx_info *, void __user *);
d337f35e 9573+
3261cfd5
AM
9574+extern int vc_add_match_ipv4(struct nx_info *, void __user *);
9575+extern int vc_get_match_ipv4(struct nx_info *, void __user *);
d337f35e 9576+
3261cfd5
AM
9577+extern int vc_add_match_ipv6(struct nx_info *, void __user *);
9578+extern int vc_get_match_ipv6(struct nx_info *, void __user *);
d337f35e 9579+
3261cfd5
AM
9580+extern int vc_get_nflags(struct nx_info *, void __user *);
9581+extern int vc_set_nflags(struct nx_info *, void __user *);
d337f35e 9582+
3261cfd5
AM
9583+extern int vc_get_ncaps(struct nx_info *, void __user *);
9584+extern int vc_set_ncaps(struct nx_info *, void __user *);
d337f35e 9585+
3261cfd5
AM
9586+#endif /* _VSERVER_CONTEXT_CMD_H */
9587diff -NurpP --minimal linux-4.9.207/include/linux/vserver/network.h linux-4.9.207-vs2.3.9.11/include/linux/vserver/network.h
9588--- linux-4.9.207/include/linux/vserver/network.h 1970-01-01 00:00:00.000000000 +0000
9589+++ linux-4.9.207-vs2.3.9.11/include/linux/vserver/network.h 2018-10-20 04:58:14.000000000 +0000
9590@@ -0,0 +1,76 @@
9591+#ifndef _VSERVER_NETWORK_H
9592+#define _VSERVER_NETWORK_H
d337f35e 9593+
d337f35e 9594+
3261cfd5
AM
9595+#include <linux/list.h>
9596+#include <linux/spinlock.h>
9597+#include <linux/rcupdate.h>
9598+#include <linux/in.h>
9599+#include <linux/in6.h>
9600+#include <asm/atomic.h>
9601+#include <uapi/vserver/network.h>
d337f35e 9602+
3261cfd5
AM
9603+struct nx_addr_v4 {
9604+ struct nx_addr_v4 *next;
9605+ struct in_addr ip[2];
9606+ struct in_addr mask;
9607+ uint16_t type;
9608+ uint16_t flags;
9609+};
d337f35e 9610+
3261cfd5
AM
9611+struct nx_addr_v6 {
9612+ struct nx_addr_v6 *next;
9613+ struct in6_addr ip;
9614+ struct in6_addr mask;
9615+ uint32_t prefix;
9616+ uint16_t type;
9617+ uint16_t flags;
9618+};
d337f35e 9619+
3261cfd5
AM
9620+struct nx_info {
9621+ struct hlist_node nx_hlist; /* linked list of nxinfos */
9622+ vnid_t nx_id; /* vnet id */
9623+ atomic_t nx_usecnt; /* usage count */
9624+ atomic_t nx_tasks; /* tasks count */
9625+ int nx_state; /* context state */
d337f35e 9626+
3261cfd5
AM
9627+ uint64_t nx_flags; /* network flag word */
9628+ uint64_t nx_ncaps; /* network capabilities */
d337f35e 9629+
3261cfd5
AM
9630+ spinlock_t addr_lock; /* protect address changes */
9631+ struct in_addr v4_lback; /* Loopback address */
9632+ struct in_addr v4_bcast; /* Broadcast address */
9633+ struct nx_addr_v4 v4; /* First/Single ipv4 address */
9634+#ifdef CONFIG_IPV6
9635+ struct nx_addr_v6 v6; /* First/Single ipv6 address */
9636+#endif
9637+ char nx_name[65]; /* network context name */
9638+};
2380c486 9639+
2380c486 9640+
3261cfd5 9641+/* status flags */
d337f35e 9642+
3261cfd5
AM
9643+#define NXS_HASHED 0x0001
9644+#define NXS_SHUTDOWN 0x0100
9645+#define NXS_RELEASED 0x8000
d337f35e 9646+
3261cfd5 9647+extern struct nx_info *lookup_nx_info(int);
d337f35e 9648+
3261cfd5
AM
9649+extern int get_nid_list(int, unsigned int *, int);
9650+extern int nid_is_hashed(vnid_t);
d337f35e 9651+
3261cfd5 9652+extern int nx_migrate_task(struct task_struct *, struct nx_info *);
d337f35e 9653+
3261cfd5 9654+extern long vs_net_change(struct nx_info *, unsigned int);
d337f35e 9655+
3261cfd5 9656+struct sock;
d337f35e 9657+
d337f35e 9658+
3261cfd5
AM
9659+#define NX_IPV4(n) ((n)->v4.type != NXA_TYPE_NONE)
9660+#ifdef CONFIG_IPV6
9661+#define NX_IPV6(n) ((n)->v6.type != NXA_TYPE_NONE)
d33d7b00 9662+#else
3261cfd5 9663+#define NX_IPV6(n) (0)
d33d7b00 9664+#endif
d337f35e 9665+
3261cfd5
AM
9666+#endif /* _VSERVER_NETWORK_H */
9667diff -NurpP --minimal linux-4.9.207/include/linux/vserver/percpu.h linux-4.9.207-vs2.3.9.11/include/linux/vserver/percpu.h
9668--- linux-4.9.207/include/linux/vserver/percpu.h 1970-01-01 00:00:00.000000000 +0000
9669+++ linux-4.9.207-vs2.3.9.11/include/linux/vserver/percpu.h 2018-10-20 04:58:14.000000000 +0000
9670@@ -0,0 +1,14 @@
9671+#ifndef _VSERVER_PERCPU_H
9672+#define _VSERVER_PERCPU_H
d337f35e 9673+
3261cfd5
AM
9674+#include "cvirt_def.h"
9675+#include "sched_def.h"
d337f35e 9676+
3261cfd5
AM
9677+struct _vx_percpu {
9678+ struct _vx_cvirt_pc cvirt;
9679+ struct _vx_sched_pc sched;
9680+};
d337f35e 9681+
3261cfd5 9682+#define PERCPU_PERCTX (sizeof(struct _vx_percpu))
d337f35e 9683+
3261cfd5
AM
9684+#endif /* _VSERVER_PERCPU_H */
9685diff -NurpP --minimal linux-4.9.207/include/linux/vserver/pid.h linux-4.9.207-vs2.3.9.11/include/linux/vserver/pid.h
9686--- linux-4.9.207/include/linux/vserver/pid.h 1970-01-01 00:00:00.000000000 +0000
9687+++ linux-4.9.207-vs2.3.9.11/include/linux/vserver/pid.h 2018-10-20 04:58:14.000000000 +0000
9688@@ -0,0 +1,51 @@
9689+#ifndef _VSERVER_PID_H
9690+#define _VSERVER_PID_H
d337f35e 9691+
3261cfd5 9692+/* pid faking stuff */
d337f35e 9693+
3261cfd5
AM
9694+#define vx_info_map_pid(v, p) \
9695+ __vx_info_map_pid((v), (p), __func__, __FILE__, __LINE__)
9696+#define vx_info_map_tgid(v,p) vx_info_map_pid(v,p)
9697+#define vx_map_pid(p) vx_info_map_pid(current_vx_info(), p)
9698+#define vx_map_tgid(p) vx_map_pid(p)
d337f35e 9699+
3261cfd5
AM
9700+static inline int __vx_info_map_pid(struct vx_info *vxi, int pid,
9701+ const char *func, const char *file, int line)
9702+{
9703+ if (vx_info_flags(vxi, VXF_INFO_INIT, 0)) {
9704+ vxfprintk(VXD_CBIT(cvirt, 2),
9705+ "vx_map_tgid: %p/%llx: %d -> %d",
9706+ vxi, (long long)vxi->vx_flags, pid,
9707+ (pid && pid == vxi->vx_initpid) ? 1 : pid,
9708+ func, file, line);
9709+ if (pid == 0)
9710+ return 0;
9711+ if (pid == vxi->vx_initpid)
9712+ return 1;
9713+ }
9714+ return pid;
9715+}
d337f35e 9716+
3261cfd5
AM
9717+#define vx_info_rmap_pid(v, p) \
9718+ __vx_info_rmap_pid((v), (p), __func__, __FILE__, __LINE__)
9719+#define vx_rmap_pid(p) vx_info_rmap_pid(current_vx_info(), p)
9720+#define vx_rmap_tgid(p) vx_rmap_pid(p)
d337f35e 9721+
3261cfd5
AM
9722+static inline int __vx_info_rmap_pid(struct vx_info *vxi, int pid,
9723+ const char *func, const char *file, int line)
9724+{
9725+ if (vx_info_flags(vxi, VXF_INFO_INIT, 0)) {
9726+ vxfprintk(VXD_CBIT(cvirt, 2),
9727+ "vx_rmap_tgid: %p/%llx: %d -> %d",
9728+ vxi, (long long)vxi->vx_flags, pid,
9729+ (pid == 1) ? vxi->vx_initpid : pid,
9730+ func, file, line);
9731+ if ((pid == 1) && vxi->vx_initpid)
9732+ return vxi->vx_initpid;
9733+ if (pid == vxi->vx_initpid)
9734+ return ~0U;
9735+ }
9736+ return pid;
9737+}
d337f35e 9738+
3261cfd5
AM
9739+#endif
9740diff -NurpP --minimal linux-4.9.207/include/linux/vserver/sched_cmd.h linux-4.9.207-vs2.3.9.11/include/linux/vserver/sched_cmd.h
9741--- linux-4.9.207/include/linux/vserver/sched_cmd.h 1970-01-01 00:00:00.000000000 +0000
9742+++ linux-4.9.207-vs2.3.9.11/include/linux/vserver/sched_cmd.h 2018-10-20 04:58:14.000000000 +0000
9743@@ -0,0 +1,11 @@
9744+#ifndef _VSERVER_SCHED_CMD_H
9745+#define _VSERVER_SCHED_CMD_H
d337f35e 9746+
d337f35e 9747+
3261cfd5
AM
9748+#include <linux/compiler.h>
9749+#include <uapi/vserver/sched_cmd.h>
d337f35e 9750+
3261cfd5
AM
9751+extern int vc_set_prio_bias(struct vx_info *, void __user *);
9752+extern int vc_get_prio_bias(struct vx_info *, void __user *);
d337f35e 9753+
3261cfd5
AM
9754+#endif /* _VSERVER_SCHED_CMD_H */
9755diff -NurpP --minimal linux-4.9.207/include/linux/vserver/sched_def.h linux-4.9.207-vs2.3.9.11/include/linux/vserver/sched_def.h
9756--- linux-4.9.207/include/linux/vserver/sched_def.h 1970-01-01 00:00:00.000000000 +0000
9757+++ linux-4.9.207-vs2.3.9.11/include/linux/vserver/sched_def.h 2018-10-20 04:58:14.000000000 +0000
9758@@ -0,0 +1,38 @@
9759+#ifndef _VSERVER_SCHED_DEF_H
9760+#define _VSERVER_SCHED_DEF_H
d337f35e 9761+
3261cfd5
AM
9762+#include <linux/spinlock.h>
9763+#include <linux/jiffies.h>
9764+#include <linux/cpumask.h>
9765+#include <asm/atomic.h>
9766+#include <asm/param.h>
d337f35e 9767+
d337f35e 9768+
3261cfd5 9769+/* context sub struct */
d337f35e 9770+
3261cfd5
AM
9771+struct _vx_sched {
9772+ int prio_bias; /* bias offset for priority */
d337f35e 9773+
3261cfd5
AM
9774+ cpumask_t update; /* CPUs which should update */
9775+};
d337f35e 9776+
3261cfd5
AM
9777+struct _vx_sched_pc {
9778+ int prio_bias; /* bias offset for priority */
3bac966d 9779+
3261cfd5
AM
9780+ uint64_t user_ticks; /* token tick events */
9781+ uint64_t sys_ticks; /* token tick events */
9782+ uint64_t hold_ticks; /* token ticks paused */
d337f35e
JR
9783+};
9784+
d337f35e 9785+
3261cfd5 9786+#ifdef CONFIG_VSERVER_DEBUG
d337f35e 9787+
3261cfd5
AM
9788+static inline void __dump_vx_sched(struct _vx_sched *sched)
9789+{
9790+ printk("\t_vx_sched:\n");
9791+ printk("\t priority = %4d\n", sched->prio_bias);
9792+}
d337f35e 9793+
3261cfd5 9794+#endif
d337f35e 9795+
3261cfd5
AM
9796+#endif /* _VSERVER_SCHED_DEF_H */
9797diff -NurpP --minimal linux-4.9.207/include/linux/vserver/sched.h linux-4.9.207-vs2.3.9.11/include/linux/vserver/sched.h
9798--- linux-4.9.207/include/linux/vserver/sched.h 1970-01-01 00:00:00.000000000 +0000
9799+++ linux-4.9.207-vs2.3.9.11/include/linux/vserver/sched.h 2018-10-20 04:58:14.000000000 +0000
9800@@ -0,0 +1,23 @@
9801+#ifndef _VSERVER_SCHED_H
9802+#define _VSERVER_SCHED_H
d337f35e 9803+
d337f35e 9804+
3261cfd5 9805+#ifdef __KERNEL__
d337f35e 9806+
3261cfd5 9807+struct timespec;
d337f35e 9808+
3261cfd5 9809+void vx_vsi_uptime(struct timespec *, struct timespec *);
d337f35e
JR
9810+
9811+
3261cfd5 9812+struct vx_info;
d337f35e 9813+
3261cfd5 9814+void vx_update_load(struct vx_info *);
3bac966d 9815+
d337f35e 9816+
3261cfd5
AM
9817+void vx_update_sched_param(struct _vx_sched *sched,
9818+ struct _vx_sched_pc *sched_pc);
d337f35e 9819+
3261cfd5
AM
9820+#endif /* __KERNEL__ */
9821+#else /* _VSERVER_SCHED_H */
9822+#warning duplicate inclusion
9823+#endif /* _VSERVER_SCHED_H */
9824diff -NurpP --minimal linux-4.9.207/include/linux/vserver/signal_cmd.h linux-4.9.207-vs2.3.9.11/include/linux/vserver/signal_cmd.h
9825--- linux-4.9.207/include/linux/vserver/signal_cmd.h 1970-01-01 00:00:00.000000000 +0000
9826+++ linux-4.9.207-vs2.3.9.11/include/linux/vserver/signal_cmd.h 2018-10-20 04:58:14.000000000 +0000
9827@@ -0,0 +1,14 @@
9828+#ifndef _VSERVER_SIGNAL_CMD_H
9829+#define _VSERVER_SIGNAL_CMD_H
d337f35e 9830+
3261cfd5 9831+#include <uapi/vserver/signal_cmd.h>
d337f35e 9832+
d337f35e 9833+
3261cfd5
AM
9834+extern int vc_ctx_kill(struct vx_info *, void __user *);
9835+extern int vc_wait_exit(struct vx_info *, void __user *);
d337f35e 9836+
d337f35e 9837+
3261cfd5
AM
9838+extern int vc_get_pflags(uint32_t pid, void __user *);
9839+extern int vc_set_pflags(uint32_t pid, void __user *);
d337f35e 9840+
3261cfd5
AM
9841+#endif /* _VSERVER_SIGNAL_CMD_H */
9842diff -NurpP --minimal linux-4.9.207/include/linux/vserver/signal.h linux-4.9.207-vs2.3.9.11/include/linux/vserver/signal.h
9843--- linux-4.9.207/include/linux/vserver/signal.h 1970-01-01 00:00:00.000000000 +0000
9844+++ linux-4.9.207-vs2.3.9.11/include/linux/vserver/signal.h 2018-10-20 04:58:14.000000000 +0000
9845@@ -0,0 +1,14 @@
9846+#ifndef _VSERVER_SIGNAL_H
9847+#define _VSERVER_SIGNAL_H
d337f35e
JR
9848+
9849+
3261cfd5 9850+#ifdef __KERNEL__
d337f35e 9851+
3261cfd5 9852+struct vx_info;
d337f35e 9853+
3261cfd5 9854+int vx_info_kill(struct vx_info *, int, int);
d337f35e 9855+
3261cfd5
AM
9856+#endif /* __KERNEL__ */
9857+#else /* _VSERVER_SIGNAL_H */
9858+#warning duplicate inclusion
9859+#endif /* _VSERVER_SIGNAL_H */
9860diff -NurpP --minimal linux-4.9.207/include/linux/vserver/space_cmd.h linux-4.9.207-vs2.3.9.11/include/linux/vserver/space_cmd.h
9861--- linux-4.9.207/include/linux/vserver/space_cmd.h 1970-01-01 00:00:00.000000000 +0000
9862+++ linux-4.9.207-vs2.3.9.11/include/linux/vserver/space_cmd.h 2018-10-20 04:58:14.000000000 +0000
9863@@ -0,0 +1,13 @@
9864+#ifndef _VSERVER_SPACE_CMD_H
9865+#define _VSERVER_SPACE_CMD_H
d337f35e 9866+
3261cfd5 9867+#include <uapi/vserver/space_cmd.h>
d337f35e 9868+
d337f35e 9869+
3261cfd5
AM
9870+extern int vc_enter_space_v1(struct vx_info *, void __user *);
9871+extern int vc_set_space_v1(struct vx_info *, void __user *);
9872+extern int vc_enter_space(struct vx_info *, void __user *);
9873+extern int vc_set_space(struct vx_info *, void __user *);
9874+extern int vc_get_space_mask(void __user *, int);
d337f35e 9875+
3261cfd5
AM
9876+#endif /* _VSERVER_SPACE_CMD_H */
9877diff -NurpP --minimal linux-4.9.207/include/linux/vserver/space.h linux-4.9.207-vs2.3.9.11/include/linux/vserver/space.h
9878--- linux-4.9.207/include/linux/vserver/space.h 1970-01-01 00:00:00.000000000 +0000
9879+++ linux-4.9.207-vs2.3.9.11/include/linux/vserver/space.h 2018-10-20 04:58:14.000000000 +0000
9880@@ -0,0 +1,12 @@
9881+#ifndef _VSERVER_SPACE_H
9882+#define _VSERVER_SPACE_H
d337f35e 9883+
3261cfd5 9884+#include <linux/types.h>
d337f35e 9885+
3261cfd5 9886+struct vx_info;
d337f35e 9887+
3261cfd5 9888+int vx_set_space(struct vx_info *vxi, unsigned long mask, unsigned index);
d337f35e 9889+
3261cfd5
AM
9890+#else /* _VSERVER_SPACE_H */
9891+#warning duplicate inclusion
9892+#endif /* _VSERVER_SPACE_H */
9893diff -NurpP --minimal linux-4.9.207/include/linux/vserver/switch.h linux-4.9.207-vs2.3.9.11/include/linux/vserver/switch.h
9894--- linux-4.9.207/include/linux/vserver/switch.h 1970-01-01 00:00:00.000000000 +0000
9895+++ linux-4.9.207-vs2.3.9.11/include/linux/vserver/switch.h 2018-10-20 04:58:14.000000000 +0000
9896@@ -0,0 +1,8 @@
9897+#ifndef _VSERVER_SWITCH_H
9898+#define _VSERVER_SWITCH_H
d337f35e 9899+
2380c486 9900+
3261cfd5
AM
9901+#include <linux/errno.h>
9902+#include <uapi/vserver/switch.h>
adc1caaa 9903+
3261cfd5
AM
9904+#endif /* _VSERVER_SWITCH_H */
9905diff -NurpP --minimal linux-4.9.207/include/linux/vserver/tag_cmd.h linux-4.9.207-vs2.3.9.11/include/linux/vserver/tag_cmd.h
9906--- linux-4.9.207/include/linux/vserver/tag_cmd.h 1970-01-01 00:00:00.000000000 +0000
9907+++ linux-4.9.207-vs2.3.9.11/include/linux/vserver/tag_cmd.h 2018-10-20 04:58:14.000000000 +0000
9908@@ -0,0 +1,10 @@
9909+#ifndef _VSERVER_TAG_CMD_H
9910+#define _VSERVER_TAG_CMD_H
d337f35e 9911+
3261cfd5 9912+#include <uapi/vserver/tag_cmd.h>
d337f35e 9913+
3261cfd5 9914+extern int vc_task_tag(uint32_t);
d337f35e 9915+
3261cfd5 9916+extern int vc_tag_migrate(uint32_t);
d337f35e 9917+
3261cfd5
AM
9918+#endif /* _VSERVER_TAG_CMD_H */
9919diff -NurpP --minimal linux-4.9.207/include/linux/vserver/tag.h linux-4.9.207-vs2.3.9.11/include/linux/vserver/tag.h
9920--- linux-4.9.207/include/linux/vserver/tag.h 1970-01-01 00:00:00.000000000 +0000
9921+++ linux-4.9.207-vs2.3.9.11/include/linux/vserver/tag.h 2018-10-20 04:58:14.000000000 +0000
9922@@ -0,0 +1,160 @@
9923+#ifndef _DX_TAG_H
9924+#define _DX_TAG_H
d337f35e 9925+
3261cfd5
AM
9926+#include <linux/types.h>
9927+#include <linux/uidgid.h>
d337f35e 9928+
2380c486 9929+
3261cfd5 9930+#define DX_TAG(in) (IS_TAGGED(in))
d337f35e 9931+
d337f35e 9932+
3261cfd5
AM
9933+#ifdef CONFIG_TAG_NFSD
9934+#define DX_TAG_NFSD 1
9935+#else
9936+#define DX_TAG_NFSD 0
9937+#endif
d337f35e 9938+
d337f35e 9939+
3261cfd5 9940+#ifdef CONFIG_TAGGING_NONE
d337f35e 9941+
3261cfd5
AM
9942+#define MAX_UID 0xFFFFFFFF
9943+#define MAX_GID 0xFFFFFFFF
d337f35e 9944+
3261cfd5 9945+#define INOTAG_TAG(cond, uid, gid, tag) (0)
d337f35e 9946+
3261cfd5
AM
9947+#define TAGINO_UID(cond, uid, tag) (uid)
9948+#define TAGINO_GID(cond, gid, tag) (gid)
d337f35e 9949+
3261cfd5 9950+#endif
d337f35e 9951+
d337f35e 9952+
3261cfd5 9953+#ifdef CONFIG_TAGGING_GID16
d337f35e 9954+
3261cfd5
AM
9955+#define MAX_UID 0xFFFFFFFF
9956+#define MAX_GID 0x0000FFFF
d337f35e 9957+
3261cfd5
AM
9958+#define INOTAG_TAG(cond, uid, gid, tag) \
9959+ ((cond) ? (((gid) >> 16) & 0xFFFF) : 0)
d337f35e 9960+
3261cfd5
AM
9961+#define TAGINO_UID(cond, uid, tag) (uid)
9962+#define TAGINO_GID(cond, gid, tag) \
9963+ ((cond) ? (((gid) & 0xFFFF) | ((tag) << 16)) : (gid))
d337f35e 9964+
3261cfd5 9965+#endif
d337f35e 9966+
d337f35e 9967+
3261cfd5 9968+#ifdef CONFIG_TAGGING_ID24
d337f35e 9969+
3261cfd5
AM
9970+#define MAX_UID 0x00FFFFFF
9971+#define MAX_GID 0x00FFFFFF
d337f35e 9972+
3261cfd5
AM
9973+#define INOTAG_TAG(cond, uid, gid, tag) \
9974+ ((cond) ? ((((uid) >> 16) & 0xFF00) | (((gid) >> 24) & 0xFF)) : 0)
d337f35e 9975+
3261cfd5
AM
9976+#define TAGINO_UID(cond, uid, tag) \
9977+ ((cond) ? (((uid) & 0xFFFFFF) | (((tag) & 0xFF00) << 16)) : (uid))
9978+#define TAGINO_GID(cond, gid, tag) \
9979+ ((cond) ? (((gid) & 0xFFFFFF) | (((tag) & 0x00FF) << 24)) : (gid))
d337f35e 9980+
3261cfd5 9981+#endif
d337f35e 9982+
d337f35e 9983+
3261cfd5 9984+#ifdef CONFIG_TAGGING_UID16
d337f35e 9985+
3261cfd5
AM
9986+#define MAX_UID 0x0000FFFF
9987+#define MAX_GID 0xFFFFFFFF
d337f35e 9988+
3261cfd5
AM
9989+#define INOTAG_TAG(cond, uid, gid, tag) \
9990+ ((cond) ? (((uid) >> 16) & 0xFFFF) : 0)
d337f35e 9991+
3261cfd5
AM
9992+#define TAGINO_UID(cond, uid, tag) \
9993+ ((cond) ? (((uid) & 0xFFFF) | ((tag) << 16)) : (uid))
9994+#define TAGINO_GID(cond, gid, tag) (gid)
d337f35e 9995+
3261cfd5 9996+#endif
d337f35e 9997+
d337f35e 9998+
3261cfd5 9999+#ifdef CONFIG_TAGGING_INTERN
d337f35e 10000+
3261cfd5
AM
10001+#define MAX_UID 0xFFFFFFFF
10002+#define MAX_GID 0xFFFFFFFF
d337f35e 10003+
3261cfd5
AM
10004+#define INOTAG_TAG(cond, uid, gid, tag) \
10005+ ((cond) ? (tag) : 0)
d337f35e 10006+
3261cfd5
AM
10007+#define TAGINO_UID(cond, uid, tag) (uid)
10008+#define TAGINO_GID(cond, gid, tag) (gid)
d337f35e 10009+
3261cfd5 10010+#endif
d337f35e 10011+
3261cfd5
AM
10012+
10013+#ifndef CONFIG_TAGGING_NONE
10014+#define dx_current_fstag(sb) \
10015+ ((sb)->s_flags & MS_TAGGED ? dx_current_tag() : 0)
10016+#else
10017+#define dx_current_fstag(sb) (0)
10018+#endif
10019+
10020+#ifndef CONFIG_TAGGING_INTERN
10021+#define TAGINO_TAG(cond, tag) (0)
10022+#else
10023+#define TAGINO_TAG(cond, tag) ((cond) ? (tag) : 0)
10024+#endif
10025+
10026+#define TAGINO_KUID(cond, kuid, ktag) \
10027+ KUIDT_INIT(TAGINO_UID(cond, __kuid_val(kuid), __ktag_val(ktag)))
10028+#define TAGINO_KGID(cond, kgid, ktag) \
10029+ KGIDT_INIT(TAGINO_GID(cond, __kgid_val(kgid), __ktag_val(ktag)))
10030+#define TAGINO_KTAG(cond, ktag) \
10031+ KTAGT_INIT(TAGINO_TAG(cond, __ktag_val(ktag)))
10032+
10033+
10034+#define INOTAG_UID(cond, uid, gid) \
10035+ ((cond) ? ((uid) & MAX_UID) : (uid))
10036+#define INOTAG_GID(cond, uid, gid) \
10037+ ((cond) ? ((gid) & MAX_GID) : (gid))
10038+
10039+#define INOTAG_KUID(cond, kuid, kgid) \
10040+ KUIDT_INIT(INOTAG_UID(cond, __kuid_val(kuid), __kgid_val(kgid)))
10041+#define INOTAG_KGID(cond, kuid, kgid) \
10042+ KGIDT_INIT(INOTAG_GID(cond, __kuid_val(kuid), __kgid_val(kgid)))
10043+#define INOTAG_KTAG(cond, kuid, kgid, ktag) \
10044+ KTAGT_INIT(INOTAG_TAG(cond, \
10045+ __kuid_val(kuid), __kgid_val(kgid), __ktag_val(ktag)))
10046+
10047+
10048+static inline uid_t dx_map_uid(uid_t uid)
d33d7b00 10049+{
3261cfd5
AM
10050+ if ((uid > MAX_UID) && (uid != -1))
10051+ uid = -2;
10052+ return (uid & MAX_UID);
d33d7b00 10053+}
d337f35e 10054+
3261cfd5 10055+static inline gid_t dx_map_gid(gid_t gid)
d33d7b00 10056+{
3261cfd5
AM
10057+ if ((gid > MAX_GID) && (gid != -1))
10058+ gid = -2;
10059+ return (gid & MAX_GID);
d33d7b00 10060+}
d337f35e 10061+
3261cfd5
AM
10062+struct peer_tag {
10063+ int32_t xid;
10064+ int32_t nid;
10065+};
d337f35e 10066+
3261cfd5 10067+#define dx_notagcheck(sb) ((sb) && ((sb)->s_flags & MS_NOTAGCHECK))
d337f35e 10068+
3261cfd5
AM
10069+int dx_parse_tag(char *string, vtag_t *tag, int remove, int *mnt_flags,
10070+ unsigned long *flags);
d337f35e 10071+
3261cfd5 10072+#ifdef CONFIG_PROPAGATE
d337f35e 10073+
3261cfd5 10074+void __dx_propagate_tag(struct nameidata *nd, struct inode *inode);
d337f35e 10075+
3261cfd5 10076+#define dx_propagate_tag(n, i) __dx_propagate_tag(n, i)
d337f35e 10077+
3261cfd5
AM
10078+#else
10079+#define dx_propagate_tag(n, i) do { } while (0)
10080+#endif
d337f35e 10081+
3261cfd5
AM
10082+#endif /* _DX_TAG_H */
10083diff -NurpP --minimal linux-4.9.207/include/linux/vs_inet6.h linux-4.9.207-vs2.3.9.11/include/linux/vs_inet6.h
10084--- linux-4.9.207/include/linux/vs_inet6.h 1970-01-01 00:00:00.000000000 +0000
10085+++ linux-4.9.207-vs2.3.9.11/include/linux/vs_inet6.h 2018-10-20 04:58:14.000000000 +0000
10086@@ -0,0 +1,264 @@
10087+#ifndef _VS_INET6_H
10088+#define _VS_INET6_H
d337f35e 10089+
3261cfd5
AM
10090+#include "vserver/base.h"
10091+#include "vserver/network.h"
10092+#include "vserver/debug.h"
d337f35e 10093+
3261cfd5 10094+#include <net/ipv6.h>
2380c486 10095+
3261cfd5
AM
10096+#define NXAV6(a) &(a)->ip, &(a)->mask, (a)->prefix, (a)->type
10097+#define NXAV6_FMT "[%pI6/%pI6/%d:%04x]"
d337f35e 10098+
d337f35e 10099+
3261cfd5 10100+#ifdef CONFIG_IPV6
d337f35e 10101+
3261cfd5
AM
10102+static inline
10103+int v6_addr_match(struct nx_addr_v6 *nxa,
10104+ const struct in6_addr *addr, uint16_t mask)
10105+{
10106+ int ret = 0;
d337f35e 10107+
3261cfd5
AM
10108+ switch (nxa->type & mask) {
10109+ case NXA_TYPE_MASK:
10110+ ret = ipv6_masked_addr_cmp(&nxa->ip, &nxa->mask, addr);
10111+ break;
10112+ case NXA_TYPE_ADDR:
10113+ ret = ipv6_addr_equal(&nxa->ip, addr);
10114+ break;
10115+ case NXA_TYPE_ANY:
10116+ ret = 1;
10117+ break;
10118+ }
10119+ vxdprintk(VXD_CBIT(net, 0),
10120+ "v6_addr_match(%p" NXAV6_FMT ",%pI6,%04x) = %d",
10121+ nxa, NXAV6(nxa), addr, mask, ret);
10122+ return ret;
10123+}
3bac966d 10124+
3261cfd5
AM
10125+static inline
10126+int v6_addr_in_nx_info(struct nx_info *nxi,
10127+ const struct in6_addr *addr, uint16_t mask)
10128+{
10129+ struct nx_addr_v6 *nxa;
10130+ unsigned long irqflags;
10131+ int ret = 1;
d337f35e 10132+
3261cfd5
AM
10133+ if (!nxi)
10134+ goto out;
d337f35e 10135+
3261cfd5
AM
10136+ spin_lock_irqsave(&nxi->addr_lock, irqflags);
10137+ for (nxa = &nxi->v6; nxa; nxa = nxa->next)
10138+ if (v6_addr_match(nxa, addr, mask))
10139+ goto out_unlock;
10140+ ret = 0;
10141+out_unlock:
10142+ spin_unlock_irqrestore(&nxi->addr_lock, irqflags);
10143+out:
10144+ vxdprintk(VXD_CBIT(net, 0),
10145+ "v6_addr_in_nx_info(%p[#%u],%pI6,%04x) = %d",
10146+ nxi, nxi ? nxi->nx_id : 0, addr, mask, ret);
10147+ return ret;
10148+}
d337f35e 10149+
3261cfd5
AM
10150+static inline
10151+int v6_nx_addr_match(struct nx_addr_v6 *nxa, struct nx_addr_v6 *addr, uint16_t mask)
10152+{
10153+ /* FIXME: needs full range checks */
10154+ return v6_addr_match(nxa, &addr->ip, mask);
10155+}
d337f35e 10156+
3261cfd5
AM
10157+static inline
10158+int v6_nx_addr_in_nx_info(struct nx_info *nxi, struct nx_addr_v6 *nxa, uint16_t mask)
10159+{
10160+ struct nx_addr_v6 *ptr;
10161+ unsigned long irqflags;
10162+ int ret = 1;
d337f35e 10163+
3261cfd5
AM
10164+ spin_lock_irqsave(&nxi->addr_lock, irqflags);
10165+ for (ptr = &nxi->v6; ptr; ptr = ptr->next)
10166+ if (v6_nx_addr_match(ptr, nxa, mask))
10167+ goto out_unlock;
10168+ ret = 0;
10169+out_unlock:
10170+ spin_unlock_irqrestore(&nxi->addr_lock, irqflags);
10171+ return ret;
10172+}
d337f35e 10173+
d337f35e 10174+
3261cfd5
AM
10175+/*
10176+ * Check if a given address matches for a socket
10177+ *
10178+ * nxi: the socket's nx_info if any
10179+ * addr: to be verified address
10180+ */
10181+static inline
10182+int v6_sock_addr_match (
10183+ struct nx_info *nxi,
10184+ struct inet_sock *inet,
10185+ struct in6_addr *addr)
10186+{
10187+ struct sock *sk = &inet->sk;
10188+ const struct in6_addr *saddr = inet6_rcv_saddr(sk);
d337f35e 10189+
3261cfd5
AM
10190+ if (!ipv6_addr_any(addr) &&
10191+ ipv6_addr_equal(saddr, addr))
10192+ return 1;
10193+ if (ipv6_addr_any(saddr))
10194+ return v6_addr_in_nx_info(nxi, addr, -1);
10195+ return 0;
10196+}
d337f35e 10197+
3261cfd5
AM
10198+/*
10199+ * check if address is covered by socket
10200+ *
10201+ * sk: the socket to check against
10202+ * addr: the address in question (must be != 0)
10203+ */
d337f35e 10204+
3261cfd5
AM
10205+static inline
10206+int __v6_addr_match_socket(const struct sock *sk, struct nx_addr_v6 *nxa)
10207+{
10208+ struct nx_info *nxi = sk->sk_nx_info;
10209+ const struct in6_addr *saddr = inet6_rcv_saddr(sk);
d337f35e 10210+
3261cfd5
AM
10211+ vxdprintk(VXD_CBIT(net, 5),
10212+ "__v6_addr_in_socket(%p," NXAV6_FMT ") %p:%pI6 %p;%lx",
10213+ sk, NXAV6(nxa), nxi, saddr, sk->sk_socket,
10214+ (sk->sk_socket?sk->sk_socket->flags:0));
d337f35e 10215+
3261cfd5
AM
10216+ if (!ipv6_addr_any(saddr)) { /* direct address match */
10217+ return v6_addr_match(nxa, saddr, -1);
10218+ } else if (nxi) { /* match against nx_info */
10219+ return v6_nx_addr_in_nx_info(nxi, nxa, -1);
10220+ } else { /* unrestricted any socket */
10221+ return 1;
10222+ }
10223+}
d337f35e 10224+
d337f35e 10225+
3261cfd5 10226+/* inet related checks and helpers */
d337f35e 10227+
d337f35e 10228+
3261cfd5
AM
10229+struct in_ifaddr;
10230+struct net_device;
10231+struct sock;
d337f35e 10232+
d337f35e 10233+
3261cfd5
AM
10234+#include <linux/netdevice.h>
10235+#include <linux/inetdevice.h>
10236+#include <net/inet_timewait_sock.h>
d337f35e
JR
10237+
10238+
3261cfd5
AM
10239+int dev_in_nx_info(struct net_device *, struct nx_info *);
10240+int v6_dev_in_nx_info(struct net_device *, struct nx_info *);
10241+int nx_v6_addr_conflict(struct nx_info *, struct nx_info *);
d337f35e 10242+
d337f35e 10243+
d337f35e 10244+
3261cfd5
AM
10245+static inline
10246+int v6_ifa_in_nx_info(struct inet6_ifaddr *ifa, struct nx_info *nxi)
10247+{
10248+ if (!nxi)
10249+ return 1;
10250+ if (!ifa)
10251+ return 0;
10252+ return v6_addr_in_nx_info(nxi, &ifa->addr, -1);
10253+}
d337f35e 10254+
3261cfd5
AM
10255+static inline
10256+int nx_v6_ifa_visible(struct nx_info *nxi, struct inet6_ifaddr *ifa)
10257+{
10258+ vxdprintk(VXD_CBIT(net, 1), "nx_v6_ifa_visible(%p[#%u],%p) %d",
10259+ nxi, nxi ? nxi->nx_id : 0, ifa,
10260+ nxi ? v6_ifa_in_nx_info(ifa, nxi) : 0);
d337f35e 10261+
3261cfd5
AM
10262+ if (!nx_info_flags(nxi, NXF_HIDE_NETIF, 0))
10263+ return 1;
10264+ if (v6_ifa_in_nx_info(ifa, nxi))
10265+ return 1;
10266+ return 0;
10267+}
d337f35e 10268+
d337f35e 10269+
3261cfd5
AM
10270+struct nx_v6_sock_addr {
10271+ struct in6_addr saddr; /* Address used for validation */
10272+ struct in6_addr baddr; /* Address used for socket bind */
10273+};
d337f35e 10274+
3261cfd5
AM
10275+static inline
10276+int v6_map_sock_addr(struct inet_sock *inet, struct sockaddr_in6 *addr,
10277+ struct nx_v6_sock_addr *nsa)
10278+{
10279+ // struct sock *sk = &inet->sk;
10280+ // struct nx_info *nxi = sk->sk_nx_info;
10281+ struct in6_addr saddr = addr->sin6_addr;
10282+ struct in6_addr baddr = saddr;
d337f35e 10283+
3261cfd5
AM
10284+ nsa->saddr = saddr;
10285+ nsa->baddr = baddr;
10286+ return 0;
10287+}
d337f35e 10288+
3261cfd5
AM
10289+static inline
10290+void v6_set_sock_addr(struct inet_sock *inet, struct nx_v6_sock_addr *nsa)
10291+{
10292+ // struct sock *sk = &inet->sk;
10293+ // struct in6_addr *saddr = inet6_rcv_saddr(sk);
d337f35e 10294+
3261cfd5
AM
10295+ // *saddr = nsa->baddr;
10296+ // inet->inet_saddr = nsa->baddr;
10297+}
d337f35e 10298+
3261cfd5
AM
10299+static inline
10300+int nx_info_has_v6(struct nx_info *nxi)
10301+{
10302+ if (!nxi)
10303+ return 1;
10304+ if (NX_IPV6(nxi))
10305+ return 1;
10306+ return 0;
10307+}
d337f35e 10308+
3261cfd5 10309+#else /* CONFIG_IPV6 */
d337f35e 10310+
3261cfd5
AM
10311+static inline
10312+int nx_v6_dev_visible(struct nx_info *n, struct net_device *d)
10313+{
10314+ return 1;
10315+}
d337f35e 10316+
d337f35e 10317+
3261cfd5
AM
10318+static inline
10319+int nx_v6_addr_conflict(struct nx_info *n, uint32_t a, const struct sock *s)
10320+{
10321+ return 1;
10322+}
d337f35e 10323+
3261cfd5
AM
10324+static inline
10325+int v6_ifa_in_nx_info(struct in_ifaddr *a, struct nx_info *n)
10326+{
10327+ return 1;
10328+}
adc1caaa 10329+
3261cfd5
AM
10330+static inline
10331+int nx_info_has_v6(struct nx_info *nxi)
10332+{
10333+ return 0;
10334+}
d337f35e 10335+
3261cfd5
AM
10336+static inline
10337+int v6_addr_in_nx_info(struct nx_info *nxi,
10338+ const struct in6_addr *addr, uint16_t mask)
10339+{
10340+ return 0;
10341+}
d337f35e 10342+
3261cfd5 10343+#endif /* CONFIG_IPV6 */
d337f35e 10344+
3261cfd5
AM
10345+#define current_nx_info_has_v6() \
10346+ nx_info_has_v6(current_nx_info())
d337f35e 10347+
3261cfd5
AM
10348+#else
10349+#warning duplicate inclusion
10350+#endif
10351diff -NurpP --minimal linux-4.9.207/include/linux/vs_inet.h linux-4.9.207-vs2.3.9.11/include/linux/vs_inet.h
10352--- linux-4.9.207/include/linux/vs_inet.h 1970-01-01 00:00:00.000000000 +0000
10353+++ linux-4.9.207-vs2.3.9.11/include/linux/vs_inet.h 2018-10-20 04:58:14.000000000 +0000
10354@@ -0,0 +1,364 @@
10355+#ifndef _VS_INET_H
10356+#define _VS_INET_H
d337f35e 10357+
3261cfd5
AM
10358+#include "vserver/base.h"
10359+#include "vserver/network.h"
10360+#include "vserver/debug.h"
d337f35e 10361+
3261cfd5 10362+#define IPI_LOOPBACK htonl(INADDR_LOOPBACK)
d337f35e 10363+
3261cfd5
AM
10364+#define NXAV4(a) NIPQUAD((a)->ip[0]), NIPQUAD((a)->ip[1]), \
10365+ NIPQUAD((a)->mask), (a)->type
10366+#define NXAV4_FMT "[" NIPQUAD_FMT "-" NIPQUAD_FMT "/" NIPQUAD_FMT ":%04x]"
d337f35e 10367+
3261cfd5
AM
10368+#define NIPQUAD(addr) \
10369+ ((unsigned char *)&addr)[0], \
10370+ ((unsigned char *)&addr)[1], \
10371+ ((unsigned char *)&addr)[2], \
10372+ ((unsigned char *)&addr)[3]
2380c486 10373+
3261cfd5 10374+#define NIPQUAD_FMT "%u.%u.%u.%u"
adc1caaa 10375+
adc1caaa 10376+
3261cfd5
AM
10377+static inline
10378+int v4_addr_match(struct nx_addr_v4 *nxa, __be32 addr, uint16_t tmask)
3bac966d 10379+{
3261cfd5
AM
10380+ __be32 ip = nxa->ip[0].s_addr;
10381+ __be32 mask = nxa->mask.s_addr;
10382+ __be32 bcast = ip | ~mask;
10383+ int ret = 0;
d337f35e 10384+
3261cfd5
AM
10385+ switch (nxa->type & tmask) {
10386+ case NXA_TYPE_MASK:
10387+ ret = (ip == (addr & mask));
10388+ break;
10389+ case NXA_TYPE_ADDR:
10390+ ret = 3;
10391+ if (addr == ip)
10392+ break;
10393+ /* fall through to broadcast */
10394+ case NXA_MOD_BCAST:
10395+ ret = ((tmask & NXA_MOD_BCAST) && (addr == bcast));
10396+ break;
10397+ case NXA_TYPE_RANGE:
10398+ ret = ((nxa->ip[0].s_addr <= addr) &&
10399+ (nxa->ip[1].s_addr > addr));
10400+ break;
10401+ case NXA_TYPE_ANY:
10402+ ret = 2;
10403+ break;
d33d7b00 10404+ }
d337f35e 10405+
3261cfd5
AM
10406+ vxdprintk(VXD_CBIT(net, 0),
10407+ "v4_addr_match(%p" NXAV4_FMT "," NIPQUAD_FMT ",%04x) = %d",
10408+ nxa, NXAV4(nxa), NIPQUAD(addr), tmask, ret);
10409+ return ret;
d33d7b00 10410+}
d337f35e 10411+
3bac966d 10412+static inline
3261cfd5 10413+int v4_addr_in_nx_info(struct nx_info *nxi, __be32 addr, uint16_t tmask)
3bac966d 10414+{
3261cfd5
AM
10415+ struct nx_addr_v4 *nxa;
10416+ unsigned long irqflags;
10417+ int ret = 1;
d337f35e 10418+
3261cfd5
AM
10419+ if (!nxi)
10420+ goto out;
10421+
10422+ ret = 2;
10423+ /* allow 127.0.0.1 when remapping lback */
10424+ if ((tmask & NXA_LOOPBACK) &&
10425+ (addr == IPI_LOOPBACK) &&
10426+ nx_info_flags(nxi, NXF_LBACK_REMAP, 0))
10427+ goto out;
10428+ ret = 3;
10429+ /* check for lback address */
10430+ if ((tmask & NXA_MOD_LBACK) &&
10431+ (nxi->v4_lback.s_addr == addr))
10432+ goto out;
10433+ ret = 4;
10434+ /* check for broadcast address */
10435+ if ((tmask & NXA_MOD_BCAST) &&
10436+ (nxi->v4_bcast.s_addr == addr))
10437+ goto out;
10438+ ret = 5;
10439+
10440+ /* check for v4 addresses */
10441+ spin_lock_irqsave(&nxi->addr_lock, irqflags);
10442+ for (nxa = &nxi->v4; nxa; nxa = nxa->next)
10443+ if (v4_addr_match(nxa, addr, tmask))
10444+ goto out_unlock;
10445+ ret = 0;
10446+out_unlock:
10447+ spin_unlock_irqrestore(&nxi->addr_lock, irqflags);
10448+out:
10449+ vxdprintk(VXD_CBIT(net, 0),
10450+ "v4_addr_in_nx_info(%p[#%u]," NIPQUAD_FMT ",%04x) = %d",
10451+ nxi, nxi ? nxi->nx_id : 0, NIPQUAD(addr), tmask, ret);
10452+ return ret;
3bac966d 10453+}
d337f35e 10454+
3bac966d 10455+static inline
3261cfd5 10456+int v4_nx_addr_match(struct nx_addr_v4 *nxa, struct nx_addr_v4 *addr, uint16_t mask)
3bac966d 10457+{
3261cfd5
AM
10458+ /* FIXME: needs full range checks */
10459+ return v4_addr_match(nxa, addr->ip[0].s_addr, mask);
3bac966d 10460+}
d337f35e 10461+
3bac966d 10462+static inline
3261cfd5 10463+int v4_nx_addr_in_nx_info(struct nx_info *nxi, struct nx_addr_v4 *nxa, uint16_t mask)
3bac966d 10464+{
3261cfd5
AM
10465+ struct nx_addr_v4 *ptr;
10466+ unsigned long irqflags;
10467+ int ret = 1;
d337f35e 10468+
3261cfd5
AM
10469+ spin_lock_irqsave(&nxi->addr_lock, irqflags);
10470+ for (ptr = &nxi->v4; ptr; ptr = ptr->next)
10471+ if (v4_nx_addr_match(ptr, nxa, mask))
10472+ goto out_unlock;
10473+ ret = 0;
10474+out_unlock:
10475+ spin_unlock_irqrestore(&nxi->addr_lock, irqflags);
10476+ return ret;
10477+}
2380c486 10478+
3261cfd5 10479+#include <net/inet_sock.h>
d337f35e 10480+
3261cfd5
AM
10481+/*
10482+ * Check if a given address matches for a socket
10483+ *
10484+ * nxi: the socket's nx_info if any
10485+ * addr: to be verified address
10486+ */
10487+static inline
10488+int v4_sock_addr_match (
10489+ struct nx_info *nxi,
10490+ struct inet_sock *inet,
10491+ __be32 addr)
3bac966d 10492+{
3261cfd5
AM
10493+ __be32 saddr = inet->inet_rcv_saddr;
10494+ __be32 bcast = nxi ? nxi->v4_bcast.s_addr : INADDR_BROADCAST;
d337f35e 10495+
3261cfd5 10496+ if (addr && (saddr == addr || bcast == addr))
3bac966d 10497+ return 1;
3261cfd5
AM
10498+ if (!saddr)
10499+ return v4_addr_in_nx_info(nxi, addr, NXA_MASK_BIND);
10500+ return 0;
10501+}
d337f35e 10502+
d337f35e 10503+
3261cfd5 10504+/* inet related checks and helpers */
d337f35e 10505+
d337f35e 10506+
3261cfd5
AM
10507+struct in_ifaddr;
10508+struct net_device;
10509+struct sock;
d337f35e 10510+
3261cfd5 10511+#ifdef CONFIG_INET
d33d7b00 10512+
3261cfd5
AM
10513+#include <linux/netdevice.h>
10514+#include <linux/inetdevice.h>
10515+#include <net/inet_sock.h>
10516+#include <net/inet_timewait_sock.h>
d337f35e 10517+
d337f35e 10518+
3261cfd5
AM
10519+int dev_in_nx_info(struct net_device *, struct nx_info *);
10520+int v4_dev_in_nx_info(struct net_device *, struct nx_info *);
10521+int nx_v4_addr_conflict(struct nx_info *, struct nx_info *);
10522+
10523+
10524+/*
10525+ * check if address is covered by socket
10526+ *
10527+ * sk: the socket to check against
10528+ * addr: the address in question (must be != 0)
10529+ */
d337f35e 10530+
3bac966d 10531+static inline
3261cfd5 10532+int __v4_addr_match_socket(const struct sock *sk, struct nx_addr_v4 *nxa)
3bac966d 10533+{
3261cfd5
AM
10534+ struct nx_info *nxi = sk->sk_nx_info;
10535+ __be32 saddr = sk->sk_rcv_saddr;
d337f35e 10536+
3261cfd5
AM
10537+ vxdprintk(VXD_CBIT(net, 5),
10538+ "__v4_addr_in_socket(%p," NXAV4_FMT ") %p:" NIPQUAD_FMT " %p;%lx",
10539+ sk, NXAV4(nxa), nxi, NIPQUAD(saddr), sk->sk_socket,
10540+ (sk->sk_socket?sk->sk_socket->flags:0));
10541+
10542+ if (saddr) { /* direct address match */
10543+ return v4_addr_match(nxa, saddr, -1);
10544+ } else if (nxi) { /* match against nx_info */
10545+ return v4_nx_addr_in_nx_info(nxi, nxa, -1);
10546+ } else { /* unrestricted any socket */
10547+ return 1;
d33d7b00 10548+ }
3bac966d 10549+}
d337f35e 10550+
3261cfd5
AM
10551+
10552+
3bac966d 10553+static inline
3261cfd5 10554+int nx_dev_visible(struct nx_info *nxi, struct net_device *dev)
3bac966d 10555+{
3261cfd5
AM
10556+ vxdprintk(VXD_CBIT(net, 1),
10557+ "nx_dev_visible(%p[#%u],%p " VS_Q("%s") ") %d",
10558+ nxi, nxi ? nxi->nx_id : 0, dev, dev->name,
10559+ nxi ? dev_in_nx_info(dev, nxi) : 0);
d337f35e 10560+
3261cfd5
AM
10561+ if (!nx_info_flags(nxi, NXF_HIDE_NETIF, 0))
10562+ return 1;
10563+ if (dev_in_nx_info(dev, nxi))
10564+ return 1;
10565+ return 0;
10566+}
d33d7b00 10567+
d33d7b00 10568+
3261cfd5
AM
10569+static inline
10570+int v4_ifa_in_nx_info(struct in_ifaddr *ifa, struct nx_info *nxi)
10571+{
10572+ if (!nxi)
10573+ return 1;
10574+ if (!ifa)
10575+ return 0;
10576+ return v4_addr_in_nx_info(nxi, ifa->ifa_local, NXA_MASK_SHOW);
3bac966d 10577+}
d337f35e 10578+
3261cfd5
AM
10579+static inline
10580+int nx_v4_ifa_visible(struct nx_info *nxi, struct in_ifaddr *ifa)
3bac966d 10581+{
3261cfd5
AM
10582+ vxdprintk(VXD_CBIT(net, 1), "nx_v4_ifa_visible(%p[#%u],%p) %d",
10583+ nxi, nxi ? nxi->nx_id : 0, ifa,
10584+ nxi ? v4_ifa_in_nx_info(ifa, nxi) : 0);
d33d7b00 10585+
3261cfd5 10586+ if (!nx_info_flags(nxi, NXF_HIDE_NETIF, 0))
3bac966d 10587+ return 1;
3261cfd5 10588+ if (v4_ifa_in_nx_info(ifa, nxi))
3bac966d 10589+ return 1;
3261cfd5
AM
10590+ return 0;
10591+}
d337f35e
JR
10592+
10593+
3261cfd5
AM
10594+struct nx_v4_sock_addr {
10595+ __be32 saddr; /* Address used for validation */
10596+ __be32 baddr; /* Address used for socket bind */
10597+};
d33d7b00 10598+
3261cfd5
AM
10599+static inline
10600+int v4_map_sock_addr(struct inet_sock *inet, struct sockaddr_in *addr,
10601+ struct nx_v4_sock_addr *nsa)
10602+{
10603+ struct sock *sk = &inet->sk;
10604+ struct nx_info *nxi = sk->sk_nx_info;
10605+ __be32 saddr = addr->sin_addr.s_addr;
10606+ __be32 baddr = saddr;
10607+
10608+ vxdprintk(VXD_CBIT(net, 3),
10609+ "inet_bind(%p)* %p,%p;%lx " NIPQUAD_FMT,
10610+ sk, sk->sk_nx_info, sk->sk_socket,
10611+ (sk->sk_socket ? sk->sk_socket->flags : 0),
10612+ NIPQUAD(saddr));
d337f35e 10613+
3261cfd5
AM
10614+ if (nxi) {
10615+ if (saddr == INADDR_ANY) {
10616+ if (nx_info_flags(nxi, NXF_SINGLE_IP, 0))
10617+ baddr = nxi->v4.ip[0].s_addr;
10618+ } else if (saddr == IPI_LOOPBACK) {
10619+ if (nx_info_flags(nxi, NXF_LBACK_REMAP, 0))
10620+ baddr = nxi->v4_lback.s_addr;
10621+ } else if (!ipv4_is_multicast(saddr) ||
10622+ !nx_info_ncaps(nxi, NXC_MULTICAST)) {
10623+ /* normal address bind */
10624+ if (!v4_addr_in_nx_info(nxi, saddr, NXA_MASK_BIND))
10625+ return -EADDRNOTAVAIL;
10626+ }
10627+ }
d337f35e 10628+
3261cfd5
AM
10629+ vxdprintk(VXD_CBIT(net, 3),
10630+ "inet_bind(%p) " NIPQUAD_FMT ", " NIPQUAD_FMT,
10631+ sk, NIPQUAD(saddr), NIPQUAD(baddr));
10632+
10633+ nsa->saddr = saddr;
10634+ nsa->baddr = baddr;
10635+ return 0;
10636+}
10637+
10638+static inline
10639+void v4_set_sock_addr(struct inet_sock *inet, struct nx_v4_sock_addr *nsa)
3bac966d 10640+{
3261cfd5
AM
10641+ inet->inet_saddr = nsa->baddr;
10642+ inet->inet_rcv_saddr = nsa->baddr;
10643+}
d337f35e 10644+
d337f35e 10645+
3261cfd5
AM
10646+/*
10647+ * helper to simplify inet_lookup_listener
10648+ *
10649+ * nxi: the socket's nx_info if any
10650+ * addr: to be verified address
10651+ * saddr: socket address
10652+ */
10653+static inline int v4_inet_addr_match (
10654+ struct nx_info *nxi,
10655+ __be32 addr,
10656+ __be32 saddr)
10657+{
10658+ if (addr && (saddr == addr))
10659+ return 1;
10660+ if (!saddr)
10661+ return nxi ? v4_addr_in_nx_info(nxi, addr, NXA_MASK_BIND) : 1;
10662+ return 0;
10663+}
d33d7b00 10664+
3261cfd5
AM
10665+static inline __be32 nx_map_sock_lback(struct nx_info *nxi, __be32 addr)
10666+{
10667+ if (nx_info_flags(nxi, NXF_HIDE_LBACK, 0) &&
10668+ (addr == nxi->v4_lback.s_addr))
10669+ return IPI_LOOPBACK;
10670+ return addr;
10671+}
d33d7b00 10672+
3261cfd5
AM
10673+static inline
10674+int nx_info_has_v4(struct nx_info *nxi)
10675+{
10676+ if (!nxi)
10677+ return 1;
10678+ if (NX_IPV4(nxi))
10679+ return 1;
10680+ if (nx_info_flags(nxi, NXF_LBACK_REMAP, 0))
10681+ return 1;
10682+ return 0;
3bac966d 10683+}
d337f35e 10684+
3261cfd5 10685+#else /* CONFIG_INET */
d337f35e 10686+
3261cfd5
AM
10687+static inline
10688+int nx_dev_visible(struct nx_info *n, struct net_device *d)
10689+{
10690+ return 1;
10691+}
d337f35e 10692+
3261cfd5
AM
10693+static inline
10694+int nx_v4_addr_conflict(struct nx_info *n, uint32_t a, const struct sock *s)
10695+{
10696+ return 1;
10697+}
d337f35e 10698+
3261cfd5
AM
10699+static inline
10700+int v4_ifa_in_nx_info(struct in_ifaddr *a, struct nx_info *n)
10701+{
10702+ return 1;
10703+}
d337f35e 10704+
3261cfd5
AM
10705+static inline
10706+int nx_info_has_v4(struct nx_info *nxi)
10707+{
10708+ return 0;
10709+}
d337f35e 10710+
3261cfd5 10711+#endif /* CONFIG_INET */
d337f35e 10712+
3261cfd5
AM
10713+#define current_nx_info_has_v4() \
10714+ nx_info_has_v4(current_nx_info())
d337f35e 10715+
3261cfd5
AM
10716+#else
10717+// #warning duplicate inclusion
10718+#endif
10719diff -NurpP --minimal linux-4.9.207/include/linux/vs_limit.h linux-4.9.207-vs2.3.9.11/include/linux/vs_limit.h
10720--- linux-4.9.207/include/linux/vs_limit.h 1970-01-01 00:00:00.000000000 +0000
10721+++ linux-4.9.207-vs2.3.9.11/include/linux/vs_limit.h 2018-10-20 04:58:14.000000000 +0000
10722@@ -0,0 +1,140 @@
10723+#ifndef _VS_LIMIT_H
10724+#define _VS_LIMIT_H
d337f35e 10725+
3261cfd5
AM
10726+#include "vserver/limit.h"
10727+#include "vserver/base.h"
10728+#include "vserver/context.h"
10729+#include "vserver/debug.h"
10730+#include "vserver/context.h"
10731+#include "vserver/limit_int.h"
d337f35e
JR
10732+
10733+
3261cfd5
AM
10734+#define vx_acc_cres(v, d, p, r) \
10735+ __vx_acc_cres(v, r, d, p, __FILE__, __LINE__)
d337f35e 10736+
3261cfd5
AM
10737+#define vx_acc_cres_cond(x, d, p, r) \
10738+ __vx_acc_cres(((x) == vx_current_xid()) ? current_vx_info() : 0, \
10739+ r, d, p, __FILE__, __LINE__)
d337f35e 10740+
d337f35e 10741+
3261cfd5
AM
10742+#define vx_add_cres(v, a, p, r) \
10743+ __vx_add_cres(v, r, a, p, __FILE__, __LINE__)
10744+#define vx_sub_cres(v, a, p, r) vx_add_cres(v, -(a), p, r)
d337f35e 10745+
3261cfd5
AM
10746+#define vx_add_cres_cond(x, a, p, r) \
10747+ __vx_add_cres(((x) == vx_current_xid()) ? current_vx_info() : 0, \
10748+ r, a, p, __FILE__, __LINE__)
10749+#define vx_sub_cres_cond(x, a, p, r) vx_add_cres_cond(x, -(a), p, r)
d337f35e
JR
10750+
10751+
3261cfd5 10752+/* process and file limits */
d337f35e 10753+
3261cfd5
AM
10754+#define vx_nproc_inc(p) \
10755+ vx_acc_cres((p)->vx_info, 1, p, RLIMIT_NPROC)
d337f35e 10756+
3261cfd5
AM
10757+#define vx_nproc_dec(p) \
10758+ vx_acc_cres((p)->vx_info,-1, p, RLIMIT_NPROC)
10759+
10760+#define vx_files_inc(f) \
10761+ vx_acc_cres_cond((f)->f_xid, 1, f, RLIMIT_NOFILE)
d337f35e 10762+
3261cfd5
AM
10763+#define vx_files_dec(f) \
10764+ vx_acc_cres_cond((f)->f_xid,-1, f, RLIMIT_NOFILE)
d337f35e 10765+
3261cfd5
AM
10766+#define vx_locks_inc(l) \
10767+ vx_acc_cres_cond((l)->fl_xid, 1, l, RLIMIT_LOCKS)
d337f35e 10768+
3261cfd5
AM
10769+#define vx_locks_dec(l) \
10770+ vx_acc_cres_cond((l)->fl_xid,-1, l, RLIMIT_LOCKS)
d337f35e 10771+
3261cfd5
AM
10772+#define vx_openfd_inc(f) \
10773+ vx_acc_cres(current_vx_info(), 1, (void *)(long)(f), VLIMIT_OPENFD)
d337f35e 10774+
3261cfd5
AM
10775+#define vx_openfd_dec(f) \
10776+ vx_acc_cres(current_vx_info(),-1, (void *)(long)(f), VLIMIT_OPENFD)
d337f35e 10777+
d337f35e 10778+
3261cfd5
AM
10779+#define vx_cres_avail(v, n, r) \
10780+ __vx_cres_avail(v, r, n, __FILE__, __LINE__)
d337f35e 10781+
d337f35e 10782+
3261cfd5
AM
10783+#define vx_nproc_avail(n) \
10784+ vx_cres_avail(current_vx_info(), n, RLIMIT_NPROC)
d337f35e 10785+
3261cfd5
AM
10786+#define vx_files_avail(n) \
10787+ vx_cres_avail(current_vx_info(), n, RLIMIT_NOFILE)
d337f35e 10788+
3261cfd5
AM
10789+#define vx_locks_avail(n) \
10790+ vx_cres_avail(current_vx_info(), n, RLIMIT_LOCKS)
d337f35e 10791+
3261cfd5
AM
10792+#define vx_openfd_avail(n) \
10793+ vx_cres_avail(current_vx_info(), n, VLIMIT_OPENFD)
d33d7b00 10794+
d337f35e 10795+
3261cfd5 10796+/* dentry limits */
d337f35e 10797+
3261cfd5
AM
10798+#define vx_dentry_inc(d) do { \
10799+ if (d_count(d) == 1) \
10800+ vx_acc_cres(current_vx_info(), 1, d, VLIMIT_DENTRY); \
10801+ } while (0)
d337f35e 10802+
3261cfd5
AM
10803+#define vx_dentry_dec(d) do { \
10804+ if (d_count(d) == 0) \
10805+ vx_acc_cres(current_vx_info(),-1, d, VLIMIT_DENTRY); \
10806+ } while (0)
d337f35e 10807+
3261cfd5
AM
10808+#define vx_dentry_avail(n) \
10809+ vx_cres_avail(current_vx_info(), n, VLIMIT_DENTRY)
d337f35e 10810+
9795bf04 10811+
3261cfd5 10812+/* socket limits */
d337f35e 10813+
3261cfd5
AM
10814+#define vx_sock_inc(s) \
10815+ vx_acc_cres((s)->sk_vx_info, 1, s, VLIMIT_NSOCK)
d337f35e 10816+
3261cfd5
AM
10817+#define vx_sock_dec(s) \
10818+ vx_acc_cres((s)->sk_vx_info,-1, s, VLIMIT_NSOCK)
d337f35e 10819+
3261cfd5
AM
10820+#define vx_sock_avail(n) \
10821+ vx_cres_avail(current_vx_info(), n, VLIMIT_NSOCK)
d337f35e 10822+
d337f35e 10823+
3261cfd5 10824+/* ipc resource limits */
d337f35e 10825+
3261cfd5
AM
10826+#define vx_ipcmsg_add(v, u, a) \
10827+ vx_add_cres(v, a, u, RLIMIT_MSGQUEUE)
d337f35e 10828+
3261cfd5
AM
10829+#define vx_ipcmsg_sub(v, u, a) \
10830+ vx_sub_cres(v, a, u, RLIMIT_MSGQUEUE)
d337f35e 10831+
3261cfd5
AM
10832+#define vx_ipcmsg_avail(v, a) \
10833+ vx_cres_avail(v, a, RLIMIT_MSGQUEUE)
d337f35e 10834+
d337f35e 10835+
3261cfd5
AM
10836+#define vx_ipcshm_add(v, k, a) \
10837+ vx_add_cres(v, a, (void *)(long)(k), VLIMIT_SHMEM)
d337f35e 10838+
3261cfd5
AM
10839+#define vx_ipcshm_sub(v, k, a) \
10840+ vx_sub_cres(v, a, (void *)(long)(k), VLIMIT_SHMEM)
d337f35e 10841+
3261cfd5
AM
10842+#define vx_ipcshm_avail(v, a) \
10843+ vx_cres_avail(v, a, VLIMIT_SHMEM)
d337f35e 10844+
d337f35e 10845+
3261cfd5
AM
10846+#define vx_semary_inc(a) \
10847+ vx_acc_cres(current_vx_info(), 1, a, VLIMIT_SEMARY)
10848+
10849+#define vx_semary_dec(a) \
10850+ vx_acc_cres(current_vx_info(), -1, a, VLIMIT_SEMARY)
d337f35e 10851+
d337f35e 10852+
3261cfd5
AM
10853+#define vx_nsems_add(a,n) \
10854+ vx_add_cres(current_vx_info(), n, a, VLIMIT_NSEMS)
d337f35e 10855+
3261cfd5
AM
10856+#define vx_nsems_sub(a,n) \
10857+ vx_sub_cres(current_vx_info(), n, a, VLIMIT_NSEMS)
10858+
10859+
10860+#else
4bf69007 10861+#warning duplicate inclusion
3261cfd5
AM
10862+#endif
10863diff -NurpP --minimal linux-4.9.207/include/linux/vs_network.h linux-4.9.207-vs2.3.9.11/include/linux/vs_network.h
10864--- linux-4.9.207/include/linux/vs_network.h 1970-01-01 00:00:00.000000000 +0000
10865+++ linux-4.9.207-vs2.3.9.11/include/linux/vs_network.h 2018-10-20 04:58:14.000000000 +0000
10866@@ -0,0 +1,169 @@
10867+#ifndef _NX_VS_NETWORK_H
10868+#define _NX_VS_NETWORK_H
2380c486 10869+
3261cfd5
AM
10870+#include "vserver/context.h"
10871+#include "vserver/network.h"
10872+#include "vserver/base.h"
10873+#include "vserver/check.h"
10874+#include "vserver/debug.h"
2380c486 10875+
3261cfd5 10876+#include <linux/sched.h>
d337f35e 10877+
d337f35e 10878+
3261cfd5 10879+#define get_nx_info(i) __get_nx_info(i, __FILE__, __LINE__)
d33d7b00 10880+
3261cfd5
AM
10881+static inline struct nx_info *__get_nx_info(struct nx_info *nxi,
10882+ const char *_file, int _line)
10883+{
10884+ if (!nxi)
10885+ return NULL;
d33d7b00 10886+
3261cfd5
AM
10887+ vxlprintk(VXD_CBIT(nid, 2), "get_nx_info(%p[#%d.%d])",
10888+ nxi, nxi ? nxi->nx_id : 0,
10889+ nxi ? atomic_read(&nxi->nx_usecnt) : 0,
10890+ _file, _line);
d337f35e 10891+
3261cfd5
AM
10892+ atomic_inc(&nxi->nx_usecnt);
10893+ return nxi;
10894+}
d337f35e 10895+
d337f35e 10896+
3261cfd5 10897+extern void free_nx_info(struct nx_info *);
d337f35e 10898+
3261cfd5 10899+#define put_nx_info(i) __put_nx_info(i, __FILE__, __LINE__)
d337f35e 10900+
3261cfd5
AM
10901+static inline void __put_nx_info(struct nx_info *nxi, const char *_file, int _line)
10902+{
10903+ if (!nxi)
10904+ return;
10905+
10906+ vxlprintk(VXD_CBIT(nid, 2), "put_nx_info(%p[#%d.%d])",
10907+ nxi, nxi ? nxi->nx_id : 0,
10908+ nxi ? atomic_read(&nxi->nx_usecnt) : 0,
10909+ _file, _line);
d337f35e 10910+
3261cfd5
AM
10911+ if (atomic_dec_and_test(&nxi->nx_usecnt))
10912+ free_nx_info(nxi);
10913+}
d337f35e 10914+
d337f35e 10915+
3261cfd5
AM
10916+#define init_nx_info(p, i) __init_nx_info(p, i, __FILE__, __LINE__)
10917+
10918+static inline void __init_nx_info(struct nx_info **nxp, struct nx_info *nxi,
10919+ const char *_file, int _line)
4bf69007 10920+{
3261cfd5
AM
10921+ if (nxi) {
10922+ vxlprintk(VXD_CBIT(nid, 3),
10923+ "init_nx_info(%p[#%d.%d])",
10924+ nxi, nxi ? nxi->nx_id : 0,
10925+ nxi ? atomic_read(&nxi->nx_usecnt) : 0,
10926+ _file, _line);
10927+
10928+ atomic_inc(&nxi->nx_usecnt);
10929+ }
10930+ *nxp = nxi;
4bf69007 10931+}
d337f35e 10932+
4bf69007 10933+
3261cfd5 10934+#define set_nx_info(p, i) __set_nx_info(p, i, __FILE__, __LINE__)
d337f35e 10935+
3261cfd5
AM
10936+static inline void __set_nx_info(struct nx_info **nxp, struct nx_info *nxi,
10937+ const char *_file, int _line)
10938+{
10939+ struct nx_info *nxo;
d337f35e 10940+
3261cfd5
AM
10941+ if (!nxi)
10942+ return;
4bf69007 10943+
3261cfd5
AM
10944+ vxlprintk(VXD_CBIT(nid, 3), "set_nx_info(%p[#%d.%d])",
10945+ nxi, nxi ? nxi->nx_id : 0,
10946+ nxi ? atomic_read(&nxi->nx_usecnt) : 0,
10947+ _file, _line);
4bf69007 10948+
3261cfd5
AM
10949+ atomic_inc(&nxi->nx_usecnt);
10950+ nxo = xchg(nxp, nxi);
10951+ BUG_ON(nxo);
10952+}
d337f35e 10953+
3261cfd5 10954+#define clr_nx_info(p) __clr_nx_info(p, __FILE__, __LINE__)
d337f35e 10955+
3261cfd5
AM
10956+static inline void __clr_nx_info(struct nx_info **nxp,
10957+ const char *_file, int _line)
10958+{
10959+ struct nx_info *nxo;
d337f35e 10960+
3261cfd5
AM
10961+ nxo = xchg(nxp, NULL);
10962+ if (!nxo)
10963+ return;
d337f35e 10964+
3261cfd5
AM
10965+ vxlprintk(VXD_CBIT(nid, 3), "clr_nx_info(%p[#%d.%d])",
10966+ nxo, nxo ? nxo->nx_id : 0,
10967+ nxo ? atomic_read(&nxo->nx_usecnt) : 0,
10968+ _file, _line);
d337f35e 10969+
3261cfd5
AM
10970+ if (atomic_dec_and_test(&nxo->nx_usecnt))
10971+ free_nx_info(nxo);
10972+}
d337f35e 10973+
adc1caaa 10974+
3261cfd5 10975+#define claim_nx_info(v, p) __claim_nx_info(v, p, __FILE__, __LINE__)
d337f35e 10976+
3261cfd5
AM
10977+static inline void __claim_nx_info(struct nx_info *nxi,
10978+ struct task_struct *task, const char *_file, int _line)
10979+{
10980+ vxlprintk(VXD_CBIT(nid, 3), "claim_nx_info(%p[#%d.%d.%d]) %p",
10981+ nxi, nxi ? nxi->nx_id : 0,
10982+ nxi?atomic_read(&nxi->nx_usecnt):0,
10983+ nxi?atomic_read(&nxi->nx_tasks):0,
10984+ task, _file, _line);
d337f35e 10985+
3261cfd5
AM
10986+ atomic_inc(&nxi->nx_tasks);
10987+}
d337f35e 10988+
9f7054f1 10989+
3261cfd5 10990+extern void unhash_nx_info(struct nx_info *);
9f7054f1 10991+
3261cfd5 10992+#define release_nx_info(v, p) __release_nx_info(v, p, __FILE__, __LINE__)
d337f35e 10993+
3261cfd5
AM
10994+static inline void __release_nx_info(struct nx_info *nxi,
10995+ struct task_struct *task, const char *_file, int _line)
10996+{
10997+ vxlprintk(VXD_CBIT(nid, 3), "release_nx_info(%p[#%d.%d.%d]) %p",
10998+ nxi, nxi ? nxi->nx_id : 0,
10999+ nxi ? atomic_read(&nxi->nx_usecnt) : 0,
11000+ nxi ? atomic_read(&nxi->nx_tasks) : 0,
11001+ task, _file, _line);
d337f35e 11002+
3261cfd5 11003+ might_sleep();
d337f35e 11004+
3261cfd5
AM
11005+ if (atomic_dec_and_test(&nxi->nx_tasks))
11006+ unhash_nx_info(nxi);
11007+}
d337f35e 11008+
d337f35e 11009+
3261cfd5 11010+#define task_get_nx_info(i) __task_get_nx_info(i, __FILE__, __LINE__)
2380c486 11011+
3261cfd5
AM
11012+static __inline__ struct nx_info *__task_get_nx_info(struct task_struct *p,
11013+ const char *_file, int _line)
11014+{
11015+ struct nx_info *nxi;
d337f35e 11016+
3261cfd5
AM
11017+ task_lock(p);
11018+ vxlprintk(VXD_CBIT(nid, 5), "task_get_nx_info(%p)",
11019+ p, _file, _line);
11020+ nxi = __get_nx_info(p->nx_info, _file, _line);
11021+ task_unlock(p);
11022+ return nxi;
11023+}
d337f35e 11024+
d337f35e 11025+
3261cfd5
AM
11026+static inline void exit_nx_info(struct task_struct *p)
11027+{
11028+ if (p->nx_info)
11029+ release_nx_info(p->nx_info, p);
11030+}
9f7054f1 11031+
d337f35e 11032+
4bf69007 11033+#else
3261cfd5 11034+#warning duplicate inclusion
4bf69007 11035+#endif
3261cfd5
AM
11036diff -NurpP --minimal linux-4.9.207/include/linux/vs_pid.h linux-4.9.207-vs2.3.9.11/include/linux/vs_pid.h
11037--- linux-4.9.207/include/linux/vs_pid.h 1970-01-01 00:00:00.000000000 +0000
11038+++ linux-4.9.207-vs2.3.9.11/include/linux/vs_pid.h 2018-10-20 04:58:14.000000000 +0000
11039@@ -0,0 +1,50 @@
11040+#ifndef _VS_PID_H
11041+#define _VS_PID_H
2380c486 11042+
3261cfd5
AM
11043+#include "vserver/base.h"
11044+#include "vserver/check.h"
11045+#include "vserver/context.h"
11046+#include "vserver/debug.h"
11047+#include "vserver/pid.h"
11048+#include <linux/pid_namespace.h>
2380c486 11049+
d337f35e 11050+
3261cfd5 11051+#define VXF_FAKE_INIT (VXF_INFO_INIT | VXF_STATE_INIT)
d337f35e 11052+
3261cfd5
AM
11053+static inline
11054+int vx_proc_task_visible(struct task_struct *task)
11055+{
11056+ if ((task->pid == 1) &&
11057+ !vx_flags(VXF_FAKE_INIT, VXF_FAKE_INIT))
11058+ /* show a blend through init */
11059+ goto visible;
11060+ if (vx_check(vx_task_xid(task), VS_WATCH | VS_IDENT))
11061+ goto visible;
11062+ return 0;
11063+visible:
11064+ return 1;
11065+}
d337f35e 11066+
3261cfd5 11067+#define find_task_by_real_pid(pid) find_task_by_pid_ns(pid, &init_pid_ns)
d337f35e
JR
11068+
11069+
3261cfd5
AM
11070+static inline
11071+struct task_struct *vx_get_proc_task(struct inode *inode, struct pid *pid)
11072+{
11073+ struct task_struct *task = get_pid_task(pid, PIDTYPE_PID);
d337f35e 11074+
3261cfd5
AM
11075+ if (task && !vx_proc_task_visible(task)) {
11076+ vxdprintk(VXD_CBIT(misc, 6),
11077+ "dropping task (get) %p[#%u,%u] for %p[#%u,%u]",
11078+ task, task->xid, task->pid,
11079+ current, current->xid, current->pid);
11080+ put_task_struct(task);
11081+ task = NULL;
11082+ }
11083+ return task;
11084+}
d337f35e 11085+
d337f35e 11086+
3261cfd5
AM
11087+#else
11088+#warning duplicate inclusion
11089+#endif
11090diff -NurpP --minimal linux-4.9.207/include/linux/vs_sched.h linux-4.9.207-vs2.3.9.11/include/linux/vs_sched.h
11091--- linux-4.9.207/include/linux/vs_sched.h 1970-01-01 00:00:00.000000000 +0000
11092+++ linux-4.9.207-vs2.3.9.11/include/linux/vs_sched.h 2018-10-20 04:58:14.000000000 +0000
11093@@ -0,0 +1,40 @@
11094+#ifndef _VS_SCHED_H
11095+#define _VS_SCHED_H
d337f35e 11096+
3261cfd5
AM
11097+#include "vserver/base.h"
11098+#include "vserver/context.h"
11099+#include "vserver/sched.h"
d337f35e 11100+
d337f35e 11101+
3261cfd5
AM
11102+#define MAX_PRIO_BIAS 20
11103+#define MIN_PRIO_BIAS -20
d337f35e 11104+
3261cfd5
AM
11105+static inline
11106+int vx_adjust_prio(struct task_struct *p, int prio, int max_user)
11107+{
11108+ struct vx_info *vxi = p->vx_info;
d337f35e 11109+
3261cfd5
AM
11110+ if (vxi)
11111+ prio += vx_cpu(vxi, sched_pc).prio_bias;
11112+ return prio;
11113+}
d337f35e 11114+
3261cfd5
AM
11115+static inline void vx_account_user(struct vx_info *vxi,
11116+ cputime_t cputime, int nice)
11117+{
11118+ if (!vxi)
11119+ return;
11120+ vx_cpu(vxi, sched_pc).user_ticks += cputime;
11121+}
d337f35e 11122+
3261cfd5
AM
11123+static inline void vx_account_system(struct vx_info *vxi,
11124+ cputime_t cputime, int idle)
11125+{
11126+ if (!vxi)
11127+ return;
11128+ vx_cpu(vxi, sched_pc).sys_ticks += cputime;
11129+}
d337f35e 11130+
3261cfd5
AM
11131+#else
11132+#warning duplicate inclusion
4bf69007 11133+#endif
3261cfd5
AM
11134diff -NurpP --minimal linux-4.9.207/include/linux/vs_socket.h linux-4.9.207-vs2.3.9.11/include/linux/vs_socket.h
11135--- linux-4.9.207/include/linux/vs_socket.h 1970-01-01 00:00:00.000000000 +0000
11136+++ linux-4.9.207-vs2.3.9.11/include/linux/vs_socket.h 2018-10-20 04:58:14.000000000 +0000
11137@@ -0,0 +1,67 @@
11138+#ifndef _VS_SOCKET_H
11139+#define _VS_SOCKET_H
d337f35e 11140+
3261cfd5
AM
11141+#include "vserver/debug.h"
11142+#include "vserver/base.h"
11143+#include "vserver/cacct.h"
11144+#include "vserver/context.h"
11145+#include "vserver/tag.h"
d337f35e 11146+
3bac966d 11147+
3261cfd5 11148+/* socket accounting */
d337f35e 11149+
3261cfd5 11150+#include <linux/socket.h>
d337f35e 11151+
3261cfd5
AM
11152+static inline int vx_sock_type(int family)
11153+{
11154+ switch (family) {
11155+ case PF_UNSPEC:
11156+ return VXA_SOCK_UNSPEC;
11157+ case PF_UNIX:
11158+ return VXA_SOCK_UNIX;
11159+ case PF_INET:
11160+ return VXA_SOCK_INET;
11161+ case PF_INET6:
11162+ return VXA_SOCK_INET6;
11163+ case PF_PACKET:
11164+ return VXA_SOCK_PACKET;
11165+ default:
11166+ return VXA_SOCK_OTHER;
11167+ }
11168+}
d337f35e 11169+
3261cfd5
AM
11170+#define vx_acc_sock(v, f, p, s) \
11171+ __vx_acc_sock(v, f, p, s, __FILE__, __LINE__)
d337f35e 11172+
3261cfd5
AM
11173+static inline void __vx_acc_sock(struct vx_info *vxi,
11174+ int family, int pos, int size, char *file, int line)
11175+{
11176+ if (vxi) {
11177+ int type = vx_sock_type(family);
d337f35e 11178+
3261cfd5
AM
11179+ atomic_long_inc(&vxi->cacct.sock[type][pos].count);
11180+ atomic_long_add(size, &vxi->cacct.sock[type][pos].total);
11181+ }
11182+}
d337f35e 11183+
3261cfd5
AM
11184+#define vx_sock_recv(sk, s) \
11185+ vx_acc_sock((sk)->sk_vx_info, (sk)->sk_family, 0, s)
11186+#define vx_sock_send(sk, s) \
11187+ vx_acc_sock((sk)->sk_vx_info, (sk)->sk_family, 1, s)
11188+#define vx_sock_fail(sk, s) \
11189+ vx_acc_sock((sk)->sk_vx_info, (sk)->sk_family, 2, s)
d337f35e 11190+
d337f35e 11191+
3261cfd5
AM
11192+#define sock_vx_init(s) do { \
11193+ (s)->sk_xid = 0; \
11194+ (s)->sk_vx_info = NULL; \
11195+ } while (0)
d337f35e 11196+
3261cfd5
AM
11197+#define sock_nx_init(s) do { \
11198+ (s)->sk_nid = 0; \
11199+ (s)->sk_nx_info = NULL; \
11200+ } while (0)
d337f35e 11201+
4bf69007 11202+#else
3261cfd5 11203+#warning duplicate inclusion
4bf69007 11204+#endif
3261cfd5
AM
11205diff -NurpP --minimal linux-4.9.207/include/linux/vs_tag.h linux-4.9.207-vs2.3.9.11/include/linux/vs_tag.h
11206--- linux-4.9.207/include/linux/vs_tag.h 1970-01-01 00:00:00.000000000 +0000
11207+++ linux-4.9.207-vs2.3.9.11/include/linux/vs_tag.h 2018-10-20 04:58:14.000000000 +0000
11208@@ -0,0 +1,47 @@
11209+#ifndef _VS_TAG_H
11210+#define _VS_TAG_H
d337f35e 11211+
3261cfd5 11212+#include <linux/vserver/tag.h>
d337f35e 11213+
3261cfd5 11214+/* check conditions */
a4a22af8 11215+
3261cfd5
AM
11216+#define DX_ADMIN 0x0001
11217+#define DX_WATCH 0x0002
11218+#define DX_HOSTID 0x0008
a4a22af8 11219+
3261cfd5 11220+#define DX_IDENT 0x0010
d337f35e 11221+
3261cfd5 11222+#define DX_ARG_MASK 0x0010
a4a22af8 11223+
d337f35e 11224+
3261cfd5 11225+#define dx_task_tag(t) ((t)->tag)
d337f35e 11226+
3261cfd5 11227+#define dx_current_tag() dx_task_tag(current)
d337f35e 11228+
3261cfd5 11229+#define dx_check(c, m) __dx_check(dx_current_tag(), c, m)
d337f35e 11230+
3261cfd5 11231+#define dx_weak_check(c, m) ((m) ? dx_check(c, m) : 1)
2380c486 11232+
d337f35e 11233+
3261cfd5
AM
11234+/*
11235+ * check current context for ADMIN/WATCH and
11236+ * optionally against supplied argument
11237+ */
11238+static inline int __dx_check(vtag_t cid, vtag_t id, unsigned int mode)
11239+{
11240+ if (mode & DX_ARG_MASK) {
11241+ if ((mode & DX_IDENT) && (id == cid))
11242+ return 1;
11243+ }
11244+ return (((mode & DX_ADMIN) && (cid == 0)) ||
11245+ ((mode & DX_WATCH) && (cid == 1)) ||
11246+ ((mode & DX_HOSTID) && (id == 0)));
11247+}
d337f35e 11248+
3261cfd5
AM
11249+struct inode;
11250+int dx_permission(const struct inode *inode, int mask);
d337f35e 11251+
d337f35e 11252+
4bf69007 11253+#else
3261cfd5 11254+#warning duplicate inclusion
4bf69007 11255+#endif
3261cfd5
AM
11256diff -NurpP --minimal linux-4.9.207/include/linux/vs_time.h linux-4.9.207-vs2.3.9.11/include/linux/vs_time.h
11257--- linux-4.9.207/include/linux/vs_time.h 1970-01-01 00:00:00.000000000 +0000
11258+++ linux-4.9.207-vs2.3.9.11/include/linux/vs_time.h 2018-10-20 04:58:14.000000000 +0000
11259@@ -0,0 +1,21 @@
11260+#ifndef _VS_TIME_H
11261+#define _VS_TIME_H
d337f35e 11262+
d337f35e 11263+
3261cfd5 11264+/* time faking stuff */
d337f35e 11265+
3261cfd5
AM
11266+#ifdef CONFIG_VSERVER_VTIME
11267+
11268+extern void vx_adjust_timespec(struct timespec *ts);
11269+extern int vx_settimeofday(const struct timespec *ts);
11270+extern int vx_settimeofday64(const struct timespec64 *ts);
3bac966d 11271+
3261cfd5
AM
11272+#else
11273+#define vx_adjust_timespec(t) do { } while (0)
11274+#define vx_settimeofday(t) do_settimeofday(t)
11275+#define vx_settimeofday64(t) do_settimeofday64(t)
11276+#endif
3bac966d 11277+
3261cfd5
AM
11278+#else
11279+#warning duplicate inclusion
11280+#endif
11281diff -NurpP --minimal linux-4.9.207/include/net/addrconf.h linux-4.9.207-vs2.3.9.11/include/net/addrconf.h
11282--- linux-4.9.207/include/net/addrconf.h 2019-12-25 15:28:40.237269280 +0000
11283+++ linux-4.9.207-vs2.3.9.11/include/net/addrconf.h 2018-10-20 04:58:14.000000000 +0000
cc23e853 11284@@ -85,7 +85,7 @@ struct inet6_ifaddr *ipv6_get_ifaddr(str
c2e5f7c8
JR
11285
11286 int ipv6_dev_get_saddr(struct net *net, const struct net_device *dev,
11287 const struct in6_addr *daddr, unsigned int srcprefs,
11288- struct in6_addr *saddr);
11289+ struct in6_addr *saddr, struct nx_info *nxi);
11290 int __ipv6_get_lladdr(struct inet6_dev *idev, struct in6_addr *addr,
bb20add7 11291 u32 banned_flags);
c2e5f7c8 11292 int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *addr,
3261cfd5
AM
11293diff -NurpP --minimal linux-4.9.207/include/net/af_unix.h linux-4.9.207-vs2.3.9.11/include/net/af_unix.h
11294--- linux-4.9.207/include/net/af_unix.h 2016-12-11 19:17:54.000000000 +0000
11295+++ linux-4.9.207-vs2.3.9.11/include/net/af_unix.h 2018-10-20 04:58:14.000000000 +0000
4bf69007
AM
11296@@ -4,6 +4,7 @@
11297 #include <linux/socket.h>
11298 #include <linux/un.h>
11299 #include <linux/mutex.h>
cc23e853 11300+// #include <linux/vs_base.h>
4bf69007
AM
11301 #include <net/sock.h>
11302
cc23e853 11303 void unix_inflight(struct user_struct *user, struct file *fp);
3261cfd5
AM
11304diff -NurpP --minimal linux-4.9.207/include/net/inet_timewait_sock.h linux-4.9.207-vs2.3.9.11/include/net/inet_timewait_sock.h
11305--- linux-4.9.207/include/net/inet_timewait_sock.h 2019-12-25 15:28:41.037256346 +0000
11306+++ linux-4.9.207-vs2.3.9.11/include/net/inet_timewait_sock.h 2018-10-20 04:58:14.000000000 +0000
09a55596 11307@@ -72,6 +72,10 @@ struct inet_timewait_sock {
b00e13aa 11308 #define tw_num __tw_common.skc_num
cc23e853
AM
11309 #define tw_cookie __tw_common.skc_cookie
11310 #define tw_dr __tw_common.skc_tw_dr
4bf69007
AM
11311+#define tw_xid __tw_common.skc_xid
11312+#define tw_vx_info __tw_common.skc_vx_info
11313+#define tw_nid __tw_common.skc_nid
11314+#define tw_nx_info __tw_common.skc_nx_info
b00e13aa 11315
4bf69007
AM
11316 int tw_timeout;
11317 volatile unsigned char tw_substate;
3261cfd5
AM
11318diff -NurpP --minimal linux-4.9.207/include/net/ip6_route.h linux-4.9.207-vs2.3.9.11/include/net/ip6_route.h
11319--- linux-4.9.207/include/net/ip6_route.h 2019-12-25 15:28:41.057256025 +0000
11320+++ linux-4.9.207-vs2.3.9.11/include/net/ip6_route.h 2018-10-20 04:58:14.000000000 +0000
cc23e853
AM
11321@@ -26,6 +26,7 @@ struct route_info {
11322 #include <linux/ip.h>
11323 #include <linux/ipv6.h>
11324 #include <linux/route.h>
11325+#include <linux/vs_inet6.h>
11326
11327 #define RT6_LOOKUP_F_IFACE 0x00000001
11328 #define RT6_LOOKUP_F_REACHABLE 0x00000002
11329@@ -98,17 +99,19 @@ int ip6_del_rt(struct rt6_info *);
11330 static inline int ip6_route_get_saddr(struct net *net, struct rt6_info *rt,
11331 const struct in6_addr *daddr,
11332 unsigned int prefs,
11333- struct in6_addr *saddr)
11334+ struct in6_addr *saddr,
11335+ struct nx_info *nxi)
11336 {
11337 struct inet6_dev *idev =
11338 rt ? ip6_dst_idev((struct dst_entry *)rt) : NULL;
11339 int err = 0;
11340
11341- if (rt && rt->rt6i_prefsrc.plen)
11342+ if (rt && rt->rt6i_prefsrc.plen && (!nxi ||
11343+ v6_addr_in_nx_info(nxi, &rt->rt6i_prefsrc.addr, NXA_TYPE_ADDR)))
11344 *saddr = rt->rt6i_prefsrc.addr;
11345 else
11346 err = ipv6_dev_get_saddr(net, idev ? idev->dev : NULL,
11347- daddr, prefs, saddr);
11348+ daddr, prefs, saddr, nxi);
11349
11350 return err;
11351 }
3261cfd5
AM
11352diff -NurpP --minimal linux-4.9.207/include/net/route.h linux-4.9.207-vs2.3.9.11/include/net/route.h
11353--- linux-4.9.207/include/net/route.h 2019-12-25 15:28:41.657246322 +0000
11354+++ linux-4.9.207-vs2.3.9.11/include/net/route.h 2018-10-20 04:58:14.000000000 +0000
09a55596 11355@@ -226,6 +226,9 @@ static inline void ip_rt_put(struct rtab
b00e13aa 11356 dst_release(&rt->dst);
4bf69007
AM
11357 }
11358
11359+#include <linux/vs_base.h>
11360+#include <linux/vs_inet.h>
d337f35e 11361+
4bf69007
AM
11362 #define IPTOS_RT_MASK (IPTOS_TOS_MASK & ~3)
11363
11364 extern const __u8 ip_tos2prio[16];
09a55596 11365@@ -273,6 +276,9 @@ static inline void ip_route_connect_init
4bf69007
AM
11366 protocol, flow_flags, dst, src, dport, sport);
11367 }
11368
11369+extern struct rtable *ip_v4_find_src(struct net *net, struct nx_info *,
11370+ struct flowi4 *);
d337f35e 11371+
4bf69007
AM
11372 static inline struct rtable *ip_route_connect(struct flowi4 *fl4,
11373 __be32 dst, __be32 src, u32 tos,
11374 int oif, u8 protocol,
09a55596 11375@@ -281,11 +287,25 @@ static inline struct rtable *ip_route_co
4bf69007
AM
11376 {
11377 struct net *net = sock_net(sk);
11378 struct rtable *rt;
11379+ struct nx_info *nx_info = current_nx_info();
11380
11381 ip_route_connect_init(fl4, dst, src, tos, oif, protocol,
f15949f2 11382 sport, dport, sk);
4bf69007
AM
11383
11384- if (!dst || !src) {
11385+ if (sk)
11386+ nx_info = sk->sk_nx_info;
d337f35e 11387+
4bf69007
AM
11388+ vxdprintk(VXD_CBIT(net, 4),
11389+ "ip_route_connect(%p) %p,%p;%lx",
11390+ sk, nx_info, sk->sk_socket,
11391+ (sk->sk_socket?sk->sk_socket->flags:0));
d337f35e 11392+
4bf69007
AM
11393+ rt = ip_v4_find_src(net, nx_info, fl4);
11394+ if (IS_ERR(rt))
11395+ return rt;
11396+ ip_rt_put(rt);
d337f35e 11397+
4bf69007
AM
11398+ if (!fl4->daddr || !fl4->saddr) {
11399 rt = __ip_route_output_key(net, fl4);
11400 if (IS_ERR(rt))
11401 return rt;
3261cfd5
AM
11402diff -NurpP --minimal linux-4.9.207/include/net/sock.h linux-4.9.207-vs2.3.9.11/include/net/sock.h
11403--- linux-4.9.207/include/net/sock.h 2019-12-25 15:28:41.707245516 +0000
11404+++ linux-4.9.207-vs2.3.9.11/include/net/sock.h 2019-12-25 15:37:52.288424537 +0000
cc23e853
AM
11405@@ -187,6 +187,10 @@ struct sock_common {
11406 struct in6_addr skc_v6_daddr;
11407 struct in6_addr skc_v6_rcv_saddr;
4bf69007 11408 #endif
61333608 11409+ vxid_t skc_xid;
4bf69007 11410+ struct vx_info *skc_vx_info;
61333608 11411+ vnid_t skc_nid;
4bf69007 11412+ struct nx_info *skc_nx_info;
c2e5f7c8 11413
cc23e853
AM
11414 atomic64_t skc_cookie;
11415
3261cfd5 11416@@ -337,8 +341,12 @@ struct sock {
4bf69007
AM
11417 #define sk_prot __sk_common.skc_prot
11418 #define sk_net __sk_common.skc_net
c2e5f7c8
JR
11419 #define sk_v6_daddr __sk_common.skc_v6_daddr
11420-#define sk_v6_rcv_saddr __sk_common.skc_v6_rcv_saddr
11421+#define sk_v6_rcv_saddr __sk_common.skc_v6_rcv_saddr
cc23e853 11422 #define sk_cookie __sk_common.skc_cookie
4bf69007
AM
11423+#define sk_xid __sk_common.skc_xid
11424+#define sk_vx_info __sk_common.skc_vx_info
11425+#define sk_nid __sk_common.skc_nid
11426+#define sk_nx_info __sk_common.skc_nx_info
cc23e853
AM
11427 #define sk_incoming_cpu __sk_common.skc_incoming_cpu
11428 #define sk_flags __sk_common.skc_flags
11429 #define sk_rxhash __sk_common.skc_rxhash
3261cfd5
AM
11430diff -NurpP --minimal linux-4.9.207/include/uapi/Kbuild linux-4.9.207-vs2.3.9.11/include/uapi/Kbuild
11431--- linux-4.9.207/include/uapi/Kbuild 2016-12-11 19:17:54.000000000 +0000
11432+++ linux-4.9.207-vs2.3.9.11/include/uapi/Kbuild 2018-10-20 04:58:14.000000000 +0000
bb20add7 11433@@ -13,3 +13,4 @@ header-y += drm/
4bf69007
AM
11434 header-y += xen/
11435 header-y += scsi/
bb20add7 11436 header-y += misc/
4bf69007 11437+header-y += vserver/
3261cfd5
AM
11438diff -NurpP --minimal linux-4.9.207/include/uapi/linux/btrfs_tree.h linux-4.9.207-vs2.3.9.11/include/uapi/linux/btrfs_tree.h
11439--- linux-4.9.207/include/uapi/linux/btrfs_tree.h 2019-12-25 15:28:42.297235975 +0000
11440+++ linux-4.9.207-vs2.3.9.11/include/uapi/linux/btrfs_tree.h 2019-02-22 08:37:55.713049558 +0000
09a55596 11441@@ -564,11 +564,14 @@ struct btrfs_inode_item {
cc23e853
AM
11442 /* modification sequence number for NFS */
11443 __le64 sequence;
11444
11445+ __le16 tag;
11446 /*
11447 * a little future expansion, for more than this we can
11448 * just grow the inode item and version it
11449 */
11450- __le64 reserved[4];
11451+ __le16 reserved16;
11452+ __le32 reserved32;
11453+ __le64 reserved[3];
11454 struct btrfs_timespec atime;
11455 struct btrfs_timespec ctime;
11456 struct btrfs_timespec mtime;
3261cfd5
AM
11457diff -NurpP --minimal linux-4.9.207/include/uapi/linux/capability.h linux-4.9.207-vs2.3.9.11/include/uapi/linux/capability.h
11458--- linux-4.9.207/include/uapi/linux/capability.h 2016-12-11 19:17:54.000000000 +0000
11459+++ linux-4.9.207-vs2.3.9.11/include/uapi/linux/capability.h 2018-10-20 04:58:14.000000000 +0000
cc23e853 11460@@ -257,6 +257,7 @@ struct vfs_cap_data {
4bf69007
AM
11461 arbitrary SCSI commands */
11462 /* Allow setting encryption key on loopback filesystem */
11463 /* Allow setting zone reclaim policy */
11464+/* Allow the selection of a security context */
11465
11466 #define CAP_SYS_ADMIN 21
11467
cc23e853 11468@@ -352,7 +353,12 @@ struct vfs_cap_data {
4bf69007 11469
bb20add7 11470 #define CAP_LAST_CAP CAP_AUDIT_READ
4bf69007
AM
11471
11472-#define cap_valid(x) ((x) >= 0 && (x) <= CAP_LAST_CAP)
11473+/* Allow context manipulations */
11474+/* Allow changing context info on files */
d337f35e 11475+
4bf69007 11476+#define CAP_CONTEXT 63
d337f35e 11477+
4bf69007
AM
11478+#define cap_valid(x) ((x) >= 0 && ((x) <= CAP_LAST_CAP || (x) == CAP_CONTEXT))
11479
11480 /*
11481 * Bit location of each capability (used by user-space library and kernel)
3261cfd5
AM
11482diff -NurpP --minimal linux-4.9.207/include/uapi/linux/fs.h linux-4.9.207-vs2.3.9.11/include/uapi/linux/fs.h
11483--- linux-4.9.207/include/uapi/linux/fs.h 2019-12-25 15:28:42.337235329 +0000
11484+++ linux-4.9.207-vs2.3.9.11/include/uapi/linux/fs.h 2018-10-20 04:58:14.000000000 +0000
cc23e853 11485@@ -130,6 +130,9 @@ struct inodes_stat_t {
4bf69007
AM
11486 #define MS_I_VERSION (1<<23) /* Update inode I_version field */
11487 #define MS_STRICTATIME (1<<24) /* Always perform atime updates */
cc23e853 11488 #define MS_LAZYTIME (1<<25) /* Update the on-disk [acm]times lazily */
b00e13aa
AM
11489+#define MS_TAGGED (1<<8) /* use generic inode tagging */
11490+#define MS_NOTAGCHECK (1<<9) /* don't check tags */
cc23e853 11491+#define MS_TAGID (1<<26) /* use specific tag for this mount */
b00e13aa
AM
11492
11493 /* These sb flags are internal to the kernel */
cc23e853
AM
11494 #define MS_SUBMOUNT (1<<26)
11495@@ -313,13 +316,16 @@ struct fscrypt_policy {
11496 #define FS_EA_INODE_FL 0x00200000 /* Inode used for large EA */
11497 #define FS_EOFBLOCKS_FL 0x00400000 /* Reserved for ext4 */
4bf69007
AM
11498 #define FS_NOCOW_FL 0x00800000 /* Do not cow file */
11499+#define FS_IXUNLINK_FL 0x08000000 /* Immutable invert on unlink */
cc23e853
AM
11500 #define FS_INLINE_DATA_FL 0x10000000 /* Reserved for ext4 */
11501 #define FS_PROJINHERIT_FL 0x20000000 /* Create with parents projid */
4bf69007
AM
11502 #define FS_RESERVED_FL 0x80000000 /* reserved for ext2 lib */
11503
11504-#define FS_FL_USER_VISIBLE 0x0003DFFF /* User visible flags */
11505-#define FS_FL_USER_MODIFIABLE 0x000380FF /* User modifiable flags */
11506+#define FS_BARRIER_FL 0x04000000 /* Barrier for chroot() */
11507+#define FS_COW_FL 0x20000000 /* Copy on Write marker */
11508
11509+#define FS_FL_USER_VISIBLE 0x0103DFFF /* User visible flags */
11510+#define FS_FL_USER_MODIFIABLE 0x010380FF /* User modifiable flags */
11511
11512 #define SYNC_FILE_RANGE_WAIT_BEFORE 1
11513 #define SYNC_FILE_RANGE_WRITE 2
3261cfd5
AM
11514diff -NurpP --minimal linux-4.9.207/include/uapi/linux/gfs2_ondisk.h linux-4.9.207-vs2.3.9.11/include/uapi/linux/gfs2_ondisk.h
11515--- linux-4.9.207/include/uapi/linux/gfs2_ondisk.h 2016-12-11 19:17:54.000000000 +0000
11516+++ linux-4.9.207-vs2.3.9.11/include/uapi/linux/gfs2_ondisk.h 2018-10-20 04:58:14.000000000 +0000
4bf69007
AM
11517@@ -225,6 +225,9 @@ enum {
11518 gfs2fl_Sync = 8,
11519 gfs2fl_System = 9,
11520 gfs2fl_TopLevel = 10,
11521+ gfs2fl_IXUnlink = 16,
11522+ gfs2fl_Barrier = 17,
11523+ gfs2fl_Cow = 18,
11524 gfs2fl_TruncInProg = 29,
11525 gfs2fl_InheritDirectio = 30,
11526 gfs2fl_InheritJdata = 31,
11527@@ -242,6 +245,9 @@ enum {
11528 #define GFS2_DIF_SYNC 0x00000100
11529 #define GFS2_DIF_SYSTEM 0x00000200 /* New in gfs2 */
11530 #define GFS2_DIF_TOPDIR 0x00000400 /* New in gfs2 */
11531+#define GFS2_DIF_IXUNLINK 0x00010000
11532+#define GFS2_DIF_BARRIER 0x00020000
11533+#define GFS2_DIF_COW 0x00040000
11534 #define GFS2_DIF_TRUNC_IN_PROG 0x20000000 /* New in gfs2 */
11535 #define GFS2_DIF_INHERIT_DIRECTIO 0x40000000 /* only in gfs1 */
11536 #define GFS2_DIF_INHERIT_JDATA 0x80000000
3261cfd5
AM
11537diff -NurpP --minimal linux-4.9.207/include/uapi/linux/if_tun.h linux-4.9.207-vs2.3.9.11/include/uapi/linux/if_tun.h
11538--- linux-4.9.207/include/uapi/linux/if_tun.h 2016-12-11 19:17:54.000000000 +0000
11539+++ linux-4.9.207-vs2.3.9.11/include/uapi/linux/if_tun.h 2018-10-20 04:58:14.000000000 +0000
cc23e853
AM
11540@@ -56,6 +56,7 @@
11541 */
11542 #define TUNSETVNETBE _IOW('T', 222, int)
11543 #define TUNGETVNETBE _IOR('T', 223, int)
11544+#define TUNSETNID _IOW('T', 224, int)
4bf69007
AM
11545
11546 /* TUNSETIFF ifr flags */
11547 #define IFF_TUN 0x0001
3261cfd5
AM
11548diff -NurpP --minimal linux-4.9.207/include/uapi/linux/major.h linux-4.9.207-vs2.3.9.11/include/uapi/linux/major.h
11549--- linux-4.9.207/include/uapi/linux/major.h 2016-12-11 19:17:54.000000000 +0000
11550+++ linux-4.9.207-vs2.3.9.11/include/uapi/linux/major.h 2018-10-20 04:58:14.000000000 +0000
4bf69007
AM
11551@@ -15,6 +15,7 @@
11552 #define HD_MAJOR IDE0_MAJOR
11553 #define PTY_SLAVE_MAJOR 3
11554 #define TTY_MAJOR 4
11555+#define VROOT_MAJOR 4
11556 #define TTYAUX_MAJOR 5
11557 #define LP_MAJOR 6
11558 #define VCS_MAJOR 7
3261cfd5
AM
11559diff -NurpP --minimal linux-4.9.207/include/uapi/linux/nfs_mount.h linux-4.9.207-vs2.3.9.11/include/uapi/linux/nfs_mount.h
11560--- linux-4.9.207/include/uapi/linux/nfs_mount.h 2016-12-11 19:17:54.000000000 +0000
11561+++ linux-4.9.207-vs2.3.9.11/include/uapi/linux/nfs_mount.h 2018-10-20 04:58:14.000000000 +0000
4bf69007 11562@@ -63,7 +63,8 @@ struct nfs_mount_data {
c2e5f7c8 11563 #define NFS_MOUNT_SECFLAVOUR 0x2000 /* 5 non-text parsed mount data only */
4bf69007
AM
11564 #define NFS_MOUNT_NORDIRPLUS 0x4000 /* 5 */
11565 #define NFS_MOUNT_UNSHARED 0x8000 /* 5 */
11566-#define NFS_MOUNT_FLAGMASK 0xFFFF
11567+#define NFS_MOUNT_TAGGED 0x10000 /* context tagging */
11568+#define NFS_MOUNT_FLAGMASK 0x1FFFF
11569
11570 /* The following are for internal use only */
11571 #define NFS_MOUNT_LOOKUP_CACHE_NONEG 0x10000
3261cfd5
AM
11572diff -NurpP --minimal linux-4.9.207/include/uapi/linux/reboot.h linux-4.9.207-vs2.3.9.11/include/uapi/linux/reboot.h
11573--- linux-4.9.207/include/uapi/linux/reboot.h 2016-12-11 19:17:54.000000000 +0000
11574+++ linux-4.9.207-vs2.3.9.11/include/uapi/linux/reboot.h 2018-10-20 04:58:14.000000000 +0000
4bf69007
AM
11575@@ -33,7 +33,7 @@
11576 #define LINUX_REBOOT_CMD_RESTART2 0xA1B2C3D4
11577 #define LINUX_REBOOT_CMD_SW_SUSPEND 0xD000FCE2
11578 #define LINUX_REBOOT_CMD_KEXEC 0x45584543
11579-
11580+#define LINUX_REBOOT_CMD_OOM 0xDEADBEEF
11581
11582
11583 #endif /* _UAPI_LINUX_REBOOT_H */
3261cfd5
AM
11584diff -NurpP --minimal linux-4.9.207/include/uapi/linux/sysctl.h linux-4.9.207-vs2.3.9.11/include/uapi/linux/sysctl.h
11585--- linux-4.9.207/include/uapi/linux/sysctl.h 2016-12-11 19:17:54.000000000 +0000
11586+++ linux-4.9.207-vs2.3.9.11/include/uapi/linux/sysctl.h 2018-10-20 04:58:14.000000000 +0000
cc23e853 11587@@ -58,6 +58,7 @@ enum
4bf69007
AM
11588 CTL_ABI=9, /* Binary emulation */
11589 CTL_CPU=10, /* CPU stuff (speed scaling, etc) */
11590 CTL_ARLAN=254, /* arlan wireless driver */
11591+ CTL_VSERVER=4242, /* Linux-VServer debug */
11592 CTL_S390DBF=5677, /* s390 debug */
11593 CTL_SUNRPC=7249, /* sunrpc debug */
11594 CTL_PM=9899, /* frv power management */
cc23e853 11595@@ -92,6 +93,7 @@ enum
4bf69007
AM
11596
11597 KERN_PANIC=15, /* int: panic timeout */
11598 KERN_REALROOTDEV=16, /* real root device to mount after initrd */
11599+ KERN_VSHELPER=17, /* string: path to vshelper policy agent */
11600
11601 KERN_SPARC_REBOOT=21, /* reboot command on Sparc */
11602 KERN_CTLALTDEL=22, /* int: allow ctl-alt-del to reboot */
3261cfd5
AM
11603diff -NurpP --minimal linux-4.9.207/include/uapi/vserver/cacct_cmd.h linux-4.9.207-vs2.3.9.11/include/uapi/vserver/cacct_cmd.h
11604--- linux-4.9.207/include/uapi/vserver/cacct_cmd.h 1970-01-01 00:00:00.000000000 +0000
11605+++ linux-4.9.207-vs2.3.9.11/include/uapi/vserver/cacct_cmd.h 2018-10-20 04:58:14.000000000 +0000
4bf69007
AM
11606@@ -0,0 +1,15 @@
11607+#ifndef _UAPI_VS_CACCT_CMD_H
11608+#define _UAPI_VS_CACCT_CMD_H
d337f35e
JR
11609+
11610+
4bf69007 11611+/* virtual host info name commands */
d337f35e 11612+
4bf69007 11613+#define VCMD_sock_stat VC_CMD(VSTAT, 5, 0)
d337f35e 11614+
4bf69007
AM
11615+struct vcmd_sock_stat_v0 {
11616+ uint32_t field;
11617+ uint32_t count[3];
11618+ uint64_t total[3];
11619+};
d337f35e 11620+
4bf69007 11621+#endif /* _UAPI_VS_CACCT_CMD_H */
3261cfd5
AM
11622diff -NurpP --minimal linux-4.9.207/include/uapi/vserver/context_cmd.h linux-4.9.207-vs2.3.9.11/include/uapi/vserver/context_cmd.h
11623--- linux-4.9.207/include/uapi/vserver/context_cmd.h 1970-01-01 00:00:00.000000000 +0000
11624+++ linux-4.9.207-vs2.3.9.11/include/uapi/vserver/context_cmd.h 2018-10-20 04:58:14.000000000 +0000
4bf69007
AM
11625@@ -0,0 +1,115 @@
11626+#ifndef _UAPI_VS_CONTEXT_CMD_H
11627+#define _UAPI_VS_CONTEXT_CMD_H
d33d7b00
AM
11628+
11629+
4bf69007 11630+/* vinfo commands */
3bac966d 11631+
4bf69007 11632+#define VCMD_task_xid VC_CMD(VINFO, 1, 0)
3bac966d 11633+
3bac966d 11634+
4bf69007 11635+#define VCMD_vx_info VC_CMD(VINFO, 5, 0)
3bac966d 11636+
4bf69007
AM
11637+struct vcmd_vx_info_v0 {
11638+ uint32_t xid;
11639+ uint32_t initpid;
11640+ /* more to come */
11641+};
3bac966d
AM
11642+
11643+
4bf69007 11644+#define VCMD_ctx_stat VC_CMD(VSTAT, 0, 0)
3bac966d 11645+
4bf69007
AM
11646+struct vcmd_ctx_stat_v0 {
11647+ uint32_t usecnt;
11648+ uint32_t tasks;
11649+ /* more to come */
11650+};
3bac966d 11651+
3bac966d 11652+
4bf69007 11653+/* context commands */
3bac966d 11654+
4bf69007
AM
11655+#define VCMD_ctx_create_v0 VC_CMD(VPROC, 1, 0)
11656+#define VCMD_ctx_create VC_CMD(VPROC, 1, 1)
3bac966d 11657+
4bf69007
AM
11658+struct vcmd_ctx_create {
11659+ uint64_t flagword;
11660+};
3bac966d 11661+
4bf69007
AM
11662+#define VCMD_ctx_migrate_v0 VC_CMD(PROCMIG, 1, 0)
11663+#define VCMD_ctx_migrate VC_CMD(PROCMIG, 1, 1)
3bac966d 11664+
4bf69007
AM
11665+struct vcmd_ctx_migrate {
11666+ uint64_t flagword;
11667+};
3bac966d 11668+
d33d7b00 11669+
d33d7b00 11670+
4bf69007 11671+/* flag commands */
d33d7b00 11672+
4bf69007
AM
11673+#define VCMD_get_cflags VC_CMD(FLAGS, 1, 0)
11674+#define VCMD_set_cflags VC_CMD(FLAGS, 2, 0)
d33d7b00 11675+
4bf69007
AM
11676+struct vcmd_ctx_flags_v0 {
11677+ uint64_t flagword;
11678+ uint64_t mask;
11679+};
3bac966d
AM
11680+
11681+
3bac966d 11682+
4bf69007 11683+/* context caps commands */
3bac966d 11684+
4bf69007
AM
11685+#define VCMD_get_ccaps VC_CMD(FLAGS, 3, 1)
11686+#define VCMD_set_ccaps VC_CMD(FLAGS, 4, 1)
d33d7b00 11687+
4bf69007
AM
11688+struct vcmd_ctx_caps_v1 {
11689+ uint64_t ccaps;
11690+ uint64_t cmask;
11691+};
d33d7b00 11692+
d33d7b00
AM
11693+
11694+
4bf69007 11695+/* bcaps commands */
d33d7b00 11696+
4bf69007
AM
11697+#define VCMD_get_bcaps VC_CMD(FLAGS, 9, 0)
11698+#define VCMD_set_bcaps VC_CMD(FLAGS, 10, 0)
d33d7b00 11699+
4bf69007
AM
11700+struct vcmd_bcaps {
11701+ uint64_t bcaps;
11702+ uint64_t bmask;
11703+};
3bac966d 11704+
d33d7b00 11705+
d33d7b00 11706+
4bf69007 11707+/* umask commands */
d33d7b00 11708+
4bf69007
AM
11709+#define VCMD_get_umask VC_CMD(FLAGS, 13, 0)
11710+#define VCMD_set_umask VC_CMD(FLAGS, 14, 0)
3bac966d 11711+
4bf69007
AM
11712+struct vcmd_umask {
11713+ uint64_t umask;
11714+ uint64_t mask;
11715+};
d33d7b00 11716+
d33d7b00
AM
11717+
11718+
4bf69007 11719+/* wmask commands */
d33d7b00 11720+
4bf69007
AM
11721+#define VCMD_get_wmask VC_CMD(FLAGS, 15, 0)
11722+#define VCMD_set_wmask VC_CMD(FLAGS, 16, 0)
d33d7b00 11723+
4bf69007
AM
11724+struct vcmd_wmask {
11725+ uint64_t wmask;
11726+ uint64_t mask;
d33d7b00
AM
11727+};
11728+
d33d7b00 11729+
d33d7b00 11730+
4bf69007 11731+/* OOM badness */
d33d7b00 11732+
4bf69007
AM
11733+#define VCMD_get_badness VC_CMD(MEMCTRL, 5, 0)
11734+#define VCMD_set_badness VC_CMD(MEMCTRL, 6, 0)
d33d7b00 11735+
4bf69007
AM
11736+struct vcmd_badness_v0 {
11737+ int64_t bias;
11738+};
d33d7b00 11739+
4bf69007 11740+#endif /* _UAPI_VS_CONTEXT_CMD_H */
3261cfd5
AM
11741diff -NurpP --minimal linux-4.9.207/include/uapi/vserver/context.h linux-4.9.207-vs2.3.9.11/include/uapi/vserver/context.h
11742--- linux-4.9.207/include/uapi/vserver/context.h 1970-01-01 00:00:00.000000000 +0000
11743+++ linux-4.9.207-vs2.3.9.11/include/uapi/vserver/context.h 2018-10-20 04:58:14.000000000 +0000
11744@@ -0,0 +1,81 @@
11745+#ifndef _UAPI_VS_CONTEXT_H
11746+#define _UAPI_VS_CONTEXT_H
11747+
11748+#include <linux/types.h>
11749+#include <linux/capability.h>
11750+
11751+
11752+/* context flags */
11753+
11754+#define VXF_INFO_SCHED 0x00000002
11755+#define VXF_INFO_NPROC 0x00000004
11756+#define VXF_INFO_PRIVATE 0x00000008
11757+
11758+#define VXF_INFO_INIT 0x00000010
11759+#define VXF_INFO_HIDE 0x00000020
11760+#define VXF_INFO_ULIMIT 0x00000040
11761+#define VXF_INFO_NSPACE 0x00000080
11762+
11763+#define VXF_SCHED_HARD 0x00000100
11764+#define VXF_SCHED_PRIO 0x00000200
11765+#define VXF_SCHED_PAUSE 0x00000400
11766+
11767+#define VXF_VIRT_MEM 0x00010000
11768+#define VXF_VIRT_UPTIME 0x00020000
11769+#define VXF_VIRT_CPU 0x00040000
11770+#define VXF_VIRT_LOAD 0x00080000
11771+#define VXF_VIRT_TIME 0x00100000
11772+
11773+#define VXF_HIDE_MOUNT 0x01000000
11774+/* was VXF_HIDE_NETIF 0x02000000 */
11775+#define VXF_HIDE_VINFO 0x04000000
11776+
11777+#define VXF_STATE_SETUP (1ULL << 32)
11778+#define VXF_STATE_INIT (1ULL << 33)
11779+#define VXF_STATE_ADMIN (1ULL << 34)
11780+
11781+#define VXF_SC_HELPER (1ULL << 36)
11782+#define VXF_REBOOT_KILL (1ULL << 37)
11783+#define VXF_PERSISTENT (1ULL << 38)
11784+
11785+#define VXF_FORK_RSS (1ULL << 48)
11786+#define VXF_PROLIFIC (1ULL << 49)
11787+
11788+#define VXF_IGNEG_NICE (1ULL << 52)
11789+
11790+#define VXF_ONE_TIME (0x0007ULL << 32)
11791+
11792+#define VXF_INIT_SET (VXF_STATE_SETUP | VXF_STATE_INIT | VXF_STATE_ADMIN)
11793+
11794+
11795+/* context migration */
11796+
11797+#define VXM_SET_INIT 0x00000001
11798+#define VXM_SET_REAPER 0x00000002
11799+
11800+/* context caps */
11801+
11802+#define VXC_SET_UTSNAME 0x00000001
11803+#define VXC_SET_RLIMIT 0x00000002
11804+#define VXC_FS_SECURITY 0x00000004
11805+#define VXC_FS_TRUSTED 0x00000008
11806+#define VXC_TIOCSTI 0x00000010
11807+
11808+/* was VXC_RAW_ICMP 0x00000100 */
11809+#define VXC_SYSLOG 0x00001000
11810+#define VXC_OOM_ADJUST 0x00002000
11811+#define VXC_AUDIT_CONTROL 0x00004000
11812+
11813+#define VXC_SECURE_MOUNT 0x00010000
11814+/* #define VXC_SECURE_REMOUNT 0x00020000 */
11815+#define VXC_BINARY_MOUNT 0x00040000
11816+#define VXC_DEV_MOUNT 0x00080000
11817+
11818+#define VXC_QUOTA_CTL 0x00100000
11819+#define VXC_ADMIN_MAPPER 0x00200000
11820+#define VXC_ADMIN_CLOOP 0x00400000
11821+
11822+#define VXC_KTHREAD 0x01000000
11823+#define VXC_NAMESPACE 0x02000000
11824+
11825+#endif /* _UAPI_VS_CONTEXT_H */
11826diff -NurpP --minimal linux-4.9.207/include/uapi/vserver/cvirt_cmd.h linux-4.9.207-vs2.3.9.11/include/uapi/vserver/cvirt_cmd.h
11827--- linux-4.9.207/include/uapi/vserver/cvirt_cmd.h 1970-01-01 00:00:00.000000000 +0000
11828+++ linux-4.9.207-vs2.3.9.11/include/uapi/vserver/cvirt_cmd.h 2018-10-20 04:58:14.000000000 +0000
4bf69007
AM
11829@@ -0,0 +1,41 @@
11830+#ifndef _UAPI_VS_CVIRT_CMD_H
11831+#define _UAPI_VS_CVIRT_CMD_H
d33d7b00 11832+
d33d7b00 11833+
4bf69007 11834+/* virtual host info name commands */
d33d7b00 11835+
4bf69007
AM
11836+#define VCMD_set_vhi_name VC_CMD(VHOST, 1, 0)
11837+#define VCMD_get_vhi_name VC_CMD(VHOST, 2, 0)
d33d7b00 11838+
4bf69007
AM
11839+struct vcmd_vhi_name_v0 {
11840+ uint32_t field;
11841+ char name[65];
11842+};
d33d7b00 11843+
d33d7b00 11844+
4bf69007
AM
11845+enum vhi_name_field {
11846+ VHIN_CONTEXT = 0,
11847+ VHIN_SYSNAME,
11848+ VHIN_NODENAME,
11849+ VHIN_RELEASE,
11850+ VHIN_VERSION,
11851+ VHIN_MACHINE,
11852+ VHIN_DOMAINNAME,
11853+};
d33d7b00 11854+
d33d7b00 11855+
d33d7b00 11856+
4bf69007 11857+#define VCMD_virt_stat VC_CMD(VSTAT, 3, 0)
d33d7b00 11858+
4bf69007
AM
11859+struct vcmd_virt_stat_v0 {
11860+ uint64_t offset;
11861+ uint64_t uptime;
11862+ uint32_t nr_threads;
11863+ uint32_t nr_running;
11864+ uint32_t nr_uninterruptible;
11865+ uint32_t nr_onhold;
11866+ uint32_t nr_forks;
11867+ uint32_t load[3];
11868+};
2380c486 11869+
4bf69007 11870+#endif /* _UAPI_VS_CVIRT_CMD_H */
3261cfd5
AM
11871diff -NurpP --minimal linux-4.9.207/include/uapi/vserver/debug_cmd.h linux-4.9.207-vs2.3.9.11/include/uapi/vserver/debug_cmd.h
11872--- linux-4.9.207/include/uapi/vserver/debug_cmd.h 1970-01-01 00:00:00.000000000 +0000
11873+++ linux-4.9.207-vs2.3.9.11/include/uapi/vserver/debug_cmd.h 2018-10-20 04:58:14.000000000 +0000
4bf69007
AM
11874@@ -0,0 +1,24 @@
11875+#ifndef _UAPI_VS_DEBUG_CMD_H
11876+#define _UAPI_VS_DEBUG_CMD_H
537831f9 11877+
537831f9 11878+
4bf69007 11879+/* debug commands */
537831f9 11880+
4bf69007 11881+#define VCMD_dump_history VC_CMD(DEBUG, 1, 0)
537831f9 11882+
4bf69007
AM
11883+#define VCMD_read_history VC_CMD(DEBUG, 5, 0)
11884+#define VCMD_read_monitor VC_CMD(DEBUG, 6, 0)
537831f9 11885+
4bf69007
AM
11886+struct vcmd_read_history_v0 {
11887+ uint32_t index;
11888+ uint32_t count;
11889+ char __user *data;
11890+};
537831f9 11891+
4bf69007
AM
11892+struct vcmd_read_monitor_v0 {
11893+ uint32_t index;
11894+ uint32_t count;
11895+ char __user *data;
11896+};
537831f9 11897+
4bf69007 11898+#endif /* _UAPI_VS_DEBUG_CMD_H */
3261cfd5
AM
11899diff -NurpP --minimal linux-4.9.207/include/uapi/vserver/device_cmd.h linux-4.9.207-vs2.3.9.11/include/uapi/vserver/device_cmd.h
11900--- linux-4.9.207/include/uapi/vserver/device_cmd.h 1970-01-01 00:00:00.000000000 +0000
11901+++ linux-4.9.207-vs2.3.9.11/include/uapi/vserver/device_cmd.h 2018-10-20 04:58:14.000000000 +0000
4bf69007
AM
11902@@ -0,0 +1,16 @@
11903+#ifndef _UAPI_VS_DEVICE_CMD_H
11904+#define _UAPI_VS_DEVICE_CMD_H
2380c486 11905+
1163e6ab 11906+
4bf69007 11907+/* device vserver commands */
1163e6ab 11908+
4bf69007
AM
11909+#define VCMD_set_mapping VC_CMD(DEVICE, 1, 0)
11910+#define VCMD_unset_mapping VC_CMD(DEVICE, 2, 0)
e915af4e 11911+
4bf69007
AM
11912+struct vcmd_set_mapping_v0 {
11913+ const char __user *device;
11914+ const char __user *target;
11915+ uint32_t flags;
11916+};
e915af4e 11917+
4bf69007 11918+#endif /* _UAPI_VS_DEVICE_CMD_H */
3261cfd5
AM
11919diff -NurpP --minimal linux-4.9.207/include/uapi/vserver/device.h linux-4.9.207-vs2.3.9.11/include/uapi/vserver/device.h
11920--- linux-4.9.207/include/uapi/vserver/device.h 1970-01-01 00:00:00.000000000 +0000
11921+++ linux-4.9.207-vs2.3.9.11/include/uapi/vserver/device.h 2018-10-20 04:58:14.000000000 +0000
11922@@ -0,0 +1,12 @@
11923+#ifndef _UAPI_VS_DEVICE_H
11924+#define _UAPI_VS_DEVICE_H
11925+
11926+
11927+#define DATTR_CREATE 0x00000001
11928+#define DATTR_OPEN 0x00000002
11929+
11930+#define DATTR_REMAP 0x00000010
11931+
11932+#define DATTR_MASK 0x00000013
11933+
11934+#endif /* _UAPI_VS_DEVICE_H */
11935diff -NurpP --minimal linux-4.9.207/include/uapi/vserver/dlimit_cmd.h linux-4.9.207-vs2.3.9.11/include/uapi/vserver/dlimit_cmd.h
11936--- linux-4.9.207/include/uapi/vserver/dlimit_cmd.h 1970-01-01 00:00:00.000000000 +0000
11937+++ linux-4.9.207-vs2.3.9.11/include/uapi/vserver/dlimit_cmd.h 2018-10-20 04:58:14.000000000 +0000
4bf69007
AM
11938@@ -0,0 +1,67 @@
11939+#ifndef _UAPI_VS_DLIMIT_CMD_H
11940+#define _UAPI_VS_DLIMIT_CMD_H
e915af4e 11941+
42bc425c 11942+
4bf69007 11943+/* dlimit vserver commands */
d337f35e 11944+
4bf69007
AM
11945+#define VCMD_add_dlimit VC_CMD(DLIMIT, 1, 0)
11946+#define VCMD_rem_dlimit VC_CMD(DLIMIT, 2, 0)
d337f35e 11947+
4bf69007
AM
11948+#define VCMD_set_dlimit VC_CMD(DLIMIT, 5, 0)
11949+#define VCMD_get_dlimit VC_CMD(DLIMIT, 6, 0)
d337f35e 11950+
4bf69007
AM
11951+struct vcmd_ctx_dlimit_base_v0 {
11952+ const char __user *name;
11953+ uint32_t flags;
11954+};
11955+
11956+struct vcmd_ctx_dlimit_v0 {
11957+ const char __user *name;
11958+ uint32_t space_used; /* used space in kbytes */
11959+ uint32_t space_total; /* maximum space in kbytes */
11960+ uint32_t inodes_used; /* used inodes */
11961+ uint32_t inodes_total; /* maximum inodes */
11962+ uint32_t reserved; /* reserved for root in % */
11963+ uint32_t flags;
11964+};
11965+
11966+#define CDLIM_UNSET ((uint32_t)0UL)
11967+#define CDLIM_INFINITY ((uint32_t)~0UL)
11968+#define CDLIM_KEEP ((uint32_t)~1UL)
11969+
11970+#define DLIME_UNIT 0
11971+#define DLIME_KILO 1
11972+#define DLIME_MEGA 2
11973+#define DLIME_GIGA 3
11974+
11975+#define DLIMF_SHIFT 0x10
11976+
11977+#define DLIMS_USED 0
11978+#define DLIMS_TOTAL 2
11979+
11980+static inline
11981+uint64_t dlimit_space_32to64(uint32_t val, uint32_t flags, int shift)
2380c486 11982+{
4bf69007
AM
11983+ int exp = (flags & DLIMF_SHIFT) ?
11984+ (flags >> shift) & DLIME_GIGA : DLIME_KILO;
11985+ return ((uint64_t)val) << (10 * exp);
2380c486
JR
11986+}
11987+
4bf69007
AM
11988+static inline
11989+uint32_t dlimit_space_64to32(uint64_t val, uint32_t *flags, int shift)
2380c486 11990+{
4bf69007 11991+ int exp = 0;
ec22aa5c 11992+
4bf69007
AM
11993+ if (*flags & DLIMF_SHIFT) {
11994+ while (val > (1LL << 32) && (exp < 3)) {
11995+ val >>= 10;
11996+ exp++;
11997+ }
11998+ *flags &= ~(DLIME_GIGA << shift);
11999+ *flags |= exp << shift;
12000+ } else
12001+ val >>= 10;
12002+ return val;
2380c486
JR
12003+}
12004+
4bf69007 12005+#endif /* _UAPI_VS_DLIMIT_CMD_H */
3261cfd5
AM
12006diff -NurpP --minimal linux-4.9.207/include/uapi/vserver/inode_cmd.h linux-4.9.207-vs2.3.9.11/include/uapi/vserver/inode_cmd.h
12007--- linux-4.9.207/include/uapi/vserver/inode_cmd.h 1970-01-01 00:00:00.000000000 +0000
12008+++ linux-4.9.207-vs2.3.9.11/include/uapi/vserver/inode_cmd.h 2018-10-20 04:58:14.000000000 +0000
4bf69007
AM
12009@@ -0,0 +1,26 @@
12010+#ifndef _UAPI_VS_INODE_CMD_H
12011+#define _UAPI_VS_INODE_CMD_H
d337f35e 12012+
db55b927 12013+
4bf69007 12014+/* inode vserver commands */
2c8c5bc5 12015+
4bf69007
AM
12016+#define VCMD_get_iattr VC_CMD(INODE, 1, 1)
12017+#define VCMD_set_iattr VC_CMD(INODE, 2, 1)
2bf5ad28 12018+
4bf69007
AM
12019+#define VCMD_fget_iattr VC_CMD(INODE, 3, 0)
12020+#define VCMD_fset_iattr VC_CMD(INODE, 4, 0)
4a036bed 12021+
4bf69007
AM
12022+struct vcmd_ctx_iattr_v1 {
12023+ const char __user *name;
12024+ uint32_t tag;
12025+ uint32_t flags;
12026+ uint32_t mask;
12027+};
4a036bed 12028+
4bf69007
AM
12029+struct vcmd_ctx_fiattr_v0 {
12030+ uint32_t tag;
12031+ uint32_t flags;
12032+ uint32_t mask;
12033+};
4a036bed 12034+
3261cfd5
AM
12035+#endif /* _UAPI_VS_INODE_CMD_H */
12036diff -NurpP --minimal linux-4.9.207/include/uapi/vserver/inode.h linux-4.9.207-vs2.3.9.11/include/uapi/vserver/inode.h
12037--- linux-4.9.207/include/uapi/vserver/inode.h 1970-01-01 00:00:00.000000000 +0000
12038+++ linux-4.9.207-vs2.3.9.11/include/uapi/vserver/inode.h 2018-10-20 04:58:14.000000000 +0000
12039@@ -0,0 +1,23 @@
12040+#ifndef _UAPI_VS_INODE_H
12041+#define _UAPI_VS_INODE_H
12042+
12043+
12044+#define IATTR_TAG 0x01000000
12045+
12046+#define IATTR_ADMIN 0x00000001
12047+#define IATTR_WATCH 0x00000002
12048+#define IATTR_HIDE 0x00000004
12049+#define IATTR_FLAGS 0x00000007
12050+
12051+#define IATTR_BARRIER 0x00010000
12052+#define IATTR_IXUNLINK 0x00020000
12053+#define IATTR_IMMUTABLE 0x00040000
12054+#define IATTR_COW 0x00080000
12055+
12056+
12057+/* inode ioctls */
12058+
12059+#define FIOC_GETXFLG _IOR('x', 5, long)
12060+#define FIOC_SETXFLG _IOW('x', 6, long)
12061+
12062+#endif /* _UAPI_VS_INODE_H */
12063diff -NurpP --minimal linux-4.9.207/include/uapi/vserver/Kbuild linux-4.9.207-vs2.3.9.11/include/uapi/vserver/Kbuild
12064--- linux-4.9.207/include/uapi/vserver/Kbuild 1970-01-01 00:00:00.000000000 +0000
12065+++ linux-4.9.207-vs2.3.9.11/include/uapi/vserver/Kbuild 2018-10-20 04:58:14.000000000 +0000
12066@@ -0,0 +1,9 @@
4a036bed 12067+
3261cfd5
AM
12068+header-y += context_cmd.h network_cmd.h space_cmd.h \
12069+ cacct_cmd.h cvirt_cmd.h limit_cmd.h dlimit_cmd.h \
12070+ inode_cmd.h tag_cmd.h sched_cmd.h signal_cmd.h \
12071+ debug_cmd.h device_cmd.h
42bc425c 12072+
3261cfd5
AM
12073+header-y += switch.h context.h network.h monitor.h \
12074+ limit.h inode.h device.h
adc1caaa 12075+
3261cfd5
AM
12076diff -NurpP --minimal linux-4.9.207/include/uapi/vserver/limit_cmd.h linux-4.9.207-vs2.3.9.11/include/uapi/vserver/limit_cmd.h
12077--- linux-4.9.207/include/uapi/vserver/limit_cmd.h 1970-01-01 00:00:00.000000000 +0000
12078+++ linux-4.9.207-vs2.3.9.11/include/uapi/vserver/limit_cmd.h 2018-10-20 04:58:14.000000000 +0000
4bf69007
AM
12079@@ -0,0 +1,40 @@
12080+#ifndef _UAPI_VS_LIMIT_CMD_H
12081+#define _UAPI_VS_LIMIT_CMD_H
adc1caaa 12082+
adc1caaa 12083+
4bf69007 12084+/* rlimit vserver commands */
adc1caaa 12085+
4bf69007
AM
12086+#define VCMD_get_rlimit VC_CMD(RLIMIT, 1, 0)
12087+#define VCMD_set_rlimit VC_CMD(RLIMIT, 2, 0)
12088+#define VCMD_get_rlimit_mask VC_CMD(RLIMIT, 3, 0)
12089+#define VCMD_reset_hits VC_CMD(RLIMIT, 7, 0)
12090+#define VCMD_reset_minmax VC_CMD(RLIMIT, 9, 0)
adc1caaa 12091+
4bf69007
AM
12092+struct vcmd_ctx_rlimit_v0 {
12093+ uint32_t id;
12094+ uint64_t minimum;
12095+ uint64_t softlimit;
12096+ uint64_t maximum;
12097+};
d33d7b00 12098+
4bf69007
AM
12099+struct vcmd_ctx_rlimit_mask_v0 {
12100+ uint32_t minimum;
12101+ uint32_t softlimit;
12102+ uint32_t maximum;
12103+};
d33d7b00 12104+
4bf69007 12105+#define VCMD_rlimit_stat VC_CMD(VSTAT, 1, 0)
d33d7b00 12106+
4bf69007
AM
12107+struct vcmd_rlimit_stat_v0 {
12108+ uint32_t id;
12109+ uint32_t hits;
12110+ uint64_t value;
12111+ uint64_t minimum;
12112+ uint64_t maximum;
12113+};
d33d7b00 12114+
4bf69007
AM
12115+#define CRLIM_UNSET (0ULL)
12116+#define CRLIM_INFINITY (~0ULL)
12117+#define CRLIM_KEEP (~1ULL)
d33d7b00 12118+
4bf69007 12119+#endif /* _UAPI_VS_LIMIT_CMD_H */
3261cfd5
AM
12120diff -NurpP --minimal linux-4.9.207/include/uapi/vserver/limit.h linux-4.9.207-vs2.3.9.11/include/uapi/vserver/limit.h
12121--- linux-4.9.207/include/uapi/vserver/limit.h 1970-01-01 00:00:00.000000000 +0000
12122+++ linux-4.9.207-vs2.3.9.11/include/uapi/vserver/limit.h 2018-10-20 04:58:14.000000000 +0000
12123@@ -0,0 +1,14 @@
12124+#ifndef _UAPI_VS_LIMIT_H
12125+#define _UAPI_VS_LIMIT_H
12126+
12127+
12128+#define VLIMIT_NSOCK 16
12129+#define VLIMIT_OPENFD 17
12130+#define VLIMIT_ANON 18
12131+#define VLIMIT_SHMEM 19
12132+#define VLIMIT_SEMARY 20
12133+#define VLIMIT_NSEMS 21
12134+#define VLIMIT_DENTRY 22
12135+#define VLIMIT_MAPPED 23
12136+
12137+#endif /* _UAPI_VS_LIMIT_H */
12138diff -NurpP --minimal linux-4.9.207/include/uapi/vserver/monitor.h linux-4.9.207-vs2.3.9.11/include/uapi/vserver/monitor.h
12139--- linux-4.9.207/include/uapi/vserver/monitor.h 1970-01-01 00:00:00.000000000 +0000
12140+++ linux-4.9.207-vs2.3.9.11/include/uapi/vserver/monitor.h 2018-10-20 04:58:14.000000000 +0000
4bf69007
AM
12141@@ -0,0 +1,96 @@
12142+#ifndef _UAPI_VS_MONITOR_H
12143+#define _UAPI_VS_MONITOR_H
d33d7b00 12144+
4bf69007 12145+#include <linux/types.h>
d33d7b00 12146+
d33d7b00 12147+
4bf69007
AM
12148+enum {
12149+ VXM_UNUSED = 0,
d33d7b00 12150+
4bf69007 12151+ VXM_SYNC = 0x10,
d33d7b00 12152+
4bf69007
AM
12153+ VXM_UPDATE = 0x20,
12154+ VXM_UPDATE_1,
12155+ VXM_UPDATE_2,
d33d7b00 12156+
4bf69007
AM
12157+ VXM_RQINFO_1 = 0x24,
12158+ VXM_RQINFO_2,
d33d7b00 12159+
4bf69007
AM
12160+ VXM_ACTIVATE = 0x40,
12161+ VXM_DEACTIVATE,
12162+ VXM_IDLE,
d33d7b00 12163+
4bf69007
AM
12164+ VXM_HOLD = 0x44,
12165+ VXM_UNHOLD,
d33d7b00 12166+
4bf69007
AM
12167+ VXM_MIGRATE = 0x48,
12168+ VXM_RESCHED,
d33d7b00 12169+
4bf69007
AM
12170+ /* all other bits are flags */
12171+ VXM_SCHED = 0x80,
12172+};
d33d7b00 12173+
4bf69007
AM
12174+struct _vxm_update_1 {
12175+ uint32_t tokens_max;
12176+ uint32_t fill_rate;
12177+ uint32_t interval;
12178+};
d33d7b00 12179+
4bf69007
AM
12180+struct _vxm_update_2 {
12181+ uint32_t tokens_min;
12182+ uint32_t fill_rate;
12183+ uint32_t interval;
12184+};
d33d7b00 12185+
4bf69007
AM
12186+struct _vxm_rqinfo_1 {
12187+ uint16_t running;
12188+ uint16_t onhold;
12189+ uint16_t iowait;
12190+ uint16_t uintr;
12191+ uint32_t idle_tokens;
12192+};
d33d7b00 12193+
4bf69007
AM
12194+struct _vxm_rqinfo_2 {
12195+ uint32_t norm_time;
12196+ uint32_t idle_time;
12197+ uint32_t idle_skip;
12198+};
d33d7b00 12199+
4bf69007
AM
12200+struct _vxm_sched {
12201+ uint32_t tokens;
12202+ uint32_t norm_time;
12203+ uint32_t idle_time;
12204+};
d33d7b00 12205+
4bf69007
AM
12206+struct _vxm_task {
12207+ uint16_t pid;
12208+ uint16_t state;
12209+};
d33d7b00 12210+
4bf69007
AM
12211+struct _vxm_event {
12212+ uint32_t jif;
12213+ union {
12214+ uint32_t seq;
12215+ uint32_t sec;
12216+ };
12217+ union {
12218+ uint32_t tokens;
12219+ uint32_t nsec;
12220+ struct _vxm_task tsk;
12221+ };
12222+};
61b0c03f 12223+
4bf69007
AM
12224+struct _vx_mon_entry {
12225+ uint16_t type;
12226+ uint16_t xid;
12227+ union {
12228+ struct _vxm_event ev;
12229+ struct _vxm_sched sd;
12230+ struct _vxm_update_1 u1;
12231+ struct _vxm_update_2 u2;
12232+ struct _vxm_rqinfo_1 q1;
12233+ struct _vxm_rqinfo_2 q2;
12234+ };
12235+};
d33d7b00 12236+
4bf69007 12237+#endif /* _UAPI_VS_MONITOR_H */
3261cfd5
AM
12238diff -NurpP --minimal linux-4.9.207/include/uapi/vserver/network_cmd.h linux-4.9.207-vs2.3.9.11/include/uapi/vserver/network_cmd.h
12239--- linux-4.9.207/include/uapi/vserver/network_cmd.h 1970-01-01 00:00:00.000000000 +0000
12240+++ linux-4.9.207-vs2.3.9.11/include/uapi/vserver/network_cmd.h 2018-10-20 04:58:14.000000000 +0000
4bf69007
AM
12241@@ -0,0 +1,123 @@
12242+#ifndef _UAPI_VS_NETWORK_CMD_H
12243+#define _UAPI_VS_NETWORK_CMD_H
2380c486 12244+
2380c486 12245+
4bf69007 12246+/* vinfo commands */
2380c486 12247+
4bf69007 12248+#define VCMD_task_nid VC_CMD(VINFO, 2, 0)
2380c486 12249+
2380c486 12250+
4bf69007 12251+#define VCMD_nx_info VC_CMD(VINFO, 6, 0)
2380c486 12252+
4bf69007
AM
12253+struct vcmd_nx_info_v0 {
12254+ uint32_t nid;
12255+ /* more to come */
12256+};
2380c486 12257+
2380c486 12258+
4bf69007
AM
12259+#include <linux/in.h>
12260+#include <linux/in6.h>
2380c486 12261+
4bf69007
AM
12262+#define VCMD_net_create_v0 VC_CMD(VNET, 1, 0)
12263+#define VCMD_net_create VC_CMD(VNET, 1, 1)
2380c486 12264+
4bf69007
AM
12265+struct vcmd_net_create {
12266+ uint64_t flagword;
12267+};
2380c486 12268+
4bf69007 12269+#define VCMD_net_migrate VC_CMD(NETMIG, 1, 0)
2380c486 12270+
4bf69007
AM
12271+#define VCMD_net_add VC_CMD(NETALT, 1, 0)
12272+#define VCMD_net_remove VC_CMD(NETALT, 2, 0)
2380c486 12273+
4bf69007
AM
12274+struct vcmd_net_addr_v0 {
12275+ uint16_t type;
12276+ uint16_t count;
12277+ struct in_addr ip[4];
12278+ struct in_addr mask[4];
12279+};
2380c486 12280+
4bf69007
AM
12281+#define VCMD_net_add_ipv4_v1 VC_CMD(NETALT, 1, 1)
12282+#define VCMD_net_rem_ipv4_v1 VC_CMD(NETALT, 2, 1)
2380c486 12283+
4bf69007
AM
12284+struct vcmd_net_addr_ipv4_v1 {
12285+ uint16_t type;
12286+ uint16_t flags;
12287+ struct in_addr ip;
12288+ struct in_addr mask;
12289+};
2380c486 12290+
4bf69007
AM
12291+#define VCMD_net_add_ipv4 VC_CMD(NETALT, 1, 2)
12292+#define VCMD_net_rem_ipv4 VC_CMD(NETALT, 2, 2)
2380c486 12293+
4bf69007
AM
12294+struct vcmd_net_addr_ipv4_v2 {
12295+ uint16_t type;
12296+ uint16_t flags;
12297+ struct in_addr ip;
12298+ struct in_addr ip2;
12299+ struct in_addr mask;
12300+};
2380c486 12301+
4bf69007
AM
12302+#define VCMD_net_add_ipv6 VC_CMD(NETALT, 3, 1)
12303+#define VCMD_net_remove_ipv6 VC_CMD(NETALT, 4, 1)
2380c486 12304+
4bf69007
AM
12305+struct vcmd_net_addr_ipv6_v1 {
12306+ uint16_t type;
12307+ uint16_t flags;
12308+ uint32_t prefix;
12309+ struct in6_addr ip;
12310+ struct in6_addr mask;
12311+};
2380c486 12312+
4bf69007
AM
12313+#define VCMD_add_match_ipv4 VC_CMD(NETALT, 5, 0)
12314+#define VCMD_get_match_ipv4 VC_CMD(NETALT, 6, 0)
2380c486 12315+
4bf69007
AM
12316+struct vcmd_match_ipv4_v0 {
12317+ uint16_t type;
12318+ uint16_t flags;
12319+ uint16_t parent;
12320+ uint16_t prefix;
12321+ struct in_addr ip;
12322+ struct in_addr ip2;
12323+ struct in_addr mask;
12324+};
2380c486 12325+
4bf69007
AM
12326+#define VCMD_add_match_ipv6 VC_CMD(NETALT, 7, 0)
12327+#define VCMD_get_match_ipv6 VC_CMD(NETALT, 8, 0)
2380c486 12328+
4bf69007
AM
12329+struct vcmd_match_ipv6_v0 {
12330+ uint16_t type;
12331+ uint16_t flags;
12332+ uint16_t parent;
12333+ uint16_t prefix;
12334+ struct in6_addr ip;
12335+ struct in6_addr ip2;
12336+ struct in6_addr mask;
12337+};
2380c486 12338+
2380c486 12339+
2380c486 12340+
2380c486 12341+
4bf69007 12342+/* flag commands */
2380c486 12343+
4bf69007
AM
12344+#define VCMD_get_nflags VC_CMD(FLAGS, 5, 0)
12345+#define VCMD_set_nflags VC_CMD(FLAGS, 6, 0)
2380c486 12346+
4bf69007
AM
12347+struct vcmd_net_flags_v0 {
12348+ uint64_t flagword;
12349+ uint64_t mask;
12350+};
2380c486 12351+
2380c486 12352+
ab30d09f 12353+
4bf69007 12354+/* network caps commands */
ab30d09f 12355+
4bf69007
AM
12356+#define VCMD_get_ncaps VC_CMD(FLAGS, 7, 0)
12357+#define VCMD_set_ncaps VC_CMD(FLAGS, 8, 0)
ec22aa5c 12358+
4bf69007
AM
12359+struct vcmd_net_caps_v0 {
12360+ uint64_t ncaps;
12361+ uint64_t cmask;
12362+};
3bac966d 12363+
4bf69007 12364+#endif /* _UAPI_VS_NETWORK_CMD_H */
3261cfd5
AM
12365diff -NurpP --minimal linux-4.9.207/include/uapi/vserver/network.h linux-4.9.207-vs2.3.9.11/include/uapi/vserver/network.h
12366--- linux-4.9.207/include/uapi/vserver/network.h 1970-01-01 00:00:00.000000000 +0000
12367+++ linux-4.9.207-vs2.3.9.11/include/uapi/vserver/network.h 2018-10-20 04:58:14.000000000 +0000
12368@@ -0,0 +1,76 @@
12369+#ifndef _UAPI_VS_NETWORK_H
12370+#define _UAPI_VS_NETWORK_H
12371+
12372+#include <linux/types.h>
12373+
12374+
12375+#define MAX_N_CONTEXT 65535 /* Arbitrary limit */
12376+
12377+
12378+/* network flags */
12379+
12380+#define NXF_INFO_PRIVATE 0x00000008
12381+
12382+#define NXF_SINGLE_IP 0x00000100
12383+#define NXF_LBACK_REMAP 0x00000200
12384+#define NXF_LBACK_ALLOW 0x00000400
12385+
12386+#define NXF_HIDE_NETIF 0x02000000
12387+#define NXF_HIDE_LBACK 0x04000000
12388+
12389+#define NXF_STATE_SETUP (1ULL << 32)
12390+#define NXF_STATE_ADMIN (1ULL << 34)
12391+
12392+#define NXF_SC_HELPER (1ULL << 36)
12393+#define NXF_PERSISTENT (1ULL << 38)
12394+
12395+#define NXF_ONE_TIME (0x0005ULL << 32)
12396+
12397+
12398+#define NXF_INIT_SET (__nxf_init_set())
12399+
12400+static inline uint64_t __nxf_init_set(void) {
12401+ return NXF_STATE_ADMIN
12402+#ifdef CONFIG_VSERVER_AUTO_LBACK
12403+ | NXF_LBACK_REMAP
12404+ | NXF_HIDE_LBACK
12405+#endif
12406+#ifdef CONFIG_VSERVER_AUTO_SINGLE
12407+ | NXF_SINGLE_IP
12408+#endif
12409+ | NXF_HIDE_NETIF;
12410+}
12411+
12412+
12413+/* network caps */
12414+
12415+#define NXC_TUN_CREATE 0x00000001
12416+
12417+#define NXC_RAW_ICMP 0x00000100
12418+
12419+#define NXC_MULTICAST 0x00001000
12420+
12421+
12422+/* address types */
12423+
12424+#define NXA_TYPE_IPV4 0x0001
12425+#define NXA_TYPE_IPV6 0x0002
12426+
12427+#define NXA_TYPE_NONE 0x0000
12428+#define NXA_TYPE_ANY 0x00FF
12429+
12430+#define NXA_TYPE_ADDR 0x0010
12431+#define NXA_TYPE_MASK 0x0020
12432+#define NXA_TYPE_RANGE 0x0040
12433+
12434+#define NXA_MASK_ALL (NXA_TYPE_ADDR | NXA_TYPE_MASK | NXA_TYPE_RANGE)
12435+
12436+#define NXA_MOD_BCAST 0x0100
12437+#define NXA_MOD_LBACK 0x0200
12438+
12439+#define NXA_LOOPBACK 0x1000
12440+
12441+#define NXA_MASK_BIND (NXA_MASK_ALL | NXA_MOD_BCAST | NXA_MOD_LBACK)
12442+#define NXA_MASK_SHOW (NXA_MASK_ALL | NXA_LOOPBACK)
12443+
12444+#endif /* _UAPI_VS_NETWORK_H */
12445diff -NurpP --minimal linux-4.9.207/include/uapi/vserver/sched_cmd.h linux-4.9.207-vs2.3.9.11/include/uapi/vserver/sched_cmd.h
12446--- linux-4.9.207/include/uapi/vserver/sched_cmd.h 1970-01-01 00:00:00.000000000 +0000
12447+++ linux-4.9.207-vs2.3.9.11/include/uapi/vserver/sched_cmd.h 2018-10-20 04:58:14.000000000 +0000
4bf69007
AM
12448@@ -0,0 +1,13 @@
12449+#ifndef _UAPI_VS_SCHED_CMD_H
12450+#define _UAPI_VS_SCHED_CMD_H
d337f35e 12451+
d337f35e 12452+
4bf69007
AM
12453+struct vcmd_prio_bias {
12454+ int32_t cpu_id;
12455+ int32_t prio_bias;
12456+};
2380c486 12457+
4bf69007
AM
12458+#define VCMD_set_prio_bias VC_CMD(SCHED, 4, 0)
12459+#define VCMD_get_prio_bias VC_CMD(SCHED, 5, 0)
d337f35e 12460+
4bf69007 12461+#endif /* _UAPI_VS_SCHED_CMD_H */
3261cfd5
AM
12462diff -NurpP --minimal linux-4.9.207/include/uapi/vserver/signal_cmd.h linux-4.9.207-vs2.3.9.11/include/uapi/vserver/signal_cmd.h
12463--- linux-4.9.207/include/uapi/vserver/signal_cmd.h 1970-01-01 00:00:00.000000000 +0000
12464+++ linux-4.9.207-vs2.3.9.11/include/uapi/vserver/signal_cmd.h 2018-10-20 04:58:14.000000000 +0000
4bf69007
AM
12465@@ -0,0 +1,31 @@
12466+#ifndef _UAPI_VS_SIGNAL_CMD_H
12467+#define _UAPI_VS_SIGNAL_CMD_H
d337f35e 12468+
d337f35e 12469+
4bf69007 12470+/* signalling vserver commands */
d337f35e 12471+
4bf69007
AM
12472+#define VCMD_ctx_kill VC_CMD(PROCTRL, 1, 0)
12473+#define VCMD_wait_exit VC_CMD(EVENT, 99, 0)
d337f35e 12474+
4bf69007
AM
12475+struct vcmd_ctx_kill_v0 {
12476+ int32_t pid;
12477+ int32_t sig;
12478+};
d337f35e 12479+
4bf69007
AM
12480+struct vcmd_wait_exit_v0 {
12481+ int32_t reboot_cmd;
12482+ int32_t exit_code;
12483+};
d337f35e 12484+
d337f35e 12485+
4bf69007 12486+/* process alteration commands */
ab30d09f 12487+
4bf69007
AM
12488+#define VCMD_get_pflags VC_CMD(PROCALT, 5, 0)
12489+#define VCMD_set_pflags VC_CMD(PROCALT, 6, 0)
d337f35e 12490+
4bf69007
AM
12491+struct vcmd_pflags_v0 {
12492+ uint32_t flagword;
12493+ uint32_t mask;
12494+};
3bac966d 12495+
4bf69007 12496+#endif /* _UAPI_VS_SIGNAL_CMD_H */
3261cfd5
AM
12497diff -NurpP --minimal linux-4.9.207/include/uapi/vserver/space_cmd.h linux-4.9.207-vs2.3.9.11/include/uapi/vserver/space_cmd.h
12498--- linux-4.9.207/include/uapi/vserver/space_cmd.h 1970-01-01 00:00:00.000000000 +0000
12499+++ linux-4.9.207-vs2.3.9.11/include/uapi/vserver/space_cmd.h 2018-10-20 04:58:14.000000000 +0000
4bf69007
AM
12500@@ -0,0 +1,28 @@
12501+#ifndef _UAPI_VS_SPACE_CMD_H
12502+#define _UAPI_VS_SPACE_CMD_H
d337f35e 12503+
d337f35e 12504+
4bf69007
AM
12505+#define VCMD_enter_space_v0 VC_CMD(PROCALT, 1, 0)
12506+#define VCMD_enter_space_v1 VC_CMD(PROCALT, 1, 1)
12507+#define VCMD_enter_space VC_CMD(PROCALT, 1, 2)
2380c486 12508+
4bf69007
AM
12509+#define VCMD_set_space_v0 VC_CMD(PROCALT, 3, 0)
12510+#define VCMD_set_space_v1 VC_CMD(PROCALT, 3, 1)
12511+#define VCMD_set_space VC_CMD(PROCALT, 3, 2)
d337f35e 12512+
4bf69007 12513+#define VCMD_get_space_mask_v0 VC_CMD(PROCALT, 4, 0)
d337f35e 12514+
4bf69007
AM
12515+#define VCMD_get_space_mask VC_CMD(VSPACE, 0, 1)
12516+#define VCMD_get_space_default VC_CMD(VSPACE, 1, 0)
d337f35e 12517+
d337f35e 12518+
4bf69007
AM
12519+struct vcmd_space_mask_v1 {
12520+ uint64_t mask;
12521+};
d337f35e 12522+
4bf69007
AM
12523+struct vcmd_space_mask_v2 {
12524+ uint64_t mask;
12525+ uint32_t index;
12526+};
d337f35e 12527+
4bf69007 12528+#endif /* _UAPI_VS_SPACE_CMD_H */
3261cfd5
AM
12529diff -NurpP --minimal linux-4.9.207/include/uapi/vserver/switch.h linux-4.9.207-vs2.3.9.11/include/uapi/vserver/switch.h
12530--- linux-4.9.207/include/uapi/vserver/switch.h 1970-01-01 00:00:00.000000000 +0000
12531+++ linux-4.9.207-vs2.3.9.11/include/uapi/vserver/switch.h 2018-10-20 04:58:14.000000000 +0000
4bf69007
AM
12532@@ -0,0 +1,90 @@
12533+#ifndef _UAPI_VS_SWITCH_H
12534+#define _UAPI_VS_SWITCH_H
d337f35e 12535+
4bf69007 12536+#include <linux/types.h>
d337f35e 12537+
d337f35e 12538+
4bf69007
AM
12539+#define VC_CATEGORY(c) (((c) >> 24) & 0x3F)
12540+#define VC_COMMAND(c) (((c) >> 16) & 0xFF)
12541+#define VC_VERSION(c) ((c) & 0xFFF)
d337f35e 12542+
4bf69007
AM
12543+#define VC_CMD(c, i, v) ((((VC_CAT_ ## c) & 0x3F) << 24) \
12544+ | (((i) & 0xFF) << 16) | ((v) & 0xFFF))
d337f35e 12545+
4bf69007 12546+/*
d337f35e 12547+
4bf69007 12548+ Syscall Matrix V2.8
d337f35e 12549+
4bf69007
AM
12550+ |VERSION|CREATE |MODIFY |MIGRATE|CONTROL|EXPERIM| |SPECIAL|SPECIAL|
12551+ |STATS |DESTROY|ALTER |CHANGE |LIMIT |TEST | | | |
12552+ |INFO |SETUP | |MOVE | | | | | |
12553+ -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
12554+ SYSTEM |VERSION|VSETUP |VHOST | | | | |DEVICE | |
12555+ HOST | 00| 01| 02| 03| 04| 05| | 06| 07|
12556+ -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
12557+ CPU | |VPROC |PROCALT|PROCMIG|PROCTRL| | |SCHED. | |
12558+ PROCESS| 08| 09| 10| 11| 12| 13| | 14| 15|
12559+ -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
12560+ MEMORY | | | | |MEMCTRL| | |SWAP | |
12561+ | 16| 17| 18| 19| 20| 21| | 22| 23|
12562+ -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
12563+ NETWORK| |VNET |NETALT |NETMIG |NETCTL | | |SERIAL | |
12564+ | 24| 25| 26| 27| 28| 29| | 30| 31|
12565+ -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
12566+ DISK | | | |TAGMIG |DLIMIT | | |INODE | |
12567+ VFS | 32| 33| 34| 35| 36| 37| | 38| 39|
12568+ -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
12569+ OTHER |VSTAT | | | | | | |VINFO | |
12570+ | 40| 41| 42| 43| 44| 45| | 46| 47|
12571+ =======+=======+=======+=======+=======+=======+=======+ +=======+=======+
12572+ SPECIAL|EVENT | | | |FLAGS | | |VSPACE | |
12573+ | 48| 49| 50| 51| 52| 53| | 54| 55|
12574+ -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
12575+ SPECIAL|DEBUG | | | |RLIMIT |SYSCALL| | |COMPAT |
12576+ | 56| 57| 58| 59| 60|TEST 61| | 62| 63|
12577+ -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
d337f35e 12578+
4bf69007 12579+*/
d337f35e 12580+
4bf69007 12581+#define VC_CAT_VERSION 0
d337f35e 12582+
4bf69007
AM
12583+#define VC_CAT_VSETUP 1
12584+#define VC_CAT_VHOST 2
d337f35e 12585+
4bf69007 12586+#define VC_CAT_DEVICE 6
d337f35e 12587+
4bf69007
AM
12588+#define VC_CAT_VPROC 9
12589+#define VC_CAT_PROCALT 10
12590+#define VC_CAT_PROCMIG 11
12591+#define VC_CAT_PROCTRL 12
d337f35e 12592+
4bf69007
AM
12593+#define VC_CAT_SCHED 14
12594+#define VC_CAT_MEMCTRL 20
d337f35e 12595+
4bf69007
AM
12596+#define VC_CAT_VNET 25
12597+#define VC_CAT_NETALT 26
12598+#define VC_CAT_NETMIG 27
12599+#define VC_CAT_NETCTRL 28
d337f35e 12600+
4bf69007
AM
12601+#define VC_CAT_TAGMIG 35
12602+#define VC_CAT_DLIMIT 36
12603+#define VC_CAT_INODE 38
d337f35e 12604+
4bf69007
AM
12605+#define VC_CAT_VSTAT 40
12606+#define VC_CAT_VINFO 46
12607+#define VC_CAT_EVENT 48
d337f35e 12608+
4bf69007
AM
12609+#define VC_CAT_FLAGS 52
12610+#define VC_CAT_VSPACE 54
12611+#define VC_CAT_DEBUG 56
12612+#define VC_CAT_RLIMIT 60
d337f35e 12613+
4bf69007
AM
12614+#define VC_CAT_SYSTEST 61
12615+#define VC_CAT_COMPAT 63
d337f35e 12616+
4bf69007 12617+/* query version */
d337f35e 12618+
4bf69007
AM
12619+#define VCMD_get_version VC_CMD(VERSION, 0, 0)
12620+#define VCMD_get_vci VC_CMD(VERSION, 1, 0)
2380c486 12621+
4bf69007 12622+#endif /* _UAPI_VS_SWITCH_H */
3261cfd5
AM
12623diff -NurpP --minimal linux-4.9.207/include/uapi/vserver/tag_cmd.h linux-4.9.207-vs2.3.9.11/include/uapi/vserver/tag_cmd.h
12624--- linux-4.9.207/include/uapi/vserver/tag_cmd.h 1970-01-01 00:00:00.000000000 +0000
12625+++ linux-4.9.207-vs2.3.9.11/include/uapi/vserver/tag_cmd.h 2018-10-20 04:58:14.000000000 +0000
4bf69007
AM
12626@@ -0,0 +1,14 @@
12627+#ifndef _UAPI_VS_TAG_CMD_H
12628+#define _UAPI_VS_TAG_CMD_H
d337f35e 12629+
d337f35e 12630+
4bf69007 12631+/* vinfo commands */
d337f35e 12632+
4bf69007 12633+#define VCMD_task_tag VC_CMD(VINFO, 3, 0)
d337f35e
JR
12634+
12635+
4bf69007 12636+/* context commands */
d337f35e 12637+
4bf69007 12638+#define VCMD_tag_migrate VC_CMD(TAGMIG, 1, 0)
2380c486 12639+
4bf69007 12640+#endif /* _UAPI_VS_TAG_CMD_H */
3261cfd5
AM
12641diff -NurpP --minimal linux-4.9.207/init/Kconfig linux-4.9.207-vs2.3.9.11/init/Kconfig
12642--- linux-4.9.207/init/Kconfig 2019-12-25 15:28:42.767228378 +0000
12643+++ linux-4.9.207-vs2.3.9.11/init/Kconfig 2018-10-20 04:58:14.000000000 +0000
cc23e853 12644@@ -958,6 +958,7 @@ config NUMA_BALANCING_DEFAULT_ENABLED
4bf69007 12645 menuconfig CGROUPS
cc23e853 12646 bool "Control Group support"
265de2f7 12647 select KERNFS
4bf69007
AM
12648+ default y
12649 help
12650 This option adds support for grouping sets of processes together, for
12651 use with process control subsystems such as Cpusets, CFS, memory
3261cfd5
AM
12652diff -NurpP --minimal linux-4.9.207/init/main.c linux-4.9.207-vs2.3.9.11/init/main.c
12653--- linux-4.9.207/init/main.c 2019-12-25 15:28:42.767228378 +0000
12654+++ linux-4.9.207-vs2.3.9.11/init/main.c 2019-10-05 14:58:45.760306119 +0000
09a55596 12655@@ -82,6 +82,7 @@
cc23e853
AM
12656 #include <linux/io.h>
12657 #include <linux/kaiser.h>
9b2a4327 12658 #include <linux/cache.h>
4bf69007
AM
12659+#include <linux/vserver/percpu.h>
12660
12661 #include <asm/io.h>
12662 #include <asm/bugs.h>
3261cfd5
AM
12663diff -NurpP --minimal linux-4.9.207/ipc/mqueue.c linux-4.9.207-vs2.3.9.11/ipc/mqueue.c
12664--- linux-4.9.207/ipc/mqueue.c 2019-12-25 15:28:42.797227893 +0000
12665+++ linux-4.9.207-vs2.3.9.11/ipc/mqueue.c 2019-10-05 15:01:19.537840241 +0000
4bf69007
AM
12666@@ -35,6 +35,8 @@
12667 #include <linux/ipc_namespace.h>
12668 #include <linux/user_namespace.h>
12669 #include <linux/slab.h>
12670+#include <linux/vs_context.h>
12671+#include <linux/vs_limit.h>
12672
12673 #include <net/sock.h>
12674 #include "util.h"
cc23e853 12675@@ -75,6 +77,7 @@ struct mqueue_inode_info {
bb20add7 12676 struct pid *notify_owner;
4bf69007
AM
12677 struct user_namespace *notify_user_ns;
12678 struct user_struct *user; /* user who created, for accounting */
12679+ struct vx_info *vxi;
12680 struct sock *notify_sock;
12681 struct sk_buff *notify_cookie;
12682
cc23e853 12683@@ -230,6 +233,7 @@ static struct inode *mqueue_get_inode(st
4bf69007
AM
12684 if (S_ISREG(mode)) {
12685 struct mqueue_inode_info *info;
12686 unsigned long mq_bytes, mq_treesize;
12687+ struct vx_info *vxi = current_vx_info();
12688
12689 inode->i_fop = &mqueue_file_operations;
12690 inode->i_size = FILENT_SIZE;
cc23e853 12691@@ -243,6 +247,7 @@ static struct inode *mqueue_get_inode(st
4bf69007
AM
12692 info->notify_user_ns = NULL;
12693 info->qsize = 0;
12694 info->user = NULL; /* set when all is ok */
12695+ info->vxi = NULL;
12696 info->msg_tree = RB_ROOT;
12697 info->node_cache = NULL;
12698 memset(&info->attr, 0, sizeof(info->attr));
cc23e853 12699@@ -276,17 +281,20 @@ static struct inode *mqueue_get_inode(st
4bf69007
AM
12700
12701 spin_lock(&mq_lock);
12702 if (u->mq_bytes + mq_bytes < u->mq_bytes ||
12703- u->mq_bytes + mq_bytes > rlimit(RLIMIT_MSGQUEUE)) {
12704+ u->mq_bytes + mq_bytes > rlimit(RLIMIT_MSGQUEUE) ||
12705+ !vx_ipcmsg_avail(vxi, mq_bytes)) {
12706 spin_unlock(&mq_lock);
12707 /* mqueue_evict_inode() releases info->messages */
12708 ret = -EMFILE;
12709 goto out_inode;
12710 }
12711 u->mq_bytes += mq_bytes;
12712+ vx_ipcmsg_add(vxi, u, mq_bytes);
12713 spin_unlock(&mq_lock);
12714
12715 /* all is ok */
12716 info->user = get_uid(u);
12717+ info->vxi = get_vx_info(vxi);
12718 } else if (S_ISDIR(mode)) {
12719 inc_nlink(inode);
12720 /* Some things misbehave if size == 0 on a directory */
3261cfd5
AM
12721@@ -393,6 +401,7 @@ static void mqueue_evict_inode(struct in
12722
4bf69007
AM
12723 user = info->user;
12724 if (user) {
12725+ struct vx_info *vxi = info->vxi;
3261cfd5 12726 unsigned long mq_bytes, mq_treesize;
d42736e7
AM
12727
12728 /* Total amount of bytes accounted for the mqueue */
3261cfd5 12729@@ -405,6 +414,7 @@ static void mqueue_evict_inode(struct in
d42736e7 12730
4bf69007
AM
12731 spin_lock(&mq_lock);
12732 user->mq_bytes -= mq_bytes;
12733+ vx_ipcmsg_sub(vxi, user, mq_bytes);
12734 /*
12735 * get_ns_from_inode() ensures that the
12736 * (ipc_ns = sb->s_fs_info) is either a valid ipc_ns
3261cfd5 12737@@ -414,6 +424,7 @@ static void mqueue_evict_inode(struct in
4bf69007
AM
12738 if (ipc_ns)
12739 ipc_ns->mq_queues_count--;
12740 spin_unlock(&mq_lock);
12741+ put_vx_info(vxi);
12742 free_uid(user);
12743 }
12744 if (ipc_ns)
3261cfd5
AM
12745diff -NurpP --minimal linux-4.9.207/ipc/msg.c linux-4.9.207-vs2.3.9.11/ipc/msg.c
12746--- linux-4.9.207/ipc/msg.c 2019-12-25 15:28:42.817227568 +0000
12747+++ linux-4.9.207-vs2.3.9.11/ipc/msg.c 2018-10-20 04:58:14.000000000 +0000
4bf69007
AM
12748@@ -37,6 +37,7 @@
12749 #include <linux/rwsem.h>
12750 #include <linux/nsproxy.h>
12751 #include <linux/ipc_namespace.h>
12752+#include <linux/vs_base.h>
12753
12754 #include <asm/current.h>
bb20add7 12755 #include <linux/uaccess.h>
cc23e853 12756@@ -124,6 +125,7 @@ static int newque(struct ipc_namespace *
4bf69007
AM
12757
12758 msq->q_perm.mode = msgflg & S_IRWXUGO;
12759 msq->q_perm.key = key;
12760+ msq->q_perm.xid = vx_current_xid();
12761
12762 msq->q_perm.security = NULL;
12763 retval = security_msg_queue_alloc(msq);
3261cfd5
AM
12764diff -NurpP --minimal linux-4.9.207/ipc/namespace.c linux-4.9.207-vs2.3.9.11/ipc/namespace.c
12765--- linux-4.9.207/ipc/namespace.c 2016-12-11 19:17:54.000000000 +0000
12766+++ linux-4.9.207-vs2.3.9.11/ipc/namespace.c 2018-10-20 04:58:14.000000000 +0000
cc23e853
AM
12767@@ -13,6 +13,7 @@
12768 #include <linux/mount.h>
12769 #include <linux/user_namespace.h>
12770 #include <linux/proc_ns.h>
12771+#include <linux/vserver/global.h>
12772
12773 #include "util.h"
12774
12775@@ -59,6 +60,7 @@ static struct ipc_namespace *create_ipc_
12776 sem_init_ns(ns);
12777 msg_init_ns(ns);
12778 shm_init_ns(ns);
12779+ atomic_inc(&vs_global_ipc_ns);
12780
12781 return ns;
12782
12783@@ -121,6 +123,7 @@ static void free_ipc_ns(struct ipc_names
12784 dec_ipc_namespaces(ns->ucounts);
12785 put_user_ns(ns->user_ns);
12786 ns_free_inum(&ns->ns);
12787+ atomic_dec(&vs_global_ipc_ns);
12788 kfree(ns);
12789 }
12790
3261cfd5
AM
12791diff -NurpP --minimal linux-4.9.207/ipc/sem.c linux-4.9.207-vs2.3.9.11/ipc/sem.c
12792--- linux-4.9.207/ipc/sem.c 2016-12-11 19:17:54.000000000 +0000
12793+++ linux-4.9.207-vs2.3.9.11/ipc/sem.c 2018-10-20 04:58:14.000000000 +0000
bb20add7 12794@@ -85,6 +85,8 @@
4bf69007
AM
12795 #include <linux/rwsem.h>
12796 #include <linux/nsproxy.h>
12797 #include <linux/ipc_namespace.h>
12798+#include <linux/vs_base.h>
12799+#include <linux/vs_limit.h>
12800
bb20add7 12801 #include <linux/uaccess.h>
4bf69007 12802 #include "util.h"
cc23e853 12803@@ -537,6 +539,7 @@ static int newary(struct ipc_namespace *
4bf69007
AM
12804
12805 sma->sem_perm.mode = (semflg & S_IRWXUGO);
12806 sma->sem_perm.key = key;
12807+ sma->sem_perm.xid = vx_current_xid();
12808
12809 sma->sem_perm.security = NULL;
12810 retval = security_sem_alloc(sma);
cc23e853 12811@@ -567,6 +570,9 @@ static int newary(struct ipc_namespace *
4bf69007
AM
12812 return id;
12813 }
12814 ns->used_sems += nsems;
12815+ /* FIXME: obsoleted? */
12816+ vx_semary_inc(sma);
12817+ vx_nsems_add(sma, nsems);
12818
bb20add7
AM
12819 sem_unlock(sma, -1);
12820 rcu_read_unlock();
cc23e853 12821@@ -1155,6 +1161,9 @@ static void freeary(struct ipc_namespace
4bf69007
AM
12822
12823 wake_up_sem_queue_do(&tasks);
12824 ns->used_sems -= sma->sem_nsems;
12825+ /* FIXME: obsoleted? */
12826+ vx_nsems_sub(sma, sma->sem_nsems);
12827+ vx_semary_dec(sma);
926e38e0 12828 ipc_rcu_putref(sma, sem_rcu_free);
4bf69007 12829 }
926e38e0 12830
3261cfd5
AM
12831diff -NurpP --minimal linux-4.9.207/ipc/shm.c linux-4.9.207-vs2.3.9.11/ipc/shm.c
12832--- linux-4.9.207/ipc/shm.c 2019-12-25 15:28:42.837227244 +0000
12833+++ linux-4.9.207-vs2.3.9.11/ipc/shm.c 2018-10-20 04:58:14.000000000 +0000
c2e5f7c8 12834@@ -42,6 +42,8 @@
4bf69007
AM
12835 #include <linux/nsproxy.h>
12836 #include <linux/mount.h>
12837 #include <linux/ipc_namespace.h>
12838+#include <linux/vs_context.h>
12839+#include <linux/vs_limit.h>
12840
bb20add7 12841 #include <linux/uaccess.h>
4bf69007 12842
09a55596 12843@@ -234,10 +236,14 @@ static void shm_open(struct vm_area_stru
4bf69007
AM
12844 static void shm_destroy(struct ipc_namespace *ns, struct shmid_kernel *shp)
12845 {
c2e5f7c8 12846 struct file *shm_file;
4bf69007
AM
12847+ struct vx_info *vxi = lookup_vx_info(shp->shm_perm.xid);
12848+ int numpages = (shp->shm_segsz + PAGE_SIZE - 1) >> PAGE_SHIFT;
c2e5f7c8
JR
12849
12850 shm_file = shp->shm_file;
12851 shp->shm_file = NULL;
12852- ns->shm_tot -= (shp->shm_segsz + PAGE_SIZE - 1) >> PAGE_SHIFT;
4bf69007
AM
12853+ vx_ipcshm_sub(vxi, shp, numpages);
12854+ ns->shm_tot -= numpages;
d337f35e 12855+
4bf69007
AM
12856 shm_rmid(ns, shp);
12857 shm_unlock(shp);
c2e5f7c8 12858 if (!is_file_hugepages(shm_file))
09a55596 12859@@ -246,6 +252,7 @@ static void shm_destroy(struct ipc_names
cc23e853
AM
12860 user_shm_unlock(i_size_read(file_inode(shm_file)),
12861 shp->mlock_user);
c2e5f7c8 12862 fput(shm_file);
4bf69007 12863+ put_vx_info(vxi);
926e38e0 12864 ipc_rcu_putref(shp, shm_rcu_free);
4bf69007
AM
12865 }
12866
09a55596 12867@@ -559,11 +566,15 @@ static int newseg(struct ipc_namespace *
bb20add7 12868 ns->shm_tot + numpages > ns->shm_ctlall)
4bf69007
AM
12869 return -ENOSPC;
12870
12871+ if (!vx_ipcshm_avail(current_vx_info(), numpages))
12872+ return -ENOSPC;
d337f35e 12873+
4bf69007
AM
12874 shp = ipc_rcu_alloc(sizeof(*shp));
12875 if (!shp)
12876 return -ENOMEM;
12877
12878 shp->shm_perm.key = key;
12879+ shp->shm_perm.xid = vx_current_xid();
12880 shp->shm_perm.mode = (shmflg & S_IRWXUGO);
12881 shp->mlock_user = NULL;
12882
09a55596 12883@@ -634,6 +645,7 @@ static int newseg(struct ipc_namespace *
926e38e0
JR
12884
12885 ipc_unlock_object(&shp->shm_perm);
12886 rcu_read_unlock();
4bf69007
AM
12887+ vx_ipcshm_add(current_vx_info(), key, numpages);
12888 return error;
12889
12890 no_id:
3261cfd5
AM
12891diff -NurpP --minimal linux-4.9.207/kernel/auditsc.c linux-4.9.207-vs2.3.9.11/kernel/auditsc.c
12892--- linux-4.9.207/kernel/auditsc.c 2019-12-25 15:28:42.937225627 +0000
12893+++ linux-4.9.207-vs2.3.9.11/kernel/auditsc.c 2019-12-25 15:37:52.348423568 +0000
09a55596 12894@@ -1967,7 +1967,7 @@ static int audit_set_loginuid_perm(kuid_
c2e5f7c8 12895 if (is_audit_feature_set(AUDIT_FEATURE_LOGINUID_IMMUTABLE))
4bf69007 12896 return -EPERM;
c2e5f7c8 12897 /* it is set, you need permission */
4bf69007
AM
12898- if (!capable(CAP_AUDIT_CONTROL))
12899+ if (!vx_capable(CAP_AUDIT_CONTROL, VXC_AUDIT_CONTROL))
12900 return -EPERM;
c2e5f7c8
JR
12901 /* reject if this is not an unset and we don't allow that */
12902 if (is_audit_feature_set(AUDIT_FEATURE_ONLY_UNSET_LOGINUID) && uid_valid(loginuid))
3261cfd5
AM
12903diff -NurpP --minimal linux-4.9.207/kernel/capability.c linux-4.9.207-vs2.3.9.11/kernel/capability.c
12904--- linux-4.9.207/kernel/capability.c 2019-12-25 15:28:43.057223690 +0000
12905+++ linux-4.9.207-vs2.3.9.11/kernel/capability.c 2018-10-20 04:58:14.000000000 +0000
bb20add7 12906@@ -17,6 +17,7 @@
4bf69007
AM
12907 #include <linux/syscalls.h>
12908 #include <linux/pid_namespace.h>
12909 #include <linux/user_namespace.h>
12910+#include <linux/vs_context.h>
12911 #include <asm/uaccess.h>
12912
12913 /*
cc23e853 12914@@ -107,6 +108,7 @@ static int cap_validate_magic(cap_user_h
4bf69007
AM
12915 return 0;
12916 }
12917
2380c486 12918+
4bf69007
AM
12919 /*
12920 * The only thing that can change the capabilities of the current
12921 * process is the current process. As such, we can't be in this code
cc23e853 12922@@ -344,6 +346,8 @@ bool has_ns_capability_noaudit(struct ta
4bf69007
AM
12923 return (ret == 0);
12924 }
12925
12926+#include <linux/vserver/base.h>
d337f35e 12927+
4bf69007
AM
12928 /**
12929 * has_capability_noaudit - Does a task have a capability (unaudited) in the
12930 * initial user ns
3261cfd5
AM
12931diff -NurpP --minimal linux-4.9.207/kernel/compat.c linux-4.9.207-vs2.3.9.11/kernel/compat.c
12932--- linux-4.9.207/kernel/compat.c 2016-12-11 19:17:54.000000000 +0000
12933+++ linux-4.9.207-vs2.3.9.11/kernel/compat.c 2018-10-20 04:58:14.000000000 +0000
4bf69007
AM
12934@@ -27,6 +27,7 @@
12935 #include <linux/times.h>
12936 #include <linux/ptrace.h>
12937 #include <linux/gfp.h>
12938+#include <linux/vs_time.h>
12939
12940 #include <asm/uaccess.h>
12941
cc23e853 12942@@ -1059,7 +1060,7 @@ COMPAT_SYSCALL_DEFINE1(stime, compat_tim
4bf69007
AM
12943 if (err)
12944 return err;
12945
12946- do_settimeofday(&tv);
12947+ vx_settimeofday(&tv);
12948 return 0;
12949 }
12950
3261cfd5
AM
12951diff -NurpP --minimal linux-4.9.207/kernel/cred.c linux-4.9.207-vs2.3.9.11/kernel/cred.c
12952--- linux-4.9.207/kernel/cred.c 2019-12-25 15:28:43.087223204 +0000
12953+++ linux-4.9.207-vs2.3.9.11/kernel/cred.c 2019-10-05 14:58:45.880304199 +0000
cc23e853 12954@@ -64,31 +64,6 @@ struct cred init_cred = {
b00e13aa 12955 .group_info = &init_groups,
4bf69007
AM
12956 };
12957
12958-static inline void set_cred_subscribers(struct cred *cred, int n)
12959-{
12960-#ifdef CONFIG_DEBUG_CREDENTIALS
12961- atomic_set(&cred->subscribers, n);
12962-#endif
12963-}
12964-
12965-static inline int read_cred_subscribers(const struct cred *cred)
12966-{
12967-#ifdef CONFIG_DEBUG_CREDENTIALS
12968- return atomic_read(&cred->subscribers);
12969-#else
12970- return 0;
12971-#endif
12972-}
12973-
12974-static inline void alter_cred_subscribers(const struct cred *_cred, int n)
12975-{
12976-#ifdef CONFIG_DEBUG_CREDENTIALS
12977- struct cred *cred = (struct cred *) _cred;
12978-
12979- atomic_add(n, &cred->subscribers);
12980-#endif
12981-}
12982-
12983 /*
b00e13aa 12984 * The RCU callback to actually dispose of a set of credentials
4bf69007 12985 */
3261cfd5 12986@@ -243,21 +218,16 @@ error:
4bf69007
AM
12987 *
12988 * Call commit_creds() or abort_creds() to clean up.
12989 */
12990-struct cred *prepare_creds(void)
12991+struct cred *__prepare_creds(const struct cred *old)
12992 {
12993- struct task_struct *task = current;
12994- const struct cred *old;
12995 struct cred *new;
12996
12997- validate_process_creds();
12998-
12999 new = kmem_cache_alloc(cred_jar, GFP_KERNEL);
13000 if (!new)
13001 return NULL;
13002
13003 kdebug("prepare_creds() alloc %p", new);
13004
13005- old = task->cred;
13006 memcpy(new, old, sizeof(struct cred));
13007
3261cfd5
AM
13008 new->non_rcu = 0;
13009@@ -287,6 +257,13 @@ error:
4bf69007
AM
13010 abort_creds(new);
13011 return NULL;
13012 }
d337f35e 13013+
4bf69007 13014+struct cred *prepare_creds(void)
2380c486 13015+{
4bf69007 13016+ validate_process_creds();
d337f35e 13017+
4bf69007 13018+ return __prepare_creds(current->cred);
2380c486 13019+}
4bf69007
AM
13020 EXPORT_SYMBOL(prepare_creds);
13021
13022 /*
3261cfd5
AM
13023diff -NurpP --minimal linux-4.9.207/kernel/exit.c linux-4.9.207-vs2.3.9.11/kernel/exit.c
13024--- linux-4.9.207/kernel/exit.c 2019-12-25 15:28:43.277220132 +0000
13025+++ linux-4.9.207-vs2.3.9.11/kernel/exit.c 2019-02-24 12:44:58.353750946 +0000
4bf69007
AM
13026@@ -48,6 +48,10 @@
13027 #include <linux/fs_struct.h>
13028 #include <linux/init_task.h>
13029 #include <linux/perf_event.h>
13030+#include <linux/vs_limit.h>
13031+#include <linux/vs_context.h>
13032+#include <linux/vs_network.h>
13033+#include <linux/vs_pid.h>
13034 #include <trace/events/sched.h>
13035 #include <linux/hw_breakpoint.h>
13036 #include <linux/oom.h>
3261cfd5
AM
13037@@ -532,15 +536,25 @@ static struct task_struct *find_child_re
13038 {
4bf69007 13039 struct pid_namespace *pid_ns = task_active_pid_ns(father);
cc23e853 13040 struct task_struct *reaper = pid_ns->child_reaper;
4bf69007 13041+ struct vx_info *vxi = task_get_vx_info(father);
3261cfd5
AM
13042 struct task_struct *p, *n;
13043
4bf69007
AM
13044+ if (vxi) {
13045+ BUG_ON(!vxi->vx_reaper);
13046+ if (vxi->vx_reaper != init_pid_ns.child_reaper &&
cc23e853 13047+ vxi->vx_reaper != father) {
4bf69007 13048+ reaper = vxi->vx_reaper;
cc23e853
AM
13049+ goto out_put;
13050+ }
13051+ }
3261cfd5 13052+
cc23e853
AM
13053 if (likely(reaper != father))
13054- return reaper;
13055+ goto out_put;
13056
13057 reaper = find_alive_thread(father);
13058 if (reaper) {
13059 pid_ns->child_reaper = reaper;
13060- return reaper;
13061+ goto out_put;
4bf69007
AM
13062 }
13063
cc23e853 13064 write_unlock_irq(&tasklist_lock);
3261cfd5 13065@@ -557,7 +571,10 @@ static struct task_struct *find_child_re
cc23e853
AM
13066 zap_pid_ns_processes(pid_ns);
13067 write_lock_irq(&tasklist_lock);
13068
13069- return father;
13070+ reaper = father;
4bf69007
AM
13071+out_put:
13072+ put_vx_info(vxi);
13073+ return reaper;
13074 }
13075
13076 /*
3261cfd5 13077@@ -645,9 +662,13 @@ static void forget_original_parent(struc
cc23e853 13078 return;
bb20add7 13079
cc23e853
AM
13080 reaper = find_new_reaper(father, reaper);
13081- list_for_each_entry(p, &father->children, sibling) {
13082+ for (p = list_first_entry(&father->children, struct task_struct, sibling);
13083+ &p->sibling != &father->children; ) {
13084+ struct task_struct *next, *this_reaper = reaper;
13085+ if (p == reaper)
13086+ this_reaper = task_active_pid_ns(reaper)->child_reaper;
13087 for_each_thread(p, t) {
4bf69007 13088- t->real_parent = reaper;
cc23e853
AM
13089+ t->real_parent = this_reaper;
13090 BUG_ON((!t->ptrace) != (t->parent == father));
13091 if (likely(!t->ptrace))
13092 t->parent = t->real_parent;
3261cfd5 13093@@ -659,10 +680,13 @@ static void forget_original_parent(struc
cc23e853
AM
13094 * If this is a threaded reparent there is no need to
13095 * notify anyone anything has happened.
13096 */
13097- if (!same_thread_group(reaper, father))
13098+ if (!same_thread_group(this_reaper, father))
13099 reparent_leader(father, p, dead);
13100+ next = list_next_entry(p, sibling);
13101+ list_add(&p->sibling, &this_reaper->children);
13102+ p = next;
13103 }
13104- list_splice_tail_init(&father->children, &reaper->children);
13105+ INIT_LIST_HEAD(&father->children);
13106 }
13107
13108 /*
3261cfd5 13109@@ -852,6 +876,9 @@ void __noreturn do_exit(long code)
4bf69007 13110 */
c2e5f7c8 13111 flush_ptrace_hw_breakpoint(tsk);
4bf69007
AM
13112
13113+ /* needs to stay before exit_notify() */
13114+ exit_vx_info_early(tsk, code);
d337f35e 13115+
cc23e853 13116 TASKS_RCU(preempt_disable());
bb20add7 13117 TASKS_RCU(tasks_rcu_i = __srcu_read_lock(&tasks_rcu_exit_srcu));
cc23e853 13118 TASKS_RCU(preempt_enable());
3261cfd5 13119@@ -884,6 +911,10 @@ void __noreturn do_exit(long code)
4bf69007 13120
5ba7a31c
AM
13121 validate_creds_for_do_exit(tsk);
13122
13123+ /* needs to stay after exit_notify() and before preempt_disable() */
4bf69007
AM
13124+ exit_vx_info(tsk, code);
13125+ exit_nx_info(tsk);
d337f35e 13126+
5ba7a31c
AM
13127 check_stack_usage();
13128 preempt_disable();
13129 if (tsk->nr_dirtied)
3261cfd5
AM
13130diff -NurpP --minimal linux-4.9.207/kernel/fork.c linux-4.9.207-vs2.3.9.11/kernel/fork.c
13131--- linux-4.9.207/kernel/fork.c 2019-12-25 15:28:43.277220132 +0000
13132+++ linux-4.9.207-vs2.3.9.11/kernel/fork.c 2019-10-22 13:47:05.619629084 +0000
cc23e853 13133@@ -77,6 +77,9 @@
265de2f7 13134 #include <linux/compiler.h>
cc23e853
AM
13135 #include <linux/sysctl.h>
13136 #include <linux/kcov.h>
4bf69007
AM
13137+#include <linux/vs_context.h>
13138+#include <linux/vs_network.h>
13139+#include <linux/vs_limit.h>
13140
13141 #include <asm/pgtable.h>
13142 #include <asm/pgalloc.h>
09a55596 13143@@ -356,6 +359,8 @@ void free_task(struct task_struct *tsk)
cc23e853
AM
13144 WARN_ON_ONCE(atomic_read(&tsk->stack_refcount) != 0);
13145 #endif
4bf69007
AM
13146 rt_mutex_debug_task_free(tsk);
13147+ clr_vx_info(&tsk->vx_info);
13148+ clr_nx_info(&tsk->nx_info);
13149 ftrace_graph_exit_task(tsk);
13150 put_seccomp_filter(tsk);
13151 arch_release_task_struct(tsk);
09a55596 13152@@ -1480,6 +1485,8 @@ static __latent_entropy struct task_stru
8d50a2ea 13153 {
4bf69007
AM
13154 int retval;
13155 struct task_struct *p;
4bf69007
AM
13156+ struct vx_info *vxi;
13157+ struct nx_info *nxi;
13158
13159 if ((clone_flags & (CLONE_NEWNS|CLONE_FS)) == (CLONE_NEWNS|CLONE_FS))
13160 return ERR_PTR(-EINVAL);
09a55596 13161@@ -1552,7 +1559,12 @@ static __latent_entropy struct task_stru
4bf69007
AM
13162 DEBUG_LOCKS_WARN_ON(!p->hardirqs_enabled);
13163 DEBUG_LOCKS_WARN_ON(!p->softirqs_enabled);
13164 #endif
13165+ init_vx_info(&p->vx_info, current_vx_info());
13166+ init_nx_info(&p->nx_info, current_nx_info());
13167+
13168 retval = -EAGAIN;
13169+ if (!vx_nproc_avail(1))
13170+ goto bad_fork_free;
13171 if (atomic_read(&p->real_cred->user->processes) >=
13172 task_rlimit(p, RLIMIT_NPROC)) {
c2e5f7c8 13173 if (p->real_cred->user != INIT_USER &&
3261cfd5 13174@@ -1853,6 +1865,18 @@ static __latent_entropy struct task_stru
4bf69007
AM
13175 total_forks++;
13176 spin_unlock(&current->sighand->siglock);
bb20add7 13177 syscall_tracepoint_update(p);
4bf69007
AM
13178+
13179+ /* p is copy of current */
13180+ vxi = p->vx_info;
13181+ if (vxi) {
13182+ claim_vx_info(vxi, p);
13183+ atomic_inc(&vxi->cvirt.nr_threads);
13184+ atomic_inc(&vxi->cvirt.total_forks);
13185+ vx_nproc_inc(p);
2380c486 13186+ }
4bf69007
AM
13187+ nxi = p->nx_info;
13188+ if (nxi)
13189+ claim_nx_info(nxi, p);
13190 write_unlock_irq(&tasklist_lock);
bb20add7 13191
4bf69007 13192 proc_fork_connector(p);
3261cfd5
AM
13193diff -NurpP --minimal linux-4.9.207/kernel/kthread.c linux-4.9.207-vs2.3.9.11/kernel/kthread.c
13194--- linux-4.9.207/kernel/kthread.c 2019-12-25 15:28:43.417217867 +0000
13195+++ linux-4.9.207-vs2.3.9.11/kernel/kthread.c 2018-10-20 05:55:43.000000000 +0000
cc23e853 13196@@ -19,6 +19,7 @@
4bf69007 13197 #include <linux/ptrace.h>
09be7631 13198 #include <linux/uaccess.h>
cc23e853 13199 #include <linux/cgroup.h>
4bf69007
AM
13200+#include <linux/vs_pid.h>
13201 #include <trace/events/sched.h>
13202
13203 static DEFINE_SPINLOCK(kthread_create_lock);
3261cfd5
AM
13204diff -NurpP --minimal linux-4.9.207/kernel/Makefile linux-4.9.207-vs2.3.9.11/kernel/Makefile
13205--- linux-4.9.207/kernel/Makefile 2019-12-25 15:28:42.867226759 +0000
13206+++ linux-4.9.207-vs2.3.9.11/kernel/Makefile 2019-10-05 14:58:46.030301805 +0000
13207@@ -40,6 +40,7 @@ obj-y += printk/
13208 obj-y += irq/
13209 obj-y += rcu/
13210 obj-y += livepatch/
13211+obj-y += vserver/
13212
13213 obj-$(CONFIG_CHECKPOINT_RESTORE) += kcmp.o
13214 obj-$(CONFIG_FREEZER) += freezer.o
13215diff -NurpP --minimal linux-4.9.207/kernel/nsproxy.c linux-4.9.207-vs2.3.9.11/kernel/nsproxy.c
13216--- linux-4.9.207/kernel/nsproxy.c 2016-12-11 19:17:54.000000000 +0000
13217+++ linux-4.9.207-vs2.3.9.11/kernel/nsproxy.c 2018-10-20 04:58:14.000000000 +0000
cc23e853 13218@@ -20,12 +20,15 @@
4bf69007
AM
13219 #include <linux/mnt_namespace.h>
13220 #include <linux/utsname.h>
13221 #include <linux/pid_namespace.h>
13222+#include <linux/vserver/global.h>
13223+#include <linux/vserver/debug.h>
13224 #include <net/net_namespace.h>
13225 #include <linux/ipc_namespace.h>
09be7631 13226 #include <linux/proc_ns.h>
4bf69007
AM
13227 #include <linux/file.h>
13228 #include <linux/syscalls.h>
cc23e853 13229 #include <linux/cgroup.h>
4bf69007
AM
13230+#include "../fs/mount.h"
13231
13232 static struct kmem_cache *nsproxy_cachep;
13233
cc23e853 13234@@ -50,8 +53,11 @@ static inline struct nsproxy *create_nsp
4bf69007
AM
13235 struct nsproxy *nsproxy;
13236
13237 nsproxy = kmem_cache_alloc(nsproxy_cachep, GFP_KERNEL);
13238- if (nsproxy)
13239+ if (nsproxy) {
13240 atomic_set(&nsproxy->count, 1);
13241+ atomic_inc(&vs_global_nsproxy);
13242+ }
13243+ vxdprintk(VXD_CBIT(space, 2), "create_nsproxy = %p[1]", nsproxy);
13244 return nsproxy;
13245 }
13246
cc23e853 13247@@ -60,9 +66,12 @@ static inline struct nsproxy *create_nsp
4bf69007
AM
13248 * Return the newly created nsproxy. Do not attach this to the task,
13249 * leave it to the caller to do proper locking and attach it to task.
13250 */
13251-static struct nsproxy *create_new_namespaces(unsigned long flags,
b00e13aa
AM
13252- struct task_struct *tsk, struct user_namespace *user_ns,
13253- struct fs_struct *new_fs)
13254+static struct nsproxy *unshare_namespaces(
13255+ unsigned long flags,
13256+ struct nsproxy *orig,
13257+ struct fs_struct *new_fs,
13258+ struct user_namespace *new_user,
13259+ struct pid_namespace *new_pid)
4bf69007
AM
13260 {
13261 struct nsproxy *new_nsp;
13262 int err;
cc23e853 13263@@ -71,39 +80,37 @@ static struct nsproxy *create_new_namesp
4bf69007
AM
13264 if (!new_nsp)
13265 return ERR_PTR(-ENOMEM);
13266
b00e13aa
AM
13267- new_nsp->mnt_ns = copy_mnt_ns(flags, tsk->nsproxy->mnt_ns, user_ns, new_fs);
13268+ new_nsp->mnt_ns = copy_mnt_ns(flags, orig->mnt_ns, new_user, new_fs);
4bf69007
AM
13269 if (IS_ERR(new_nsp->mnt_ns)) {
13270 err = PTR_ERR(new_nsp->mnt_ns);
13271 goto out_ns;
13272 }
13273
b00e13aa
AM
13274- new_nsp->uts_ns = copy_utsname(flags, user_ns, tsk->nsproxy->uts_ns);
13275+ new_nsp->uts_ns = copy_utsname(flags, new_user, orig->uts_ns);
4bf69007
AM
13276 if (IS_ERR(new_nsp->uts_ns)) {
13277 err = PTR_ERR(new_nsp->uts_ns);
13278 goto out_uts;
13279 }
13280
b00e13aa
AM
13281- new_nsp->ipc_ns = copy_ipcs(flags, user_ns, tsk->nsproxy->ipc_ns);
13282+ new_nsp->ipc_ns = copy_ipcs(flags, new_user, orig->ipc_ns);
4bf69007
AM
13283 if (IS_ERR(new_nsp->ipc_ns)) {
13284 err = PTR_ERR(new_nsp->ipc_ns);
13285 goto out_ipc;
13286 }
13287
c2e5f7c8
JR
13288- new_nsp->pid_ns_for_children =
13289- copy_pid_ns(flags, user_ns, tsk->nsproxy->pid_ns_for_children);
13290+ new_nsp->pid_ns_for_children = copy_pid_ns(flags, new_user, new_pid);
13291 if (IS_ERR(new_nsp->pid_ns_for_children)) {
13292 err = PTR_ERR(new_nsp->pid_ns_for_children);
4bf69007
AM
13293 goto out_pid;
13294 }
13295
cc23e853
AM
13296- new_nsp->cgroup_ns = copy_cgroup_ns(flags, user_ns,
13297- tsk->nsproxy->cgroup_ns);
13298+ new_nsp->cgroup_ns = copy_cgroup_ns(flags, new_user, orig->cgroup_ns);
13299 if (IS_ERR(new_nsp->cgroup_ns)) {
13300 err = PTR_ERR(new_nsp->cgroup_ns);
13301 goto out_cgroup;
13302 }
13303
b00e13aa
AM
13304- new_nsp->net_ns = copy_net_ns(flags, user_ns, tsk->nsproxy->net_ns);
13305+ new_nsp->net_ns = copy_net_ns(flags, new_user, orig->net_ns);
4bf69007
AM
13306 if (IS_ERR(new_nsp->net_ns)) {
13307 err = PTR_ERR(new_nsp->net_ns);
13308 goto out_net;
cc23e853 13309@@ -130,6 +137,43 @@ out_ns:
4bf69007
AM
13310 return ERR_PTR(err);
13311 }
13312
13313+static struct nsproxy *create_new_namespaces(unsigned long flags,
b00e13aa
AM
13314+ struct task_struct *tsk, struct user_namespace *user_ns,
13315+ struct fs_struct *new_fs)
13316+
4bf69007
AM
13317+{
13318+ return unshare_namespaces(flags, tsk->nsproxy,
b00e13aa 13319+ new_fs, user_ns, task_active_pid_ns(tsk));
2380c486 13320+}
d337f35e 13321+
4bf69007
AM
13322+/*
13323+ * copies the nsproxy, setting refcount to 1, and grabbing a
13324+ * reference to all contained namespaces.
13325+ */
13326+struct nsproxy *copy_nsproxy(struct nsproxy *orig)
2380c486 13327+{
4bf69007 13328+ struct nsproxy *ns = create_nsproxy();
d337f35e 13329+
4bf69007
AM
13330+ if (ns) {
13331+ memcpy(ns, orig, sizeof(struct nsproxy));
13332+ atomic_set(&ns->count, 1);
d337f35e 13333+
4bf69007
AM
13334+ if (ns->mnt_ns)
13335+ get_mnt_ns(ns->mnt_ns);
13336+ if (ns->uts_ns)
13337+ get_uts_ns(ns->uts_ns);
13338+ if (ns->ipc_ns)
13339+ get_ipc_ns(ns->ipc_ns);
c2e5f7c8
JR
13340+ if (ns->pid_ns_for_children)
13341+ get_pid_ns(ns->pid_ns_for_children);
4bf69007
AM
13342+ if (ns->net_ns)
13343+ get_net(ns->net_ns);
cc23e853
AM
13344+ if (ns->cgroup_ns)
13345+ get_cgroup_ns(ns->cgroup_ns);
4bf69007
AM
13346+ }
13347+ return ns;
13348+}
d337f35e 13349+
4bf69007
AM
13350 /*
13351 * called from clone. This now handles copy for nsproxy and all
13352 * namespaces therein.
cc23e853 13353@@ -138,7 +182,10 @@ int copy_namespaces(unsigned long flags,
4bf69007
AM
13354 {
13355 struct nsproxy *old_ns = tsk->nsproxy;
b00e13aa 13356 struct user_namespace *user_ns = task_cred_xxx(tsk, user_ns);
4bf69007
AM
13357- struct nsproxy *new_ns;
13358+ struct nsproxy *new_ns = NULL;
c2e5f7c8 13359+
4bf69007
AM
13360+ vxdprintk(VXD_CBIT(space, 7), "copy_namespaces(0x%08lx,%p[%p])",
13361+ flags, tsk, old_ns);
4bf69007 13362
c2e5f7c8 13363 if (likely(!(flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC |
cc23e853
AM
13364 CLONE_NEWPID | CLONE_NEWNET |
13365@@ -147,7 +194,7 @@ int copy_namespaces(unsigned long flags,
4bf69007 13366 return 0;
4bf69007 13367 }
4bf69007 13368
c2e5f7c8
JR
13369- if (!ns_capable(user_ns, CAP_SYS_ADMIN))
13370+ if (!vx_ns_can_unshare(user_ns, CAP_SYS_ADMIN, flags))
13371 return -EPERM;
13372
13373 /*
cc23e853 13374@@ -166,6 +213,9 @@ int copy_namespaces(unsigned long flags,
c2e5f7c8
JR
13375 return PTR_ERR(new_ns);
13376
13377 tsk->nsproxy = new_ns;
4bf69007 13378+ vxdprintk(VXD_CBIT(space, 3),
c2e5f7c8
JR
13379+ "copy_namespaces(0x%08lx,%p[%p]) = [%p]",
13380+ flags, tsk, old_ns, new_ns);
13381 return 0;
4bf69007
AM
13382 }
13383
cc23e853 13384@@ -179,8 +229,10 @@ void free_nsproxy(struct nsproxy *ns)
4bf69007 13385 put_ipc_ns(ns->ipc_ns);
c2e5f7c8
JR
13386 if (ns->pid_ns_for_children)
13387 put_pid_ns(ns->pid_ns_for_children);
4bf69007
AM
13388+ if (ns->net_ns)
13389+ put_net(ns->net_ns);
cc23e853
AM
13390 put_cgroup_ns(ns->cgroup_ns);
13391- put_net(ns->net_ns);
4bf69007
AM
13392+ atomic_dec(&vs_global_nsproxy);
13393 kmem_cache_free(nsproxy_cachep, ns);
13394 }
13395
cc23e853 13396@@ -194,12 +246,16 @@ int unshare_nsproxy_namespaces(unsigned
b00e13aa 13397 struct user_namespace *user_ns;
4bf69007
AM
13398 int err = 0;
13399
13400+ vxdprintk(VXD_CBIT(space, 4),
13401+ "unshare_nsproxy_namespaces(0x%08lx,[%p])",
13402+ unshare_flags, current->nsproxy);
d337f35e 13403+
4bf69007 13404 if (!(unshare_flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC |
cc23e853 13405 CLONE_NEWNET | CLONE_NEWPID | CLONE_NEWCGROUP)))
4bf69007
AM
13406 return 0;
13407
b00e13aa
AM
13408 user_ns = new_cred ? new_cred->user_ns : current_user_ns();
13409- if (!ns_capable(user_ns, CAP_SYS_ADMIN))
13410+ if (!vx_ns_can_unshare(user_ns, CAP_SYS_ADMIN, unshare_flags))
4bf69007
AM
13411 return -EPERM;
13412
b00e13aa 13413 *new_nsp = create_new_namespaces(unshare_flags, current, user_ns,
3261cfd5
AM
13414diff -NurpP --minimal linux-4.9.207/kernel/pid.c linux-4.9.207-vs2.3.9.11/kernel/pid.c
13415--- linux-4.9.207/kernel/pid.c 2019-12-25 15:28:43.497216574 +0000
13416+++ linux-4.9.207-vs2.3.9.11/kernel/pid.c 2018-10-20 04:58:14.000000000 +0000
09be7631 13417@@ -38,6 +38,7 @@
4bf69007 13418 #include <linux/syscalls.h>
09be7631 13419 #include <linux/proc_ns.h>
b00e13aa 13420 #include <linux/proc_fs.h>
4bf69007
AM
13421+#include <linux/vs_pid.h>
13422
13423 #define pid_hashfn(nr, ns) \
13424 hash_long((unsigned long)nr + (unsigned long)ns, pidhash_shift)
09a55596 13425@@ -381,7 +382,7 @@ EXPORT_SYMBOL_GPL(find_pid_ns);
4bf69007
AM
13426
13427 struct pid *find_vpid(int nr)
13428 {
b00e13aa
AM
13429- return find_pid_ns(nr, task_active_pid_ns(current));
13430+ return find_pid_ns(vx_rmap_pid(nr), task_active_pid_ns(current));
4bf69007
AM
13431 }
13432 EXPORT_SYMBOL_GPL(find_vpid);
13433
09a55596 13434@@ -437,6 +438,9 @@ void transfer_pid(struct task_struct *ol
4bf69007
AM
13435 struct task_struct *pid_task(struct pid *pid, enum pid_type type)
13436 {
13437 struct task_struct *result = NULL;
d337f35e 13438+
cc23e853 13439+ if (type == __PIDTYPE_REALPID)
4bf69007
AM
13440+ type = PIDTYPE_PID;
13441 if (pid) {
13442 struct hlist_node *first;
13443 first = rcu_dereference_check(hlist_first_rcu(&pid->tasks[type]),
09a55596 13444@@ -455,7 +459,7 @@ struct task_struct *find_task_by_pid_ns(
cc23e853
AM
13445 {
13446 RCU_LOCKDEP_WARN(!rcu_read_lock_held(),
13447 "find_task_by_pid_ns() needs rcu_read_lock() protection");
4bf69007
AM
13448- return pid_task(find_pid_ns(nr, ns), PIDTYPE_PID);
13449+ return pid_task(find_pid_ns(vx_rmap_pid(nr), ns), PIDTYPE_PID);
13450 }
13451
13452 struct task_struct *find_task_by_vpid(pid_t vnr)
09a55596 13453@@ -499,7 +503,7 @@ struct pid *find_get_pid(pid_t nr)
4bf69007
AM
13454 }
13455 EXPORT_SYMBOL_GPL(find_get_pid);
13456
13457-pid_t pid_nr_ns(struct pid *pid, struct pid_namespace *ns)
13458+pid_t pid_unmapped_nr_ns(struct pid *pid, struct pid_namespace *ns)
13459 {
13460 struct upid *upid;
13461 pid_t nr = 0;
09a55596 13462@@ -513,6 +517,11 @@ pid_t pid_nr_ns(struct pid *pid, struct
4bf69007
AM
13463 }
13464 EXPORT_SYMBOL_GPL(pid_nr_ns);
13465
13466+pid_t pid_nr_ns(struct pid *pid, struct pid_namespace *ns)
2380c486 13467+{
4bf69007
AM
13468+ return vx_map_pid(pid_unmapped_nr_ns(pid, ns));
13469+}
d337f35e 13470+
4bf69007
AM
13471 pid_t pid_vnr(struct pid *pid)
13472 {
b00e13aa 13473 return pid_nr_ns(pid, task_active_pid_ns(current));
3261cfd5
AM
13474diff -NurpP --minimal linux-4.9.207/kernel/pid_namespace.c linux-4.9.207-vs2.3.9.11/kernel/pid_namespace.c
13475--- linux-4.9.207/kernel/pid_namespace.c 2019-12-25 15:28:43.497216574 +0000
13476+++ linux-4.9.207-vs2.3.9.11/kernel/pid_namespace.c 2019-10-05 14:58:46.030301805 +0000
b00e13aa 13477@@ -18,6 +18,7 @@
09be7631 13478 #include <linux/proc_ns.h>
4bf69007
AM
13479 #include <linux/reboot.h>
13480 #include <linux/export.h>
13481+#include <linux/vserver/global.h>
13482
09be7631
JR
13483 struct pid_cache {
13484 int nr_ids;
cc23e853
AM
13485@@ -124,6 +125,7 @@ static struct pid_namespace *create_pid_
13486 ns->ns.ops = &pidns_operations;
4bf69007
AM
13487
13488 kref_init(&ns->kref);
13489+ atomic_inc(&vs_global_pid_ns);
13490 ns->level = level;
13491 ns->parent = get_pid_ns(parent_pid_ns);
b00e13aa 13492 ns->user_ns = get_user_ns(user_ns);
cc23e853 13493@@ -142,6 +144,7 @@ static struct pid_namespace *create_pid_
c2e5f7c8
JR
13494 out_free_map:
13495 kfree(ns->pidmap[0].page);
13496 out_free:
4bf69007
AM
13497+ atomic_dec(&vs_global_pid_ns);
13498 kmem_cache_free(pid_ns_cachep, ns);
cc23e853
AM
13499 out_dec:
13500 dec_pid_namespaces(ucounts);
3261cfd5
AM
13501diff -NurpP --minimal linux-4.9.207/kernel/printk/printk.c linux-4.9.207-vs2.3.9.11/kernel/printk/printk.c
13502--- linux-4.9.207/kernel/printk/printk.c 2019-12-25 15:28:43.597214959 +0000
13503+++ linux-4.9.207-vs2.3.9.11/kernel/printk/printk.c 2019-12-25 15:37:52.568420017 +0000
cc23e853 13504@@ -45,6 +45,7 @@
09be7631 13505 #include <linux/utsname.h>
bb20add7 13506 #include <linux/ctype.h>
cc23e853 13507 #include <linux/uio.h>
4bf69007
AM
13508+#include <linux/vs_cvirt.h>
13509
13510 #include <asm/uaccess.h>
cc23e853 13511 #include <asm/sections.h>
3261cfd5 13512@@ -611,7 +612,7 @@ int check_syslog_permissions(int type, i
cc23e853 13513 goto ok;
4bf69007
AM
13514
13515 if (syslog_action_restricted(type)) {
13516- if (capable(CAP_SYSLOG))
13517+ if (vx_capable(CAP_SYSLOG, VXC_SYSLOG))
cc23e853 13518 goto ok;
092a4f51
JR
13519 /*
13520 * For historical reasons, accept CAP_SYS_ADMIN too, with
3261cfd5 13521@@ -1398,12 +1399,9 @@ int do_syslog(int type, char __user *buf
4bf69007 13522 if (error)
cc23e853 13523 goto out;
4bf69007
AM
13524
13525- switch (type) {
13526- case SYSLOG_ACTION_CLOSE: /* Close log */
13527- break;
13528- case SYSLOG_ACTION_OPEN: /* Open log */
13529- break;
13530- case SYSLOG_ACTION_READ: /* Read from log */
13531+ if ((type == SYSLOG_ACTION_READ) ||
13532+ (type == SYSLOG_ACTION_READ_ALL) ||
13533+ (type == SYSLOG_ACTION_READ_CLEAR)) {
13534 error = -EINVAL;
13535 if (!buf || len < 0)
13536 goto out;
3261cfd5 13537@@ -1414,6 +1412,16 @@ int do_syslog(int type, char __user *buf
4bf69007
AM
13538 error = -EFAULT;
13539 goto out;
13540 }
13541+ }
13542+ if (!vx_check(0, VS_ADMIN|VS_WATCH))
13543+ return vx_do_syslog(type, buf, len);
d337f35e 13544+
4bf69007
AM
13545+ switch (type) {
13546+ case SYSLOG_ACTION_CLOSE: /* Close log */
13547+ break;
13548+ case SYSLOG_ACTION_OPEN: /* Open log */
13549+ break;
13550+ case SYSLOG_ACTION_READ: /* Read from log */
13551 error = wait_event_interruptible(log_wait,
13552 syslog_seq != log_next_seq);
13553 if (error)
3261cfd5 13554@@ -1426,16 +1434,6 @@ int do_syslog(int type, char __user *buf
4bf69007
AM
13555 /* FALL THRU */
13556 /* Read last kernel messages */
13557 case SYSLOG_ACTION_READ_ALL:
13558- error = -EINVAL;
13559- if (!buf || len < 0)
13560- goto out;
13561- error = 0;
13562- if (!len)
13563- goto out;
13564- if (!access_ok(VERIFY_WRITE, buf, len)) {
13565- error = -EFAULT;
13566- goto out;
13567- }
13568 error = syslog_print_all(buf, len, clear);
13569 break;
13570 /* Clear ring buffer */
3261cfd5
AM
13571diff -NurpP --minimal linux-4.9.207/kernel/ptrace.c linux-4.9.207-vs2.3.9.11/kernel/ptrace.c
13572--- linux-4.9.207/kernel/ptrace.c 2019-12-25 15:28:43.597214959 +0000
13573+++ linux-4.9.207-vs2.3.9.11/kernel/ptrace.c 2019-10-05 14:59:56.929168738 +0000
09be7631 13574@@ -23,6 +23,7 @@
4bf69007
AM
13575 #include <linux/syscalls.h>
13576 #include <linux/uaccess.h>
13577 #include <linux/regset.h>
13578+#include <linux/vs_context.h>
13579 #include <linux/hw_breakpoint.h>
13580 #include <linux/cn_proc.h>
09be7631 13581 #include <linux/compat.h>
3261cfd5
AM
13582@@ -336,6 +337,11 @@ ok:
13583 !ptrace_has_cap(mm->user_ns, mode)))
13584 return -EPERM;
b00e13aa 13585
4bf69007
AM
13586+ if (!vx_check(task->xid, VS_ADMIN_P|VS_WATCH_P|VS_IDENT))
13587+ return -EPERM;
13588+ if (!vx_check(task->xid, VS_IDENT) &&
3261cfd5 13589+ !task_vx_flags(task, VXF_STATE_ADMIN, 0))
4bf69007 13590+ return -EACCES;
3261cfd5
AM
13591 if (mode & PTRACE_MODE_SCHED)
13592 return 0;
4bf69007 13593 return security_ptrace_access_check(task, mode);
3261cfd5
AM
13594diff -NurpP --minimal linux-4.9.207/kernel/reboot.c linux-4.9.207-vs2.3.9.11/kernel/reboot.c
13595--- linux-4.9.207/kernel/reboot.c 2016-12-11 19:17:54.000000000 +0000
13596+++ linux-4.9.207-vs2.3.9.11/kernel/reboot.c 2018-10-20 04:58:15.000000000 +0000
c2e5f7c8
JR
13597@@ -16,6 +16,7 @@
13598 #include <linux/syscalls.h>
13599 #include <linux/syscore_ops.h>
13600 #include <linux/uaccess.h>
13601+#include <linux/vs_pid.h>
13602
13603 /*
13604 * this indicates whether you can reboot with ctrl-alt-del: the default is yes
bb20add7 13605@@ -269,6 +270,8 @@ EXPORT_SYMBOL_GPL(kernel_power_off);
c2e5f7c8
JR
13606
13607 static DEFINE_MUTEX(reboot_mutex);
13608
13609+long vs_reboot(unsigned int, void __user *);
13610+
13611 /*
13612 * Reboot system call: for obvious reasons only root may call it,
13613 * and even root needs to set up some magic numbers in the registers
bb20add7 13614@@ -311,6 +314,9 @@ SYSCALL_DEFINE4(reboot, int, magic1, int
c2e5f7c8
JR
13615 if ((cmd == LINUX_REBOOT_CMD_POWER_OFF) && !pm_power_off)
13616 cmd = LINUX_REBOOT_CMD_HALT;
13617
13618+ if (!vx_check(0, VS_ADMIN|VS_WATCH))
13619+ return vs_reboot(cmd, arg);
13620+
13621 mutex_lock(&reboot_mutex);
13622 switch (cmd) {
13623 case LINUX_REBOOT_CMD_RESTART:
3261cfd5
AM
13624diff -NurpP --minimal linux-4.9.207/kernel/sched/core.c linux-4.9.207-vs2.3.9.11/kernel/sched/core.c
13625--- linux-4.9.207/kernel/sched/core.c 2019-12-25 15:28:43.667213827 +0000
13626+++ linux-4.9.207-vs2.3.9.11/kernel/sched/core.c 2019-10-22 13:47:05.639628767 +0000
cc23e853 13627@@ -75,6 +75,8 @@
265de2f7 13628 #include <linux/compiler.h>
cc23e853
AM
13629 #include <linux/frame.h>
13630 #include <linux/prefetch.h>
4bf69007
AM
13631+#include <linux/vs_sched.h>
13632+#include <linux/vs_cvirt.h>
13633
13634 #include <asm/switch_to.h>
13635 #include <asm/tlb.h>
09a55596 13636@@ -3431,6 +3433,7 @@ void __noreturn do_task_dead(void)
cc23e853
AM
13637 __set_current_state(TASK_DEAD);
13638 current->flags |= PF_NOFREEZE; /* tell freezer to ignore us */
13639 __schedule(false);
13640+ printk("bad task: %p [%lx]\n", current, current->state);
13641 BUG();
13642 /* Avoid "noreturn function does return". */
13643 for (;;)
09a55596 13644@@ -3824,7 +3827,7 @@ SYSCALL_DEFINE1(nice, int, increment)
4bf69007 13645
bb20add7 13646 nice = clamp_val(nice, MIN_NICE, MAX_NICE);
4bf69007
AM
13647 if (increment < 0 && !can_nice(current, nice))
13648- return -EPERM;
13649+ return vx_flags(VXF_IGNEG_NICE, 0) ? 0 : -EPERM;
13650
13651 retval = security_task_setnice(current, nice);
13652 if (retval)
3261cfd5
AM
13653diff -NurpP --minimal linux-4.9.207/kernel/sched/cputime.c linux-4.9.207-vs2.3.9.11/kernel/sched/cputime.c
13654--- linux-4.9.207/kernel/sched/cputime.c 2019-12-25 15:28:43.697213342 +0000
13655+++ linux-4.9.207-vs2.3.9.11/kernel/sched/cputime.c 2018-10-20 11:46:17.000000000 +0000
b00e13aa 13656@@ -4,6 +4,7 @@
4bf69007
AM
13657 #include <linux/kernel_stat.h>
13658 #include <linux/static_key.h>
b00e13aa 13659 #include <linux/context_tracking.h>
4bf69007
AM
13660+#include <linux/vs_sched.h>
13661 #include "sched.h"
cc23e853
AM
13662 #ifdef CONFIG_PARAVIRT
13663 #include <asm/paravirt.h>
09a55596 13664@@ -125,14 +126,17 @@ static inline void task_group_account_fi
4bf69007
AM
13665 void account_user_time(struct task_struct *p, cputime_t cputime,
13666 cputime_t cputime_scaled)
13667 {
13668+ struct vx_info *vxi = p->vx_info; /* p is _always_ current */
ca5d134c 13669+ int nice = (task_nice(p) > 0);
4bf69007
AM
13670 int index;
13671
13672 /* Add user time to process. */
13673 p->utime += cputime;
13674 p->utimescaled += cputime_scaled;
13675+ vx_account_user(vxi, cputime, nice);
13676 account_group_user_time(p, cputime);
13677
ca5d134c 13678- index = (task_nice(p) > 0) ? CPUTIME_NICE : CPUTIME_USER;
4bf69007
AM
13679+ index = (nice) ? CPUTIME_NICE : CPUTIME_USER;
13680
13681 /* Add user time to cpustat. */
09a55596
AM
13682 task_group_account_field(p, index, cputime_to_nsecs(cputime));
13683@@ -179,9 +183,12 @@ static inline
ca5d134c
JR
13684 void __account_system_time(struct task_struct *p, cputime_t cputime,
13685 cputime_t cputime_scaled, int index)
13686 {
13687+ struct vx_info *vxi = p->vx_info; /* p is _always_ current */
13688+
13689 /* Add system time to process. */
13690 p->stime += cputime;
13691 p->stimescaled += cputime_scaled;
13692+ vx_account_system(vxi, cputime, 0 /* do we have idle time? */);
13693 account_group_system_time(p, cputime);
13694
13695 /* Add system time to cpustat. */
3261cfd5
AM
13696diff -NurpP --minimal linux-4.9.207/kernel/sched/fair.c linux-4.9.207-vs2.3.9.11/kernel/sched/fair.c
13697--- linux-4.9.207/kernel/sched/fair.c 2019-12-25 15:28:43.697213342 +0000
13698+++ linux-4.9.207-vs2.3.9.11/kernel/sched/fair.c 2019-12-25 15:37:52.578419856 +0000
bb20add7 13699@@ -30,6 +30,7 @@
b00e13aa
AM
13700 #include <linux/mempolicy.h>
13701 #include <linux/migrate.h>
13702 #include <linux/task_work.h>
4bf69007
AM
13703+#include <linux/vs_cvirt.h>
13704
13705 #include <trace/events/sched.h>
13706
3261cfd5 13707@@ -3431,6 +3432,8 @@ enqueue_entity(struct cfs_rq *cfs_rq, st
4bf69007
AM
13708 __enqueue_entity(cfs_rq, se);
13709 se->on_rq = 1;
13710
13711+ if (entity_is_task(se))
13712+ vx_activate_task(task_of(se));
13713 if (cfs_rq->nr_running == 1) {
13714 list_add_leaf_cfs_rq(cfs_rq);
13715 check_enqueue_throttle(cfs_rq);
3261cfd5 13716@@ -3500,6 +3503,8 @@ dequeue_entity(struct cfs_rq *cfs_rq, st
4bf69007
AM
13717 if (se != cfs_rq->curr)
13718 __dequeue_entity(cfs_rq, se);
13719 se->on_rq = 0;
13720+ if (entity_is_task(se))
13721+ vx_deactivate_task(task_of(se));
4bf69007
AM
13722 account_entity_dequeue(cfs_rq, se);
13723
b00e13aa 13724 /*
3261cfd5
AM
13725diff -NurpP --minimal linux-4.9.207/kernel/sched/loadavg.c linux-4.9.207-vs2.3.9.11/kernel/sched/loadavg.c
13726--- linux-4.9.207/kernel/sched/loadavg.c 2019-12-25 15:28:43.697213342 +0000
13727+++ linux-4.9.207-vs2.3.9.11/kernel/sched/loadavg.c 2018-10-20 04:58:15.000000000 +0000
5ba7a31c
AM
13728@@ -73,9 +73,16 @@ EXPORT_SYMBOL(avenrun); /* should be rem
13729 */
13730 void get_avenrun(unsigned long *loads, unsigned long offset, int shift)
13731 {
13732- loads[0] = (avenrun[0] + offset) << shift;
13733- loads[1] = (avenrun[1] + offset) << shift;
13734- loads[2] = (avenrun[2] + offset) << shift;
13735+ if (vx_flags(VXF_VIRT_LOAD, 0)) {
13736+ struct vx_info *vxi = current_vx_info();
13737+ loads[0] = (vxi->cvirt.load[0] + offset) << shift;
13738+ loads[1] = (vxi->cvirt.load[1] + offset) << shift;
13739+ loads[2] = (vxi->cvirt.load[2] + offset) << shift;
13740+ } else {
13741+ loads[0] = (avenrun[0] + offset) << shift;
13742+ loads[1] = (avenrun[1] + offset) << shift;
13743+ loads[2] = (avenrun[2] + offset) << shift;
13744+ }
13745 }
13746
13747 long calc_load_fold_active(struct rq *this_rq, long adjust)
3261cfd5
AM
13748diff -NurpP --minimal linux-4.9.207/kernel/signal.c linux-4.9.207-vs2.3.9.11/kernel/signal.c
13749--- linux-4.9.207/kernel/signal.c 2019-12-25 15:28:43.717213017 +0000
13750+++ linux-4.9.207-vs2.3.9.11/kernel/signal.c 2019-12-25 15:37:52.578419856 +0000
bb20add7 13751@@ -34,6 +34,8 @@
b00e13aa 13752 #include <linux/compat.h>
09be7631 13753 #include <linux/cn_proc.h>
265de2f7 13754 #include <linux/compiler.h>
4bf69007
AM
13755+#include <linux/vs_context.h>
13756+#include <linux/vs_pid.h>
265de2f7 13757
4bf69007
AM
13758 #define CREATE_TRACE_POINTS
13759 #include <trace/events/signal.h>
3261cfd5 13760@@ -772,9 +774,18 @@ static int check_kill_permission(int sig
4bf69007
AM
13761 struct pid *sid;
13762 int error;
13763
13764+ vxdprintk(VXD_CBIT(misc, 7),
13765+ "check_kill_permission(%d,%p,%p[#%u,%u])",
13766+ sig, info, t, vx_task_xid(t), t->pid);
d337f35e 13767+
4bf69007
AM
13768 if (!valid_signal(sig))
13769 return -EINVAL;
13770
13771+/* FIXME: needed? if so, why?
13772+ if ((info != SEND_SIG_NOINFO) &&
13773+ (is_si_special(info) || !si_fromuser(info)))
13774+ goto skip; */
d337f35e 13775+
4bf69007
AM
13776 if (!si_fromuser(info))
13777 return 0;
13778
3261cfd5 13779@@ -798,6 +809,20 @@ static int check_kill_permission(int sig
4bf69007
AM
13780 }
13781 }
13782
13783+ error = -EPERM;
13784+ if (t->pid == 1 && current->xid)
13785+ return error;
d337f35e 13786+
4bf69007
AM
13787+ error = -ESRCH;
13788+ /* FIXME: we shouldn't return ESRCH ever, to avoid
13789+ loops, maybe ENOENT or EACCES? */
13790+ if (!vx_check(vx_task_xid(t), VS_WATCH_P | VS_IDENT)) {
13791+ vxdprintk(current->xid || VXD_CBIT(misc, 7),
13792+ "signal %d[%p] xid mismatch %p[#%u,%u] xid=#%u",
13793+ sig, info, t, vx_task_xid(t), t->pid, current->xid);
13794+ return error;
2380c486 13795+ }
4bf69007
AM
13796+/* skip: */
13797 return security_task_kill(t, info, sig, 0);
13798 }
13799
3261cfd5 13800@@ -1349,8 +1374,14 @@ int kill_pid_info(int sig, struct siginf
cc23e853
AM
13801 for (;;) {
13802 rcu_read_lock();
13803 p = pid_task(pid, PIDTYPE_PID);
13804- if (p)
13805- error = group_send_sig_info(sig, info, p);
13806+ if (p) {
13807+ if (vx_check(vx_task_xid(p), VS_IDENT))
13808+ error = group_send_sig_info(sig, info, p);
13809+ else {
13810+ rcu_read_unlock();
13811+ return -ESRCH;
13812+ }
13813+ }
13814 rcu_read_unlock();
13815 if (likely(!p || error != -ESRCH))
13816 return error;
3261cfd5 13817@@ -1395,7 +1426,7 @@ int kill_pid_info_as_cred(int sig, struc
4bf69007
AM
13818
13819 rcu_read_lock();
13820 p = pid_task(pid, PIDTYPE_PID);
13821- if (!p) {
13822+ if (!p || !vx_check(vx_task_xid(p), VS_IDENT)) {
13823 ret = -ESRCH;
13824 goto out_unlock;
13825 }
3261cfd5 13826@@ -1451,8 +1482,10 @@ static int kill_something_info(int sig,
4bf69007
AM
13827 struct task_struct * p;
13828
13829 for_each_process(p) {
13830- if (task_pid_vnr(p) > 1 &&
13831- !same_thread_group(p, current)) {
13832+ if (vx_check(vx_task_xid(p), VS_ADMIN|VS_IDENT) &&
13833+ task_pid_vnr(p) > 1 &&
13834+ !same_thread_group(p, current) &&
13835+ !vx_current_initpid(p->pid)) {
13836 int err = group_send_sig_info(sig, info, p);
13837 ++count;
13838 if (err != -EPERM)
3261cfd5 13839@@ -2323,6 +2356,11 @@ relock:
4bf69007
AM
13840 !sig_kernel_only(signr))
13841 continue;
13842
13843+ /* virtual init is protected against user signals */
bb20add7 13844+ if ((ksig->info.si_code == SI_USER) &&
4bf69007
AM
13845+ vx_current_initpid(current->pid))
13846+ continue;
d337f35e 13847+
4bf69007
AM
13848 if (sig_kernel_stop(signr)) {
13849 /*
13850 * The default action is to stop all threads in
3261cfd5
AM
13851diff -NurpP --minimal linux-4.9.207/kernel/softirq.c linux-4.9.207-vs2.3.9.11/kernel/softirq.c
13852--- linux-4.9.207/kernel/softirq.c 2019-12-25 15:28:43.727212857 +0000
13853+++ linux-4.9.207-vs2.3.9.11/kernel/softirq.c 2018-10-20 05:55:43.000000000 +0000
bb20add7 13854@@ -26,6 +26,7 @@
4bf69007
AM
13855 #include <linux/smpboot.h>
13856 #include <linux/tick.h>
265de2f7 13857 #include <linux/irq.h>
4bf69007
AM
13858+#include <linux/vs_context.h>
13859
13860 #define CREATE_TRACE_POINTS
13861 #include <trace/events/irq.h>
3261cfd5
AM
13862diff -NurpP --minimal linux-4.9.207/kernel/sys.c linux-4.9.207-vs2.3.9.11/kernel/sys.c
13863--- linux-4.9.207/kernel/sys.c 2019-12-25 15:28:43.747212532 +0000
13864+++ linux-4.9.207-vs2.3.9.11/kernel/sys.c 2019-10-13 16:09:18.098106817 +0000
09a55596
AM
13865@@ -56,6 +56,7 @@
13866 #include <linux/nospec.h>
4bf69007
AM
13867
13868 #include <linux/kmsg_dump.h>
b00e13aa 13869+#include <linux/vs_pid.h>
4bf69007 13870 /* Move somewhere else to avoid recompiling? */
b00e13aa
AM
13871 #include <generated/utsrelease.h>
13872
09a55596 13873@@ -159,7 +160,10 @@ static int set_one_prio(struct task_stru
4bf69007
AM
13874 goto out;
13875 }
13876 if (niceval < task_nice(p) && !can_nice(p, niceval)) {
13877- error = -EACCES;
13878+ if (vx_flags(VXF_IGNEG_NICE, 0))
13879+ error = 0;
13880+ else
13881+ error = -EACCES;
13882 goto out;
13883 }
13884 no_nice = security_task_setnice(p, niceval);
09a55596 13885@@ -210,6 +214,8 @@ SYSCALL_DEFINE3(setpriority, int, which,
bb20add7
AM
13886 else
13887 pgrp = task_pgrp(current);
13888 do_each_pid_thread(pgrp, PIDTYPE_PGID, p) {
13889+ if (!vx_check(p->xid, VS_ADMIN_P | VS_IDENT))
13890+ continue;
13891 error = set_one_prio(p, niceval, error);
13892 } while_each_pid_thread(pgrp, PIDTYPE_PGID, p);
13893 break;
09a55596 13894@@ -276,6 +282,8 @@ SYSCALL_DEFINE2(getpriority, int, which,
bb20add7
AM
13895 else
13896 pgrp = task_pgrp(current);
13897 do_each_pid_thread(pgrp, PIDTYPE_PGID, p) {
13898+ if (!vx_check(p->xid, VS_ADMIN_P | VS_IDENT))
13899+ continue;
13900 niceval = nice_to_rlimit(task_nice(p));
13901 if (niceval > retval)
13902 retval = niceval;
09a55596 13903@@ -292,6 +300,8 @@ SYSCALL_DEFINE2(getpriority, int, which,
bb20add7
AM
13904 goto out_unlock; /* No processes for this user */
13905 }
13906 do_each_thread(g, p) {
13907+ if (!vx_check(p->xid, VS_ADMIN_P | VS_IDENT))
13908+ continue;
cc23e853 13909 if (uid_eq(task_uid(p), uid) && task_pid_vnr(p)) {
bb20add7 13910 niceval = nice_to_rlimit(task_nice(p));
4bf69007 13911 if (niceval > retval)
09a55596 13912@@ -1211,7 +1221,8 @@ SYSCALL_DEFINE2(sethostname, char __user
4bf69007
AM
13913 int errno;
13914 char tmp[__NEW_UTS_LEN];
13915
13916- if (!ns_capable(current->nsproxy->uts_ns->user_ns, CAP_SYS_ADMIN))
13917+ if (!vx_ns_capable(current->nsproxy->uts_ns->user_ns,
13918+ CAP_SYS_ADMIN, VXC_SET_UTSNAME))
13919 return -EPERM;
13920
13921 if (len < 0 || len > __NEW_UTS_LEN)
09a55596 13922@@ -1264,7 +1275,8 @@ SYSCALL_DEFINE2(setdomainname, char __us
4bf69007
AM
13923 int errno;
13924 char tmp[__NEW_UTS_LEN];
13925
13926- if (!ns_capable(current->nsproxy->uts_ns->user_ns, CAP_SYS_ADMIN))
13927+ if (!vx_ns_capable(current->nsproxy->uts_ns->user_ns,
13928+ CAP_SYS_ADMIN, VXC_SET_UTSNAME))
13929 return -EPERM;
13930 if (len < 0 || len > __NEW_UTS_LEN)
13931 return -EINVAL;
09a55596 13932@@ -1384,7 +1396,7 @@ int do_prlimit(struct task_struct *tsk,
4bf69007
AM
13933 /* Keep the capable check against init_user_ns until
13934 cgroups can contain all limits */
13935 if (new_rlim->rlim_max > rlim->rlim_max &&
13936- !capable(CAP_SYS_RESOURCE))
13937+ !vx_capable(CAP_SYS_RESOURCE, VXC_SET_RLIMIT))
13938 retval = -EPERM;
13939 if (!retval)
13940 retval = security_task_setrlimit(tsk->group_leader,
09a55596 13941@@ -1437,7 +1449,8 @@ static int check_prlimit_permission(stru
4bf69007
AM
13942 gid_eq(cred->gid, tcred->sgid) &&
13943 gid_eq(cred->gid, tcred->gid))
13944 return 0;
13945- if (ns_capable(tcred->user_ns, CAP_SYS_RESOURCE))
13946+ if (vx_ns_capable(tcred->user_ns,
13947+ CAP_SYS_RESOURCE, VXC_SET_RLIMIT))
13948 return 0;
13949
13950 return -EPERM;
3261cfd5
AM
13951@@ -2326,7 +2339,12 @@ static int do_sysinfo(struct sysinfo *in
13952
13953 get_avenrun(info->loads, 0, SI_LOAD_SHIFT - FSHIFT);
13954
13955- info->procs = nr_threads;
13956+ if (vx_flags(VXF_VIRT_LOAD, 0)) {
13957+ struct vx_info *vxi = current_vx_info();
13958+ info->procs = atomic_read(&vxi->cvirt.nr_threads);
13959+ } else {
13960+ info->procs = nr_threads;
13961+ }
13962
13963 si_meminfo(info);
13964 si_swapinfo(info);
13965diff -NurpP --minimal linux-4.9.207/kernel/sysctl_binary.c linux-4.9.207-vs2.3.9.11/kernel/sysctl_binary.c
13966--- linux-4.9.207/kernel/sysctl_binary.c 2016-12-11 19:17:54.000000000 +0000
13967+++ linux-4.9.207-vs2.3.9.11/kernel/sysctl_binary.c 2018-10-20 04:58:15.000000000 +0000
13968@@ -74,6 +74,7 @@ static const struct bin_table bin_kern_t
13969
13970 { CTL_INT, KERN_PANIC, "panic" },
13971 { CTL_INT, KERN_REALROOTDEV, "real-root-dev" },
13972+ { CTL_STR, KERN_VSHELPER, "vshelper" },
13973
13974 { CTL_STR, KERN_SPARC_REBOOT, "reboot-cmd" },
13975 { CTL_INT, KERN_CTLALTDEL, "ctrl-alt-del" },
13976diff -NurpP --minimal linux-4.9.207/kernel/sysctl.c linux-4.9.207-vs2.3.9.11/kernel/sysctl.c
13977--- linux-4.9.207/kernel/sysctl.c 2019-12-25 15:28:43.747212532 +0000
13978+++ linux-4.9.207-vs2.3.9.11/kernel/sysctl.c 2019-10-05 14:58:46.110300525 +0000
cc23e853 13979@@ -87,6 +87,7 @@
4bf69007
AM
13980 #if defined(CONFIG_PROVE_LOCKING) || defined(CONFIG_LOCK_STAT)
13981 #include <linux/lockdep.h>
13982 #endif
13983+extern char vshelper_path[];
13984 #ifdef CONFIG_CHR_DEV_SG
13985 #include <scsi/sg.h>
13986 #endif
3261cfd5 13987@@ -284,6 +285,13 @@ static int max_extfrag_threshold = 1000;
bb20add7
AM
13988
13989 static struct ctl_table kern_table[] = {
13990 {
4bf69007
AM
13991+ .procname = "vshelper",
13992+ .data = &vshelper_path,
13993+ .maxlen = 256,
13994+ .mode = 0644,
bb20add7 13995+ .proc_handler = proc_dostring,
4bf69007 13996+ },
bb20add7
AM
13997+ {
13998 .procname = "sched_child_runs_first",
13999 .data = &sysctl_sched_child_runs_first,
14000 .maxlen = sizeof(unsigned int),
3261cfd5 14001@@ -1429,7 +1437,6 @@ static struct ctl_table vm_table[] = {
cc23e853
AM
14002 .extra1 = &zero,
14003 .extra2 = &one,
bb20add7
AM
14004 },
14005-
14006 #endif /* CONFIG_COMPACTION */
4bf69007 14007 {
bb20add7 14008 .procname = "min_free_kbytes",
3261cfd5
AM
14009diff -NurpP --minimal linux-4.9.207/kernel/time/posix-timers.c linux-4.9.207-vs2.3.9.11/kernel/time/posix-timers.c
14010--- linux-4.9.207/kernel/time/posix-timers.c 2019-12-25 15:28:43.837211076 +0000
14011+++ linux-4.9.207-vs2.3.9.11/kernel/time/posix-timers.c 2019-02-22 08:37:55.983044969 +0000
bb20add7
AM
14012@@ -48,6 +48,7 @@
14013 #include <linux/workqueue.h>
14014 #include <linux/export.h>
14015 #include <linux/hashtable.h>
14016+#include <linux/vs_context.h>
4bf69007 14017
bb20add7 14018 #include "timekeeping.h"
4bf69007 14019
3261cfd5 14020@@ -417,6 +418,7 @@ int posix_timer_event(struct k_itimer *t
bb20add7
AM
14021 {
14022 struct task_struct *task;
14023 int shared, ret = -1;
14024+
14025 /*
14026 * FIXME: if ->sigq is queued we can race with
14027 * dequeue_signal()->do_schedule_next_timer().
3261cfd5 14028@@ -433,10 +435,18 @@ int posix_timer_event(struct k_itimer *t
bb20add7
AM
14029 rcu_read_lock();
14030 task = pid_task(timr->it_pid, PIDTYPE_PID);
14031 if (task) {
14032+ struct vx_info_save vxis;
14033+ struct vx_info *vxi;
14034+
14035+ vxi = get_vx_info(task->vx_info);
14036+ enter_vx_info(vxi, &vxis);
14037 shared = !(timr->it_sigev_notify & SIGEV_THREAD_ID);
14038 ret = send_sigqueue(timr->sigq, task, shared);
14039+ leave_vx_info(&vxis);
14040+ put_vx_info(vxi);
14041 }
14042 rcu_read_unlock();
14043+
14044 /* If we failed to send the signal the timer stops. */
14045 return ret > 0;
4bf69007 14046 }
3261cfd5
AM
14047diff -NurpP --minimal linux-4.9.207/kernel/time/time.c linux-4.9.207-vs2.3.9.11/kernel/time/time.c
14048--- linux-4.9.207/kernel/time/time.c 2019-12-25 15:28:43.857210755 +0000
14049+++ linux-4.9.207-vs2.3.9.11/kernel/time/time.c 2018-10-20 05:55:43.000000000 +0000
09a55596 14050@@ -38,6 +38,7 @@
4bf69007
AM
14051 #include <linux/fs.h>
14052 #include <linux/math64.h>
14053 #include <linux/ptrace.h>
14054+#include <linux/vs_time.h>
14055
14056 #include <asm/uaccess.h>
14057 #include <asm/unistd.h>
09a55596 14058@@ -94,7 +95,7 @@ SYSCALL_DEFINE1(stime, time_t __user *,
4bf69007
AM
14059 if (err)
14060 return err;
14061
14062- do_settimeofday(&tv);
14063+ vx_settimeofday(&tv);
14064 return 0;
14065 }
14066
09a55596 14067@@ -187,7 +188,7 @@ int do_sys_settimeofday64(const struct t
4bf69007
AM
14068 }
14069 }
14070 if (tv)
cc23e853
AM
14071- return do_settimeofday64(tv);
14072+ return vx_settimeofday64(tv);
4bf69007
AM
14073 return 0;
14074 }
14075
3261cfd5
AM
14076diff -NurpP --minimal linux-4.9.207/kernel/time/timekeeping.c linux-4.9.207-vs2.3.9.11/kernel/time/timekeeping.c
14077--- linux-4.9.207/kernel/time/timekeeping.c 2019-12-25 15:28:43.857210755 +0000
14078+++ linux-4.9.207-vs2.3.9.11/kernel/time/timekeeping.c 2019-12-25 15:09:47.185439847 +0000
14079@@ -23,6 +23,8 @@
bb20add7
AM
14080 #include <linux/stop_machine.h>
14081 #include <linux/pvclock_gtod.h>
14082 #include <linux/compiler.h>
14083+#include <linux/vs_time.h>
3261cfd5
AM
14084+#include <linux/vs_base.h>
14085
14086 #include "tick-internal.h"
14087 #include "ntp_internal.h"
14088@@ -768,6 +770,15 @@ ktime_t ktime_get_with_offset(enum tk_of
14089
14090 } while (read_seqcount_retry(&tk_core.seq, seq));
14091
14092+#ifdef CONFIG_VSERVER_VTIME
14093+ if ((offs == TK_OFFS_BOOT) &&
14094+ vx_flags(VXF_VIRT_UPTIME, 0) &&
14095+ !vx_check(0, VS_ADMIN|VS_WATCH)) {
14096+ struct vx_info *vxi = current_vx_info();
14097+ ktime_t bias_uptime = timespec64_to_ktime(vxi->cvirt.bias_uptime);
14098+ base = ktime_sub(base, bias_uptime);
14099+ }
14100+#endif
14101 return ktime_add_ns(base, nsecs);
bb20add7 14102
3261cfd5
AM
14103 }
14104diff -NurpP --minimal linux-4.9.207/kernel/time/timer.c linux-4.9.207-vs2.3.9.11/kernel/time/timer.c
14105--- linux-4.9.207/kernel/time/timer.c 2019-12-25 15:28:43.857210755 +0000
14106+++ linux-4.9.207-vs2.3.9.11/kernel/time/timer.c 2019-10-22 13:47:05.659628449 +0000
09be7631 14107@@ -42,6 +42,10 @@
b00e13aa 14108 #include <linux/sched/sysctl.h>
4bf69007 14109 #include <linux/slab.h>
09be7631 14110 #include <linux/compat.h>
4bf69007
AM
14111+#include <linux/vs_base.h>
14112+#include <linux/vs_cvirt.h>
14113+#include <linux/vs_pid.h>
14114+#include <linux/vserver/sched.h>
14115
14116 #include <asm/uaccess.h>
14117 #include <asm/unistd.h>
3261cfd5
AM
14118diff -NurpP --minimal linux-4.9.207/kernel/user_namespace.c linux-4.9.207-vs2.3.9.11/kernel/user_namespace.c
14119--- linux-4.9.207/kernel/user_namespace.c 2019-12-25 15:28:43.967208975 +0000
14120+++ linux-4.9.207-vs2.3.9.11/kernel/user_namespace.c 2018-10-20 05:55:43.000000000 +0000
b00e13aa 14121@@ -22,6 +22,7 @@
4bf69007
AM
14122 #include <linux/ctype.h>
14123 #include <linux/projid.h>
b00e13aa 14124 #include <linux/fs_struct.h>
4bf69007
AM
14125+#include <linux/vserver/global.h>
14126
14127 static struct kmem_cache *user_ns_cachep __read_mostly;
bb20add7 14128 static DEFINE_MUTEX(userns_state_mutex);
cc23e853 14129@@ -115,6 +116,7 @@ int create_user_ns(struct cred *new)
4bf69007 14130
b00e13aa
AM
14131 atomic_set(&ns->count, 1);
14132 /* Leave the new->user_ns reference with the new user namespace. */
4bf69007
AM
14133+ atomic_inc(&vs_global_user_ns);
14134 ns->parent = parent_ns;
09be7631 14135 ns->level = parent_ns->level + 1;
4bf69007 14136 ns->owner = owner;
cc23e853
AM
14137@@ -185,6 +187,7 @@ static void free_user_ns(struct work_str
14138 key_put(ns->persistent_keyring_register);
14139 #endif
14140 ns_free_inum(&ns->ns);
14141+ atomic_dec(&vs_global_user_ns);
14142 kmem_cache_free(user_ns_cachep, ns);
14143 dec_user_namespaces(ucounts);
14144 ns = parent;
14145@@ -404,6 +407,18 @@ gid_t from_kgid_munged(struct user_names
bb20add7
AM
14146 }
14147 EXPORT_SYMBOL(from_kgid_munged);
14148
14149+ktag_t make_ktag(struct user_namespace *from, vtag_t tag)
14150+{
14151+ return KTAGT_INIT(tag);
14152+}
14153+EXPORT_SYMBOL(make_ktag);
14154+
14155+vtag_t from_ktag(struct user_namespace *to, ktag_t tag)
14156+{
14157+ return __ktag_val(tag);
14158+}
14159+EXPORT_SYMBOL(from_ktag);
14160+
14161 /**
14162 * make_kprojid - Map a user-namespace projid pair into a kprojid.
14163 * @ns: User namespace that the projid is in
3261cfd5
AM
14164diff -NurpP --minimal linux-4.9.207/kernel/utsname.c linux-4.9.207-vs2.3.9.11/kernel/utsname.c
14165--- linux-4.9.207/kernel/utsname.c 2016-12-11 19:17:54.000000000 +0000
14166+++ linux-4.9.207-vs2.3.9.11/kernel/utsname.c 2018-10-20 04:58:15.000000000 +0000
cc23e853 14167@@ -16,6 +16,7 @@
4bf69007
AM
14168 #include <linux/slab.h>
14169 #include <linux/user_namespace.h>
09be7631 14170 #include <linux/proc_ns.h>
4bf69007
AM
14171+#include <linux/vserver/global.h>
14172
cc23e853 14173 static struct ucounts *inc_uts_namespaces(struct user_namespace *ns)
4bf69007 14174 {
cc23e853 14175@@ -32,8 +33,10 @@ static struct uts_namespace *create_uts_
4bf69007
AM
14176 struct uts_namespace *uts_ns;
14177
14178 uts_ns = kmalloc(sizeof(struct uts_namespace), GFP_KERNEL);
14179- if (uts_ns)
14180+ if (uts_ns) {
c2e5f7c8 14181 kref_init(&uts_ns->kref);
4bf69007
AM
14182+ atomic_inc(&vs_global_uts_ns);
14183+ }
14184 return uts_ns;
14185 }
14186
cc23e853
AM
14187@@ -111,6 +114,7 @@ void free_uts_ns(struct kref *kref)
14188 dec_uts_namespaces(ns->ucounts);
4bf69007 14189 put_user_ns(ns->user_ns);
cc23e853 14190 ns_free_inum(&ns->ns);
4bf69007
AM
14191+ atomic_dec(&vs_global_uts_ns);
14192 kfree(ns);
3261cfd5
AM
14193 }
14194
14195diff -NurpP --minimal linux-4.9.207/kernel/vserver/cacct.c linux-4.9.207-vs2.3.9.11/kernel/vserver/cacct.c
14196--- linux-4.9.207/kernel/vserver/cacct.c 1970-01-01 00:00:00.000000000 +0000
14197+++ linux-4.9.207-vs2.3.9.11/kernel/vserver/cacct.c 2018-10-20 04:58:15.000000000 +0000
4bf69007
AM
14198@@ -0,0 +1,42 @@
14199+/*
14200+ * linux/kernel/vserver/cacct.c
14201+ *
14202+ * Virtual Server: Context Accounting
14203+ *
cc23e853 14204+ * Copyright (C) 2006-2007 Herbert P?tzl
4bf69007
AM
14205+ *
14206+ * V0.01 added accounting stats
14207+ *
14208+ */
d337f35e 14209+
4bf69007
AM
14210+#include <linux/types.h>
14211+#include <linux/vs_context.h>
14212+#include <linux/vserver/cacct_cmd.h>
14213+#include <linux/vserver/cacct_int.h>
d337f35e 14214+
4bf69007
AM
14215+#include <asm/errno.h>
14216+#include <asm/uaccess.h>
14217+
14218+
14219+int vc_sock_stat(struct vx_info *vxi, void __user *data)
d337f35e 14220+{
4bf69007
AM
14221+ struct vcmd_sock_stat_v0 vc_data;
14222+ int j, field;
d337f35e 14223+
2380c486
JR
14224+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
14225+ return -EFAULT;
14226+
4bf69007
AM
14227+ field = vc_data.field;
14228+ if ((field < 0) || (field >= VXA_SOCK_SIZE))
14229+ return -EINVAL;
7e46296a 14230+
4bf69007
AM
14231+ for (j = 0; j < 3; j++) {
14232+ vc_data.count[j] = vx_sock_count(&vxi->cacct, field, j);
14233+ vc_data.total[j] = vx_sock_total(&vxi->cacct, field, j);
14234+ }
7e46296a
AM
14235+
14236+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
14237+ return -EFAULT;
14238+ return 0;
14239+}
14240+
3261cfd5
AM
14241diff -NurpP --minimal linux-4.9.207/kernel/vserver/cacct_init.h linux-4.9.207-vs2.3.9.11/kernel/vserver/cacct_init.h
14242--- linux-4.9.207/kernel/vserver/cacct_init.h 1970-01-01 00:00:00.000000000 +0000
14243+++ linux-4.9.207-vs2.3.9.11/kernel/vserver/cacct_init.h 2018-10-20 04:58:15.000000000 +0000
4bf69007 14244@@ -0,0 +1,25 @@
7e46296a
AM
14245+
14246+
4bf69007 14247+static inline void vx_info_init_cacct(struct _vx_cacct *cacct)
265d6dcc 14248+{
4bf69007 14249+ int i, j;
265d6dcc 14250+
265d6dcc 14251+
4bf69007
AM
14252+ for (i = 0; i < VXA_SOCK_SIZE; i++) {
14253+ for (j = 0; j < 3; j++) {
14254+ atomic_long_set(&cacct->sock[i][j].count, 0);
14255+ atomic_long_set(&cacct->sock[i][j].total, 0);
14256+ }
14257+ }
14258+ for (i = 0; i < 8; i++)
14259+ atomic_set(&cacct->slab[i], 0);
14260+ for (i = 0; i < 5; i++)
14261+ for (j = 0; j < 4; j++)
14262+ atomic_set(&cacct->page[i][j], 0);
265d6dcc
JR
14263+}
14264+
4bf69007 14265+static inline void vx_info_exit_cacct(struct _vx_cacct *cacct)
265d6dcc 14266+{
4bf69007 14267+ return;
265d6dcc
JR
14268+}
14269+
3261cfd5
AM
14270diff -NurpP --minimal linux-4.9.207/kernel/vserver/cacct_proc.h linux-4.9.207-vs2.3.9.11/kernel/vserver/cacct_proc.h
14271--- linux-4.9.207/kernel/vserver/cacct_proc.h 1970-01-01 00:00:00.000000000 +0000
14272+++ linux-4.9.207-vs2.3.9.11/kernel/vserver/cacct_proc.h 2018-10-20 04:58:15.000000000 +0000
4bf69007
AM
14273@@ -0,0 +1,53 @@
14274+#ifndef _VX_CACCT_PROC_H
14275+#define _VX_CACCT_PROC_H
265d6dcc 14276+
4bf69007 14277+#include <linux/vserver/cacct_int.h>
d337f35e 14278+
d337f35e 14279+
4bf69007
AM
14280+#define VX_SOCKA_TOP \
14281+ "Type\t recv #/bytes\t\t send #/bytes\t\t fail #/bytes\n"
d337f35e 14282+
4bf69007 14283+static inline int vx_info_proc_cacct(struct _vx_cacct *cacct, char *buffer)
d337f35e 14284+{
4bf69007
AM
14285+ int i, j, length = 0;
14286+ static char *type[VXA_SOCK_SIZE] = {
14287+ "UNSPEC", "UNIX", "INET", "INET6", "PACKET", "OTHER"
14288+ };
d337f35e 14289+
4bf69007
AM
14290+ length += sprintf(buffer + length, VX_SOCKA_TOP);
14291+ for (i = 0; i < VXA_SOCK_SIZE; i++) {
14292+ length += sprintf(buffer + length, "%s:", type[i]);
14293+ for (j = 0; j < 3; j++) {
14294+ length += sprintf(buffer + length,
14295+ "\t%10lu/%-10lu",
14296+ vx_sock_count(cacct, i, j),
14297+ vx_sock_total(cacct, i, j));
14298+ }
14299+ buffer[length++] = '\n';
14300+ }
d337f35e 14301+
4bf69007
AM
14302+ length += sprintf(buffer + length, "\n");
14303+ length += sprintf(buffer + length,
14304+ "slab:\t %8u %8u %8u %8u\n",
14305+ atomic_read(&cacct->slab[1]),
14306+ atomic_read(&cacct->slab[4]),
14307+ atomic_read(&cacct->slab[0]),
14308+ atomic_read(&cacct->slab[2]));
d337f35e 14309+
4bf69007
AM
14310+ length += sprintf(buffer + length, "\n");
14311+ for (i = 0; i < 5; i++) {
14312+ length += sprintf(buffer + length,
14313+ "page[%d]: %8u %8u %8u %8u\t %8u %8u %8u %8u\n", i,
14314+ atomic_read(&cacct->page[i][0]),
14315+ atomic_read(&cacct->page[i][1]),
14316+ atomic_read(&cacct->page[i][2]),
14317+ atomic_read(&cacct->page[i][3]),
14318+ atomic_read(&cacct->page[i][4]),
14319+ atomic_read(&cacct->page[i][5]),
14320+ atomic_read(&cacct->page[i][6]),
14321+ atomic_read(&cacct->page[i][7]));
14322+ }
14323+ return length;
14324+}
d337f35e 14325+
4bf69007 14326+#endif /* _VX_CACCT_PROC_H */
3261cfd5
AM
14327diff -NurpP --minimal linux-4.9.207/kernel/vserver/context.c linux-4.9.207-vs2.3.9.11/kernel/vserver/context.c
14328--- linux-4.9.207/kernel/vserver/context.c 1970-01-01 00:00:00.000000000 +0000
14329+++ linux-4.9.207-vs2.3.9.11/kernel/vserver/context.c 2018-10-20 04:58:15.000000000 +0000
4bf69007 14330@@ -0,0 +1,1119 @@
2380c486 14331+/*
4bf69007 14332+ * linux/kernel/vserver/context.c
2380c486 14333+ *
4bf69007 14334+ * Virtual Server: Context Support
2380c486 14335+ *
cc23e853 14336+ * Copyright (C) 2003-2011 Herbert P?tzl
2380c486 14337+ *
4bf69007
AM
14338+ * V0.01 context helper
14339+ * V0.02 vx_ctx_kill syscall command
14340+ * V0.03 replaced context_info calls
14341+ * V0.04 redesign of struct (de)alloc
14342+ * V0.05 rlimit basic implementation
14343+ * V0.06 task_xid and info commands
14344+ * V0.07 context flags and caps
14345+ * V0.08 switch to RCU based hash
14346+ * V0.09 revert to non RCU for now
14347+ * V0.10 and back to working RCU hash
14348+ * V0.11 and back to locking again
14349+ * V0.12 referenced context store
14350+ * V0.13 separate per cpu data
14351+ * V0.14 changed vcmds to vxi arg
14352+ * V0.15 added context stat
14353+ * V0.16 have __create claim() the vxi
14354+ * V0.17 removed older and legacy stuff
14355+ * V0.18 added user credentials
14356+ * V0.19 added warn mask
2380c486
JR
14357+ *
14358+ */
d337f35e 14359+
4bf69007 14360+#include <linux/slab.h>
2380c486 14361+#include <linux/types.h>
4bf69007
AM
14362+#include <linux/security.h>
14363+#include <linux/pid_namespace.h>
14364+#include <linux/capability.h>
1e8b8f9b 14365+
4bf69007
AM
14366+#include <linux/vserver/context.h>
14367+#include <linux/vserver/network.h>
14368+#include <linux/vserver/debug.h>
14369+#include <linux/vserver/limit.h>
14370+#include <linux/vserver/limit_int.h>
14371+#include <linux/vserver/space.h>
14372+#include <linux/init_task.h>
14373+#include <linux/fs_struct.h>
14374+#include <linux/cred.h>
1e8b8f9b 14375+
4bf69007
AM
14376+#include <linux/vs_context.h>
14377+#include <linux/vs_limit.h>
14378+#include <linux/vs_pid.h>
14379+#include <linux/vserver/context_cmd.h>
d337f35e 14380+
4bf69007
AM
14381+#include "cvirt_init.h"
14382+#include "cacct_init.h"
14383+#include "limit_init.h"
14384+#include "sched_init.h"
d337f35e 14385+
d337f35e 14386+
4bf69007
AM
14387+atomic_t vx_global_ctotal = ATOMIC_INIT(0);
14388+atomic_t vx_global_cactive = ATOMIC_INIT(0);
d337f35e 14389+
d337f35e 14390+
4bf69007 14391+/* now inactive context structures */
d337f35e 14392+
4bf69007 14393+static struct hlist_head vx_info_inactive = HLIST_HEAD_INIT;
2380c486 14394+
4bf69007 14395+static DEFINE_SPINLOCK(vx_info_inactive_lock);
d337f35e 14396+
2380c486 14397+
4bf69007 14398+/* __alloc_vx_info()
d337f35e 14399+
4bf69007
AM
14400+ * allocate an initialized vx_info struct
14401+ * doesn't make it visible (hash) */
d337f35e 14402+
61333608 14403+static struct vx_info *__alloc_vx_info(vxid_t xid)
4bf69007
AM
14404+{
14405+ struct vx_info *new = NULL;
14406+ int cpu, index;
d337f35e 14407+
4bf69007 14408+ vxdprintk(VXD_CBIT(xid, 0), "alloc_vx_info(%d)*", xid);
d337f35e 14409+
4bf69007
AM
14410+ /* would this benefit from a slab cache? */
14411+ new = kmalloc(sizeof(struct vx_info), GFP_KERNEL);
14412+ if (!new)
14413+ return 0;
2380c486 14414+
4bf69007
AM
14415+ memset(new, 0, sizeof(struct vx_info));
14416+#ifdef CONFIG_SMP
14417+ new->ptr_pc = alloc_percpu(struct _vx_info_pc);
14418+ if (!new->ptr_pc)
14419+ goto error;
14420+#endif
14421+ new->vx_id = xid;
14422+ INIT_HLIST_NODE(&new->vx_hlist);
14423+ atomic_set(&new->vx_usecnt, 0);
14424+ atomic_set(&new->vx_tasks, 0);
14425+ new->vx_parent = NULL;
14426+ new->vx_state = 0;
14427+ init_waitqueue_head(&new->vx_wait);
2380c486 14428+
4bf69007
AM
14429+ /* prepare reaper */
14430+ get_task_struct(init_pid_ns.child_reaper);
14431+ new->vx_reaper = init_pid_ns.child_reaper;
14432+ new->vx_badness_bias = 0;
d337f35e 14433+
4bf69007
AM
14434+ /* rest of init goes here */
14435+ vx_info_init_limit(&new->limit);
14436+ vx_info_init_sched(&new->sched);
14437+ vx_info_init_cvirt(&new->cvirt);
14438+ vx_info_init_cacct(&new->cacct);
d337f35e 14439+
4bf69007
AM
14440+ /* per cpu data structures */
14441+ for_each_possible_cpu(cpu) {
14442+ vx_info_init_sched_pc(
14443+ &vx_per_cpu(new, sched_pc, cpu), cpu);
14444+ vx_info_init_cvirt_pc(
14445+ &vx_per_cpu(new, cvirt_pc, cpu), cpu);
14446+ }
d337f35e 14447+
4bf69007
AM
14448+ new->vx_flags = VXF_INIT_SET;
14449+ new->vx_bcaps = CAP_FULL_SET; // maybe ~CAP_SETPCAP
14450+ new->vx_ccaps = 0;
14451+ new->vx_umask = 0;
14452+ new->vx_wmask = 0;
d337f35e 14453+
4bf69007
AM
14454+ new->reboot_cmd = 0;
14455+ new->exit_code = 0;
d337f35e 14456+
4bf69007
AM
14457+ // preconfig spaces
14458+ for (index = 0; index < VX_SPACES; index++) {
14459+ struct _vx_space *space = &new->space[index];
d337f35e 14460+
4bf69007
AM
14461+ // filesystem
14462+ spin_lock(&init_fs.lock);
14463+ init_fs.users++;
14464+ spin_unlock(&init_fs.lock);
14465+ space->vx_fs = &init_fs;
2380c486 14466+
4bf69007
AM
14467+ /* FIXME: do we want defaults? */
14468+ // space->vx_real_cred = 0;
14469+ // space->vx_cred = 0;
2380c486 14470+ }
4bf69007
AM
14471+
14472+
14473+ vxdprintk(VXD_CBIT(xid, 0),
14474+ "alloc_vx_info(%d) = %p", xid, new);
14475+ vxh_alloc_vx_info(new);
14476+ atomic_inc(&vx_global_ctotal);
14477+ return new;
14478+#ifdef CONFIG_SMP
14479+error:
14480+ kfree(new);
14481+ return 0;
14482+#endif
d337f35e
JR
14483+}
14484+
4bf69007 14485+/* __dealloc_vx_info()
d337f35e 14486+
4bf69007 14487+ * final disposal of vx_info */
d337f35e 14488+
4bf69007 14489+static void __dealloc_vx_info(struct vx_info *vxi)
d337f35e 14490+{
4bf69007
AM
14491+#ifdef CONFIG_VSERVER_WARN
14492+ struct vx_info_save vxis;
14493+ int cpu;
14494+#endif
14495+ vxdprintk(VXD_CBIT(xid, 0),
14496+ "dealloc_vx_info(%p)", vxi);
14497+ vxh_dealloc_vx_info(vxi);
d337f35e 14498+
4bf69007
AM
14499+#ifdef CONFIG_VSERVER_WARN
14500+ enter_vx_info(vxi, &vxis);
14501+ vx_info_exit_limit(&vxi->limit);
14502+ vx_info_exit_sched(&vxi->sched);
14503+ vx_info_exit_cvirt(&vxi->cvirt);
14504+ vx_info_exit_cacct(&vxi->cacct);
d337f35e 14505+
4bf69007
AM
14506+ for_each_possible_cpu(cpu) {
14507+ vx_info_exit_sched_pc(
14508+ &vx_per_cpu(vxi, sched_pc, cpu), cpu);
14509+ vx_info_exit_cvirt_pc(
14510+ &vx_per_cpu(vxi, cvirt_pc, cpu), cpu);
14511+ }
14512+ leave_vx_info(&vxis);
14513+#endif
d337f35e 14514+
4bf69007
AM
14515+ vxi->vx_id = -1;
14516+ vxi->vx_state |= VXS_RELEASED;
d337f35e 14517+
4bf69007
AM
14518+#ifdef CONFIG_SMP
14519+ free_percpu(vxi->ptr_pc);
14520+#endif
14521+ kfree(vxi);
14522+ atomic_dec(&vx_global_ctotal);
d337f35e
JR
14523+}
14524+
4bf69007 14525+static void __shutdown_vx_info(struct vx_info *vxi)
d337f35e 14526+{
4bf69007
AM
14527+ struct nsproxy *nsproxy;
14528+ struct fs_struct *fs;
14529+ struct cred *cred;
14530+ int index, kill;
d337f35e 14531+
4bf69007 14532+ might_sleep();
d337f35e 14533+
4bf69007
AM
14534+ vxi->vx_state |= VXS_SHUTDOWN;
14535+ vs_state_change(vxi, VSC_SHUTDOWN);
d337f35e 14536+
4bf69007
AM
14537+ for (index = 0; index < VX_SPACES; index++) {
14538+ struct _vx_space *space = &vxi->space[index];
d337f35e 14539+
4bf69007
AM
14540+ nsproxy = xchg(&space->vx_nsproxy, NULL);
14541+ if (nsproxy)
14542+ put_nsproxy(nsproxy);
2380c486 14543+
4bf69007
AM
14544+ fs = xchg(&space->vx_fs, NULL);
14545+ spin_lock(&fs->lock);
14546+ kill = !--fs->users;
14547+ spin_unlock(&fs->lock);
14548+ if (kill)
14549+ free_fs_struct(fs);
d337f35e 14550+
4bf69007
AM
14551+ cred = (struct cred *)xchg(&space->vx_cred, NULL);
14552+ if (cred)
14553+ abort_creds(cred);
14554+ }
d337f35e
JR
14555+}
14556+
4bf69007 14557+/* exported stuff */
d337f35e 14558+
4bf69007 14559+void free_vx_info(struct vx_info *vxi)
d337f35e 14560+{
4bf69007
AM
14561+ unsigned long flags;
14562+ unsigned index;
d337f35e 14563+
4bf69007
AM
14564+ /* check for reference counts first */
14565+ BUG_ON(atomic_read(&vxi->vx_usecnt));
14566+ BUG_ON(atomic_read(&vxi->vx_tasks));
2380c486 14567+
4bf69007
AM
14568+ /* context must not be hashed */
14569+ BUG_ON(vx_info_state(vxi, VXS_HASHED));
d337f35e 14570+
4bf69007
AM
14571+ /* context shutdown is mandatory */
14572+ BUG_ON(!vx_info_state(vxi, VXS_SHUTDOWN));
d337f35e 14573+
4bf69007
AM
14574+ /* spaces check */
14575+ for (index = 0; index < VX_SPACES; index++) {
14576+ struct _vx_space *space = &vxi->space[index];
d337f35e 14577+
4bf69007
AM
14578+ BUG_ON(space->vx_nsproxy);
14579+ BUG_ON(space->vx_fs);
14580+ // BUG_ON(space->vx_real_cred);
14581+ // BUG_ON(space->vx_cred);
14582+ }
d337f35e 14583+
4bf69007
AM
14584+ spin_lock_irqsave(&vx_info_inactive_lock, flags);
14585+ hlist_del(&vxi->vx_hlist);
14586+ spin_unlock_irqrestore(&vx_info_inactive_lock, flags);
d337f35e 14587+
4bf69007
AM
14588+ __dealloc_vx_info(vxi);
14589+}
eab5a9a6 14590+
d337f35e 14591+
4bf69007 14592+/* hash table for vx_info hash */
93de0823 14593+
4bf69007 14594+#define VX_HASH_SIZE 13
d337f35e 14595+
4bf69007
AM
14596+static struct hlist_head vx_info_hash[VX_HASH_SIZE] =
14597+ { [0 ... VX_HASH_SIZE-1] = HLIST_HEAD_INIT };
d337f35e 14598+
4bf69007 14599+static DEFINE_SPINLOCK(vx_info_hash_lock);
d337f35e 14600+
93de0823 14601+
61333608 14602+static inline unsigned int __hashval(vxid_t xid)
4bf69007
AM
14603+{
14604+ return (xid % VX_HASH_SIZE);
d337f35e
JR
14605+}
14606+
14607+
d337f35e 14608+
4bf69007 14609+/* __hash_vx_info()
d337f35e 14610+
4bf69007
AM
14611+ * add the vxi to the global hash table
14612+ * requires the hash_lock to be held */
d337f35e 14613+
4bf69007 14614+static inline void __hash_vx_info(struct vx_info *vxi)
d337f35e 14615+{
4bf69007 14616+ struct hlist_head *head;
d337f35e 14617+
4bf69007
AM
14618+ vxd_assert_lock(&vx_info_hash_lock);
14619+ vxdprintk(VXD_CBIT(xid, 4),
14620+ "__hash_vx_info: %p[#%d]", vxi, vxi->vx_id);
14621+ vxh_hash_vx_info(vxi);
d337f35e 14622+
4bf69007
AM
14623+ /* context must not be hashed */
14624+ BUG_ON(vx_info_state(vxi, VXS_HASHED));
d337f35e 14625+
4bf69007
AM
14626+ vxi->vx_state |= VXS_HASHED;
14627+ head = &vx_info_hash[__hashval(vxi->vx_id)];
14628+ hlist_add_head(&vxi->vx_hlist, head);
14629+ atomic_inc(&vx_global_cactive);
2380c486 14630+}
d337f35e 14631+
4bf69007 14632+/* __unhash_vx_info()
d337f35e 14633+
4bf69007
AM
14634+ * remove the vxi from the global hash table
14635+ * requires the hash_lock to be held */
d337f35e 14636+
4bf69007 14637+static inline void __unhash_vx_info(struct vx_info *vxi)
d337f35e 14638+{
4bf69007
AM
14639+ unsigned long flags;
14640+
14641+ vxd_assert_lock(&vx_info_hash_lock);
14642+ vxdprintk(VXD_CBIT(xid, 4),
14643+ "__unhash_vx_info: %p[#%d.%d.%d]", vxi, vxi->vx_id,
14644+ atomic_read(&vxi->vx_usecnt), atomic_read(&vxi->vx_tasks));
14645+ vxh_unhash_vx_info(vxi);
14646+
14647+ /* context must be hashed */
14648+ BUG_ON(!vx_info_state(vxi, VXS_HASHED));
14649+ /* but without tasks */
14650+ BUG_ON(atomic_read(&vxi->vx_tasks));
14651+
14652+ vxi->vx_state &= ~VXS_HASHED;
14653+ hlist_del_init(&vxi->vx_hlist);
14654+ spin_lock_irqsave(&vx_info_inactive_lock, flags);
14655+ hlist_add_head(&vxi->vx_hlist, &vx_info_inactive);
14656+ spin_unlock_irqrestore(&vx_info_inactive_lock, flags);
14657+ atomic_dec(&vx_global_cactive);
2380c486 14658+}
d337f35e 14659+
d337f35e 14660+
4bf69007 14661+/* __lookup_vx_info()
d337f35e 14662+
4bf69007
AM
14663+ * requires the hash_lock to be held
14664+ * doesn't increment the vx_refcnt */
2380c486 14665+
61333608 14666+static inline struct vx_info *__lookup_vx_info(vxid_t xid)
d337f35e 14667+{
4bf69007
AM
14668+ struct hlist_head *head = &vx_info_hash[__hashval(xid)];
14669+ struct hlist_node *pos;
14670+ struct vx_info *vxi;
d337f35e 14671+
4bf69007
AM
14672+ vxd_assert_lock(&vx_info_hash_lock);
14673+ hlist_for_each(pos, head) {
14674+ vxi = hlist_entry(pos, struct vx_info, vx_hlist);
d337f35e 14675+
4bf69007
AM
14676+ if (vxi->vx_id == xid)
14677+ goto found;
14678+ }
14679+ vxi = NULL;
14680+found:
14681+ vxdprintk(VXD_CBIT(xid, 0),
14682+ "__lookup_vx_info(#%u): %p[#%u]",
14683+ xid, vxi, vxi ? vxi->vx_id : 0);
14684+ vxh_lookup_vx_info(vxi, xid);
14685+ return vxi;
14686+}
d337f35e 14687+
d337f35e 14688+
4bf69007 14689+/* __create_vx_info()
d337f35e 14690+
4bf69007
AM
14691+ * create the requested context
14692+ * get(), claim() and hash it */
2380c486 14693+
4bf69007
AM
14694+static struct vx_info *__create_vx_info(int id)
14695+{
14696+ struct vx_info *new, *vxi = NULL;
2380c486 14697+
4bf69007 14698+ vxdprintk(VXD_CBIT(xid, 1), "create_vx_info(%d)*", id);
d337f35e 14699+
4bf69007
AM
14700+ if (!(new = __alloc_vx_info(id)))
14701+ return ERR_PTR(-ENOMEM);
d337f35e 14702+
4bf69007
AM
14703+ /* required to make dynamic xids unique */
14704+ spin_lock(&vx_info_hash_lock);
d337f35e 14705+
4bf69007
AM
14706+ /* static context requested */
14707+ if ((vxi = __lookup_vx_info(id))) {
14708+ vxdprintk(VXD_CBIT(xid, 0),
14709+ "create_vx_info(%d) = %p (already there)", id, vxi);
14710+ if (vx_info_flags(vxi, VXF_STATE_SETUP, 0))
14711+ vxi = ERR_PTR(-EBUSY);
14712+ else
14713+ vxi = ERR_PTR(-EEXIST);
14714+ goto out_unlock;
14715+ }
14716+ /* new context */
14717+ vxdprintk(VXD_CBIT(xid, 0),
14718+ "create_vx_info(%d) = %p (new)", id, new);
14719+ claim_vx_info(new, NULL);
14720+ __hash_vx_info(get_vx_info(new));
14721+ vxi = new, new = NULL;
d337f35e 14722+
4bf69007
AM
14723+out_unlock:
14724+ spin_unlock(&vx_info_hash_lock);
14725+ vxh_create_vx_info(IS_ERR(vxi) ? NULL : vxi, id);
14726+ if (new)
14727+ __dealloc_vx_info(new);
14728+ return vxi;
14729+}
d337f35e 14730+
d337f35e 14731+
4bf69007 14732+/* exported stuff */
d337f35e 14733+
d337f35e 14734+
4bf69007 14735+void unhash_vx_info(struct vx_info *vxi)
d337f35e 14736+{
4bf69007
AM
14737+ spin_lock(&vx_info_hash_lock);
14738+ __unhash_vx_info(vxi);
14739+ spin_unlock(&vx_info_hash_lock);
14740+ __shutdown_vx_info(vxi);
14741+ __wakeup_vx_info(vxi);
2380c486 14742+}
d337f35e 14743+
2380c486 14744+
4bf69007 14745+/* lookup_vx_info()
2380c486 14746+
4bf69007
AM
14747+ * search for a vx_info and get() it
14748+ * negative id means current */
2380c486 14749+
4bf69007 14750+struct vx_info *lookup_vx_info(int id)
2380c486 14751+{
4bf69007
AM
14752+ struct vx_info *vxi = NULL;
14753+
14754+ if (id < 0) {
14755+ vxi = get_vx_info(current_vx_info());
14756+ } else if (id > 1) {
14757+ spin_lock(&vx_info_hash_lock);
14758+ vxi = get_vx_info(__lookup_vx_info(id));
14759+ spin_unlock(&vx_info_hash_lock);
2380c486 14760+ }
4bf69007 14761+ return vxi;
d337f35e
JR
14762+}
14763+
4bf69007 14764+/* xid_is_hashed()
d337f35e 14765+
4bf69007 14766+ * verify that xid is still hashed */
d337f35e 14767+
61333608 14768+int xid_is_hashed(vxid_t xid)
4bf69007
AM
14769+{
14770+ int hashed;
d337f35e 14771+
4bf69007
AM
14772+ spin_lock(&vx_info_hash_lock);
14773+ hashed = (__lookup_vx_info(xid) != NULL);
14774+ spin_unlock(&vx_info_hash_lock);
14775+ return hashed;
14776+}
d337f35e 14777+
4bf69007 14778+#ifdef CONFIG_PROC_FS
d337f35e 14779+
4bf69007 14780+/* get_xid_list()
d337f35e 14781+
4bf69007
AM
14782+ * get a subset of hashed xids for proc
14783+ * assumes size is at least one */
d337f35e 14784+
4bf69007
AM
14785+int get_xid_list(int index, unsigned int *xids, int size)
14786+{
14787+ int hindex, nr_xids = 0;
d337f35e 14788+
4bf69007
AM
14789+ /* only show current and children */
14790+ if (!vx_check(0, VS_ADMIN | VS_WATCH)) {
14791+ if (index > 0)
14792+ return 0;
14793+ xids[nr_xids] = vx_current_xid();
14794+ return 1;
14795+ }
d337f35e 14796+
4bf69007
AM
14797+ for (hindex = 0; hindex < VX_HASH_SIZE; hindex++) {
14798+ struct hlist_head *head = &vx_info_hash[hindex];
14799+ struct hlist_node *pos;
d337f35e 14800+
4bf69007
AM
14801+ spin_lock(&vx_info_hash_lock);
14802+ hlist_for_each(pos, head) {
14803+ struct vx_info *vxi;
d337f35e 14804+
4bf69007
AM
14805+ if (--index > 0)
14806+ continue;
d337f35e 14807+
4bf69007
AM
14808+ vxi = hlist_entry(pos, struct vx_info, vx_hlist);
14809+ xids[nr_xids] = vxi->vx_id;
14810+ if (++nr_xids >= size) {
14811+ spin_unlock(&vx_info_hash_lock);
14812+ goto out;
14813+ }
14814+ }
14815+ /* keep the lock time short */
14816+ spin_unlock(&vx_info_hash_lock);
14817+ }
14818+out:
14819+ return nr_xids;
14820+}
14821+#endif
d337f35e 14822+
4bf69007 14823+#ifdef CONFIG_VSERVER_DEBUG
d337f35e 14824+
4bf69007 14825+void dump_vx_info_inactive(int level)
d337f35e 14826+{
4bf69007 14827+ struct hlist_node *entry, *next;
d337f35e 14828+
4bf69007
AM
14829+ hlist_for_each_safe(entry, next, &vx_info_inactive) {
14830+ struct vx_info *vxi =
14831+ list_entry(entry, struct vx_info, vx_hlist);
d337f35e 14832+
4bf69007
AM
14833+ dump_vx_info(vxi, level);
14834+ }
d337f35e
JR
14835+}
14836+
4bf69007 14837+#endif
d337f35e 14838+
4bf69007
AM
14839+#if 0
14840+int vx_migrate_user(struct task_struct *p, struct vx_info *vxi)
d337f35e 14841+{
4bf69007 14842+ struct user_struct *new_user, *old_user;
d337f35e 14843+
4bf69007
AM
14844+ if (!p || !vxi)
14845+ BUG();
d337f35e 14846+
4bf69007
AM
14847+ if (vx_info_flags(vxi, VXF_INFO_PRIVATE, 0))
14848+ return -EACCES;
d337f35e 14849+
4bf69007
AM
14850+ new_user = alloc_uid(vxi->vx_id, p->uid);
14851+ if (!new_user)
14852+ return -ENOMEM;
d337f35e 14853+
4bf69007
AM
14854+ old_user = p->user;
14855+ if (new_user != old_user) {
14856+ atomic_inc(&new_user->processes);
14857+ atomic_dec(&old_user->processes);
14858+ p->user = new_user;
d337f35e 14859+ }
4bf69007
AM
14860+ free_uid(old_user);
14861+ return 0;
d337f35e 14862+}
4bf69007 14863+#endif
d337f35e 14864+
4bf69007
AM
14865+#if 0
14866+void vx_mask_cap_bset(struct vx_info *vxi, struct task_struct *p)
d337f35e 14867+{
4bf69007
AM
14868+ // p->cap_effective &= vxi->vx_cap_bset;
14869+ p->cap_effective =
14870+ cap_intersect(p->cap_effective, vxi->cap_bset);
14871+ // p->cap_inheritable &= vxi->vx_cap_bset;
14872+ p->cap_inheritable =
14873+ cap_intersect(p->cap_inheritable, vxi->cap_bset);
14874+ // p->cap_permitted &= vxi->vx_cap_bset;
14875+ p->cap_permitted =
14876+ cap_intersect(p->cap_permitted, vxi->cap_bset);
14877+}
14878+#endif
d337f35e
JR
14879+
14880+
4bf69007
AM
14881+#include <linux/file.h>
14882+#include <linux/fdtable.h>
d337f35e 14883+
4bf69007
AM
14884+static int vx_openfd_task(struct task_struct *tsk)
14885+{
14886+ struct files_struct *files = tsk->files;
14887+ struct fdtable *fdt;
14888+ const unsigned long *bptr;
14889+ int count, total;
d337f35e 14890+
4bf69007
AM
14891+ /* no rcu_read_lock() because of spin_lock() */
14892+ spin_lock(&files->file_lock);
14893+ fdt = files_fdtable(files);
14894+ bptr = fdt->open_fds;
14895+ count = fdt->max_fds / (sizeof(unsigned long) * 8);
14896+ for (total = 0; count > 0; count--) {
14897+ if (*bptr)
14898+ total += hweight_long(*bptr);
14899+ bptr++;
14900+ }
14901+ spin_unlock(&files->file_lock);
14902+ return total;
d337f35e
JR
14903+}
14904+
d337f35e 14905+
4bf69007
AM
14906+/* for *space compatibility */
14907+
14908+asmlinkage long sys_unshare(unsigned long);
14909+
14910+/*
14911+ * migrate task to new context
14912+ * gets vxi, puts old_vxi on change
14913+ * optionally unshares namespaces (hack)
2380c486 14914+ */
4bf69007
AM
14915+
14916+int vx_migrate_task(struct task_struct *p, struct vx_info *vxi, int unshare)
2380c486 14917+{
4bf69007
AM
14918+ struct vx_info *old_vxi;
14919+ int ret = 0;
d337f35e 14920+
4bf69007
AM
14921+ if (!p || !vxi)
14922+ BUG();
d337f35e 14923+
4bf69007
AM
14924+ vxdprintk(VXD_CBIT(xid, 5),
14925+ "vx_migrate_task(%p,%p[#%d.%d])", p, vxi,
14926+ vxi->vx_id, atomic_read(&vxi->vx_usecnt));
d337f35e 14927+
4bf69007
AM
14928+ if (vx_info_flags(vxi, VXF_INFO_PRIVATE, 0) &&
14929+ !vx_info_flags(vxi, VXF_STATE_SETUP, 0))
14930+ return -EACCES;
2380c486 14931+
4bf69007
AM
14932+ if (vx_info_state(vxi, VXS_SHUTDOWN))
14933+ return -EFAULT;
d337f35e 14934+
4bf69007
AM
14935+ old_vxi = task_get_vx_info(p);
14936+ if (old_vxi == vxi)
14937+ goto out;
d337f35e 14938+
4bf69007
AM
14939+// if (!(ret = vx_migrate_user(p, vxi))) {
14940+ {
14941+ int openfd;
d337f35e 14942+
4bf69007
AM
14943+ task_lock(p);
14944+ openfd = vx_openfd_task(p);
14945+
14946+ if (old_vxi) {
14947+ atomic_dec(&old_vxi->cvirt.nr_threads);
14948+ atomic_dec(&old_vxi->cvirt.nr_running);
14949+ __rlim_dec(&old_vxi->limit, RLIMIT_NPROC);
14950+ /* FIXME: what about the struct files here? */
14951+ __rlim_sub(&old_vxi->limit, VLIMIT_OPENFD, openfd);
14952+ /* account for the executable */
14953+ __rlim_dec(&old_vxi->limit, VLIMIT_DENTRY);
2380c486 14954+ }
4bf69007
AM
14955+ atomic_inc(&vxi->cvirt.nr_threads);
14956+ atomic_inc(&vxi->cvirt.nr_running);
14957+ __rlim_inc(&vxi->limit, RLIMIT_NPROC);
14958+ /* FIXME: what about the struct files here? */
14959+ __rlim_add(&vxi->limit, VLIMIT_OPENFD, openfd);
14960+ /* account for the executable */
14961+ __rlim_inc(&vxi->limit, VLIMIT_DENTRY);
2380c486 14962+
4bf69007
AM
14963+ if (old_vxi) {
14964+ release_vx_info(old_vxi, p);
14965+ clr_vx_info(&p->vx_info);
14966+ }
14967+ claim_vx_info(vxi, p);
14968+ set_vx_info(&p->vx_info, vxi);
14969+ p->xid = vxi->vx_id;
d337f35e 14970+
4bf69007
AM
14971+ vxdprintk(VXD_CBIT(xid, 5),
14972+ "moved task %p into vxi:%p[#%d]",
14973+ p, vxi, vxi->vx_id);
d337f35e 14974+
4bf69007
AM
14975+ // vx_mask_cap_bset(vxi, p);
14976+ task_unlock(p);
d337f35e 14977+
4bf69007
AM
14978+ /* hack for *spaces to provide compatibility */
14979+ if (unshare) {
14980+ struct nsproxy *old_nsp, *new_nsp;
d337f35e 14981+
4bf69007
AM
14982+ ret = unshare_nsproxy_namespaces(
14983+ CLONE_NEWUTS | CLONE_NEWIPC | CLONE_NEWUSER,
b00e13aa 14984+ &new_nsp, NULL, NULL);
4bf69007
AM
14985+ if (ret)
14986+ goto out;
d337f35e 14987+
4bf69007
AM
14988+ old_nsp = xchg(&p->nsproxy, new_nsp);
14989+ vx_set_space(vxi,
14990+ CLONE_NEWUTS | CLONE_NEWIPC | CLONE_NEWUSER, 0);
14991+ put_nsproxy(old_nsp);
14992+ }
14993+ }
14994+out:
14995+ put_vx_info(old_vxi);
2380c486
JR
14996+ return ret;
14997+}
d337f35e 14998+
4bf69007 14999+int vx_set_reaper(struct vx_info *vxi, struct task_struct *p)
d337f35e 15000+{
4bf69007
AM
15001+ struct task_struct *old_reaper;
15002+ struct vx_info *reaper_vxi;
d337f35e 15003+
4bf69007
AM
15004+ if (!vxi)
15005+ return -EINVAL;
d337f35e 15006+
4bf69007
AM
15007+ vxdprintk(VXD_CBIT(xid, 6),
15008+ "vx_set_reaper(%p[#%d],%p[#%d,%d])",
15009+ vxi, vxi->vx_id, p, p->xid, p->pid);
d337f35e 15010+
4bf69007
AM
15011+ old_reaper = vxi->vx_reaper;
15012+ if (old_reaper == p)
15013+ return 0;
d337f35e 15014+
4bf69007
AM
15015+ reaper_vxi = task_get_vx_info(p);
15016+ if (reaper_vxi && reaper_vxi != vxi) {
15017+ vxwprintk(1,
15018+ "Unsuitable reaper [" VS_Q("%s") ",%u:#%u] "
15019+ "for [xid #%u]",
15020+ p->comm, p->pid, p->xid, vx_current_xid());
2380c486
JR
15021+ goto out;
15022+ }
4bf69007
AM
15023+
15024+ /* set new child reaper */
15025+ get_task_struct(p);
15026+ vxi->vx_reaper = p;
15027+ put_task_struct(old_reaper);
2380c486 15028+out:
4bf69007
AM
15029+ put_vx_info(reaper_vxi);
15030+ return 0;
2380c486 15031+}
d337f35e 15032+
4bf69007 15033+int vx_set_init(struct vx_info *vxi, struct task_struct *p)
d337f35e 15034+{
4bf69007
AM
15035+ if (!vxi)
15036+ return -EINVAL;
d337f35e 15037+
4bf69007
AM
15038+ vxdprintk(VXD_CBIT(xid, 6),
15039+ "vx_set_init(%p[#%d],%p[#%d,%d,%d])",
15040+ vxi, vxi->vx_id, p, p->xid, p->pid, p->tgid);
d337f35e 15041+
4bf69007
AM
15042+ vxi->vx_flags &= ~VXF_STATE_INIT;
15043+ // vxi->vx_initpid = p->tgid;
15044+ vxi->vx_initpid = p->pid;
2380c486 15045+ return 0;
d337f35e
JR
15046+}
15047+
4bf69007 15048+void vx_exit_init(struct vx_info *vxi, struct task_struct *p, int code)
d337f35e 15049+{
4bf69007
AM
15050+ vxdprintk(VXD_CBIT(xid, 6),
15051+ "vx_exit_init(%p[#%d],%p[#%d,%d,%d])",
15052+ vxi, vxi->vx_id, p, p->xid, p->pid, p->tgid);
2380c486 15053+
4bf69007
AM
15054+ vxi->exit_code = code;
15055+ vxi->vx_initpid = 0;
d337f35e
JR
15056+}
15057+
2380c486 15058+
4bf69007 15059+void vx_set_persistent(struct vx_info *vxi)
d337f35e 15060+{
4bf69007
AM
15061+ vxdprintk(VXD_CBIT(xid, 6),
15062+ "vx_set_persistent(%p[#%d])", vxi, vxi->vx_id);
2380c486 15063+
4bf69007
AM
15064+ get_vx_info(vxi);
15065+ claim_vx_info(vxi, NULL);
d337f35e
JR
15066+}
15067+
4bf69007 15068+void vx_clear_persistent(struct vx_info *vxi)
2380c486 15069+{
4bf69007
AM
15070+ vxdprintk(VXD_CBIT(xid, 6),
15071+ "vx_clear_persistent(%p[#%d])", vxi, vxi->vx_id);
d337f35e 15072+
4bf69007
AM
15073+ release_vx_info(vxi, NULL);
15074+ put_vx_info(vxi);
2380c486 15075+}
d337f35e 15076+
4bf69007 15077+void vx_update_persistent(struct vx_info *vxi)
d337f35e 15078+{
4bf69007
AM
15079+ if (vx_info_flags(vxi, VXF_PERSISTENT, 0))
15080+ vx_set_persistent(vxi);
2380c486 15081+ else
4bf69007 15082+ vx_clear_persistent(vxi);
2380c486 15083+}
d337f35e 15084+
d337f35e 15085+
4bf69007
AM
15086+/* task must be current or locked */
15087+
15088+void exit_vx_info(struct task_struct *p, int code)
2380c486 15089+{
4bf69007 15090+ struct vx_info *vxi = p->vx_info;
d337f35e 15091+
4bf69007
AM
15092+ if (vxi) {
15093+ atomic_dec(&vxi->cvirt.nr_threads);
15094+ vx_nproc_dec(p);
d337f35e 15095+
4bf69007
AM
15096+ vxi->exit_code = code;
15097+ release_vx_info(vxi, p);
15098+ }
2380c486 15099+}
d337f35e 15100+
4bf69007 15101+void exit_vx_info_early(struct task_struct *p, int code)
2380c486 15102+{
4bf69007 15103+ struct vx_info *vxi = p->vx_info;
d337f35e 15104+
4bf69007
AM
15105+ if (vxi) {
15106+ if (vxi->vx_initpid == p->pid)
15107+ vx_exit_init(vxi, p, code);
15108+ if (vxi->vx_reaper == p)
15109+ vx_set_reaper(vxi, init_pid_ns.child_reaper);
15110+ }
d337f35e
JR
15111+}
15112+
15113+
4bf69007 15114+/* vserver syscall commands below here */
d337f35e 15115+
4bf69007 15116+/* taks xid and vx_info functions */
d337f35e 15117+
4bf69007 15118+#include <asm/uaccess.h>
d337f35e 15119+
d337f35e 15120+
4bf69007 15121+int vc_task_xid(uint32_t id)
d337f35e 15122+{
61333608 15123+ vxid_t xid;
d337f35e 15124+
4bf69007
AM
15125+ if (id) {
15126+ struct task_struct *tsk;
d337f35e 15127+
4bf69007
AM
15128+ rcu_read_lock();
15129+ tsk = find_task_by_real_pid(id);
15130+ xid = (tsk) ? tsk->xid : -ESRCH;
15131+ rcu_read_unlock();
15132+ } else
15133+ xid = vx_current_xid();
15134+ return xid;
d337f35e
JR
15135+}
15136+
d337f35e 15137+
4bf69007
AM
15138+int vc_vx_info(struct vx_info *vxi, void __user *data)
15139+{
15140+ struct vcmd_vx_info_v0 vc_data;
d337f35e 15141+
4bf69007
AM
15142+ vc_data.xid = vxi->vx_id;
15143+ vc_data.initpid = vxi->vx_initpid;
d337f35e 15144+
4bf69007
AM
15145+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
15146+ return -EFAULT;
15147+ return 0;
15148+}
d337f35e 15149+
d337f35e 15150+
4bf69007 15151+int vc_ctx_stat(struct vx_info *vxi, void __user *data)
d337f35e 15152+{
4bf69007 15153+ struct vcmd_ctx_stat_v0 vc_data;
d337f35e 15154+
4bf69007
AM
15155+ vc_data.usecnt = atomic_read(&vxi->vx_usecnt);
15156+ vc_data.tasks = atomic_read(&vxi->vx_tasks);
d337f35e 15157+
4bf69007
AM
15158+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
15159+ return -EFAULT;
15160+ return 0;
d337f35e
JR
15161+}
15162+
d337f35e 15163+
4bf69007 15164+/* context functions */
d337f35e 15165+
4bf69007 15166+int vc_ctx_create(uint32_t xid, void __user *data)
d337f35e 15167+{
4bf69007
AM
15168+ struct vcmd_ctx_create vc_data = { .flagword = VXF_INIT_SET };
15169+ struct vx_info *new_vxi;
15170+ int ret;
d337f35e 15171+
4bf69007
AM
15172+ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
15173+ return -EFAULT;
d337f35e 15174+
4bf69007
AM
15175+ if ((xid > MAX_S_CONTEXT) || (xid < 2))
15176+ return -EINVAL;
d337f35e 15177+
4bf69007
AM
15178+ new_vxi = __create_vx_info(xid);
15179+ if (IS_ERR(new_vxi))
15180+ return PTR_ERR(new_vxi);
d337f35e 15181+
4bf69007
AM
15182+ /* initial flags */
15183+ new_vxi->vx_flags = vc_data.flagword;
d337f35e 15184+
4bf69007
AM
15185+ ret = -ENOEXEC;
15186+ if (vs_state_change(new_vxi, VSC_STARTUP))
15187+ goto out;
d337f35e 15188+
4bf69007
AM
15189+ ret = vx_migrate_task(current, new_vxi, (!data));
15190+ if (ret)
15191+ goto out;
d337f35e 15192+
4bf69007
AM
15193+ /* return context id on success */
15194+ ret = new_vxi->vx_id;
d337f35e 15195+
4bf69007
AM
15196+ /* get a reference for persistent contexts */
15197+ if ((vc_data.flagword & VXF_PERSISTENT))
15198+ vx_set_persistent(new_vxi);
15199+out:
15200+ release_vx_info(new_vxi, NULL);
15201+ put_vx_info(new_vxi);
15202+ return ret;
15203+}
d337f35e
JR
15204+
15205+
4bf69007 15206+int vc_ctx_migrate(struct vx_info *vxi, void __user *data)
d337f35e 15207+{
4bf69007
AM
15208+ struct vcmd_ctx_migrate vc_data = { .flagword = 0 };
15209+ int ret;
d337f35e 15210+
4bf69007
AM
15211+ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
15212+ return -EFAULT;
d337f35e 15213+
4bf69007
AM
15214+ ret = vx_migrate_task(current, vxi, 0);
15215+ if (ret)
15216+ return ret;
15217+ if (vc_data.flagword & VXM_SET_INIT)
15218+ ret = vx_set_init(vxi, current);
15219+ if (ret)
15220+ return ret;
15221+ if (vc_data.flagword & VXM_SET_REAPER)
15222+ ret = vx_set_reaper(vxi, current);
15223+ return ret;
15224+}
d337f35e 15225+
d337f35e 15226+
4bf69007 15227+int vc_get_cflags(struct vx_info *vxi, void __user *data)
d337f35e 15228+{
4bf69007 15229+ struct vcmd_ctx_flags_v0 vc_data;
d337f35e 15230+
4bf69007 15231+ vc_data.flagword = vxi->vx_flags;
d337f35e 15232+
4bf69007
AM
15233+ /* special STATE flag handling */
15234+ vc_data.mask = vs_mask_flags(~0ULL, vxi->vx_flags, VXF_ONE_TIME);
d337f35e 15235+
4bf69007
AM
15236+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
15237+ return -EFAULT;
15238+ return 0;
d337f35e
JR
15239+}
15240+
4bf69007
AM
15241+int vc_set_cflags(struct vx_info *vxi, void __user *data)
15242+{
15243+ struct vcmd_ctx_flags_v0 vc_data;
15244+ uint64_t mask, trigger;
d337f35e 15245+
4bf69007
AM
15246+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
15247+ return -EFAULT;
d337f35e 15248+
4bf69007
AM
15249+ /* special STATE flag handling */
15250+ mask = vs_mask_mask(vc_data.mask, vxi->vx_flags, VXF_ONE_TIME);
15251+ trigger = (mask & vxi->vx_flags) ^ (mask & vc_data.flagword);
d337f35e 15252+
4bf69007
AM
15253+ if (vxi == current_vx_info()) {
15254+ /* if (trigger & VXF_STATE_SETUP)
15255+ vx_mask_cap_bset(vxi, current); */
15256+ if (trigger & VXF_STATE_INIT) {
15257+ int ret;
d337f35e 15258+
4bf69007
AM
15259+ ret = vx_set_init(vxi, current);
15260+ if (ret)
15261+ return ret;
15262+ ret = vx_set_reaper(vxi, current);
15263+ if (ret)
15264+ return ret;
d337f35e
JR
15265+ }
15266+ }
4bf69007
AM
15267+
15268+ vxi->vx_flags = vs_mask_flags(vxi->vx_flags,
15269+ vc_data.flagword, mask);
15270+ if (trigger & VXF_PERSISTENT)
15271+ vx_update_persistent(vxi);
15272+
15273+ return 0;
d337f35e
JR
15274+}
15275+
15276+
4bf69007 15277+static inline uint64_t caps_from_cap_t(kernel_cap_t c)
d337f35e 15278+{
4bf69007 15279+ uint64_t v = c.cap[0] | ((uint64_t)c.cap[1] << 32);
d337f35e 15280+
4bf69007
AM
15281+ // printk("caps_from_cap_t(%08x:%08x) = %016llx\n", c.cap[1], c.cap[0], v);
15282+ return v;
d337f35e
JR
15283+}
15284+
4bf69007 15285+static inline kernel_cap_t cap_t_from_caps(uint64_t v)
d337f35e 15286+{
4bf69007 15287+ kernel_cap_t c = __cap_empty_set;
d337f35e 15288+
4bf69007
AM
15289+ c.cap[0] = v & 0xFFFFFFFF;
15290+ c.cap[1] = (v >> 32) & 0xFFFFFFFF;
d337f35e 15291+
4bf69007
AM
15292+ // printk("cap_t_from_caps(%016llx) = %08x:%08x\n", v, c.cap[1], c.cap[0]);
15293+ return c;
d337f35e
JR
15294+}
15295+
15296+
4bf69007 15297+static int do_get_caps(struct vx_info *vxi, uint64_t *bcaps, uint64_t *ccaps)
d337f35e 15298+{
4bf69007
AM
15299+ if (bcaps)
15300+ *bcaps = caps_from_cap_t(vxi->vx_bcaps);
15301+ if (ccaps)
15302+ *ccaps = vxi->vx_ccaps;
d337f35e 15303+
4bf69007
AM
15304+ return 0;
15305+}
d337f35e 15306+
4bf69007
AM
15307+int vc_get_ccaps(struct vx_info *vxi, void __user *data)
15308+{
15309+ struct vcmd_ctx_caps_v1 vc_data;
15310+ int ret;
d337f35e 15311+
4bf69007
AM
15312+ ret = do_get_caps(vxi, NULL, &vc_data.ccaps);
15313+ if (ret)
15314+ return ret;
15315+ vc_data.cmask = ~0ULL;
d337f35e 15316+
4bf69007
AM
15317+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
15318+ return -EFAULT;
15319+ return 0;
d337f35e
JR
15320+}
15321+
4bf69007
AM
15322+static int do_set_caps(struct vx_info *vxi,
15323+ uint64_t bcaps, uint64_t bmask, uint64_t ccaps, uint64_t cmask)
d337f35e 15324+{
4bf69007 15325+ uint64_t bcold = caps_from_cap_t(vxi->vx_bcaps);
d337f35e 15326+
4bf69007
AM
15327+#if 0
15328+ printk("do_set_caps(%16llx, %16llx, %16llx, %16llx)\n",
15329+ bcaps, bmask, ccaps, cmask);
15330+#endif
15331+ vxi->vx_bcaps = cap_t_from_caps(
15332+ vs_mask_flags(bcold, bcaps, bmask));
15333+ vxi->vx_ccaps = vs_mask_flags(vxi->vx_ccaps, ccaps, cmask);
d337f35e 15334+
4bf69007 15335+ return 0;
d337f35e
JR
15336+}
15337+
4bf69007 15338+int vc_set_ccaps(struct vx_info *vxi, void __user *data)
d337f35e 15339+{
4bf69007 15340+ struct vcmd_ctx_caps_v1 vc_data;
d337f35e 15341+
2380c486 15342+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
d337f35e
JR
15343+ return -EFAULT;
15344+
4bf69007 15345+ return do_set_caps(vxi, 0, 0, vc_data.ccaps, vc_data.cmask);
d337f35e
JR
15346+}
15347+
4bf69007 15348+int vc_get_bcaps(struct vx_info *vxi, void __user *data)
d337f35e 15349+{
4bf69007
AM
15350+ struct vcmd_bcaps vc_data;
15351+ int ret;
d337f35e 15352+
4bf69007
AM
15353+ ret = do_get_caps(vxi, &vc_data.bcaps, NULL);
15354+ if (ret)
15355+ return ret;
15356+ vc_data.bmask = ~0ULL;
d337f35e 15357+
4bf69007
AM
15358+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
15359+ return -EFAULT;
15360+ return 0;
d337f35e
JR
15361+}
15362+
4bf69007 15363+int vc_set_bcaps(struct vx_info *vxi, void __user *data)
d337f35e 15364+{
4bf69007 15365+ struct vcmd_bcaps vc_data;
d337f35e 15366+
2380c486 15367+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
d337f35e
JR
15368+ return -EFAULT;
15369+
4bf69007 15370+ return do_set_caps(vxi, vc_data.bcaps, vc_data.bmask, 0, 0);
d337f35e
JR
15371+}
15372+
d337f35e 15373+
4bf69007 15374+int vc_get_umask(struct vx_info *vxi, void __user *data)
d337f35e 15375+{
4bf69007 15376+ struct vcmd_umask vc_data;
7e46296a 15377+
4bf69007
AM
15378+ vc_data.umask = vxi->vx_umask;
15379+ vc_data.mask = ~0ULL;
d337f35e 15380+
4bf69007
AM
15381+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
15382+ return -EFAULT;
15383+ return 0;
15384+}
d337f35e 15385+
4bf69007
AM
15386+int vc_set_umask(struct vx_info *vxi, void __user *data)
15387+{
15388+ struct vcmd_umask vc_data;
d337f35e 15389+
4bf69007
AM
15390+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
15391+ return -EFAULT;
7e46296a 15392+
4bf69007
AM
15393+ vxi->vx_umask = vs_mask_flags(vxi->vx_umask,
15394+ vc_data.umask, vc_data.mask);
15395+ return 0;
15396+}
7e46296a 15397+
d337f35e 15398+
4bf69007
AM
15399+int vc_get_wmask(struct vx_info *vxi, void __user *data)
15400+{
15401+ struct vcmd_wmask vc_data;
d337f35e 15402+
4bf69007
AM
15403+ vc_data.wmask = vxi->vx_wmask;
15404+ vc_data.mask = ~0ULL;
d337f35e 15405+
4bf69007
AM
15406+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
15407+ return -EFAULT;
15408+ return 0;
d337f35e
JR
15409+}
15410+
4bf69007 15411+int vc_set_wmask(struct vx_info *vxi, void __user *data)
d337f35e 15412+{
4bf69007 15413+ struct vcmd_wmask vc_data;
d337f35e 15414+
2380c486 15415+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
d337f35e
JR
15416+ return -EFAULT;
15417+
4bf69007
AM
15418+ vxi->vx_wmask = vs_mask_flags(vxi->vx_wmask,
15419+ vc_data.wmask, vc_data.mask);
15420+ return 0;
d337f35e
JR
15421+}
15422+
d337f35e 15423+
4bf69007 15424+int vc_get_badness(struct vx_info *vxi, void __user *data)
d337f35e 15425+{
4bf69007
AM
15426+ struct vcmd_badness_v0 vc_data;
15427+
15428+ vc_data.bias = vxi->vx_badness_bias;
15429+
15430+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
15431+ return -EFAULT;
15432+ return 0;
15433+}
15434+
15435+int vc_set_badness(struct vx_info *vxi, void __user *data)
15436+{
15437+ struct vcmd_badness_v0 vc_data;
d337f35e 15438+
2380c486 15439+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
d337f35e
JR
15440+ return -EFAULT;
15441+
4bf69007
AM
15442+ vxi->vx_badness_bias = vc_data.bias;
15443+ return 0;
d337f35e
JR
15444+}
15445+
4bf69007 15446+#include <linux/module.h>
d337f35e 15447+
4bf69007 15448+EXPORT_SYMBOL_GPL(free_vx_info);
d337f35e 15449+
3261cfd5
AM
15450diff -NurpP --minimal linux-4.9.207/kernel/vserver/cvirt.c linux-4.9.207-vs2.3.9.11/kernel/vserver/cvirt.c
15451--- linux-4.9.207/kernel/vserver/cvirt.c 1970-01-01 00:00:00.000000000 +0000
15452+++ linux-4.9.207-vs2.3.9.11/kernel/vserver/cvirt.c 2018-10-20 04:58:15.000000000 +0000
cc23e853 15453@@ -0,0 +1,350 @@
4bf69007
AM
15454+/*
15455+ * linux/kernel/vserver/cvirt.c
15456+ *
15457+ * Virtual Server: Context Virtualization
15458+ *
cc23e853 15459+ * Copyright (C) 2004-2007 Herbert P?tzl
4bf69007
AM
15460+ *
15461+ * V0.01 broken out from limit.c
15462+ * V0.02 added utsname stuff
15463+ * V0.03 changed vcmds to vxi arg
15464+ *
15465+ */
d337f35e 15466+
4bf69007
AM
15467+#include <linux/types.h>
15468+#include <linux/utsname.h>
15469+#include <linux/vs_cvirt.h>
15470+#include <linux/vserver/switch.h>
15471+#include <linux/vserver/cvirt_cmd.h>
d337f35e 15472+
4bf69007 15473+#include <asm/uaccess.h>
d337f35e 15474+
d337f35e 15475+
369dbd59 15476+void vx_vsi_boottime64(struct timespec64 *boottime)
4bf69007
AM
15477+{
15478+ struct vx_info *vxi = current_vx_info();
d337f35e 15479+
369dbd59 15480+ set_normalized_timespec64(boottime,
4bf69007
AM
15481+ boottime->tv_sec + vxi->cvirt.bias_uptime.tv_sec,
15482+ boottime->tv_nsec + vxi->cvirt.bias_uptime.tv_nsec);
15483+ return;
d337f35e
JR
15484+}
15485+
4bf69007 15486+void vx_vsi_uptime(struct timespec *uptime, struct timespec *idle)
d337f35e 15487+{
4bf69007 15488+ struct vx_info *vxi = current_vx_info();
d337f35e 15489+
4bf69007
AM
15490+ set_normalized_timespec(uptime,
15491+ uptime->tv_sec - vxi->cvirt.bias_uptime.tv_sec,
15492+ uptime->tv_nsec - vxi->cvirt.bias_uptime.tv_nsec);
15493+ if (!idle)
15494+ return;
15495+ set_normalized_timespec(idle,
15496+ idle->tv_sec - vxi->cvirt.bias_idle.tv_sec,
15497+ idle->tv_nsec - vxi->cvirt.bias_idle.tv_nsec);
15498+ return;
d337f35e
JR
15499+}
15500+
4bf69007 15501+uint64_t vx_idle_jiffies(void)
d337f35e 15502+{
4bf69007 15503+ return init_task.utime + init_task.stime;
d337f35e
JR
15504+}
15505+
d337f35e
JR
15506+
15507+
4bf69007
AM
15508+static inline uint32_t __update_loadavg(uint32_t load,
15509+ int wsize, int delta, int n)
d337f35e 15510+{
4bf69007 15511+ unsigned long long calc, prev;
d337f35e 15512+
4bf69007
AM
15513+ /* just set it to n */
15514+ if (unlikely(delta >= wsize))
15515+ return (n << FSHIFT);
d337f35e 15516+
4bf69007
AM
15517+ calc = delta * n;
15518+ calc <<= FSHIFT;
15519+ prev = (wsize - delta);
15520+ prev *= load;
15521+ calc += prev;
15522+ do_div(calc, wsize);
15523+ return calc;
15524+}
d337f35e 15525+
d337f35e 15526+
4bf69007
AM
15527+void vx_update_load(struct vx_info *vxi)
15528+{
15529+ uint32_t now, last, delta;
15530+ unsigned int nr_running, nr_uninterruptible;
15531+ unsigned int total;
15532+ unsigned long flags;
d337f35e 15533+
4bf69007 15534+ spin_lock_irqsave(&vxi->cvirt.load_lock, flags);
d337f35e 15535+
4bf69007
AM
15536+ now = jiffies;
15537+ last = vxi->cvirt.load_last;
15538+ delta = now - last;
d337f35e 15539+
4bf69007
AM
15540+ if (delta < 5*HZ)
15541+ goto out;
d337f35e 15542+
4bf69007
AM
15543+ nr_running = atomic_read(&vxi->cvirt.nr_running);
15544+ nr_uninterruptible = atomic_read(&vxi->cvirt.nr_uninterruptible);
15545+ total = nr_running + nr_uninterruptible;
d337f35e 15546+
4bf69007
AM
15547+ vxi->cvirt.load[0] = __update_loadavg(vxi->cvirt.load[0],
15548+ 60*HZ, delta, total);
15549+ vxi->cvirt.load[1] = __update_loadavg(vxi->cvirt.load[1],
15550+ 5*60*HZ, delta, total);
15551+ vxi->cvirt.load[2] = __update_loadavg(vxi->cvirt.load[2],
15552+ 15*60*HZ, delta, total);
d337f35e 15553+
4bf69007
AM
15554+ vxi->cvirt.load_last = now;
15555+out:
15556+ atomic_inc(&vxi->cvirt.load_updates);
15557+ spin_unlock_irqrestore(&vxi->cvirt.load_lock, flags);
d337f35e
JR
15558+}
15559+
d337f35e 15560+
d337f35e 15561+/*
4bf69007 15562+ * Commands to do_syslog:
d337f35e 15563+ *
4bf69007
AM
15564+ * 0 -- Close the log. Currently a NOP.
15565+ * 1 -- Open the log. Currently a NOP.
15566+ * 2 -- Read from the log.
15567+ * 3 -- Read all messages remaining in the ring buffer.
15568+ * 4 -- Read and clear all messages remaining in the ring buffer
15569+ * 5 -- Clear ring buffer.
15570+ * 6 -- Disable printk's to console
15571+ * 7 -- Enable printk's to console
15572+ * 8 -- Set level of messages printed to console
15573+ * 9 -- Return number of unread characters in the log buffer
15574+ * 10 -- Return size of the log buffer
d337f35e 15575+ */
4bf69007
AM
15576+int vx_do_syslog(int type, char __user *buf, int len)
15577+{
15578+ int error = 0;
15579+ int do_clear = 0;
15580+ struct vx_info *vxi = current_vx_info();
15581+ struct _vx_syslog *log;
d337f35e 15582+
4bf69007
AM
15583+ if (!vxi)
15584+ return -EINVAL;
15585+ log = &vxi->cvirt.syslog;
15586+
15587+ switch (type) {
15588+ case 0: /* Close log */
15589+ case 1: /* Open log */
15590+ break;
15591+ case 2: /* Read from log */
15592+ error = wait_event_interruptible(log->log_wait,
15593+ (log->log_start - log->log_end));
15594+ if (error)
15595+ break;
15596+ spin_lock_irq(&log->logbuf_lock);
15597+ spin_unlock_irq(&log->logbuf_lock);
15598+ break;
15599+ case 4: /* Read/clear last kernel messages */
15600+ do_clear = 1;
15601+ /* fall through */
15602+ case 3: /* Read last kernel messages */
15603+ return 0;
d337f35e 15604+
4bf69007
AM
15605+ case 5: /* Clear ring buffer */
15606+ return 0;
d337f35e 15607+
4bf69007
AM
15608+ case 6: /* Disable logging to console */
15609+ case 7: /* Enable logging to console */
15610+ case 8: /* Set level of messages printed to console */
15611+ break;
d337f35e 15612+
4bf69007
AM
15613+ case 9: /* Number of chars in the log buffer */
15614+ return 0;
15615+ case 10: /* Size of the log buffer */
15616+ return 0;
15617+ default:
15618+ error = -EINVAL;
15619+ break;
15620+ }
15621+ return error;
1e8b8f9b 15622+}
d337f35e 15623+
4bf69007
AM
15624+
15625+/* virtual host info names */
15626+
15627+static char *vx_vhi_name(struct vx_info *vxi, int id)
d337f35e 15628+{
4bf69007
AM
15629+ struct nsproxy *nsproxy;
15630+ struct uts_namespace *uts;
d337f35e 15631+
4bf69007
AM
15632+ if (id == VHIN_CONTEXT)
15633+ return vxi->vx_name;
15634+
15635+ nsproxy = vxi->space[0].vx_nsproxy;
15636+ if (!nsproxy)
15637+ return NULL;
15638+
15639+ uts = nsproxy->uts_ns;
15640+ if (!uts)
15641+ return NULL;
15642+
15643+ switch (id) {
15644+ case VHIN_SYSNAME:
15645+ return uts->name.sysname;
15646+ case VHIN_NODENAME:
15647+ return uts->name.nodename;
15648+ case VHIN_RELEASE:
15649+ return uts->name.release;
15650+ case VHIN_VERSION:
15651+ return uts->name.version;
15652+ case VHIN_MACHINE:
15653+ return uts->name.machine;
15654+ case VHIN_DOMAINNAME:
15655+ return uts->name.domainname;
15656+ default:
15657+ return NULL;
d337f35e 15658+ }
4bf69007 15659+ return NULL;
d337f35e
JR
15660+}
15661+
4bf69007 15662+int vc_set_vhi_name(struct vx_info *vxi, void __user *data)
d337f35e 15663+{
4bf69007
AM
15664+ struct vcmd_vhi_name_v0 vc_data;
15665+ char *name;
d337f35e 15666+
4bf69007
AM
15667+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
15668+ return -EFAULT;
d337f35e 15669+
4bf69007
AM
15670+ name = vx_vhi_name(vxi, vc_data.field);
15671+ if (!name)
15672+ return -EINVAL;
d337f35e 15673+
4bf69007
AM
15674+ memcpy(name, vc_data.name, 65);
15675+ return 0;
15676+}
d337f35e 15677+
4bf69007
AM
15678+int vc_get_vhi_name(struct vx_info *vxi, void __user *data)
15679+{
15680+ struct vcmd_vhi_name_v0 vc_data;
15681+ char *name;
d337f35e 15682+
4bf69007
AM
15683+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
15684+ return -EFAULT;
d337f35e 15685+
4bf69007
AM
15686+ name = vx_vhi_name(vxi, vc_data.field);
15687+ if (!name)
15688+ return -EINVAL;
d337f35e 15689+
4bf69007
AM
15690+ memcpy(vc_data.name, name, 65);
15691+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
15692+ return -EFAULT;
15693+ return 0;
15694+}
d337f35e 15695+
d337f35e 15696+
4bf69007
AM
15697+int vc_virt_stat(struct vx_info *vxi, void __user *data)
15698+{
15699+ struct vcmd_virt_stat_v0 vc_data;
15700+ struct _vx_cvirt *cvirt = &vxi->cvirt;
cc23e853 15701+ struct timespec64 uptime;
99a884b4 15702+
369dbd59
AM
15703+ ktime_get_ts64(&uptime);
15704+ set_normalized_timespec64(&uptime,
4bf69007
AM
15705+ uptime.tv_sec - cvirt->bias_uptime.tv_sec,
15706+ uptime.tv_nsec - cvirt->bias_uptime.tv_nsec);
d337f35e 15707+
cc23e853
AM
15708+ vc_data.offset = timespec64_to_ns(&cvirt->bias_ts);
15709+ vc_data.uptime = timespec64_to_ns(&uptime);
4bf69007
AM
15710+ vc_data.nr_threads = atomic_read(&cvirt->nr_threads);
15711+ vc_data.nr_running = atomic_read(&cvirt->nr_running);
15712+ vc_data.nr_uninterruptible = atomic_read(&cvirt->nr_uninterruptible);
15713+ vc_data.nr_onhold = atomic_read(&cvirt->nr_onhold);
15714+ vc_data.nr_forks = atomic_read(&cvirt->total_forks);
15715+ vc_data.load[0] = cvirt->load[0];
15716+ vc_data.load[1] = cvirt->load[1];
15717+ vc_data.load[2] = cvirt->load[2];
15718+
15719+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
15720+ return -EFAULT;
15721+ return 0;
d337f35e
JR
15722+}
15723+
15724+
4bf69007
AM
15725+#ifdef CONFIG_VSERVER_VTIME
15726+
15727+/* virtualized time base */
15728+
15729+void vx_adjust_timespec(struct timespec *ts)
d337f35e 15730+{
4bf69007 15731+ struct vx_info *vxi;
d337f35e 15732+
4bf69007
AM
15733+ if (!vx_flags(VXF_VIRT_TIME, 0))
15734+ return;
d337f35e 15735+
4bf69007
AM
15736+ vxi = current_vx_info();
15737+ ts->tv_sec += vxi->cvirt.bias_ts.tv_sec;
15738+ ts->tv_nsec += vxi->cvirt.bias_ts.tv_nsec;
d337f35e 15739+
4bf69007
AM
15740+ if (ts->tv_nsec >= NSEC_PER_SEC) {
15741+ ts->tv_sec++;
15742+ ts->tv_nsec -= NSEC_PER_SEC;
15743+ } else if (ts->tv_nsec < 0) {
15744+ ts->tv_sec--;
15745+ ts->tv_nsec += NSEC_PER_SEC;
d337f35e 15746+ }
d337f35e
JR
15747+}
15748+
cc23e853
AM
15749+void vx_adjust_timespec64(struct timespec64 *ts)
15750+{
15751+ struct vx_info *vxi;
15752+
15753+ if (!vx_flags(VXF_VIRT_TIME, 0))
15754+ return;
15755+
15756+ vxi = current_vx_info();
15757+ ts->tv_sec += vxi->cvirt.bias_ts.tv_sec;
15758+ ts->tv_nsec += vxi->cvirt.bias_ts.tv_nsec;
15759+
15760+ if (ts->tv_nsec >= NSEC_PER_SEC) {
15761+ ts->tv_sec++;
15762+ ts->tv_nsec -= NSEC_PER_SEC;
15763+ } else if (ts->tv_nsec < 0) {
15764+ ts->tv_sec--;
15765+ ts->tv_nsec += NSEC_PER_SEC;
15766+ }
15767+}
15768+
4bf69007 15769+int vx_settimeofday(const struct timespec *ts)
99a884b4 15770+{
4bf69007
AM
15771+ struct timespec ats, delta;
15772+ struct vx_info *vxi;
99a884b4 15773+
4bf69007
AM
15774+ if (!vx_flags(VXF_VIRT_TIME, 0))
15775+ return do_settimeofday(ts);
99a884b4 15776+
4bf69007
AM
15777+ getnstimeofday(&ats);
15778+ delta = timespec_sub(*ts, ats);
99a884b4 15779+
4bf69007 15780+ vxi = current_vx_info();
cc23e853
AM
15781+ vxi->cvirt.bias_ts = timespec64_add(vxi->cvirt.bias_ts,
15782+ timespec_to_timespec64(delta));
15783+ return 0;
15784+}
15785+
15786+int vx_settimeofday64(const struct timespec64 *ts)
15787+{
15788+ struct timespec64 ats, delta;
15789+ struct vx_info *vxi;
15790+
15791+ if (!vx_flags(VXF_VIRT_TIME, 0))
15792+ return do_settimeofday64(ts);
15793+
15794+ getnstimeofday64(&ats);
15795+ delta = timespec64_sub(*ts, ats);
15796+
15797+ vxi = current_vx_info();
15798+ vxi->cvirt.bias_ts = timespec64_add(vxi->cvirt.bias_ts, delta);
99a884b4
AM
15799+ return 0;
15800+}
d337f35e 15801+
4bf69007 15802+#endif
d337f35e 15803+
3261cfd5
AM
15804diff -NurpP --minimal linux-4.9.207/kernel/vserver/cvirt_init.h linux-4.9.207-vs2.3.9.11/kernel/vserver/cvirt_init.h
15805--- linux-4.9.207/kernel/vserver/cvirt_init.h 1970-01-01 00:00:00.000000000 +0000
15806+++ linux-4.9.207-vs2.3.9.11/kernel/vserver/cvirt_init.h 2018-10-20 04:58:15.000000000 +0000
4bf69007 15807@@ -0,0 +1,70 @@
d337f35e 15808+
d337f35e 15809+
4bf69007 15810+extern uint64_t vx_idle_jiffies(void);
d337f35e 15811+
4bf69007
AM
15812+static inline void vx_info_init_cvirt(struct _vx_cvirt *cvirt)
15813+{
15814+ uint64_t idle_jiffies = vx_idle_jiffies();
15815+ uint64_t nsuptime;
d337f35e 15816+
cc23e853 15817+ ktime_get_ts64(&cvirt->bias_uptime);
4bf69007
AM
15818+ nsuptime = (unsigned long long)cvirt->bias_uptime.tv_sec
15819+ * NSEC_PER_SEC + cvirt->bias_uptime.tv_nsec;
15820+ cvirt->bias_clock = nsec_to_clock_t(nsuptime);
15821+ cvirt->bias_ts.tv_sec = 0;
15822+ cvirt->bias_ts.tv_nsec = 0;
d337f35e 15823+
cc23e853 15824+ jiffies_to_timespec64(idle_jiffies, &cvirt->bias_idle);
4bf69007
AM
15825+ atomic_set(&cvirt->nr_threads, 0);
15826+ atomic_set(&cvirt->nr_running, 0);
15827+ atomic_set(&cvirt->nr_uninterruptible, 0);
15828+ atomic_set(&cvirt->nr_onhold, 0);
d337f35e 15829+
4bf69007
AM
15830+ spin_lock_init(&cvirt->load_lock);
15831+ cvirt->load_last = jiffies;
15832+ atomic_set(&cvirt->load_updates, 0);
15833+ cvirt->load[0] = 0;
15834+ cvirt->load[1] = 0;
15835+ cvirt->load[2] = 0;
15836+ atomic_set(&cvirt->total_forks, 0);
d337f35e 15837+
4bf69007
AM
15838+ spin_lock_init(&cvirt->syslog.logbuf_lock);
15839+ init_waitqueue_head(&cvirt->syslog.log_wait);
15840+ cvirt->syslog.log_start = 0;
15841+ cvirt->syslog.log_end = 0;
15842+ cvirt->syslog.con_start = 0;
15843+ cvirt->syslog.logged_chars = 0;
15844+}
15845+
15846+static inline
15847+void vx_info_init_cvirt_pc(struct _vx_cvirt_pc *cvirt_pc, int cpu)
d337f35e 15848+{
4bf69007
AM
15849+ // cvirt_pc->cpustat = { 0 };
15850+}
d337f35e 15851+
4bf69007
AM
15852+static inline void vx_info_exit_cvirt(struct _vx_cvirt *cvirt)
15853+{
15854+#ifdef CONFIG_VSERVER_WARN
15855+ int value;
15856+#endif
15857+ vxwprintk_xid((value = atomic_read(&cvirt->nr_threads)),
15858+ "!!! cvirt: %p[nr_threads] = %d on exit.",
15859+ cvirt, value);
15860+ vxwprintk_xid((value = atomic_read(&cvirt->nr_running)),
15861+ "!!! cvirt: %p[nr_running] = %d on exit.",
15862+ cvirt, value);
15863+ vxwprintk_xid((value = atomic_read(&cvirt->nr_uninterruptible)),
15864+ "!!! cvirt: %p[nr_uninterruptible] = %d on exit.",
15865+ cvirt, value);
15866+ vxwprintk_xid((value = atomic_read(&cvirt->nr_onhold)),
15867+ "!!! cvirt: %p[nr_onhold] = %d on exit.",
15868+ cvirt, value);
15869+ return;
15870+}
d337f35e 15871+
4bf69007
AM
15872+static inline
15873+void vx_info_exit_cvirt_pc(struct _vx_cvirt_pc *cvirt_pc, int cpu)
15874+{
15875+ return;
15876+}
d337f35e 15877+
3261cfd5
AM
15878diff -NurpP --minimal linux-4.9.207/kernel/vserver/cvirt_proc.h linux-4.9.207-vs2.3.9.11/kernel/vserver/cvirt_proc.h
15879--- linux-4.9.207/kernel/vserver/cvirt_proc.h 1970-01-01 00:00:00.000000000 +0000
15880+++ linux-4.9.207-vs2.3.9.11/kernel/vserver/cvirt_proc.h 2018-10-20 04:58:15.000000000 +0000
4bf69007
AM
15881@@ -0,0 +1,123 @@
15882+#ifndef _VX_CVIRT_PROC_H
15883+#define _VX_CVIRT_PROC_H
d337f35e 15884+
4bf69007
AM
15885+#include <linux/nsproxy.h>
15886+#include <linux/mnt_namespace.h>
15887+#include <linux/ipc_namespace.h>
15888+#include <linux/utsname.h>
15889+#include <linux/ipc.h>
d337f35e 15890+
4bf69007 15891+extern int vx_info_mnt_namespace(struct mnt_namespace *, char *);
d337f35e 15892+
4bf69007
AM
15893+static inline
15894+int vx_info_proc_nsproxy(struct nsproxy *nsproxy, char *buffer)
15895+{
15896+ struct mnt_namespace *ns;
15897+ struct uts_namespace *uts;
15898+ struct ipc_namespace *ipc;
15899+ int length = 0;
d337f35e 15900+
4bf69007
AM
15901+ if (!nsproxy)
15902+ goto out;
d337f35e 15903+
4bf69007
AM
15904+ length += sprintf(buffer + length,
15905+ "NSProxy:\t%p [%p,%p,%p]\n",
15906+ nsproxy, nsproxy->mnt_ns,
15907+ nsproxy->uts_ns, nsproxy->ipc_ns);
d337f35e 15908+
4bf69007
AM
15909+ ns = nsproxy->mnt_ns;
15910+ if (!ns)
15911+ goto skip_ns;
d337f35e 15912+
4bf69007 15913+ length += vx_info_mnt_namespace(ns, buffer + length);
d337f35e 15914+
4bf69007 15915+skip_ns:
d337f35e 15916+
4bf69007
AM
15917+ uts = nsproxy->uts_ns;
15918+ if (!uts)
15919+ goto skip_uts;
d337f35e 15920+
4bf69007
AM
15921+ length += sprintf(buffer + length,
15922+ "SysName:\t%.*s\n"
15923+ "NodeName:\t%.*s\n"
15924+ "Release:\t%.*s\n"
15925+ "Version:\t%.*s\n"
15926+ "Machine:\t%.*s\n"
15927+ "DomainName:\t%.*s\n",
15928+ __NEW_UTS_LEN, uts->name.sysname,
15929+ __NEW_UTS_LEN, uts->name.nodename,
15930+ __NEW_UTS_LEN, uts->name.release,
15931+ __NEW_UTS_LEN, uts->name.version,
15932+ __NEW_UTS_LEN, uts->name.machine,
15933+ __NEW_UTS_LEN, uts->name.domainname);
15934+skip_uts:
d337f35e 15935+
4bf69007
AM
15936+ ipc = nsproxy->ipc_ns;
15937+ if (!ipc)
15938+ goto skip_ipc;
d337f35e 15939+
4bf69007
AM
15940+ length += sprintf(buffer + length,
15941+ "SEMS:\t\t%d %d %d %d %d\n"
15942+ "MSG:\t\t%d %d %d\n"
b00e13aa 15943+ "SHM:\t\t%lu %lu %d %ld\n",
4bf69007
AM
15944+ ipc->sem_ctls[0], ipc->sem_ctls[1],
15945+ ipc->sem_ctls[2], ipc->sem_ctls[3],
15946+ ipc->used_sems,
15947+ ipc->msg_ctlmax, ipc->msg_ctlmnb, ipc->msg_ctlmni,
15948+ (unsigned long)ipc->shm_ctlmax,
15949+ (unsigned long)ipc->shm_ctlall,
15950+ ipc->shm_ctlmni, ipc->shm_tot);
15951+skip_ipc:
15952+out:
15953+ return length;
15954+}
d337f35e
JR
15955+
15956+
4bf69007 15957+#include <linux/sched.h>
d337f35e 15958+
4bf69007
AM
15959+#define LOAD_INT(x) ((x) >> FSHIFT)
15960+#define LOAD_FRAC(x) LOAD_INT(((x) & (FIXED_1 - 1)) * 100)
d337f35e 15961+
4bf69007
AM
15962+static inline
15963+int vx_info_proc_cvirt(struct _vx_cvirt *cvirt, char *buffer)
d337f35e 15964+{
4bf69007
AM
15965+ int length = 0;
15966+ int a, b, c;
d337f35e 15967+
4bf69007 15968+ length += sprintf(buffer + length,
cc23e853
AM
15969+ "BiasUptime:\t%llu.%02lu\n",
15970+ (unsigned long long)cvirt->bias_uptime.tv_sec,
4bf69007 15971+ (cvirt->bias_uptime.tv_nsec / (NSEC_PER_SEC / 100)));
d337f35e 15972+
4bf69007
AM
15973+ a = cvirt->load[0] + (FIXED_1 / 200);
15974+ b = cvirt->load[1] + (FIXED_1 / 200);
15975+ c = cvirt->load[2] + (FIXED_1 / 200);
15976+ length += sprintf(buffer + length,
15977+ "nr_threads:\t%d\n"
15978+ "nr_running:\t%d\n"
15979+ "nr_unintr:\t%d\n"
15980+ "nr_onhold:\t%d\n"
15981+ "load_updates:\t%d\n"
15982+ "loadavg:\t%d.%02d %d.%02d %d.%02d\n"
15983+ "total_forks:\t%d\n",
15984+ atomic_read(&cvirt->nr_threads),
15985+ atomic_read(&cvirt->nr_running),
15986+ atomic_read(&cvirt->nr_uninterruptible),
15987+ atomic_read(&cvirt->nr_onhold),
15988+ atomic_read(&cvirt->load_updates),
15989+ LOAD_INT(a), LOAD_FRAC(a),
15990+ LOAD_INT(b), LOAD_FRAC(b),
15991+ LOAD_INT(c), LOAD_FRAC(c),
15992+ atomic_read(&cvirt->total_forks));
15993+ return length;
d337f35e
JR
15994+}
15995+
4bf69007
AM
15996+static inline
15997+int vx_info_proc_cvirt_pc(struct _vx_cvirt_pc *cvirt_pc,
15998+ char *buffer, int cpu)
15999+{
16000+ int length = 0;
16001+ return length;
16002+}
d337f35e 16003+
4bf69007 16004+#endif /* _VX_CVIRT_PROC_H */
3261cfd5
AM
16005diff -NurpP --minimal linux-4.9.207/kernel/vserver/debug.c linux-4.9.207-vs2.3.9.11/kernel/vserver/debug.c
16006--- linux-4.9.207/kernel/vserver/debug.c 1970-01-01 00:00:00.000000000 +0000
16007+++ linux-4.9.207-vs2.3.9.11/kernel/vserver/debug.c 2018-10-20 04:58:15.000000000 +0000
4bf69007
AM
16008@@ -0,0 +1,32 @@
16009+/*
16010+ * kernel/vserver/debug.c
16011+ *
cc23e853 16012+ * Copyright (C) 2005-2007 Herbert P?tzl
4bf69007
AM
16013+ *
16014+ * V0.01 vx_info dump support
16015+ *
16016+ */
d337f35e 16017+
4bf69007 16018+#include <linux/module.h>
d337f35e 16019+
4bf69007 16020+#include <linux/vserver/context.h>
d337f35e 16021+
d337f35e 16022+
4bf69007 16023+void dump_vx_info(struct vx_info *vxi, int level)
d337f35e 16024+{
4bf69007
AM
16025+ printk("vx_info %p[#%d, %d.%d, %4x]\n", vxi, vxi->vx_id,
16026+ atomic_read(&vxi->vx_usecnt),
16027+ atomic_read(&vxi->vx_tasks),
16028+ vxi->vx_state);
16029+ if (level > 0) {
16030+ __dump_vx_limit(&vxi->limit);
16031+ __dump_vx_sched(&vxi->sched);
16032+ __dump_vx_cvirt(&vxi->cvirt);
16033+ __dump_vx_cacct(&vxi->cacct);
16034+ }
16035+ printk("---\n");
16036+}
d337f35e 16037+
d337f35e 16038+
4bf69007 16039+EXPORT_SYMBOL_GPL(dump_vx_info);
d337f35e 16040+
3261cfd5
AM
16041diff -NurpP --minimal linux-4.9.207/kernel/vserver/device.c linux-4.9.207-vs2.3.9.11/kernel/vserver/device.c
16042--- linux-4.9.207/kernel/vserver/device.c 1970-01-01 00:00:00.000000000 +0000
16043+++ linux-4.9.207-vs2.3.9.11/kernel/vserver/device.c 2018-10-20 04:58:15.000000000 +0000
4bf69007
AM
16044@@ -0,0 +1,443 @@
16045+/*
16046+ * linux/kernel/vserver/device.c
16047+ *
16048+ * Linux-VServer: Device Support
16049+ *
cc23e853 16050+ * Copyright (C) 2006 Herbert P?tzl
4bf69007
AM
16051+ * Copyright (C) 2007 Daniel Hokka Zakrisson
16052+ *
16053+ * V0.01 device mapping basics
16054+ * V0.02 added defaults
16055+ *
16056+ */
d337f35e 16057+
4bf69007
AM
16058+#include <linux/slab.h>
16059+#include <linux/rcupdate.h>
16060+#include <linux/fs.h>
16061+#include <linux/namei.h>
16062+#include <linux/hash.h>
d337f35e 16063+
4bf69007
AM
16064+#include <asm/errno.h>
16065+#include <asm/uaccess.h>
16066+#include <linux/vserver/base.h>
16067+#include <linux/vserver/debug.h>
16068+#include <linux/vserver/context.h>
16069+#include <linux/vserver/device.h>
16070+#include <linux/vserver/device_cmd.h>
d337f35e 16071+
d337f35e 16072+
4bf69007 16073+#define DMAP_HASH_BITS 4
d337f35e 16074+
d337f35e 16075+
4bf69007
AM
16076+struct vs_mapping {
16077+ union {
16078+ struct hlist_node hlist;
16079+ struct list_head list;
16080+ } u;
16081+#define dm_hlist u.hlist
16082+#define dm_list u.list
61333608 16083+ vxid_t xid;
4bf69007
AM
16084+ dev_t device;
16085+ struct vx_dmap_target target;
16086+};
d337f35e 16087+
d337f35e 16088+
4bf69007 16089+static struct hlist_head dmap_main_hash[1 << DMAP_HASH_BITS];
d337f35e 16090+
4bf69007 16091+static DEFINE_SPINLOCK(dmap_main_hash_lock);
d337f35e 16092+
4bf69007
AM
16093+static struct vx_dmap_target dmap_defaults[2] = {
16094+ { .flags = DATTR_OPEN },
16095+ { .flags = DATTR_OPEN },
16096+};
d337f35e
JR
16097+
16098+
4bf69007 16099+struct kmem_cache *dmap_cachep __read_mostly;
d337f35e 16100+
4bf69007
AM
16101+int __init dmap_cache_init(void)
16102+{
16103+ dmap_cachep = kmem_cache_create("dmap_cache",
16104+ sizeof(struct vs_mapping), 0,
16105+ SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL);
d337f35e
JR
16106+ return 0;
16107+}
16108+
4bf69007 16109+__initcall(dmap_cache_init);
d337f35e 16110+
4bf69007
AM
16111+
16112+static inline unsigned int __hashval(dev_t dev, int bits)
d337f35e 16113+{
4bf69007
AM
16114+ return hash_long((unsigned long)dev, bits);
16115+}
d337f35e 16116+
d337f35e 16117+
4bf69007
AM
16118+/* __hash_mapping()
16119+ * add the mapping to the hash table
16120+ */
16121+static inline void __hash_mapping(struct vx_info *vxi, struct vs_mapping *vdm)
16122+{
16123+ spinlock_t *hash_lock = &dmap_main_hash_lock;
16124+ struct hlist_head *head, *hash = dmap_main_hash;
16125+ int device = vdm->device;
d337f35e 16126+
4bf69007
AM
16127+ spin_lock(hash_lock);
16128+ vxdprintk(VXD_CBIT(misc, 8), "__hash_mapping: %p[#%d] %08x:%08x",
16129+ vxi, vxi ? vxi->vx_id : 0, device, vdm->target.target);
d337f35e 16130+
4bf69007
AM
16131+ head = &hash[__hashval(device, DMAP_HASH_BITS)];
16132+ hlist_add_head(&vdm->dm_hlist, head);
16133+ spin_unlock(hash_lock);
16134+}
16135+
16136+
16137+static inline int __mode_to_default(umode_t mode)
16138+{
16139+ switch (mode) {
16140+ case S_IFBLK:
16141+ return 0;
16142+ case S_IFCHR:
16143+ return 1;
16144+ default:
16145+ BUG();
d337f35e 16146+ }
d337f35e
JR
16147+}
16148+
4bf69007
AM
16149+
16150+/* __set_default()
16151+ * set a default
16152+ */
16153+static inline void __set_default(struct vx_info *vxi, umode_t mode,
16154+ struct vx_dmap_target *vdmt)
d337f35e 16155+{
4bf69007
AM
16156+ spinlock_t *hash_lock = &dmap_main_hash_lock;
16157+ spin_lock(hash_lock);
d337f35e 16158+
4bf69007
AM
16159+ if (vxi)
16160+ vxi->dmap.targets[__mode_to_default(mode)] = *vdmt;
16161+ else
16162+ dmap_defaults[__mode_to_default(mode)] = *vdmt;
d337f35e 16163+
d337f35e 16164+
4bf69007 16165+ spin_unlock(hash_lock);
d337f35e 16166+
4bf69007
AM
16167+ vxdprintk(VXD_CBIT(misc, 8), "__set_default: %p[#%u] %08x %04x",
16168+ vxi, vxi ? vxi->vx_id : 0, vdmt->target, vdmt->flags);
d337f35e
JR
16169+}
16170+
d337f35e 16171+
4bf69007
AM
16172+/* __remove_default()
16173+ * remove a default
16174+ */
16175+static inline int __remove_default(struct vx_info *vxi, umode_t mode)
d337f35e 16176+{
4bf69007
AM
16177+ spinlock_t *hash_lock = &dmap_main_hash_lock;
16178+ spin_lock(hash_lock);
d337f35e 16179+
4bf69007
AM
16180+ if (vxi)
16181+ vxi->dmap.targets[__mode_to_default(mode)].flags = 0;
16182+ else /* remove == reset */
16183+ dmap_defaults[__mode_to_default(mode)].flags = DATTR_OPEN | mode;
d337f35e 16184+
4bf69007
AM
16185+ spin_unlock(hash_lock);
16186+ return 0;
d337f35e
JR
16187+}
16188+
d337f35e 16189+
4bf69007
AM
16190+/* __find_mapping()
16191+ * find a mapping in the hash table
16192+ *
16193+ * caller must hold hash_lock
16194+ */
61333608 16195+static inline int __find_mapping(vxid_t xid, dev_t device, umode_t mode,
4bf69007
AM
16196+ struct vs_mapping **local, struct vs_mapping **global)
16197+{
16198+ struct hlist_head *hash = dmap_main_hash;
16199+ struct hlist_head *head = &hash[__hashval(device, DMAP_HASH_BITS)];
16200+ struct hlist_node *pos;
16201+ struct vs_mapping *vdm;
d337f35e 16202+
4bf69007
AM
16203+ *local = NULL;
16204+ if (global)
16205+ *global = NULL;
d337f35e 16206+
4bf69007
AM
16207+ hlist_for_each(pos, head) {
16208+ vdm = hlist_entry(pos, struct vs_mapping, dm_hlist);
d337f35e 16209+
4bf69007
AM
16210+ if ((vdm->device == device) &&
16211+ !((vdm->target.flags ^ mode) & S_IFMT)) {
16212+ if (vdm->xid == xid) {
16213+ *local = vdm;
16214+ return 1;
16215+ } else if (global && vdm->xid == 0)
16216+ *global = vdm;
2380c486
JR
16217+ }
16218+ }
16219+
4bf69007
AM
16220+ if (global && *global)
16221+ return 0;
16222+ else
16223+ return -ENOENT;
2380c486
JR
16224+}
16225+
16226+
4bf69007
AM
16227+/* __lookup_mapping()
16228+ * find a mapping and store the result in target and flags
16229+ */
16230+static inline int __lookup_mapping(struct vx_info *vxi,
16231+ dev_t device, dev_t *target, int *flags, umode_t mode)
2380c486 16232+{
4bf69007
AM
16233+ spinlock_t *hash_lock = &dmap_main_hash_lock;
16234+ struct vs_mapping *vdm, *global;
16235+ struct vx_dmap_target *vdmt;
2380c486 16236+ int ret = 0;
61333608 16237+ vxid_t xid = vxi->vx_id;
4bf69007 16238+ int index;
2380c486 16239+
4bf69007
AM
16240+ spin_lock(hash_lock);
16241+ if (__find_mapping(xid, device, mode, &vdm, &global) > 0) {
2380c486 16242+ ret = 1;
4bf69007
AM
16243+ vdmt = &vdm->target;
16244+ goto found;
16245+ }
2380c486 16246+
4bf69007
AM
16247+ index = __mode_to_default(mode);
16248+ if (vxi && vxi->dmap.targets[index].flags) {
16249+ ret = 2;
16250+ vdmt = &vxi->dmap.targets[index];
16251+ } else if (global) {
16252+ ret = 3;
16253+ vdmt = &global->target;
16254+ goto found;
16255+ } else {
16256+ ret = 4;
16257+ vdmt = &dmap_defaults[index];
d337f35e 16258+ }
2380c486 16259+
4bf69007
AM
16260+found:
16261+ if (target && (vdmt->flags & DATTR_REMAP))
16262+ *target = vdmt->target;
16263+ else if (target)
16264+ *target = device;
16265+ if (flags)
16266+ *flags = vdmt->flags;
16267+
16268+ spin_unlock(hash_lock);
2380c486
JR
16269+
16270+ return ret;
d337f35e
JR
16271+}
16272+
16273+
4bf69007
AM
16274+/* __remove_mapping()
16275+ * remove a mapping from the hash table
16276+ */
16277+static inline int __remove_mapping(struct vx_info *vxi, dev_t device,
16278+ umode_t mode)
d337f35e 16279+{
4bf69007
AM
16280+ spinlock_t *hash_lock = &dmap_main_hash_lock;
16281+ struct vs_mapping *vdm = NULL;
d337f35e
JR
16282+ int ret = 0;
16283+
4bf69007
AM
16284+ spin_lock(hash_lock);
16285+
16286+ ret = __find_mapping((vxi ? vxi->vx_id : 0), device, mode, &vdm,
16287+ NULL);
16288+ vxdprintk(VXD_CBIT(misc, 8), "__remove_mapping: %p[#%d] %08x %04x",
16289+ vxi, vxi ? vxi->vx_id : 0, device, mode);
16290+ if (ret < 0)
2380c486 16291+ goto out;
4bf69007 16292+ hlist_del(&vdm->dm_hlist);
2380c486 16293+
2380c486 16294+out:
4bf69007
AM
16295+ spin_unlock(hash_lock);
16296+ if (vdm)
16297+ kmem_cache_free(dmap_cachep, vdm);
2380c486
JR
16298+ return ret;
16299+}
16300+
16301+
2380c486 16302+
4bf69007
AM
16303+int vs_map_device(struct vx_info *vxi,
16304+ dev_t device, dev_t *target, umode_t mode)
2380c486 16305+{
4bf69007 16306+ int ret, flags = DATTR_MASK;
2380c486 16307+
4bf69007
AM
16308+ if (!vxi) {
16309+ if (target)
16310+ *target = device;
2380c486 16311+ goto out;
2380c486 16312+ }
4bf69007
AM
16313+ ret = __lookup_mapping(vxi, device, target, &flags, mode);
16314+ vxdprintk(VXD_CBIT(misc, 8), "vs_map_device: %08x target: %08x flags: %04x mode: %04x mapped=%d",
16315+ device, target ? *target : 0, flags, mode, ret);
2380c486 16316+out:
4bf69007 16317+ return (flags & DATTR_MASK);
2380c486
JR
16318+}
16319+
2380c486 16320+
4bf69007
AM
16321+
16322+static int do_set_mapping(struct vx_info *vxi,
16323+ dev_t device, dev_t target, int flags, umode_t mode)
2380c486 16324+{
4bf69007
AM
16325+ if (device) {
16326+ struct vs_mapping *new;
2380c486 16327+
4bf69007
AM
16328+ new = kmem_cache_alloc(dmap_cachep, GFP_KERNEL);
16329+ if (!new)
16330+ return -ENOMEM;
16331+
16332+ INIT_HLIST_NODE(&new->dm_hlist);
16333+ new->device = device;
16334+ new->target.target = target;
16335+ new->target.flags = flags | mode;
16336+ new->xid = (vxi ? vxi->vx_id : 0);
16337+
16338+ vxdprintk(VXD_CBIT(misc, 8), "do_set_mapping: %08x target: %08x flags: %04x", device, target, flags);
16339+ __hash_mapping(vxi, new);
16340+ } else {
16341+ struct vx_dmap_target new = {
16342+ .target = target,
16343+ .flags = flags | mode,
16344+ };
16345+ __set_default(vxi, mode, &new);
16346+ }
16347+ return 0;
2380c486
JR
16348+}
16349+
4bf69007
AM
16350+
16351+static int do_unset_mapping(struct vx_info *vxi,
16352+ dev_t device, dev_t target, int flags, umode_t mode)
2380c486 16353+{
4bf69007 16354+ int ret = -EINVAL;
763640ca 16355+
4bf69007
AM
16356+ if (device) {
16357+ ret = __remove_mapping(vxi, device, mode);
16358+ if (ret < 0)
16359+ goto out;
16360+ } else {
16361+ ret = __remove_default(vxi, mode);
16362+ if (ret < 0)
16363+ goto out;
16364+ }
2380c486 16365+
4bf69007
AM
16366+out:
16367+ return ret;
16368+}
2380c486 16369+
2380c486 16370+
4bf69007
AM
16371+static inline int __user_device(const char __user *name, dev_t *dev,
16372+ umode_t *mode)
16373+{
cc23e853 16374+ struct path path;
4bf69007 16375+ int ret;
2380c486 16376+
4bf69007
AM
16377+ if (!name) {
16378+ *dev = 0;
16379+ return 0;
16380+ }
cc23e853 16381+ ret = user_lpath(name, &path);
4bf69007
AM
16382+ if (ret)
16383+ return ret;
cc23e853
AM
16384+ if (path.dentry->d_inode) {
16385+ *dev = path.dentry->d_inode->i_rdev;
16386+ *mode = path.dentry->d_inode->i_mode;
4bf69007 16387+ }
cc23e853 16388+ path_put(&path);
4bf69007
AM
16389+ return 0;
16390+}
2380c486 16391+
4bf69007
AM
16392+static inline int __mapping_mode(dev_t device, dev_t target,
16393+ umode_t device_mode, umode_t target_mode, umode_t *mode)
16394+{
16395+ if (device)
16396+ *mode = device_mode & S_IFMT;
16397+ else if (target)
16398+ *mode = target_mode & S_IFMT;
16399+ else
16400+ return -EINVAL;
2380c486 16401+
4bf69007
AM
16402+ /* if both given, device and target mode have to match */
16403+ if (device && target &&
16404+ ((device_mode ^ target_mode) & S_IFMT))
16405+ return -EINVAL;
16406+ return 0;
16407+}
d337f35e 16408+
d337f35e 16409+
4bf69007
AM
16410+static inline int do_mapping(struct vx_info *vxi, const char __user *device_path,
16411+ const char __user *target_path, int flags, int set)
16412+{
16413+ dev_t device = ~0, target = ~0;
16414+ umode_t device_mode = 0, target_mode = 0, mode;
16415+ int ret;
2380c486 16416+
4bf69007
AM
16417+ ret = __user_device(device_path, &device, &device_mode);
16418+ if (ret)
16419+ return ret;
16420+ ret = __user_device(target_path, &target, &target_mode);
16421+ if (ret)
16422+ return ret;
2380c486 16423+
4bf69007
AM
16424+ ret = __mapping_mode(device, target,
16425+ device_mode, target_mode, &mode);
16426+ if (ret)
16427+ return ret;
2380c486 16428+
4bf69007
AM
16429+ if (set)
16430+ return do_set_mapping(vxi, device, target,
16431+ flags, mode);
16432+ else
16433+ return do_unset_mapping(vxi, device, target,
16434+ flags, mode);
d337f35e
JR
16435+}
16436+
d337f35e 16437+
4bf69007
AM
16438+int vc_set_mapping(struct vx_info *vxi, void __user *data)
16439+{
16440+ struct vcmd_set_mapping_v0 vc_data;
d337f35e 16441+
4bf69007
AM
16442+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
16443+ return -EFAULT;
d337f35e 16444+
4bf69007
AM
16445+ return do_mapping(vxi, vc_data.device, vc_data.target,
16446+ vc_data.flags, 1);
16447+}
d337f35e 16448+
4bf69007 16449+int vc_unset_mapping(struct vx_info *vxi, void __user *data)
d337f35e 16450+{
4bf69007 16451+ struct vcmd_set_mapping_v0 vc_data;
d337f35e 16452+
4bf69007
AM
16453+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
16454+ return -EFAULT;
16455+
16456+ return do_mapping(vxi, vc_data.device, vc_data.target,
16457+ vc_data.flags, 0);
d337f35e
JR
16458+}
16459+
16460+
4bf69007
AM
16461+#ifdef CONFIG_COMPAT
16462+
16463+int vc_set_mapping_x32(struct vx_info *vxi, void __user *data)
d337f35e 16464+{
4bf69007 16465+ struct vcmd_set_mapping_v0_x32 vc_data;
d337f35e 16466+
4bf69007
AM
16467+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
16468+ return -EFAULT;
16469+
16470+ return do_mapping(vxi, compat_ptr(vc_data.device_ptr),
16471+ compat_ptr(vc_data.target_ptr), vc_data.flags, 1);
d337f35e
JR
16472+}
16473+
4bf69007
AM
16474+int vc_unset_mapping_x32(struct vx_info *vxi, void __user *data)
16475+{
16476+ struct vcmd_set_mapping_v0_x32 vc_data;
16477+
16478+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
16479+ return -EFAULT;
d337f35e 16480+
4bf69007
AM
16481+ return do_mapping(vxi, compat_ptr(vc_data.device_ptr),
16482+ compat_ptr(vc_data.target_ptr), vc_data.flags, 0);
16483+}
d337f35e 16484+
4bf69007 16485+#endif /* CONFIG_COMPAT */
d337f35e 16486+
4bf69007 16487+
3261cfd5
AM
16488diff -NurpP --minimal linux-4.9.207/kernel/vserver/dlimit.c linux-4.9.207-vs2.3.9.11/kernel/vserver/dlimit.c
16489--- linux-4.9.207/kernel/vserver/dlimit.c 1970-01-01 00:00:00.000000000 +0000
16490+++ linux-4.9.207-vs2.3.9.11/kernel/vserver/dlimit.c 2018-10-20 04:58:15.000000000 +0000
b00e13aa 16491@@ -0,0 +1,528 @@
d337f35e 16492+/*
4bf69007 16493+ * linux/kernel/vserver/dlimit.c
d337f35e 16494+ *
4bf69007 16495+ * Virtual Server: Context Disk Limits
d337f35e 16496+ *
cc23e853 16497+ * Copyright (C) 2004-2009 Herbert P?tzl
d337f35e 16498+ *
4bf69007
AM
16499+ * V0.01 initial version
16500+ * V0.02 compat32 splitup
16501+ * V0.03 extended interface
d337f35e
JR
16502+ *
16503+ */
16504+
4bf69007
AM
16505+#include <linux/statfs.h>
16506+#include <linux/sched.h>
2380c486 16507+#include <linux/namei.h>
d337f35e 16508+#include <linux/vs_tag.h>
4bf69007
AM
16509+#include <linux/vs_dlimit.h>
16510+#include <linux/vserver/dlimit_cmd.h>
16511+#include <linux/slab.h>
16512+// #include <linux/gfp.h>
d337f35e 16513+
d337f35e
JR
16514+#include <asm/uaccess.h>
16515+
4bf69007 16516+/* __alloc_dl_info()
d337f35e 16517+
4bf69007
AM
16518+ * allocate an initialized dl_info struct
16519+ * doesn't make it visible (hash) */
d337f35e 16520+
61333608 16521+static struct dl_info *__alloc_dl_info(struct super_block *sb, vtag_t tag)
4bf69007
AM
16522+{
16523+ struct dl_info *new = NULL;
d337f35e 16524+
4bf69007
AM
16525+ vxdprintk(VXD_CBIT(dlim, 5),
16526+ "alloc_dl_info(%p,%d)*", sb, tag);
d337f35e 16527+
4bf69007
AM
16528+ /* would this benefit from a slab cache? */
16529+ new = kmalloc(sizeof(struct dl_info), GFP_KERNEL);
16530+ if (!new)
16531+ return 0;
d337f35e 16532+
4bf69007
AM
16533+ memset(new, 0, sizeof(struct dl_info));
16534+ new->dl_tag = tag;
16535+ new->dl_sb = sb;
16536+ // INIT_RCU_HEAD(&new->dl_rcu);
16537+ INIT_HLIST_NODE(&new->dl_hlist);
16538+ spin_lock_init(&new->dl_lock);
16539+ atomic_set(&new->dl_refcnt, 0);
16540+ atomic_set(&new->dl_usecnt, 0);
d337f35e 16541+
4bf69007 16542+ /* rest of init goes here */
d337f35e 16543+
4bf69007
AM
16544+ vxdprintk(VXD_CBIT(dlim, 4),
16545+ "alloc_dl_info(%p,%d) = %p", sb, tag, new);
16546+ return new;
16547+}
d4263eb0 16548+
4bf69007 16549+/* __dealloc_dl_info()
d337f35e 16550+
4bf69007 16551+ * final disposal of dl_info */
d337f35e 16552+
4bf69007 16553+static void __dealloc_dl_info(struct dl_info *dli)
adc1caaa 16554+{
4bf69007
AM
16555+ vxdprintk(VXD_CBIT(dlim, 4),
16556+ "dealloc_dl_info(%p)", dli);
2380c486 16557+
4bf69007
AM
16558+ dli->dl_hlist.next = LIST_POISON1;
16559+ dli->dl_tag = -1;
16560+ dli->dl_sb = 0;
2380c486 16561+
4bf69007
AM
16562+ BUG_ON(atomic_read(&dli->dl_usecnt));
16563+ BUG_ON(atomic_read(&dli->dl_refcnt));
2380c486 16564+
4bf69007 16565+ kfree(dli);
adc1caaa 16566+}
2380c486 16567+
2380c486 16568+
4bf69007 16569+/* hash table for dl_info hash */
2380c486 16570+
4bf69007 16571+#define DL_HASH_SIZE 13
2380c486 16572+
4bf69007 16573+struct hlist_head dl_info_hash[DL_HASH_SIZE];
2380c486 16574+
4bf69007 16575+static DEFINE_SPINLOCK(dl_info_hash_lock);
2380c486 16576+
d33d7b00 16577+
61333608 16578+static inline unsigned int __hashval(struct super_block *sb, vtag_t tag)
adc1caaa 16579+{
4bf69007
AM
16580+ return ((tag ^ (unsigned long)sb) % DL_HASH_SIZE);
16581+}
2380c486 16582+
2380c486 16583+
2380c486 16584+
4bf69007 16585+/* __hash_dl_info()
2380c486 16586+
4bf69007
AM
16587+ * add the dli to the global hash table
16588+ * requires the hash_lock to be held */
2380c486 16589+
4bf69007
AM
16590+static inline void __hash_dl_info(struct dl_info *dli)
16591+{
16592+ struct hlist_head *head;
d337f35e 16593+
4bf69007
AM
16594+ vxdprintk(VXD_CBIT(dlim, 6),
16595+ "__hash_dl_info: %p[#%d]", dli, dli->dl_tag);
16596+ get_dl_info(dli);
16597+ head = &dl_info_hash[__hashval(dli->dl_sb, dli->dl_tag)];
16598+ hlist_add_head_rcu(&dli->dl_hlist, head);
16599+}
d337f35e 16600+
4bf69007 16601+/* __unhash_dl_info()
3bac966d 16602+
4bf69007
AM
16603+ * remove the dli from the global hash table
16604+ * requires the hash_lock to be held */
3bac966d 16605+
4bf69007
AM
16606+static inline void __unhash_dl_info(struct dl_info *dli)
16607+{
16608+ vxdprintk(VXD_CBIT(dlim, 6),
16609+ "__unhash_dl_info: %p[#%d]", dli, dli->dl_tag);
16610+ hlist_del_rcu(&dli->dl_hlist);
16611+ put_dl_info(dli);
16612+}
3bac966d 16613+
3bac966d 16614+
4bf69007 16615+/* __lookup_dl_info()
3bac966d 16616+
4bf69007
AM
16617+ * requires the rcu_read_lock()
16618+ * doesn't increment the dl_refcnt */
3bac966d 16619+
61333608 16620+static inline struct dl_info *__lookup_dl_info(struct super_block *sb, vtag_t tag)
4bf69007
AM
16621+{
16622+ struct hlist_head *head = &dl_info_hash[__hashval(sb, tag)];
4bf69007 16623+ struct dl_info *dli;
3bac966d 16624+
b00e13aa
AM
16625+ hlist_for_each_entry_rcu(dli, head, dl_hlist) {
16626+ if (dli->dl_tag == tag && dli->dl_sb == sb)
4bf69007 16627+ return dli;
d33d7b00 16628+ }
4bf69007
AM
16629+ return NULL;
16630+}
3bac966d 16631+
3bac966d 16632+
61333608 16633+struct dl_info *locate_dl_info(struct super_block *sb, vtag_t tag)
4bf69007
AM
16634+{
16635+ struct dl_info *dli;
16636+
16637+ rcu_read_lock();
16638+ dli = get_dl_info(__lookup_dl_info(sb, tag));
16639+ vxdprintk(VXD_CBIT(dlim, 7),
16640+ "locate_dl_info(%p,#%d) = %p", sb, tag, dli);
16641+ rcu_read_unlock();
16642+ return dli;
d33d7b00 16643+}
3bac966d 16644+
4bf69007 16645+void rcu_free_dl_info(struct rcu_head *head)
d33d7b00 16646+{
4bf69007
AM
16647+ struct dl_info *dli = container_of(head, struct dl_info, dl_rcu);
16648+ int usecnt, refcnt;
3bac966d 16649+
4bf69007 16650+ BUG_ON(!dli || !head);
3bac966d 16651+
4bf69007
AM
16652+ usecnt = atomic_read(&dli->dl_usecnt);
16653+ BUG_ON(usecnt < 0);
3bac966d 16654+
4bf69007
AM
16655+ refcnt = atomic_read(&dli->dl_refcnt);
16656+ BUG_ON(refcnt < 0);
16657+
16658+ vxdprintk(VXD_CBIT(dlim, 3),
16659+ "rcu_free_dl_info(%p)", dli);
16660+ if (!usecnt)
16661+ __dealloc_dl_info(dli);
16662+ else
16663+ printk("!!! rcu didn't free\n");
d33d7b00 16664+}
3bac966d 16665+
3bac966d 16666+
4bf69007
AM
16667+
16668+
16669+static int do_addrem_dlimit(uint32_t id, const char __user *name,
16670+ uint32_t flags, int add)
d33d7b00
AM
16671+{
16672+ struct path path;
d33d7b00 16673+ int ret;
3bac966d 16674+
4bf69007 16675+ ret = user_lpath(name, &path);
d33d7b00 16676+ if (!ret) {
4bf69007
AM
16677+ struct super_block *sb;
16678+ struct dl_info *dli;
16679+
16680+ ret = -EINVAL;
16681+ if (!path.dentry->d_inode)
16682+ goto out_release;
16683+ if (!(sb = path.dentry->d_inode->i_sb))
16684+ goto out_release;
16685+
16686+ if (add) {
16687+ dli = __alloc_dl_info(sb, id);
16688+ spin_lock(&dl_info_hash_lock);
16689+
16690+ ret = -EEXIST;
16691+ if (__lookup_dl_info(sb, id))
16692+ goto out_unlock;
16693+ __hash_dl_info(dli);
16694+ dli = NULL;
16695+ } else {
16696+ spin_lock(&dl_info_hash_lock);
16697+ dli = __lookup_dl_info(sb, id);
16698+
16699+ ret = -ESRCH;
16700+ if (!dli)
16701+ goto out_unlock;
16702+ __unhash_dl_info(dli);
16703+ }
16704+ ret = 0;
16705+ out_unlock:
16706+ spin_unlock(&dl_info_hash_lock);
16707+ if (add && dli)
16708+ __dealloc_dl_info(dli);
16709+ out_release:
d33d7b00
AM
16710+ path_put(&path);
16711+ }
d33d7b00
AM
16712+ return ret;
16713+}
3bac966d 16714+
4bf69007 16715+int vc_add_dlimit(uint32_t id, void __user *data)
d33d7b00 16716+{
4bf69007 16717+ struct vcmd_ctx_dlimit_base_v0 vc_data;
3bac966d 16718+
d33d7b00
AM
16719+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
16720+ return -EFAULT;
3bac966d 16721+
4bf69007
AM
16722+ return do_addrem_dlimit(id, vc_data.name, vc_data.flags, 1);
16723+}
3bac966d 16724+
4bf69007
AM
16725+int vc_rem_dlimit(uint32_t id, void __user *data)
16726+{
16727+ struct vcmd_ctx_dlimit_base_v0 vc_data;
3bac966d 16728+
4bf69007 16729+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
d33d7b00 16730+ return -EFAULT;
4bf69007
AM
16731+
16732+ return do_addrem_dlimit(id, vc_data.name, vc_data.flags, 0);
d33d7b00 16733+}
3bac966d 16734+
4bf69007 16735+#ifdef CONFIG_COMPAT
3bac966d 16736+
4bf69007
AM
16737+int vc_add_dlimit_x32(uint32_t id, void __user *data)
16738+{
16739+ struct vcmd_ctx_dlimit_base_v0_x32 vc_data;
3bac966d 16740+
4bf69007
AM
16741+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
16742+ return -EFAULT;
d337f35e 16743+
4bf69007
AM
16744+ return do_addrem_dlimit(id,
16745+ compat_ptr(vc_data.name_ptr), vc_data.flags, 1);
16746+}
d337f35e 16747+
4bf69007 16748+int vc_rem_dlimit_x32(uint32_t id, void __user *data)
d33d7b00 16749+{
4bf69007 16750+ struct vcmd_ctx_dlimit_base_v0_x32 vc_data;
d337f35e 16751+
4bf69007
AM
16752+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
16753+ return -EFAULT;
16754+
16755+ return do_addrem_dlimit(id,
16756+ compat_ptr(vc_data.name_ptr), vc_data.flags, 0);
d33d7b00 16757+}
d337f35e 16758+
4bf69007
AM
16759+#endif /* CONFIG_COMPAT */
16760+
16761+
16762+static inline
16763+int do_set_dlimit(uint32_t id, const char __user *name,
16764+ uint32_t space_used, uint32_t space_total,
16765+ uint32_t inodes_used, uint32_t inodes_total,
16766+ uint32_t reserved, uint32_t flags)
d33d7b00 16767+{
4bf69007
AM
16768+ struct path path;
16769+ int ret;
ba86f833 16770+
4bf69007
AM
16771+ ret = user_lpath(name, &path);
16772+ if (!ret) {
16773+ struct super_block *sb;
16774+ struct dl_info *dli;
d337f35e 16775+
4bf69007
AM
16776+ ret = -EINVAL;
16777+ if (!path.dentry->d_inode)
16778+ goto out_release;
16779+ if (!(sb = path.dentry->d_inode->i_sb))
16780+ goto out_release;
d337f35e 16781+
4bf69007
AM
16782+ /* sanity checks */
16783+ if ((reserved != CDLIM_KEEP &&
16784+ reserved > 100) ||
16785+ (inodes_used != CDLIM_KEEP &&
16786+ inodes_used > inodes_total) ||
16787+ (space_used != CDLIM_KEEP &&
16788+ space_used > space_total))
16789+ goto out_release;
d337f35e 16790+
4bf69007
AM
16791+ ret = -ESRCH;
16792+ dli = locate_dl_info(sb, id);
16793+ if (!dli)
16794+ goto out_release;
ba86f833 16795+
4bf69007 16796+ spin_lock(&dli->dl_lock);
d337f35e 16797+
4bf69007
AM
16798+ if (inodes_used != CDLIM_KEEP)
16799+ dli->dl_inodes_used = inodes_used;
16800+ if (inodes_total != CDLIM_KEEP)
16801+ dli->dl_inodes_total = inodes_total;
16802+ if (space_used != CDLIM_KEEP)
16803+ dli->dl_space_used = dlimit_space_32to64(
16804+ space_used, flags, DLIMS_USED);
d337f35e 16805+
4bf69007
AM
16806+ if (space_total == CDLIM_INFINITY)
16807+ dli->dl_space_total = DLIM_INFINITY;
16808+ else if (space_total != CDLIM_KEEP)
16809+ dli->dl_space_total = dlimit_space_32to64(
16810+ space_total, flags, DLIMS_TOTAL);
78865d5b 16811+
4bf69007
AM
16812+ if (reserved != CDLIM_KEEP)
16813+ dli->dl_nrlmult = (1 << 10) * (100 - reserved) / 100;
78865d5b 16814+
4bf69007 16815+ spin_unlock(&dli->dl_lock);
d337f35e 16816+
4bf69007
AM
16817+ put_dl_info(dli);
16818+ ret = 0;
d337f35e 16819+
4bf69007
AM
16820+ out_release:
16821+ path_put(&path);
16822+ }
16823+ return ret;
16824+}
d337f35e 16825+
4bf69007
AM
16826+int vc_set_dlimit(uint32_t id, void __user *data)
16827+{
16828+ struct vcmd_ctx_dlimit_v0 vc_data;
d337f35e 16829+
4bf69007
AM
16830+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
16831+ return -EFAULT;
d337f35e 16832+
4bf69007
AM
16833+ return do_set_dlimit(id, vc_data.name,
16834+ vc_data.space_used, vc_data.space_total,
16835+ vc_data.inodes_used, vc_data.inodes_total,
16836+ vc_data.reserved, vc_data.flags);
16837+}
d337f35e 16838+
4bf69007 16839+#ifdef CONFIG_COMPAT
d337f35e 16840+
4bf69007
AM
16841+int vc_set_dlimit_x32(uint32_t id, void __user *data)
16842+{
16843+ struct vcmd_ctx_dlimit_v0_x32 vc_data;
d337f35e 16844+
4bf69007
AM
16845+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
16846+ return -EFAULT;
d337f35e 16847+
4bf69007
AM
16848+ return do_set_dlimit(id, compat_ptr(vc_data.name_ptr),
16849+ vc_data.space_used, vc_data.space_total,
16850+ vc_data.inodes_used, vc_data.inodes_total,
16851+ vc_data.reserved, vc_data.flags);
16852+}
d337f35e 16853+
4bf69007 16854+#endif /* CONFIG_COMPAT */
d337f35e 16855+
d337f35e 16856+
4bf69007
AM
16857+static inline
16858+int do_get_dlimit(uint32_t id, const char __user *name,
16859+ uint32_t *space_used, uint32_t *space_total,
16860+ uint32_t *inodes_used, uint32_t *inodes_total,
16861+ uint32_t *reserved, uint32_t *flags)
16862+{
16863+ struct path path;
16864+ int ret;
d337f35e 16865+
4bf69007
AM
16866+ ret = user_lpath(name, &path);
16867+ if (!ret) {
16868+ struct super_block *sb;
16869+ struct dl_info *dli;
d337f35e 16870+
4bf69007
AM
16871+ ret = -EINVAL;
16872+ if (!path.dentry->d_inode)
16873+ goto out_release;
16874+ if (!(sb = path.dentry->d_inode->i_sb))
16875+ goto out_release;
d337f35e 16876+
4bf69007
AM
16877+ ret = -ESRCH;
16878+ dli = locate_dl_info(sb, id);
16879+ if (!dli)
16880+ goto out_release;
d337f35e 16881+
4bf69007
AM
16882+ spin_lock(&dli->dl_lock);
16883+ *inodes_used = dli->dl_inodes_used;
16884+ *inodes_total = dli->dl_inodes_total;
d337f35e 16885+
4bf69007
AM
16886+ *space_used = dlimit_space_64to32(
16887+ dli->dl_space_used, flags, DLIMS_USED);
d337f35e 16888+
4bf69007
AM
16889+ if (dli->dl_space_total == DLIM_INFINITY)
16890+ *space_total = CDLIM_INFINITY;
16891+ else
16892+ *space_total = dlimit_space_64to32(
16893+ dli->dl_space_total, flags, DLIMS_TOTAL);
d337f35e 16894+
4bf69007
AM
16895+ *reserved = 100 - ((dli->dl_nrlmult * 100 + 512) >> 10);
16896+ spin_unlock(&dli->dl_lock);
d337f35e 16897+
4bf69007
AM
16898+ put_dl_info(dli);
16899+ ret = -EFAULT;
d337f35e 16900+
4bf69007
AM
16901+ ret = 0;
16902+ out_release:
16903+ path_put(&path);
16904+ }
16905+ return ret;
d337f35e
JR
16906+}
16907+
4bf69007
AM
16908+
16909+int vc_get_dlimit(uint32_t id, void __user *data)
d337f35e 16910+{
4bf69007 16911+ struct vcmd_ctx_dlimit_v0 vc_data;
d337f35e
JR
16912+ int ret;
16913+
2380c486 16914+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
d337f35e
JR
16915+ return -EFAULT;
16916+
4bf69007
AM
16917+ ret = do_get_dlimit(id, vc_data.name,
16918+ &vc_data.space_used, &vc_data.space_total,
16919+ &vc_data.inodes_used, &vc_data.inodes_total,
16920+ &vc_data.reserved, &vc_data.flags);
d337f35e
JR
16921+ if (ret)
16922+ return ret;
16923+
2380c486 16924+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
d337f35e
JR
16925+ return -EFAULT;
16926+ return 0;
16927+}
16928+
4bf69007 16929+#ifdef CONFIG_COMPAT
d337f35e 16930+
4bf69007 16931+int vc_get_dlimit_x32(uint32_t id, void __user *data)
d337f35e 16932+{
4bf69007 16933+ struct vcmd_ctx_dlimit_v0_x32 vc_data;
d337f35e
JR
16934+ int ret;
16935+
2380c486 16936+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
d337f35e
JR
16937+ return -EFAULT;
16938+
4bf69007
AM
16939+ ret = do_get_dlimit(id, compat_ptr(vc_data.name_ptr),
16940+ &vc_data.space_used, &vc_data.space_total,
16941+ &vc_data.inodes_used, &vc_data.inodes_total,
16942+ &vc_data.reserved, &vc_data.flags);
d337f35e
JR
16943+ if (ret)
16944+ return ret;
16945+
2380c486 16946+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
d337f35e
JR
16947+ return -EFAULT;
16948+ return 0;
16949+}
16950+
4bf69007 16951+#endif /* CONFIG_COMPAT */
ec22aa5c
AM
16952+
16953+
4bf69007 16954+void vx_vsi_statfs(struct super_block *sb, struct kstatfs *buf)
ec22aa5c 16955+{
4bf69007
AM
16956+ struct dl_info *dli;
16957+ __u64 blimit, bfree, bavail;
16958+ __u32 ifree;
ec22aa5c 16959+
4bf69007
AM
16960+ dli = locate_dl_info(sb, dx_current_tag());
16961+ if (!dli)
16962+ return;
ec22aa5c 16963+
4bf69007
AM
16964+ spin_lock(&dli->dl_lock);
16965+ if (dli->dl_inodes_total == (unsigned long)DLIM_INFINITY)
16966+ goto no_ilim;
ec22aa5c 16967+
4bf69007
AM
16968+ /* reduce max inodes available to limit */
16969+ if (buf->f_files > dli->dl_inodes_total)
16970+ buf->f_files = dli->dl_inodes_total;
ec22aa5c 16971+
4bf69007
AM
16972+ ifree = dli->dl_inodes_total - dli->dl_inodes_used;
16973+ /* reduce free inodes to min */
16974+ if (ifree < buf->f_ffree)
16975+ buf->f_ffree = ifree;
b2252bc2 16976+
4bf69007
AM
16977+no_ilim:
16978+ if (dli->dl_space_total == DLIM_INFINITY)
16979+ goto no_blim;
d337f35e 16980+
4bf69007 16981+ blimit = dli->dl_space_total >> sb->s_blocksize_bits;
d337f35e 16982+
4bf69007
AM
16983+ if (dli->dl_space_total < dli->dl_space_used)
16984+ bfree = 0;
16985+ else
16986+ bfree = (dli->dl_space_total - dli->dl_space_used)
16987+ >> sb->s_blocksize_bits;
d337f35e 16988+
4bf69007
AM
16989+ bavail = ((dli->dl_space_total >> 10) * dli->dl_nrlmult);
16990+ if (bavail < dli->dl_space_used)
16991+ bavail = 0;
16992+ else
16993+ bavail = (bavail - dli->dl_space_used)
16994+ >> sb->s_blocksize_bits;
d337f35e 16995+
4bf69007
AM
16996+ /* reduce max space available to limit */
16997+ if (buf->f_blocks > blimit)
16998+ buf->f_blocks = blimit;
d337f35e 16999+
4bf69007
AM
17000+ /* reduce free space to min */
17001+ if (bfree < buf->f_bfree)
17002+ buf->f_bfree = bfree;
d337f35e 17003+
4bf69007
AM
17004+ /* reduce avail space to min */
17005+ if (bavail < buf->f_bavail)
17006+ buf->f_bavail = bavail;
d337f35e 17007+
4bf69007
AM
17008+no_blim:
17009+ spin_unlock(&dli->dl_lock);
17010+ put_dl_info(dli);
d337f35e 17011+
4bf69007 17012+ return;
d337f35e
JR
17013+}
17014+
4bf69007 17015+#include <linux/module.h>
d337f35e 17016+
4bf69007
AM
17017+EXPORT_SYMBOL_GPL(locate_dl_info);
17018+EXPORT_SYMBOL_GPL(rcu_free_dl_info);
e3afe727 17019+
3261cfd5
AM
17020diff -NurpP --minimal linux-4.9.207/kernel/vserver/helper.c linux-4.9.207-vs2.3.9.11/kernel/vserver/helper.c
17021--- linux-4.9.207/kernel/vserver/helper.c 1970-01-01 00:00:00.000000000 +0000
17022+++ linux-4.9.207-vs2.3.9.11/kernel/vserver/helper.c 2018-10-20 04:58:15.000000000 +0000
09be7631 17023@@ -0,0 +1,242 @@
4bf69007
AM
17024+/*
17025+ * linux/kernel/vserver/helper.c
17026+ *
17027+ * Virtual Context Support
17028+ *
cc23e853 17029+ * Copyright (C) 2004-2007 Herbert P?tzl
4bf69007
AM
17030+ *
17031+ * V0.01 basic helper
17032+ *
17033+ */
e3afe727 17034+
4bf69007
AM
17035+#include <linux/kmod.h>
17036+#include <linux/reboot.h>
17037+#include <linux/vs_context.h>
17038+#include <linux/vs_network.h>
17039+#include <linux/vserver/signal.h>
e3afe727 17040+
4bf69007
AM
17041+
17042+char vshelper_path[255] = "/sbin/vshelper";
17043+
17044+static int vshelper_init(struct subprocess_info *info, struct cred *new_cred)
17045+{
09be7631 17046+ current->flags &= ~PF_NO_SETAFFINITY;
4bf69007 17047+ return 0;
d337f35e
JR
17048+}
17049+
09be7631
JR
17050+static int vs_call_usermodehelper(char *path, char **argv, char **envp, int wait)
17051+{
17052+ struct subprocess_info *info;
17053+ gfp_t gfp_mask = (wait == UMH_NO_WAIT) ? GFP_ATOMIC : GFP_KERNEL;
17054+
17055+ info = call_usermodehelper_setup(path, argv, envp, gfp_mask,
17056+ vshelper_init, NULL, NULL);
17057+ if (info == NULL)
17058+ return -ENOMEM;
17059+
17060+ return call_usermodehelper_exec(info, wait);
17061+}
17062+
4bf69007 17063+static int do_vshelper(char *name, char *argv[], char *envp[], int sync)
d337f35e 17064+{
4bf69007 17065+ int ret;
e3afe727 17066+
09be7631
JR
17067+ if ((ret = vs_call_usermodehelper(name, argv, envp,
17068+ sync ? UMH_WAIT_PROC : UMH_WAIT_EXEC))) {
4bf69007
AM
17069+ printk(KERN_WARNING "%s: (%s %s) returned %s with %d\n",
17070+ name, argv[1], argv[2],
17071+ sync ? "sync" : "async", ret);
17072+ }
17073+ vxdprintk(VXD_CBIT(switch, 4),
17074+ "%s: (%s %s) returned %s with %d",
17075+ name, argv[1], argv[2], sync ? "sync" : "async", ret);
17076+ return ret;
17077+}
e3afe727 17078+
4bf69007
AM
17079+/*
17080+ * vshelper path is set via /proc/sys
17081+ * invoked by vserver sys_reboot(), with
17082+ * the following arguments
17083+ *
17084+ * argv [0] = vshelper_path;
17085+ * argv [1] = action: "restart", "halt", "poweroff", ...
17086+ * argv [2] = context identifier
17087+ *
17088+ * envp [*] = type-specific parameters
17089+ */
e3afe727 17090+
4bf69007
AM
17091+long vs_reboot_helper(struct vx_info *vxi, int cmd, void __user *arg)
17092+{
17093+ char id_buf[8], cmd_buf[16];
17094+ char uid_buf[16], pid_buf[16];
17095+ int ret;
e3afe727 17096+
4bf69007
AM
17097+ char *argv[] = {vshelper_path, NULL, id_buf, 0};
17098+ char *envp[] = {"HOME=/", "TERM=linux",
17099+ "PATH=/sbin:/usr/sbin:/bin:/usr/bin",
17100+ uid_buf, pid_buf, cmd_buf, 0};
e3afe727 17101+
4bf69007
AM
17102+ if (vx_info_state(vxi, VXS_HELPER))
17103+ return -EAGAIN;
17104+ vxi->vx_state |= VXS_HELPER;
7b17263b 17105+
4bf69007 17106+ snprintf(id_buf, sizeof(id_buf), "%d", vxi->vx_id);
d337f35e 17107+
4bf69007 17108+ snprintf(cmd_buf, sizeof(cmd_buf), "VS_CMD=%08x", cmd);
8ce283e1
AM
17109+ snprintf(uid_buf, sizeof(uid_buf), "VS_UID=%d",
17110+ from_kuid(&init_user_ns, current_uid()));
4bf69007 17111+ snprintf(pid_buf, sizeof(pid_buf), "VS_PID=%d", current->pid);
e3afe727 17112+
4bf69007
AM
17113+ switch (cmd) {
17114+ case LINUX_REBOOT_CMD_RESTART:
17115+ argv[1] = "restart";
17116+ break;
07a627a5 17117+
4bf69007
AM
17118+ case LINUX_REBOOT_CMD_HALT:
17119+ argv[1] = "halt";
17120+ break;
e3afe727 17121+
4bf69007
AM
17122+ case LINUX_REBOOT_CMD_POWER_OFF:
17123+ argv[1] = "poweroff";
17124+ break;
d337f35e 17125+
4bf69007
AM
17126+ case LINUX_REBOOT_CMD_SW_SUSPEND:
17127+ argv[1] = "swsusp";
17128+ break;
d337f35e 17129+
4bf69007
AM
17130+ case LINUX_REBOOT_CMD_OOM:
17131+ argv[1] = "oom";
17132+ break;
d337f35e 17133+
4bf69007
AM
17134+ default:
17135+ vxi->vx_state &= ~VXS_HELPER;
17136+ return 0;
d337f35e 17137+ }
4bf69007
AM
17138+
17139+ ret = do_vshelper(vshelper_path, argv, envp, 0);
17140+ vxi->vx_state &= ~VXS_HELPER;
17141+ __wakeup_vx_info(vxi);
17142+ return (ret) ? -EPERM : 0;
d337f35e
JR
17143+}
17144+
4bf69007
AM
17145+
17146+long vs_reboot(unsigned int cmd, void __user *arg)
d337f35e 17147+{
4bf69007
AM
17148+ struct vx_info *vxi = current_vx_info();
17149+ long ret = 0;
d337f35e 17150+
4bf69007
AM
17151+ vxdprintk(VXD_CBIT(misc, 5),
17152+ "vs_reboot(%p[#%d],%u)",
17153+ vxi, vxi ? vxi->vx_id : 0, cmd);
17154+
17155+ ret = vs_reboot_helper(vxi, cmd, arg);
17156+ if (ret)
17157+ return ret;
17158+
17159+ vxi->reboot_cmd = cmd;
17160+ if (vx_info_flags(vxi, VXF_REBOOT_KILL, 0)) {
17161+ switch (cmd) {
17162+ case LINUX_REBOOT_CMD_RESTART:
17163+ case LINUX_REBOOT_CMD_HALT:
17164+ case LINUX_REBOOT_CMD_POWER_OFF:
17165+ vx_info_kill(vxi, 0, SIGKILL);
17166+ vx_info_kill(vxi, 1, SIGKILL);
17167+ default:
17168+ break;
17169+ }
d337f35e 17170+ }
4bf69007 17171+ return 0;
d337f35e
JR
17172+}
17173+
4bf69007
AM
17174+long vs_oom_action(unsigned int cmd)
17175+{
17176+ struct vx_info *vxi = current_vx_info();
17177+ long ret = 0;
d337f35e 17178+
4bf69007
AM
17179+ vxdprintk(VXD_CBIT(misc, 5),
17180+ "vs_oom_action(%p[#%d],%u)",
17181+ vxi, vxi ? vxi->vx_id : 0, cmd);
d337f35e 17182+
4bf69007
AM
17183+ ret = vs_reboot_helper(vxi, cmd, NULL);
17184+ if (ret)
17185+ return ret;
d337f35e 17186+
4bf69007
AM
17187+ vxi->reboot_cmd = cmd;
17188+ if (vx_info_flags(vxi, VXF_REBOOT_KILL, 0)) {
17189+ vx_info_kill(vxi, 0, SIGKILL);
17190+ vx_info_kill(vxi, 1, SIGKILL);
17191+ }
17192+ return 0;
17193+}
d337f35e 17194+
4bf69007
AM
17195+/*
17196+ * argv [0] = vshelper_path;
17197+ * argv [1] = action: "startup", "shutdown"
17198+ * argv [2] = context identifier
17199+ *
17200+ * envp [*] = type-specific parameters
17201+ */
d337f35e 17202+
4bf69007 17203+long vs_state_change(struct vx_info *vxi, unsigned int cmd)
d337f35e 17204+{
4bf69007
AM
17205+ char id_buf[8], cmd_buf[16];
17206+ char *argv[] = {vshelper_path, NULL, id_buf, 0};
17207+ char *envp[] = {"HOME=/", "TERM=linux",
17208+ "PATH=/sbin:/usr/sbin:/bin:/usr/bin", cmd_buf, 0};
17209+
17210+ if (!vx_info_flags(vxi, VXF_SC_HELPER, 0))
17211+ return 0;
17212+
17213+ snprintf(id_buf, sizeof(id_buf), "%d", vxi->vx_id);
17214+ snprintf(cmd_buf, sizeof(cmd_buf), "VS_CMD=%08x", cmd);
17215+
17216+ switch (cmd) {
17217+ case VSC_STARTUP:
17218+ argv[1] = "startup";
17219+ break;
17220+ case VSC_SHUTDOWN:
17221+ argv[1] = "shutdown";
17222+ break;
17223+ default:
17224+ return 0;
17225+ }
17226+
17227+ return do_vshelper(vshelper_path, argv, envp, 1);
d337f35e
JR
17228+}
17229+
d337f35e 17230+
4bf69007
AM
17231+/*
17232+ * argv [0] = vshelper_path;
17233+ * argv [1] = action: "netup", "netdown"
17234+ * argv [2] = context identifier
17235+ *
17236+ * envp [*] = type-specific parameters
17237+ */
17238+
17239+long vs_net_change(struct nx_info *nxi, unsigned int cmd)
17240+{
17241+ char id_buf[8], cmd_buf[16];
17242+ char *argv[] = {vshelper_path, NULL, id_buf, 0};
17243+ char *envp[] = {"HOME=/", "TERM=linux",
17244+ "PATH=/sbin:/usr/sbin:/bin:/usr/bin", cmd_buf, 0};
17245+
17246+ if (!nx_info_flags(nxi, NXF_SC_HELPER, 0))
17247+ return 0;
17248+
17249+ snprintf(id_buf, sizeof(id_buf), "%d", nxi->nx_id);
17250+ snprintf(cmd_buf, sizeof(cmd_buf), "VS_CMD=%08x", cmd);
17251+
17252+ switch (cmd) {
17253+ case VSC_NETUP:
17254+ argv[1] = "netup";
17255+ break;
17256+ case VSC_NETDOWN:
17257+ argv[1] = "netdown";
17258+ break;
17259+ default:
17260+ return 0;
17261+ }
17262+
17263+ return do_vshelper(vshelper_path, argv, envp, 1);
17264+}
d337f35e 17265+
3261cfd5
AM
17266diff -NurpP --minimal linux-4.9.207/kernel/vserver/history.c linux-4.9.207-vs2.3.9.11/kernel/vserver/history.c
17267--- linux-4.9.207/kernel/vserver/history.c 1970-01-01 00:00:00.000000000 +0000
17268+++ linux-4.9.207-vs2.3.9.11/kernel/vserver/history.c 2018-10-20 04:58:15.000000000 +0000
4bf69007 17269@@ -0,0 +1,258 @@
d337f35e 17270+/*
4bf69007 17271+ * kernel/vserver/history.c
d337f35e 17272+ *
4bf69007 17273+ * Virtual Context History Backtrace
d337f35e 17274+ *
cc23e853 17275+ * Copyright (C) 2004-2007 Herbert P?tzl
d337f35e 17276+ *
4bf69007
AM
17277+ * V0.01 basic structure
17278+ * V0.02 hash/unhash and trace
17279+ * V0.03 preemption fixes
d337f35e
JR
17280+ *
17281+ */
17282+
4bf69007
AM
17283+#include <linux/module.h>
17284+#include <asm/uaccess.h>
d337f35e 17285+
4bf69007
AM
17286+#include <linux/vserver/context.h>
17287+#include <linux/vserver/debug.h>
17288+#include <linux/vserver/debug_cmd.h>
17289+#include <linux/vserver/history.h>
d337f35e
JR
17290+
17291+
4bf69007
AM
17292+#ifdef CONFIG_VSERVER_HISTORY
17293+#define VXH_SIZE CONFIG_VSERVER_HISTORY_SIZE
17294+#else
17295+#define VXH_SIZE 64
17296+#endif
d337f35e 17297+
4bf69007
AM
17298+struct _vx_history {
17299+ unsigned int counter;
2380c486 17300+
4bf69007
AM
17301+ struct _vx_hist_entry entry[VXH_SIZE + 1];
17302+};
2380c486 17303+
2380c486 17304+
4bf69007 17305+DEFINE_PER_CPU(struct _vx_history, vx_history_buffer);
2380c486 17306+
4bf69007 17307+unsigned volatile int vxh_active = 1;
2380c486 17308+
4bf69007 17309+static atomic_t sequence = ATOMIC_INIT(0);
2380c486 17310+
2380c486 17311+
4bf69007 17312+/* vxh_advance()
2380c486 17313+
4bf69007
AM
17314+ * requires disabled preemption */
17315+
17316+struct _vx_hist_entry *vxh_advance(void *loc)
2380c486 17317+{
4bf69007
AM
17318+ unsigned int cpu = smp_processor_id();
17319+ struct _vx_history *hist = &per_cpu(vx_history_buffer, cpu);
17320+ struct _vx_hist_entry *entry;
17321+ unsigned int index;
17322+
17323+ index = vxh_active ? (hist->counter++ % VXH_SIZE) : VXH_SIZE;
17324+ entry = &hist->entry[index];
17325+
17326+ entry->seq = atomic_inc_return(&sequence);
17327+ entry->loc = loc;
17328+ return entry;
2380c486
JR
17329+}
17330+
4bf69007 17331+EXPORT_SYMBOL_GPL(vxh_advance);
2380c486 17332+
2380c486 17333+
4bf69007 17334+#define VXH_LOC_FMTS "(#%04x,*%d):%p"
2380c486 17335+
4bf69007 17336+#define VXH_LOC_ARGS(e) (e)->seq, cpu, (e)->loc
2380c486 17337+
2380c486 17338+
4bf69007 17339+#define VXH_VXI_FMTS "%p[#%d,%d.%d]"
2380c486 17340+
4bf69007
AM
17341+#define VXH_VXI_ARGS(e) (e)->vxi.ptr, \
17342+ (e)->vxi.ptr ? (e)->vxi.xid : 0, \
17343+ (e)->vxi.ptr ? (e)->vxi.usecnt : 0, \
17344+ (e)->vxi.ptr ? (e)->vxi.tasks : 0
17345+
17346+void vxh_dump_entry(struct _vx_hist_entry *e, unsigned cpu)
2380c486 17347+{
4bf69007
AM
17348+ switch (e->type) {
17349+ case VXH_THROW_OOPS:
17350+ printk( VXH_LOC_FMTS " oops \n", VXH_LOC_ARGS(e));
17351+ break;
2380c486 17352+
4bf69007
AM
17353+ case VXH_GET_VX_INFO:
17354+ case VXH_PUT_VX_INFO:
17355+ printk( VXH_LOC_FMTS " %s_vx_info " VXH_VXI_FMTS "\n",
17356+ VXH_LOC_ARGS(e),
17357+ (e->type == VXH_GET_VX_INFO) ? "get" : "put",
17358+ VXH_VXI_ARGS(e));
17359+ break;
2380c486 17360+
4bf69007
AM
17361+ case VXH_INIT_VX_INFO:
17362+ case VXH_SET_VX_INFO:
17363+ case VXH_CLR_VX_INFO:
17364+ printk( VXH_LOC_FMTS " %s_vx_info " VXH_VXI_FMTS " @%p\n",
17365+ VXH_LOC_ARGS(e),
17366+ (e->type == VXH_INIT_VX_INFO) ? "init" :
17367+ ((e->type == VXH_SET_VX_INFO) ? "set" : "clr"),
17368+ VXH_VXI_ARGS(e), e->sc.data);
17369+ break;
2380c486 17370+
4bf69007
AM
17371+ case VXH_CLAIM_VX_INFO:
17372+ case VXH_RELEASE_VX_INFO:
17373+ printk( VXH_LOC_FMTS " %s_vx_info " VXH_VXI_FMTS " @%p\n",
17374+ VXH_LOC_ARGS(e),
17375+ (e->type == VXH_CLAIM_VX_INFO) ? "claim" : "release",
17376+ VXH_VXI_ARGS(e), e->sc.data);
17377+ break;
2380c486 17378+
4bf69007
AM
17379+ case VXH_ALLOC_VX_INFO:
17380+ case VXH_DEALLOC_VX_INFO:
17381+ printk( VXH_LOC_FMTS " %s_vx_info " VXH_VXI_FMTS "\n",
17382+ VXH_LOC_ARGS(e),
17383+ (e->type == VXH_ALLOC_VX_INFO) ? "alloc" : "dealloc",
17384+ VXH_VXI_ARGS(e));
17385+ break;
2380c486 17386+
4bf69007
AM
17387+ case VXH_HASH_VX_INFO:
17388+ case VXH_UNHASH_VX_INFO:
17389+ printk( VXH_LOC_FMTS " __%s_vx_info " VXH_VXI_FMTS "\n",
17390+ VXH_LOC_ARGS(e),
17391+ (e->type == VXH_HASH_VX_INFO) ? "hash" : "unhash",
17392+ VXH_VXI_ARGS(e));
17393+ break;
2380c486 17394+
4bf69007
AM
17395+ case VXH_LOC_VX_INFO:
17396+ case VXH_LOOKUP_VX_INFO:
17397+ case VXH_CREATE_VX_INFO:
17398+ printk( VXH_LOC_FMTS " __%s_vx_info [#%d] -> " VXH_VXI_FMTS "\n",
17399+ VXH_LOC_ARGS(e),
17400+ (e->type == VXH_CREATE_VX_INFO) ? "create" :
17401+ ((e->type == VXH_LOC_VX_INFO) ? "loc" : "lookup"),
17402+ e->ll.arg, VXH_VXI_ARGS(e));
17403+ break;
2380c486
JR
17404+ }
17405+}
17406+
4bf69007
AM
17407+static void __vxh_dump_history(void)
17408+{
17409+ unsigned int i, cpu;
d337f35e 17410+
4bf69007
AM
17411+ printk("History:\tSEQ: %8x\tNR_CPUS: %d\n",
17412+ atomic_read(&sequence), NR_CPUS);
d337f35e 17413+
4bf69007
AM
17414+ for (i = 0; i < VXH_SIZE; i++) {
17415+ for_each_online_cpu(cpu) {
17416+ struct _vx_history *hist =
17417+ &per_cpu(vx_history_buffer, cpu);
17418+ unsigned int index = (hist->counter - i) % VXH_SIZE;
17419+ struct _vx_hist_entry *entry = &hist->entry[index];
d337f35e 17420+
4bf69007
AM
17421+ vxh_dump_entry(entry, cpu);
17422+ }
17423+ }
17424+}
d337f35e 17425+
4bf69007
AM
17426+void vxh_dump_history(void)
17427+{
17428+ vxh_active = 0;
17429+#ifdef CONFIG_SMP
17430+ local_irq_enable();
17431+ smp_send_stop();
17432+ local_irq_disable();
17433+#endif
17434+ __vxh_dump_history();
17435+}
d337f35e 17436+
d337f35e 17437+
4bf69007 17438+/* vserver syscall commands below here */
d337f35e 17439+
d337f35e 17440+
4bf69007
AM
17441+int vc_dump_history(uint32_t id)
17442+{
17443+ vxh_active = 0;
17444+ __vxh_dump_history();
17445+ vxh_active = 1;
2380c486 17446+
4bf69007 17447+ return 0;
d337f35e
JR
17448+}
17449+
d337f35e 17450+
4bf69007
AM
17451+int do_read_history(struct __user _vx_hist_entry *data,
17452+ int cpu, uint32_t *index, uint32_t *count)
d337f35e 17453+{
4bf69007
AM
17454+ int pos, ret = 0;
17455+ struct _vx_history *hist = &per_cpu(vx_history_buffer, cpu);
17456+ int end = hist->counter;
17457+ int start = end - VXH_SIZE + 2;
17458+ int idx = *index;
d337f35e 17459+
4bf69007
AM
17460+ /* special case: get current pos */
17461+ if (!*count) {
17462+ *index = end;
17463+ return 0;
17464+ }
d337f35e 17465+
4bf69007
AM
17466+ /* have we lost some data? */
17467+ if (idx < start)
17468+ idx = start;
d337f35e 17469+
4bf69007
AM
17470+ for (pos = 0; (pos < *count) && (idx < end); pos++, idx++) {
17471+ struct _vx_hist_entry *entry =
17472+ &hist->entry[idx % VXH_SIZE];
2380c486 17473+
4bf69007
AM
17474+ /* send entry to userspace */
17475+ ret = copy_to_user(&data[pos], entry, sizeof(*entry));
17476+ if (ret)
17477+ break;
17478+ }
17479+ /* save new index and count */
17480+ *index = idx;
17481+ *count = pos;
17482+ return ret ? ret : (*index < end);
d337f35e
JR
17483+}
17484+
4bf69007 17485+int vc_read_history(uint32_t id, void __user *data)
d337f35e 17486+{
4bf69007
AM
17487+ struct vcmd_read_history_v0 vc_data;
17488+ int ret;
d337f35e 17489+
4bf69007
AM
17490+ if (id >= NR_CPUS)
17491+ return -EINVAL;
d337f35e 17492+
4bf69007
AM
17493+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
17494+ return -EFAULT;
d337f35e 17495+
4bf69007
AM
17496+ ret = do_read_history((struct __user _vx_hist_entry *)vc_data.data,
17497+ id, &vc_data.index, &vc_data.count);
d337f35e 17498+
4bf69007
AM
17499+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
17500+ return -EFAULT;
17501+ return ret;
d337f35e
JR
17502+}
17503+
4bf69007 17504+#ifdef CONFIG_COMPAT
d337f35e 17505+
4bf69007 17506+int vc_read_history_x32(uint32_t id, void __user *data)
d337f35e 17507+{
4bf69007
AM
17508+ struct vcmd_read_history_v0_x32 vc_data;
17509+ int ret;
d337f35e 17510+
4bf69007
AM
17511+ if (id >= NR_CPUS)
17512+ return -EINVAL;
d337f35e 17513+
4bf69007
AM
17514+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
17515+ return -EFAULT;
2380c486 17516+
4bf69007
AM
17517+ ret = do_read_history((struct __user _vx_hist_entry *)
17518+ compat_ptr(vc_data.data_ptr),
17519+ id, &vc_data.index, &vc_data.count);
d337f35e 17520+
4bf69007
AM
17521+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
17522+ return -EFAULT;
17523+ return ret;
17524+}
d337f35e 17525+
4bf69007 17526+#endif /* CONFIG_COMPAT */
d337f35e 17527+
3261cfd5
AM
17528diff -NurpP --minimal linux-4.9.207/kernel/vserver/inet.c linux-4.9.207-vs2.3.9.11/kernel/vserver/inet.c
17529--- linux-4.9.207/kernel/vserver/inet.c 1970-01-01 00:00:00.000000000 +0000
17530+++ linux-4.9.207-vs2.3.9.11/kernel/vserver/inet.c 2018-10-20 04:58:15.000000000 +0000
7a9e40b8 17531@@ -0,0 +1,236 @@
d337f35e 17532+
4bf69007
AM
17533+#include <linux/in.h>
17534+#include <linux/inetdevice.h>
17535+#include <linux/export.h>
17536+#include <linux/vs_inet.h>
17537+#include <linux/vs_inet6.h>
17538+#include <linux/vserver/debug.h>
17539+#include <net/route.h>
17540+#include <net/addrconf.h>
d337f35e
JR
17541+
17542+
4bf69007 17543+int nx_v4_addr_conflict(struct nx_info *nxi1, struct nx_info *nxi2)
d337f35e 17544+{
4bf69007
AM
17545+ int ret = 0;
17546+
17547+ if (!nxi1 || !nxi2 || nxi1 == nxi2)
17548+ ret = 1;
17549+ else {
17550+ struct nx_addr_v4 *ptr;
7a9e40b8 17551+ unsigned long irqflags;
d337f35e 17552+
7a9e40b8 17553+ spin_lock_irqsave(&nxi1->addr_lock, irqflags);
4bf69007
AM
17554+ for (ptr = &nxi1->v4; ptr; ptr = ptr->next) {
17555+ if (v4_nx_addr_in_nx_info(nxi2, ptr, -1)) {
17556+ ret = 1;
17557+ break;
17558+ }
17559+ }
7a9e40b8 17560+ spin_unlock_irqrestore(&nxi1->addr_lock, irqflags);
4bf69007 17561+ }
d337f35e 17562+
4bf69007
AM
17563+ vxdprintk(VXD_CBIT(net, 2),
17564+ "nx_v4_addr_conflict(%p,%p): %d",
17565+ nxi1, nxi2, ret);
d337f35e 17566+
4bf69007
AM
17567+ return ret;
17568+}
d337f35e 17569+
d337f35e 17570+
4bf69007
AM
17571+#ifdef CONFIG_IPV6
17572+
17573+int nx_v6_addr_conflict(struct nx_info *nxi1, struct nx_info *nxi2)
d337f35e 17574+{
4bf69007 17575+ int ret = 0;
d337f35e 17576+
4bf69007
AM
17577+ if (!nxi1 || !nxi2 || nxi1 == nxi2)
17578+ ret = 1;
17579+ else {
17580+ struct nx_addr_v6 *ptr;
7a9e40b8 17581+ unsigned long irqflags;
d337f35e 17582+
7a9e40b8 17583+ spin_lock_irqsave(&nxi1->addr_lock, irqflags);
4bf69007
AM
17584+ for (ptr = &nxi1->v6; ptr; ptr = ptr->next) {
17585+ if (v6_nx_addr_in_nx_info(nxi2, ptr, -1)) {
17586+ ret = 1;
17587+ break;
17588+ }
17589+ }
7a9e40b8 17590+ spin_unlock_irqrestore(&nxi1->addr_lock, irqflags);
4bf69007 17591+ }
d337f35e 17592+
4bf69007
AM
17593+ vxdprintk(VXD_CBIT(net, 2),
17594+ "nx_v6_addr_conflict(%p,%p): %d",
17595+ nxi1, nxi2, ret);
d337f35e 17596+
4bf69007
AM
17597+ return ret;
17598+}
d337f35e 17599+
4bf69007 17600+#endif
d337f35e 17601+
4bf69007 17602+int v4_dev_in_nx_info(struct net_device *dev, struct nx_info *nxi)
d337f35e 17603+{
4bf69007
AM
17604+ struct in_device *in_dev;
17605+ struct in_ifaddr **ifap;
17606+ struct in_ifaddr *ifa;
17607+ int ret = 0;
d337f35e 17608+
4bf69007
AM
17609+ if (!dev)
17610+ goto out;
17611+ in_dev = in_dev_get(dev);
17612+ if (!in_dev)
17613+ goto out;
d337f35e 17614+
4bf69007
AM
17615+ for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
17616+ ifap = &ifa->ifa_next) {
17617+ if (v4_addr_in_nx_info(nxi, ifa->ifa_local, NXA_MASK_SHOW)) {
17618+ ret = 1;
17619+ break;
17620+ }
17621+ }
17622+ in_dev_put(in_dev);
17623+out:
17624+ return ret;
d337f35e
JR
17625+}
17626+
17627+
4bf69007 17628+#ifdef CONFIG_IPV6
d337f35e 17629+
4bf69007 17630+int v6_dev_in_nx_info(struct net_device *dev, struct nx_info *nxi)
d337f35e 17631+{
4bf69007
AM
17632+ struct inet6_dev *in_dev;
17633+ struct inet6_ifaddr *ifa;
17634+ int ret = 0;
d337f35e 17635+
4bf69007
AM
17636+ if (!dev)
17637+ goto out;
17638+ in_dev = in6_dev_get(dev);
17639+ if (!in_dev)
17640+ goto out;
d337f35e 17641+
4bf69007
AM
17642+ // for (ifap = &in_dev->addr_list; (ifa = *ifap) != NULL;
17643+ list_for_each_entry(ifa, &in_dev->addr_list, if_list) {
17644+ if (v6_addr_in_nx_info(nxi, &ifa->addr, -1)) {
17645+ ret = 1;
17646+ break;
17647+ }
d337f35e 17648+ }
4bf69007
AM
17649+ in6_dev_put(in_dev);
17650+out:
17651+ return ret;
d337f35e
JR
17652+}
17653+
4bf69007 17654+#endif
d337f35e 17655+
4bf69007
AM
17656+int dev_in_nx_info(struct net_device *dev, struct nx_info *nxi)
17657+{
17658+ int ret = 1;
d337f35e 17659+
4bf69007
AM
17660+ if (!nxi)
17661+ goto out;
17662+ if (nxi->v4.type && v4_dev_in_nx_info(dev, nxi))
17663+ goto out;
17664+#ifdef CONFIG_IPV6
17665+ ret = 2;
17666+ if (nxi->v6.type && v6_dev_in_nx_info(dev, nxi))
17667+ goto out;
17668+#endif
17669+ ret = 0;
17670+out:
17671+ vxdprintk(VXD_CBIT(net, 3),
17672+ "dev_in_nx_info(%p,%p[#%d]) = %d",
17673+ dev, nxi, nxi ? nxi->nx_id : 0, ret);
17674+ return ret;
17675+}
d337f35e 17676+
4bf69007
AM
17677+struct rtable *ip_v4_find_src(struct net *net, struct nx_info *nxi,
17678+ struct flowi4 *fl4)
d337f35e 17679+{
4bf69007 17680+ struct rtable *rt;
d337f35e 17681+
4bf69007
AM
17682+ if (!nxi)
17683+ return NULL;
d337f35e 17684+
4bf69007
AM
17685+ /* FIXME: handle lback only case */
17686+ if (!NX_IPV4(nxi))
17687+ return ERR_PTR(-EPERM);
d337f35e 17688+
4bf69007
AM
17689+ vxdprintk(VXD_CBIT(net, 4),
17690+ "ip_v4_find_src(%p[#%u]) " NIPQUAD_FMT " -> " NIPQUAD_FMT,
17691+ nxi, nxi ? nxi->nx_id : 0,
17692+ NIPQUAD(fl4->saddr), NIPQUAD(fl4->daddr));
d337f35e 17693+
4bf69007
AM
17694+ /* single IP is unconditional */
17695+ if (nx_info_flags(nxi, NXF_SINGLE_IP, 0) &&
17696+ (fl4->saddr == INADDR_ANY))
17697+ fl4->saddr = nxi->v4.ip[0].s_addr;
d337f35e 17698+
4bf69007
AM
17699+ if (fl4->saddr == INADDR_ANY) {
17700+ struct nx_addr_v4 *ptr;
17701+ __be32 found = 0;
17702+
17703+ rt = __ip_route_output_key(net, fl4);
17704+ if (!IS_ERR(rt)) {
17705+ found = fl4->saddr;
17706+ ip_rt_put(rt);
17707+ vxdprintk(VXD_CBIT(net, 4),
17708+ "ip_v4_find_src(%p[#%u]) rok[%u]: " NIPQUAD_FMT,
17709+ nxi, nxi ? nxi->nx_id : 0, fl4->flowi4_oif, NIPQUAD(found));
17710+ if (v4_addr_in_nx_info(nxi, found, NXA_MASK_BIND))
17711+ goto found;
17712+ }
d337f35e 17713+
8d50a2ea 17714+ WARN_ON_ONCE(in_irq());
b00e13aa 17715+ spin_lock_bh(&nxi->addr_lock);
4bf69007
AM
17716+ for (ptr = &nxi->v4; ptr; ptr = ptr->next) {
17717+ __be32 primary = ptr->ip[0].s_addr;
17718+ __be32 mask = ptr->mask.s_addr;
17719+ __be32 neta = primary & mask;
d337f35e 17720+
4bf69007
AM
17721+ vxdprintk(VXD_CBIT(net, 4), "ip_v4_find_src(%p[#%u]) chk: "
17722+ NIPQUAD_FMT "/" NIPQUAD_FMT "/" NIPQUAD_FMT,
17723+ nxi, nxi ? nxi->nx_id : 0, NIPQUAD(primary),
17724+ NIPQUAD(mask), NIPQUAD(neta));
17725+ if ((found & mask) != neta)
17726+ continue;
d337f35e 17727+
4bf69007
AM
17728+ fl4->saddr = primary;
17729+ rt = __ip_route_output_key(net, fl4);
17730+ vxdprintk(VXD_CBIT(net, 4),
17731+ "ip_v4_find_src(%p[#%u]) rok[%u]: " NIPQUAD_FMT,
17732+ nxi, nxi ? nxi->nx_id : 0, fl4->flowi4_oif, NIPQUAD(primary));
17733+ if (!IS_ERR(rt)) {
17734+ found = fl4->saddr;
17735+ ip_rt_put(rt);
17736+ if (found == primary)
5cb1760b 17737+ goto found_unlock;
4bf69007
AM
17738+ }
17739+ }
17740+ /* still no source ip? */
17741+ found = ipv4_is_loopback(fl4->daddr)
17742+ ? IPI_LOOPBACK : nxi->v4.ip[0].s_addr;
5cb1760b 17743+ found_unlock:
b00e13aa 17744+ spin_unlock_bh(&nxi->addr_lock);
4bf69007
AM
17745+ found:
17746+ /* assign src ip to flow */
17747+ fl4->saddr = found;
17748+
17749+ } else {
17750+ if (!v4_addr_in_nx_info(nxi, fl4->saddr, NXA_MASK_BIND))
17751+ return ERR_PTR(-EPERM);
17752+ }
d337f35e 17753+
4bf69007
AM
17754+ if (nx_info_flags(nxi, NXF_LBACK_REMAP, 0)) {
17755+ if (ipv4_is_loopback(fl4->daddr))
17756+ fl4->daddr = nxi->v4_lback.s_addr;
17757+ if (ipv4_is_loopback(fl4->saddr))
17758+ fl4->saddr = nxi->v4_lback.s_addr;
17759+ } else if (ipv4_is_loopback(fl4->daddr) &&
17760+ !nx_info_flags(nxi, NXF_LBACK_ALLOW, 0))
17761+ return ERR_PTR(-EPERM);
d337f35e 17762+
4bf69007 17763+ return NULL;
d337f35e
JR
17764+}
17765+
4bf69007 17766+EXPORT_SYMBOL_GPL(ip_v4_find_src);
d337f35e 17767+
3261cfd5
AM
17768diff -NurpP --minimal linux-4.9.207/kernel/vserver/init.c linux-4.9.207-vs2.3.9.11/kernel/vserver/init.c
17769--- linux-4.9.207/kernel/vserver/init.c 1970-01-01 00:00:00.000000000 +0000
17770+++ linux-4.9.207-vs2.3.9.11/kernel/vserver/init.c 2018-10-20 04:58:15.000000000 +0000
cc23e853 17771@@ -0,0 +1,46 @@
4bf69007
AM
17772+/*
17773+ * linux/kernel/init.c
17774+ *
17775+ * Virtual Server Init
17776+ *
cc23e853 17777+ * Copyright (C) 2004-2007 Herbert P?tzl
4bf69007
AM
17778+ *
17779+ * V0.01 basic structure
17780+ *
17781+ */
d337f35e 17782+
4bf69007 17783+#include <linux/init.h>
cc23e853 17784+#include <linux/module.h>
4bf69007
AM
17785+
17786+int vserver_register_sysctl(void);
17787+void vserver_unregister_sysctl(void);
17788+
17789+
17790+static int __init init_vserver(void)
d337f35e 17791+{
4bf69007 17792+ int ret = 0;
d337f35e 17793+
4bf69007
AM
17794+#ifdef CONFIG_VSERVER_DEBUG
17795+ vserver_register_sysctl();
17796+#endif
17797+ return ret;
d337f35e
JR
17798+}
17799+
d337f35e 17800+
4bf69007 17801+static void __exit exit_vserver(void)
d337f35e 17802+{
d337f35e 17803+
4bf69007
AM
17804+#ifdef CONFIG_VSERVER_DEBUG
17805+ vserver_unregister_sysctl();
17806+#endif
17807+ return;
d337f35e
JR
17808+}
17809+
4bf69007
AM
17810+/* FIXME: GFP_ZONETYPES gone
17811+long vx_slab[GFP_ZONETYPES]; */
17812+long vx_area;
d337f35e 17813+
d337f35e 17814+
4bf69007
AM
17815+module_init(init_vserver);
17816+module_exit(exit_vserver);
d337f35e 17817+
3261cfd5
AM
17818diff -NurpP --minimal linux-4.9.207/kernel/vserver/inode.c linux-4.9.207-vs2.3.9.11/kernel/vserver/inode.c
17819--- linux-4.9.207/kernel/vserver/inode.c 1970-01-01 00:00:00.000000000 +0000
17820+++ linux-4.9.207-vs2.3.9.11/kernel/vserver/inode.c 2018-10-20 04:58:15.000000000 +0000
09be7631 17821@@ -0,0 +1,440 @@
4bf69007
AM
17822+/*
17823+ * linux/kernel/vserver/inode.c
17824+ *
17825+ * Virtual Server: File System Support
17826+ *
cc23e853 17827+ * Copyright (C) 2004-2007 Herbert P?tzl
4bf69007
AM
17828+ *
17829+ * V0.01 separated from vcontext V0.05
17830+ * V0.02 moved to tag (instead of xid)
17831+ *
17832+ */
d337f35e 17833+
4bf69007
AM
17834+#include <linux/tty.h>
17835+#include <linux/proc_fs.h>
17836+#include <linux/devpts_fs.h>
17837+#include <linux/fs.h>
17838+#include <linux/file.h>
17839+#include <linux/mount.h>
17840+#include <linux/parser.h>
17841+#include <linux/namei.h>
09be7631
JR
17842+#include <linux/magic.h>
17843+#include <linux/slab.h>
4bf69007
AM
17844+#include <linux/vserver/inode.h>
17845+#include <linux/vserver/inode_cmd.h>
17846+#include <linux/vs_base.h>
17847+#include <linux/vs_tag.h>
d337f35e 17848+
4bf69007 17849+#include <asm/uaccess.h>
09be7631 17850+#include <../../fs/proc/internal.h>
d337f35e 17851+
d337f35e 17852+
4bf69007 17853+static int __vc_get_iattr(struct inode *in, uint32_t *tag, uint32_t *flags, uint32_t *mask)
d337f35e 17854+{
4bf69007 17855+ struct proc_dir_entry *entry;
d337f35e 17856+
4bf69007
AM
17857+ if (!in || !in->i_sb)
17858+ return -ESRCH;
d337f35e 17859+
4bf69007
AM
17860+ *flags = IATTR_TAG
17861+ | (IS_IMMUTABLE(in) ? IATTR_IMMUTABLE : 0)
17862+ | (IS_IXUNLINK(in) ? IATTR_IXUNLINK : 0)
17863+ | (IS_BARRIER(in) ? IATTR_BARRIER : 0)
17864+ | (IS_COW(in) ? IATTR_COW : 0);
17865+ *mask = IATTR_IXUNLINK | IATTR_IMMUTABLE | IATTR_COW;
d337f35e 17866+
4bf69007
AM
17867+ if (S_ISDIR(in->i_mode))
17868+ *mask |= IATTR_BARRIER;
d337f35e 17869+
4bf69007
AM
17870+ if (IS_TAGGED(in)) {
17871+ *tag = i_tag_read(in);
17872+ *mask |= IATTR_TAG;
17873+ }
2380c486 17874+
4bf69007
AM
17875+ switch (in->i_sb->s_magic) {
17876+ case PROC_SUPER_MAGIC:
17877+ entry = PROC_I(in)->pde;
d337f35e 17878+
4bf69007
AM
17879+ /* check for specific inodes? */
17880+ if (entry)
17881+ *mask |= IATTR_FLAGS;
17882+ if (entry)
17883+ *flags |= (entry->vx_flags & IATTR_FLAGS);
17884+ else
17885+ *flags |= (PROC_I(in)->vx_flags & IATTR_FLAGS);
17886+ break;
d337f35e 17887+
4bf69007
AM
17888+ case DEVPTS_SUPER_MAGIC:
17889+ *tag = i_tag_read(in);
17890+ *mask |= IATTR_TAG;
17891+ break;
d337f35e 17892+
4bf69007
AM
17893+ default:
17894+ break;
17895+ }
17896+ return 0;
d337f35e
JR
17897+}
17898+
4bf69007 17899+int vc_get_iattr(void __user *data)
d337f35e 17900+{
4bf69007
AM
17901+ struct path path;
17902+ struct vcmd_ctx_iattr_v1 vc_data = { .tag = -1 };
17903+ int ret;
d337f35e 17904+
4bf69007
AM
17905+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
17906+ return -EFAULT;
d337f35e 17907+
4bf69007
AM
17908+ ret = user_lpath(vc_data.name, &path);
17909+ if (!ret) {
17910+ ret = __vc_get_iattr(path.dentry->d_inode,
17911+ &vc_data.tag, &vc_data.flags, &vc_data.mask);
17912+ path_put(&path);
17913+ }
17914+ if (ret)
17915+ return ret;
d337f35e 17916+
4bf69007
AM
17917+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
17918+ ret = -EFAULT;
17919+ return ret;
d337f35e
JR
17920+}
17921+
4bf69007 17922+#ifdef CONFIG_COMPAT
d337f35e 17923+
4bf69007 17924+int vc_get_iattr_x32(void __user *data)
d337f35e 17925+{
4bf69007
AM
17926+ struct path path;
17927+ struct vcmd_ctx_iattr_v1_x32 vc_data = { .tag = -1 };
17928+ int ret;
d337f35e 17929+
4bf69007
AM
17930+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
17931+ return -EFAULT;
d337f35e 17932+
4bf69007
AM
17933+ ret = user_lpath(compat_ptr(vc_data.name_ptr), &path);
17934+ if (!ret) {
17935+ ret = __vc_get_iattr(path.dentry->d_inode,
17936+ &vc_data.tag, &vc_data.flags, &vc_data.mask);
17937+ path_put(&path);
17938+ }
17939+ if (ret)
17940+ return ret;
d337f35e 17941+
2380c486 17942+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
4bf69007
AM
17943+ ret = -EFAULT;
17944+ return ret;
d337f35e
JR
17945+}
17946+
4bf69007 17947+#endif /* CONFIG_COMPAT */
d337f35e 17948+
d337f35e 17949+
4bf69007 17950+int vc_fget_iattr(uint32_t fd, void __user *data)
d337f35e 17951+{
4bf69007
AM
17952+ struct file *filp;
17953+ struct vcmd_ctx_fiattr_v0 vc_data = { .tag = -1 };
d337f35e
JR
17954+ int ret;
17955+
4bf69007 17956+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
d337f35e
JR
17957+ return -EFAULT;
17958+
4bf69007 17959+ filp = fget(fd);
cc23e853 17960+ if (!filp || !filp->f_path.dentry || !filp->f_path.dentry->d_inode)
4bf69007 17961+ return -EBADF;
2380c486 17962+
cc23e853 17963+ ret = __vc_get_iattr(filp->f_path.dentry->d_inode,
4bf69007 17964+ &vc_data.tag, &vc_data.flags, &vc_data.mask);
2380c486 17965+
4bf69007 17966+ fput(filp);
2380c486 17967+
4bf69007
AM
17968+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
17969+ ret = -EFAULT;
d337f35e
JR
17970+ return ret;
17971+}
17972+
17973+
4bf69007 17974+static int __vc_set_iattr(struct dentry *de, uint32_t *tag, uint32_t *flags, uint32_t *mask)
2380c486 17975+{
4bf69007
AM
17976+ struct inode *in = de->d_inode;
17977+ int error = 0, is_proc = 0, has_tag = 0;
17978+ struct iattr attr = { 0 };
2380c486 17979+
4bf69007
AM
17980+ if (!in || !in->i_sb)
17981+ return -ESRCH;
2380c486 17982+
4bf69007
AM
17983+ is_proc = (in->i_sb->s_magic == PROC_SUPER_MAGIC);
17984+ if ((*mask & IATTR_FLAGS) && !is_proc)
17985+ return -EINVAL;
2380c486 17986+
4bf69007
AM
17987+ has_tag = IS_TAGGED(in) ||
17988+ (in->i_sb->s_magic == DEVPTS_SUPER_MAGIC);
17989+ if ((*mask & IATTR_TAG) && !has_tag)
17990+ return -EINVAL;
2380c486 17991+
cc23e853 17992+ inode_lock(in);
4bf69007 17993+ if (*mask & IATTR_TAG) {
8ce283e1 17994+ attr.ia_tag = make_ktag(&init_user_ns, *tag);
4bf69007 17995+ attr.ia_valid |= ATTR_TAG;
2380c486
JR
17996+ }
17997+
4bf69007
AM
17998+ if (*mask & IATTR_FLAGS) {
17999+ struct proc_dir_entry *entry = PROC_I(in)->pde;
18000+ unsigned int iflags = PROC_I(in)->vx_flags;
2380c486 18001+
4bf69007
AM
18002+ iflags = (iflags & ~(*mask & IATTR_FLAGS))
18003+ | (*flags & IATTR_FLAGS);
18004+ PROC_I(in)->vx_flags = iflags;
18005+ if (entry)
18006+ entry->vx_flags = iflags;
18007+ }
9f7054f1 18008+
4bf69007
AM
18009+ if (*mask & (IATTR_IMMUTABLE | IATTR_IXUNLINK |
18010+ IATTR_BARRIER | IATTR_COW)) {
18011+ int iflags = in->i_flags;
18012+ int vflags = in->i_vflags;
9f7054f1 18013+
4bf69007
AM
18014+ if (*mask & IATTR_IMMUTABLE) {
18015+ if (*flags & IATTR_IMMUTABLE)
18016+ iflags |= S_IMMUTABLE;
18017+ else
18018+ iflags &= ~S_IMMUTABLE;
18019+ }
18020+ if (*mask & IATTR_IXUNLINK) {
18021+ if (*flags & IATTR_IXUNLINK)
18022+ iflags |= S_IXUNLINK;
18023+ else
18024+ iflags &= ~S_IXUNLINK;
18025+ }
18026+ if (S_ISDIR(in->i_mode) && (*mask & IATTR_BARRIER)) {
18027+ if (*flags & IATTR_BARRIER)
18028+ vflags |= V_BARRIER;
18029+ else
18030+ vflags &= ~V_BARRIER;
18031+ }
18032+ if (S_ISREG(in->i_mode) && (*mask & IATTR_COW)) {
18033+ if (*flags & IATTR_COW)
18034+ vflags |= V_COW;
18035+ else
18036+ vflags &= ~V_COW;
18037+ }
18038+ if (in->i_op && in->i_op->sync_flags) {
18039+ error = in->i_op->sync_flags(in, iflags, vflags);
18040+ if (error)
18041+ goto out;
18042+ }
18043+ }
9f7054f1 18044+
4bf69007
AM
18045+ if (attr.ia_valid) {
18046+ if (in->i_op && in->i_op->setattr)
18047+ error = in->i_op->setattr(de, &attr);
18048+ else {
cc23e853 18049+ error = setattr_prepare(de, &attr);
4bf69007
AM
18050+ if (!error) {
18051+ setattr_copy(in, &attr);
18052+ mark_inode_dirty(in);
18053+ }
18054+ }
9f7054f1 18055+ }
9f7054f1 18056+
4bf69007 18057+out:
cc23e853 18058+ inode_unlock(in);
4bf69007
AM
18059+ return error;
18060+}
2380c486 18061+
4bf69007 18062+int vc_set_iattr(void __user *data)
d337f35e 18063+{
4bf69007
AM
18064+ struct path path;
18065+ struct vcmd_ctx_iattr_v1 vc_data;
18066+ int ret;
d337f35e 18067+
4bf69007
AM
18068+ if (!capable(CAP_LINUX_IMMUTABLE))
18069+ return -EPERM;
18070+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
d337f35e
JR
18071+ return -EFAULT;
18072+
4bf69007
AM
18073+ ret = user_lpath(vc_data.name, &path);
18074+ if (!ret) {
18075+ ret = __vc_set_iattr(path.dentry,
18076+ &vc_data.tag, &vc_data.flags, &vc_data.mask);
18077+ path_put(&path);
d337f35e 18078+ }
4bf69007
AM
18079+
18080+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
18081+ ret = -EFAULT;
d337f35e
JR
18082+ return ret;
18083+}
18084+
4bf69007
AM
18085+#ifdef CONFIG_COMPAT
18086+
18087+int vc_set_iattr_x32(void __user *data)
d337f35e 18088+{
4bf69007
AM
18089+ struct path path;
18090+ struct vcmd_ctx_iattr_v1_x32 vc_data;
18091+ int ret;
d337f35e 18092+
4bf69007
AM
18093+ if (!capable(CAP_LINUX_IMMUTABLE))
18094+ return -EPERM;
18095+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
2380c486
JR
18096+ return -EFAULT;
18097+
4bf69007
AM
18098+ ret = user_lpath(compat_ptr(vc_data.name_ptr), &path);
18099+ if (!ret) {
18100+ ret = __vc_set_iattr(path.dentry,
18101+ &vc_data.tag, &vc_data.flags, &vc_data.mask);
18102+ path_put(&path);
2380c486 18103+ }
4bf69007
AM
18104+
18105+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
18106+ ret = -EFAULT;
18107+ return ret;
2380c486
JR
18108+}
18109+
4bf69007 18110+#endif /* CONFIG_COMPAT */
2380c486 18111+
4bf69007 18112+int vc_fset_iattr(uint32_t fd, void __user *data)
2380c486 18113+{
4bf69007
AM
18114+ struct file *filp;
18115+ struct vcmd_ctx_fiattr_v0 vc_data;
18116+ int ret;
2380c486 18117+
4bf69007
AM
18118+ if (!capable(CAP_LINUX_IMMUTABLE))
18119+ return -EPERM;
18120+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
2380c486
JR
18121+ return -EFAULT;
18122+
4bf69007 18123+ filp = fget(fd);
cc23e853 18124+ if (!filp || !filp->f_path.dentry || !filp->f_path.dentry->d_inode)
4bf69007 18125+ return -EBADF;
2380c486 18126+
cc23e853 18127+ ret = __vc_set_iattr(filp->f_path.dentry, &vc_data.tag,
4bf69007 18128+ &vc_data.flags, &vc_data.mask);
2380c486 18129+
4bf69007 18130+ fput(filp);
2380c486 18131+
4bf69007
AM
18132+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
18133+ return -EFAULT;
18134+ return ret;
2380c486
JR
18135+}
18136+
2380c486 18137+
4bf69007 18138+enum { Opt_notagcheck, Opt_tag, Opt_notag, Opt_tagid, Opt_err };
2380c486 18139+
4bf69007
AM
18140+static match_table_t tokens = {
18141+ {Opt_notagcheck, "notagcheck"},
18142+#ifdef CONFIG_PROPAGATE
18143+ {Opt_notag, "notag"},
18144+ {Opt_tag, "tag"},
18145+ {Opt_tagid, "tagid=%u"},
18146+#endif
18147+ {Opt_err, NULL}
18148+};
2380c486 18149+
9f7054f1 18150+
4bf69007
AM
18151+static void __dx_parse_remove(char *string, char *opt)
18152+{
18153+ char *p = strstr(string, opt);
18154+ char *q = p;
2380c486 18155+
4bf69007
AM
18156+ if (p) {
18157+ while (*q != '\0' && *q != ',')
18158+ q++;
18159+ while (*q)
18160+ *p++ = *q++;
18161+ while (*p)
18162+ *p++ = '\0';
2380c486 18163+ }
2380c486
JR
18164+}
18165+
61333608 18166+int dx_parse_tag(char *string, vtag_t *tag, int remove, int *mnt_flags,
4bf69007 18167+ unsigned long *flags)
9f7054f1 18168+{
4bf69007
AM
18169+ int set = 0;
18170+ substring_t args[MAX_OPT_ARGS];
18171+ int token;
18172+ char *s, *p, *opts;
18173+#if defined(CONFIG_PROPAGATE) || defined(CONFIG_VSERVER_DEBUG)
18174+ int option = 0;
18175+#endif
9f7054f1 18176+
4bf69007
AM
18177+ if (!string)
18178+ return 0;
18179+ s = kstrdup(string, GFP_KERNEL | GFP_ATOMIC);
18180+ if (!s)
18181+ return 0;
9f7054f1 18182+
4bf69007
AM
18183+ opts = s;
18184+ while ((p = strsep(&opts, ",")) != NULL) {
18185+ token = match_token(p, tokens, args);
9f7054f1 18186+
4bf69007
AM
18187+ switch (token) {
18188+#ifdef CONFIG_PROPAGATE
18189+ case Opt_tag:
18190+ if (tag)
18191+ *tag = 0;
18192+ if (remove)
18193+ __dx_parse_remove(s, "tag");
18194+ *mnt_flags |= MNT_TAGID;
18195+ set |= MNT_TAGID;
18196+ break;
18197+ case Opt_notag:
18198+ if (remove)
18199+ __dx_parse_remove(s, "notag");
18200+ *mnt_flags |= MNT_NOTAG;
18201+ set |= MNT_NOTAG;
18202+ break;
18203+ case Opt_tagid:
18204+ if (tag && !match_int(args, &option))
18205+ *tag = option;
18206+ if (remove)
18207+ __dx_parse_remove(s, "tagid");
18208+ *mnt_flags |= MNT_TAGID;
18209+ set |= MNT_TAGID;
18210+ break;
18211+#endif /* CONFIG_PROPAGATE */
18212+ case Opt_notagcheck:
18213+ if (remove)
18214+ __dx_parse_remove(s, "notagcheck");
18215+ *flags |= MS_NOTAGCHECK;
18216+ set |= MS_NOTAGCHECK;
18217+ break;
18218+ }
18219+ vxdprintk(VXD_CBIT(tag, 7),
18220+ "dx_parse_tag(" VS_Q("%s") "): %d:#%d",
18221+ p, token, option);
18222+ }
18223+ if (set)
18224+ strcpy(string, s);
18225+ kfree(s);
18226+ return set;
9f7054f1 18227+}
2380c486 18228+
4bf69007 18229+#ifdef CONFIG_PROPAGATE
2380c486 18230+
4bf69007 18231+void __dx_propagate_tag(struct nameidata *nd, struct inode *inode)
2380c486 18232+{
61333608 18233+ vtag_t new_tag = 0;
4bf69007
AM
18234+ struct vfsmount *mnt;
18235+ int propagate;
2380c486 18236+
4bf69007
AM
18237+ if (!nd)
18238+ return;
18239+ mnt = nd->path.mnt;
18240+ if (!mnt)
18241+ return;
2380c486 18242+
4bf69007
AM
18243+ propagate = (mnt->mnt_flags & MNT_TAGID);
18244+ if (propagate)
18245+ new_tag = mnt->mnt_tag;
2380c486 18246+
4bf69007
AM
18247+ vxdprintk(VXD_CBIT(tag, 7),
18248+ "dx_propagate_tag(%p[#%lu.%d]): %d,%d",
18249+ inode, inode->i_ino, inode->i_tag,
18250+ new_tag, (propagate) ? 1 : 0);
18251+
18252+ if (propagate)
18253+ i_tag_write(inode, new_tag);
2380c486
JR
18254+}
18255+
4bf69007 18256+#include <linux/module.h>
2380c486 18257+
4bf69007 18258+EXPORT_SYMBOL_GPL(__dx_propagate_tag);
2380c486 18259+
4bf69007 18260+#endif /* CONFIG_PROPAGATE */
2380c486 18261+
3261cfd5
AM
18262diff -NurpP --minimal linux-4.9.207/kernel/vserver/Kconfig linux-4.9.207-vs2.3.9.11/kernel/vserver/Kconfig
18263--- linux-4.9.207/kernel/vserver/Kconfig 1970-01-01 00:00:00.000000000 +0000
18264+++ linux-4.9.207-vs2.3.9.11/kernel/vserver/Kconfig 2018-10-20 04:58:15.000000000 +0000
18265@@ -0,0 +1,230 @@
18266+#
18267+# Linux VServer configuration
18268+#
18269+
18270+menu "Linux VServer"
18271+
18272+config VSERVER_AUTO_LBACK
18273+ bool "Automatically Assign Loopback IP"
18274+ default y
18275+ help
18276+ Automatically assign a guest specific loopback
18277+ IP and add it to the kernel network stack on
18278+ startup.
18279+
18280+config VSERVER_AUTO_SINGLE
18281+ bool "Automatic Single IP Special Casing"
18282+ default n
18283+ help
18284+ This allows network contexts with a single IP to
18285+ automatically remap 0.0.0.0 bindings to that IP,
18286+ avoiding further network checks and improving
18287+ performance.
18288+
18289+ (note: such guests do not allow to change the ip
18290+ on the fly and do not show loopback addresses)
18291+
18292+config VSERVER_COWBL
18293+ bool "Enable COW Immutable Link Breaking"
18294+ default y
18295+ help
18296+ This enables the COW (Copy-On-Write) link break code.
18297+ It allows you to treat unified files like normal files
18298+ when writing to them (which will implicitely break the
18299+ link and create a copy of the unified file)
18300+
18301+config VSERVER_VTIME
18302+ bool "Enable Virtualized Guest Time (EXPERIMENTAL)"
18303+ default n
18304+ help
18305+ This enables per guest time offsets to allow for
18306+ adjusting the system clock individually per guest.
18307+ this adds some overhead to the time functions and
18308+ therefore should not be enabled without good reason.
18309+
18310+config VSERVER_DEVICE
18311+ bool "Enable Guest Device Mapping (EXPERIMENTAL)"
18312+ default n
18313+ help
18314+ This enables generic device remapping.
18315+
18316+config VSERVER_PROC_SECURE
18317+ bool "Enable Proc Security"
18318+ depends on PROC_FS
18319+ default y
18320+ help
18321+ This configures ProcFS security to initially hide
18322+ non-process entries for all contexts except the main and
18323+ spectator context (i.e. for all guests), which is a secure
18324+ default.
18325+
18326+ (note: on 1.2x the entries were visible by default)
18327+
18328+choice
18329+ prompt "Persistent Inode Tagging"
18330+ default TAGGING_ID24
18331+ help
18332+ This adds persistent context information to filesystems
18333+ mounted with the tagxid option. Tagging is a requirement
18334+ for per-context disk limits and per-context quota.
18335+
18336+
18337+config TAGGING_NONE
18338+ bool "Disabled"
18339+ help
18340+ do not store per-context information in inodes.
18341+
18342+config TAGGING_UID16
18343+ bool "UID16/GID32"
18344+ help
18345+ reduces UID to 16 bit, but leaves GID at 32 bit.
18346+
18347+config TAGGING_GID16
18348+ bool "UID32/GID16"
18349+ help
18350+ reduces GID to 16 bit, but leaves UID at 32 bit.
18351+
18352+config TAGGING_ID24
18353+ bool "UID24/GID24"
18354+ help
18355+ uses the upper 8bit from UID and GID for XID tagging
18356+ which leaves 24bit for UID/GID each, which should be
18357+ more than sufficient for normal use.
18358+
18359+config TAGGING_INTERN
18360+ bool "UID32/GID32"
18361+ help
18362+ this uses otherwise reserved inode fields in the on
18363+ disk representation, which limits the use to a few
18364+ filesystems (currently ext2 and ext3)
18365+
18366+endchoice
18367+
18368+config TAG_NFSD
18369+ bool "Tag NFSD User Auth and Files"
18370+ default n
18371+ help
18372+ Enable this if you do want the in-kernel NFS
18373+ Server to use the tagging specified above.
18374+ (will require patched clients too)
18375+
18376+config VSERVER_PRIVACY
18377+ bool "Honor Privacy Aspects of Guests"
18378+ default n
18379+ help
18380+ When enabled, most context checks will disallow
18381+ access to structures assigned to a specific context,
18382+ like ptys or loop devices.
18383+
18384+config VSERVER_CONTEXTS
18385+ int "Maximum number of Contexts (1-65533)" if EMBEDDED
18386+ range 1 65533
18387+ default "768" if 64BIT
18388+ default "256"
18389+ help
18390+ This setting will optimize certain data structures
18391+ and memory allocations according to the expected
18392+ maximum.
18393+
18394+ note: this is not a strict upper limit.
18395+
18396+config VSERVER_WARN
18397+ bool "VServer Warnings"
18398+ default y
18399+ help
18400+ This enables various runtime warnings, which will
18401+ notify about potential manipulation attempts or
18402+ resource shortage. It is generally considered to
18403+ be a good idea to have that enabled.
18404+
18405+config VSERVER_WARN_DEVPTS
18406+ bool "VServer DevPTS Warnings"
18407+ depends on VSERVER_WARN
18408+ default y
18409+ help
18410+ This enables DevPTS related warnings, issued when a
18411+ process inside a context tries to lookup or access
18412+ a dynamic pts from the host or a different context.
18413+
18414+config VSERVER_DEBUG
18415+ bool "VServer Debugging Code"
18416+ default n
18417+ help
18418+ Set this to yes if you want to be able to activate
18419+ debugging output at runtime. It adds a very small
18420+ overhead to all vserver related functions and
18421+ increases the kernel size by about 20k.
18422+
18423+config VSERVER_HISTORY
18424+ bool "VServer History Tracing"
18425+ depends on VSERVER_DEBUG
18426+ default n
18427+ help
18428+ Set this to yes if you want to record the history of
18429+ linux-vserver activities, so they can be replayed in
18430+ the event of a kernel panic or oops.
18431+
18432+config VSERVER_HISTORY_SIZE
18433+ int "Per-CPU History Size (32-65536)"
18434+ depends on VSERVER_HISTORY
18435+ range 32 65536
18436+ default 64
18437+ help
18438+ This allows you to specify the number of entries in
18439+ the per-CPU history buffer.
18440+
18441+config VSERVER_EXTRA_MNT_CHECK
18442+ bool "Extra Checks for Reachability"
18443+ default n
18444+ help
18445+ Set this to yes if you want to do extra checks for
18446+ vfsmount reachability in the proc filesystem code.
18447+ This shouldn't be required on any setup utilizing
18448+ mnt namespaces.
18449+
18450+choice
18451+ prompt "Quotes used in debug and warn messages"
18452+ default QUOTES_ISO8859
18453+
18454+config QUOTES_ISO8859
18455+ bool "Extended ASCII (ISO 8859) angle quotes"
18456+ help
18457+ This uses the extended ASCII characters \xbb
18458+ and \xab for quoting file and process names.
18459+
18460+config QUOTES_UTF8
18461+ bool "UTF-8 angle quotes"
18462+ help
18463+ This uses the the UTF-8 sequences for angle
18464+ quotes to quote file and process names.
18465+
18466+config QUOTES_ASCII
18467+ bool "ASCII single quotes"
18468+ help
18469+ This uses the ASCII single quote character
18470+ (\x27) to quote file and process names.
18471+
18472+endchoice
18473+
18474+endmenu
18475+
18476+
18477+config VSERVER
18478+ bool
18479+ default y
18480+ select NAMESPACES
18481+ select UTS_NS
18482+ select IPC_NS
18483+# select USER_NS
18484+ select SYSVIPC
18485+
18486+config VSERVER_SECURITY
18487+ bool
18488+ depends on SECURITY
18489+ default y
18490+ select SECURITY_CAPABILITIES
18491+
18492+config VSERVER_DISABLED
18493+ bool
18494+ default n
18495+
18496diff -NurpP --minimal linux-4.9.207/kernel/vserver/limit.c linux-4.9.207-vs2.3.9.11/kernel/vserver/limit.c
18497--- linux-4.9.207/kernel/vserver/limit.c 1970-01-01 00:00:00.000000000 +0000
18498+++ linux-4.9.207-vs2.3.9.11/kernel/vserver/limit.c 2018-10-20 04:58:15.000000000 +0000
369dbd59 18499@@ -0,0 +1,386 @@
4bf69007
AM
18500+/*
18501+ * linux/kernel/vserver/limit.c
18502+ *
18503+ * Virtual Server: Context Limits
18504+ *
cc23e853 18505+ * Copyright (C) 2004-2010 Herbert P?tzl
4bf69007
AM
18506+ *
18507+ * V0.01 broken out from vcontext V0.05
18508+ * V0.02 changed vcmds to vxi arg
18509+ * V0.03 added memory cgroup support
18510+ *
18511+ */
2380c486 18512+
4bf69007
AM
18513+#include <linux/sched.h>
18514+#include <linux/module.h>
18515+#include <linux/memcontrol.h>
cc23e853 18516+#include <linux/page_counter.h>
4bf69007
AM
18517+#include <linux/vs_limit.h>
18518+#include <linux/vserver/limit.h>
18519+#include <linux/vserver/limit_cmd.h>
2380c486 18520+
4bf69007 18521+#include <asm/uaccess.h>
d337f35e 18522+
d337f35e 18523+
4bf69007
AM
18524+const char *vlimit_name[NUM_LIMITS] = {
18525+ [RLIMIT_CPU] = "CPU",
18526+ [RLIMIT_NPROC] = "NPROC",
18527+ [RLIMIT_NOFILE] = "NOFILE",
18528+ [RLIMIT_LOCKS] = "LOCKS",
18529+ [RLIMIT_SIGPENDING] = "SIGP",
18530+ [RLIMIT_MSGQUEUE] = "MSGQ",
d337f35e 18531+
4bf69007
AM
18532+ [VLIMIT_NSOCK] = "NSOCK",
18533+ [VLIMIT_OPENFD] = "OPENFD",
18534+ [VLIMIT_SHMEM] = "SHMEM",
18535+ [VLIMIT_DENTRY] = "DENTRY",
18536+};
2380c486 18537+
4bf69007 18538+EXPORT_SYMBOL_GPL(vlimit_name);
2380c486 18539+
4bf69007 18540+#define MASK_ENTRY(x) (1 << (x))
d337f35e 18541+
4bf69007
AM
18542+const struct vcmd_ctx_rlimit_mask_v0 vlimit_mask = {
18543+ /* minimum */
18544+ 0
18545+ , /* softlimit */
18546+ 0
18547+ , /* maximum */
18548+ MASK_ENTRY( RLIMIT_NPROC ) |
18549+ MASK_ENTRY( RLIMIT_NOFILE ) |
18550+ MASK_ENTRY( RLIMIT_LOCKS ) |
18551+ MASK_ENTRY( RLIMIT_MSGQUEUE ) |
d337f35e 18552+
4bf69007
AM
18553+ MASK_ENTRY( VLIMIT_NSOCK ) |
18554+ MASK_ENTRY( VLIMIT_OPENFD ) |
18555+ MASK_ENTRY( VLIMIT_SHMEM ) |
18556+ MASK_ENTRY( VLIMIT_DENTRY ) |
18557+ 0
18558+};
18559+ /* accounting only */
18560+uint32_t account_mask =
18561+ MASK_ENTRY( VLIMIT_SEMARY ) |
18562+ MASK_ENTRY( VLIMIT_NSEMS ) |
18563+ MASK_ENTRY( VLIMIT_MAPPED ) |
18564+ 0;
d337f35e 18565+
4bf69007
AM
18566+
18567+static int is_valid_vlimit(int id)
18568+{
18569+ uint32_t mask = vlimit_mask.minimum |
18570+ vlimit_mask.softlimit | vlimit_mask.maximum;
18571+ return mask & (1 << id);
d337f35e
JR
18572+}
18573+
4bf69007 18574+static int is_accounted_vlimit(int id)
d337f35e 18575+{
4bf69007
AM
18576+ if (is_valid_vlimit(id))
18577+ return 1;
18578+ return account_mask & (1 << id);
18579+}
d337f35e 18580+
d337f35e 18581+
4bf69007
AM
18582+static inline uint64_t vc_get_soft(struct vx_info *vxi, int id)
18583+{
18584+ rlim_t limit = __rlim_soft(&vxi->limit, id);
18585+ return VX_VLIM(limit);
18586+}
d337f35e 18587+
4bf69007
AM
18588+static inline uint64_t vc_get_hard(struct vx_info *vxi, int id)
18589+{
18590+ rlim_t limit = __rlim_hard(&vxi->limit, id);
18591+ return VX_VLIM(limit);
18592+}
d337f35e 18593+
4bf69007
AM
18594+static int do_get_rlimit(struct vx_info *vxi, uint32_t id,
18595+ uint64_t *minimum, uint64_t *softlimit, uint64_t *maximum)
18596+{
18597+ if (!is_valid_vlimit(id))
18598+ return -EINVAL;
18599+
18600+ if (minimum)
18601+ *minimum = CRLIM_UNSET;
18602+ if (softlimit)
18603+ *softlimit = vc_get_soft(vxi, id);
18604+ if (maximum)
18605+ *maximum = vc_get_hard(vxi, id);
d337f35e
JR
18606+ return 0;
18607+}
18608+
4bf69007 18609+int vc_get_rlimit(struct vx_info *vxi, void __user *data)
d337f35e 18610+{
4bf69007
AM
18611+ struct vcmd_ctx_rlimit_v0 vc_data;
18612+ int ret;
d337f35e 18613+
4bf69007
AM
18614+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
18615+ return -EFAULT;
18616+
18617+ ret = do_get_rlimit(vxi, vc_data.id,
18618+ &vc_data.minimum, &vc_data.softlimit, &vc_data.maximum);
18619+ if (ret)
18620+ return ret;
d337f35e 18621+
2380c486 18622+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
d337f35e
JR
18623+ return -EFAULT;
18624+ return 0;
18625+}
18626+
4bf69007
AM
18627+static int do_set_rlimit(struct vx_info *vxi, uint32_t id,
18628+ uint64_t minimum, uint64_t softlimit, uint64_t maximum)
d337f35e 18629+{
4bf69007
AM
18630+ if (!is_valid_vlimit(id))
18631+ return -EINVAL;
d337f35e 18632+
4bf69007
AM
18633+ if (maximum != CRLIM_KEEP)
18634+ __rlim_hard(&vxi->limit, id) = VX_RLIM(maximum);
18635+ if (softlimit != CRLIM_KEEP)
18636+ __rlim_soft(&vxi->limit, id) = VX_RLIM(softlimit);
18637+
18638+ /* clamp soft limit */
18639+ if (__rlim_soft(&vxi->limit, id) > __rlim_hard(&vxi->limit, id))
18640+ __rlim_soft(&vxi->limit, id) = __rlim_hard(&vxi->limit, id);
d337f35e 18641+
d337f35e
JR
18642+ return 0;
18643+}
18644+
4bf69007
AM
18645+int vc_set_rlimit(struct vx_info *vxi, void __user *data)
18646+{
18647+ struct vcmd_ctx_rlimit_v0 vc_data;
d337f35e 18648+
4bf69007
AM
18649+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
18650+ return -EFAULT;
d337f35e 18651+
4bf69007
AM
18652+ return do_set_rlimit(vxi, vc_data.id,
18653+ vc_data.minimum, vc_data.softlimit, vc_data.maximum);
18654+}
d337f35e 18655+
4bf69007 18656+#ifdef CONFIG_IA32_EMULATION
2380c486 18657+
4bf69007
AM
18658+int vc_set_rlimit_x32(struct vx_info *vxi, void __user *data)
18659+{
18660+ struct vcmd_ctx_rlimit_v0_x32 vc_data;
d337f35e 18661+
4bf69007
AM
18662+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
18663+ return -EFAULT;
d337f35e 18664+
4bf69007
AM
18665+ return do_set_rlimit(vxi, vc_data.id,
18666+ vc_data.minimum, vc_data.softlimit, vc_data.maximum);
18667+}
d337f35e 18668+
4bf69007
AM
18669+int vc_get_rlimit_x32(struct vx_info *vxi, void __user *data)
18670+{
18671+ struct vcmd_ctx_rlimit_v0_x32 vc_data;
18672+ int ret;
d337f35e 18673+
4bf69007
AM
18674+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
18675+ return -EFAULT;
d337f35e 18676+
4bf69007
AM
18677+ ret = do_get_rlimit(vxi, vc_data.id,
18678+ &vc_data.minimum, &vc_data.softlimit, &vc_data.maximum);
18679+ if (ret)
18680+ return ret;
2380c486 18681+
4bf69007
AM
18682+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
18683+ return -EFAULT;
18684+ return 0;
2380c486 18685+}
d337f35e 18686+
4bf69007 18687+#endif /* CONFIG_IA32_EMULATION */
d337f35e
JR
18688+
18689+
4bf69007
AM
18690+int vc_get_rlimit_mask(uint32_t id, void __user *data)
18691+{
18692+ if (copy_to_user(data, &vlimit_mask, sizeof(vlimit_mask)))
18693+ return -EFAULT;
18694+ return 0;
18695+}
d337f35e
JR
18696+
18697+
4bf69007
AM
18698+static inline void vx_reset_hits(struct _vx_limit *limit)
18699+{
18700+ int lim;
d337f35e 18701+
4bf69007
AM
18702+ for (lim = 0; lim < NUM_LIMITS; lim++) {
18703+ atomic_set(&__rlim_lhit(limit, lim), 0);
18704+ }
18705+}
d337f35e 18706+
4bf69007 18707+int vc_reset_hits(struct vx_info *vxi, void __user *data)
d337f35e 18708+{
4bf69007
AM
18709+ vx_reset_hits(&vxi->limit);
18710+ return 0;
d337f35e
JR
18711+}
18712+
4bf69007 18713+static inline void vx_reset_minmax(struct _vx_limit *limit)
d337f35e 18714+{
4bf69007
AM
18715+ rlim_t value;
18716+ int lim;
18717+
18718+ for (lim = 0; lim < NUM_LIMITS; lim++) {
18719+ value = __rlim_get(limit, lim);
18720+ __rlim_rmax(limit, lim) = value;
18721+ __rlim_rmin(limit, lim) = value;
18722+ }
d337f35e
JR
18723+}
18724+
4bf69007 18725+int vc_reset_minmax(struct vx_info *vxi, void __user *data)
d337f35e 18726+{
4bf69007
AM
18727+ vx_reset_minmax(&vxi->limit);
18728+ return 0;
d337f35e
JR
18729+}
18730+
18731+
4bf69007 18732+int vc_rlimit_stat(struct vx_info *vxi, void __user *data)
d337f35e 18733+{
4bf69007
AM
18734+ struct vcmd_rlimit_stat_v0 vc_data;
18735+ struct _vx_limit *limit = &vxi->limit;
18736+ int id;
d337f35e 18737+
4bf69007
AM
18738+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
18739+ return -EFAULT;
d337f35e 18740+
4bf69007
AM
18741+ id = vc_data.id;
18742+ if (!is_accounted_vlimit(id))
18743+ return -EINVAL;
2380c486 18744+
4bf69007
AM
18745+ vx_limit_fixup(limit, id);
18746+ vc_data.hits = atomic_read(&__rlim_lhit(limit, id));
18747+ vc_data.value = __rlim_get(limit, id);
18748+ vc_data.minimum = __rlim_rmin(limit, id);
18749+ vc_data.maximum = __rlim_rmax(limit, id);
2380c486 18750+
4bf69007
AM
18751+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
18752+ return -EFAULT;
18753+ return 0;
d337f35e
JR
18754+}
18755+
d337f35e 18756+
cc23e853 18757+#ifdef CONFIG_MEMCG
369dbd59
AM
18758+
18759+void dump_sysinfo(struct sysinfo *si)
18760+{
18761+ printk(KERN_INFO "sysinfo: memunit=%u\n"
18762+ "\ttotalram:\t%lu\n"
18763+ "\tfreeram:\t%lu\n"
18764+ "\tsharedram:\t%lu\n"
18765+ "\tbufferram:\t%lu\n"
18766+ "\ttotalswap:\t%lu\n"
18767+ "\tfreeswap:\t%lu\n"
18768+ "\ttotalhigh:\t%lu\n"
18769+ "\tfreehigh:\t%lu\n",
18770+ si->mem_unit,
18771+ si->totalram,
18772+ si->freeram,
18773+ si->sharedram,
18774+ si->bufferram,
18775+ si->totalswap,
18776+ si->freeswap,
18777+ si->totalhigh,
18778+ si->freehigh);
18779+}
18780+
4bf69007 18781+void vx_vsi_meminfo(struct sysinfo *val)
d337f35e 18782+{
4bf69007 18783+ struct mem_cgroup *mcg;
369dbd59
AM
18784+ unsigned long res_limit, res_usage;
18785+ unsigned shift;
18786+
18787+ if (VXD_CBIT(cvirt, 4))
18788+ dump_sysinfo(val);
d337f35e 18789+
4bf69007
AM
18790+ rcu_read_lock();
18791+ mcg = mem_cgroup_from_task(current);
369dbd59
AM
18792+ if (VXD_CBIT(cvirt, 5))
18793+ dump_mem_cgroup(mcg);
4bf69007
AM
18794+ rcu_read_unlock();
18795+ if (!mcg)
18796+ goto out;
d337f35e 18797+
cc23e853
AM
18798+ res_limit = mem_cgroup_mem_limit_pages(mcg);
18799+ res_usage = mem_cgroup_mem_usage_pages(mcg);
369dbd59 18800+ shift = val->mem_unit == 1 ? PAGE_SHIFT : 0;
2380c486 18801+
cc23e853 18802+ if (res_limit != PAGE_COUNTER_MAX)
369dbd59
AM
18803+ val->totalram = res_limit << shift;
18804+ val->freeram = val->totalram - (res_usage << shift);
4bf69007
AM
18805+ val->bufferram = 0;
18806+ val->totalhigh = 0;
18807+ val->freehigh = 0;
18808+out:
4bf69007 18809+ return;
d337f35e
JR
18810+}
18811+
4bf69007 18812+void vx_vsi_swapinfo(struct sysinfo *val)
d337f35e 18813+{
4bf69007
AM
18814+#ifdef CONFIG_MEMCG_SWAP
18815+ struct mem_cgroup *mcg;
369dbd59
AM
18816+ unsigned long res_limit, res_usage, memsw_limit, memsw_usage;
18817+ signed long swap_limit, swap_usage;
18818+ unsigned shift;
18819+
18820+ if (VXD_CBIT(cvirt, 6))
18821+ dump_sysinfo(val);
d337f35e 18822+
4bf69007
AM
18823+ rcu_read_lock();
18824+ mcg = mem_cgroup_from_task(current);
369dbd59
AM
18825+ if (VXD_CBIT(cvirt, 7))
18826+ dump_mem_cgroup(mcg);
4bf69007
AM
18827+ rcu_read_unlock();
18828+ if (!mcg)
18829+ goto out;
d337f35e 18830+
cc23e853 18831+ res_limit = mem_cgroup_mem_limit_pages(mcg);
d337f35e 18832+
4bf69007 18833+ /* memory unlimited */
cc23e853 18834+ if (res_limit == PAGE_COUNTER_MAX)
4bf69007 18835+ goto out;
d337f35e 18836+
369dbd59
AM
18837+ res_usage = mem_cgroup_mem_usage_pages(mcg);
18838+ memsw_limit = mem_cgroup_memsw_limit_pages(mcg);
18839+ memsw_usage = mem_cgroup_memsw_usage_pages(mcg);
18840+ shift = val->mem_unit == 1 ? PAGE_SHIFT : 0;
18841+
4bf69007
AM
18842+ swap_limit = memsw_limit - res_limit;
18843+ /* we have a swap limit? */
cc23e853 18844+ if (memsw_limit != PAGE_COUNTER_MAX)
369dbd59 18845+ val->totalswap = swap_limit << shift;
d337f35e 18846+
4bf69007
AM
18847+ /* calculate swap part */
18848+ swap_usage = (memsw_usage > res_usage) ?
18849+ memsw_usage - res_usage : 0;
18850+
18851+ /* total shown minus usage gives free swap */
18852+ val->freeswap = (swap_usage < swap_limit) ?
369dbd59 18853+ val->totalswap - (swap_usage << shift) : 0;
4bf69007
AM
18854+out:
18855+#else /* !CONFIG_MEMCG_SWAP */
18856+ val->totalswap = 0;
18857+ val->freeswap = 0;
18858+#endif /* !CONFIG_MEMCG_SWAP */
4bf69007 18859+ return;
d337f35e
JR
18860+}
18861+
4bf69007 18862+long vx_vsi_cached(struct sysinfo *val)
d337f35e 18863+{
4bf69007 18864+ long cache = 0;
cc23e853 18865+#ifdef CONFIG_MEMCG_BROKEN
4bf69007 18866+ struct mem_cgroup *mcg;
d337f35e 18867+
369dbd59
AM
18868+ if (VXD_CBIT(cvirt, 8))
18869+ dump_sysinfo(val);
18870+
4bf69007
AM
18871+ rcu_read_lock();
18872+ mcg = mem_cgroup_from_task(current);
369dbd59
AM
18873+ if (VXD_CBIT(cvirt, 9))
18874+ dump_mem_cgroup(mcg);
4bf69007
AM
18875+ rcu_read_unlock();
18876+ if (!mcg)
18877+ goto out;
2380c486 18878+
cc23e853 18879+ // cache = mem_cgroup_stat_read_cache(mcg);
4bf69007 18880+out:
2380c486 18881+#endif
4bf69007 18882+ return cache;
d337f35e 18883+}
cc23e853 18884+#endif /* !CONFIG_MEMCG */
d337f35e 18885+
3261cfd5
AM
18886diff -NurpP --minimal linux-4.9.207/kernel/vserver/limit_init.h linux-4.9.207-vs2.3.9.11/kernel/vserver/limit_init.h
18887--- linux-4.9.207/kernel/vserver/limit_init.h 1970-01-01 00:00:00.000000000 +0000
18888+++ linux-4.9.207-vs2.3.9.11/kernel/vserver/limit_init.h 2018-10-20 04:58:15.000000000 +0000
4bf69007 18889@@ -0,0 +1,31 @@
d337f35e
JR
18890+
18891+
4bf69007
AM
18892+static inline void vx_info_init_limit(struct _vx_limit *limit)
18893+{
18894+ int lim;
d337f35e 18895+
4bf69007
AM
18896+ for (lim = 0; lim < NUM_LIMITS; lim++) {
18897+ __rlim_soft(limit, lim) = RLIM_INFINITY;
18898+ __rlim_hard(limit, lim) = RLIM_INFINITY;
18899+ __rlim_set(limit, lim, 0);
18900+ atomic_set(&__rlim_lhit(limit, lim), 0);
18901+ __rlim_rmin(limit, lim) = 0;
18902+ __rlim_rmax(limit, lim) = 0;
18903+ }
18904+}
d337f35e 18905+
4bf69007 18906+static inline void vx_info_exit_limit(struct _vx_limit *limit)
d337f35e 18907+{
4bf69007
AM
18908+ rlim_t value;
18909+ int lim;
d337f35e 18910+
4bf69007
AM
18911+ for (lim = 0; lim < NUM_LIMITS; lim++) {
18912+ if ((1 << lim) & VLIM_NOCHECK)
18913+ continue;
18914+ value = __rlim_get(limit, lim);
18915+ vxwprintk_xid(value,
18916+ "!!! limit: %p[%s,%d] = %ld on exit.",
18917+ limit, vlimit_name[lim], lim, (long)value);
18918+ }
18919+}
d337f35e 18920+
3261cfd5
AM
18921diff -NurpP --minimal linux-4.9.207/kernel/vserver/limit_proc.h linux-4.9.207-vs2.3.9.11/kernel/vserver/limit_proc.h
18922--- linux-4.9.207/kernel/vserver/limit_proc.h 1970-01-01 00:00:00.000000000 +0000
18923+++ linux-4.9.207-vs2.3.9.11/kernel/vserver/limit_proc.h 2018-10-20 04:58:15.000000000 +0000
4bf69007
AM
18924@@ -0,0 +1,57 @@
18925+#ifndef _VX_LIMIT_PROC_H
18926+#define _VX_LIMIT_PROC_H
d337f35e 18927+
4bf69007 18928+#include <linux/vserver/limit_int.h>
d337f35e 18929+
d337f35e 18930+
4bf69007
AM
18931+#define VX_LIMIT_FMT ":\t%8ld\t%8ld/%8ld\t%8lld/%8lld\t%6d\n"
18932+#define VX_LIMIT_TOP \
18933+ "Limit\t current\t min/max\t\t soft/hard\t\thits\n"
d337f35e 18934+
4bf69007
AM
18935+#define VX_LIMIT_ARG(r) \
18936+ (unsigned long)__rlim_get(limit, r), \
18937+ (unsigned long)__rlim_rmin(limit, r), \
18938+ (unsigned long)__rlim_rmax(limit, r), \
18939+ VX_VLIM(__rlim_soft(limit, r)), \
18940+ VX_VLIM(__rlim_hard(limit, r)), \
18941+ atomic_read(&__rlim_lhit(limit, r))
d337f35e 18942+
4bf69007
AM
18943+static inline int vx_info_proc_limit(struct _vx_limit *limit, char *buffer)
18944+{
18945+ vx_limit_fixup(limit, -1);
18946+ return sprintf(buffer, VX_LIMIT_TOP
18947+ "PROC" VX_LIMIT_FMT
18948+ "VM" VX_LIMIT_FMT
18949+ "VML" VX_LIMIT_FMT
18950+ "RSS" VX_LIMIT_FMT
18951+ "ANON" VX_LIMIT_FMT
18952+ "RMAP" VX_LIMIT_FMT
18953+ "FILES" VX_LIMIT_FMT
18954+ "OFD" VX_LIMIT_FMT
18955+ "LOCKS" VX_LIMIT_FMT
18956+ "SOCK" VX_LIMIT_FMT
18957+ "MSGQ" VX_LIMIT_FMT
18958+ "SHM" VX_LIMIT_FMT
18959+ "SEMA" VX_LIMIT_FMT
18960+ "SEMS" VX_LIMIT_FMT
18961+ "DENT" VX_LIMIT_FMT,
18962+ VX_LIMIT_ARG(RLIMIT_NPROC),
18963+ VX_LIMIT_ARG(RLIMIT_AS),
18964+ VX_LIMIT_ARG(RLIMIT_MEMLOCK),
18965+ VX_LIMIT_ARG(RLIMIT_RSS),
18966+ VX_LIMIT_ARG(VLIMIT_ANON),
18967+ VX_LIMIT_ARG(VLIMIT_MAPPED),
18968+ VX_LIMIT_ARG(RLIMIT_NOFILE),
18969+ VX_LIMIT_ARG(VLIMIT_OPENFD),
18970+ VX_LIMIT_ARG(RLIMIT_LOCKS),
18971+ VX_LIMIT_ARG(VLIMIT_NSOCK),
18972+ VX_LIMIT_ARG(RLIMIT_MSGQUEUE),
18973+ VX_LIMIT_ARG(VLIMIT_SHMEM),
18974+ VX_LIMIT_ARG(VLIMIT_SEMARY),
18975+ VX_LIMIT_ARG(VLIMIT_NSEMS),
18976+ VX_LIMIT_ARG(VLIMIT_DENTRY));
d337f35e
JR
18977+}
18978+
4bf69007 18979+#endif /* _VX_LIMIT_PROC_H */
d337f35e 18980+
d337f35e 18981+
3261cfd5
AM
18982diff -NurpP --minimal linux-4.9.207/kernel/vserver/Makefile linux-4.9.207-vs2.3.9.11/kernel/vserver/Makefile
18983--- linux-4.9.207/kernel/vserver/Makefile 1970-01-01 00:00:00.000000000 +0000
18984+++ linux-4.9.207-vs2.3.9.11/kernel/vserver/Makefile 2018-10-20 04:58:15.000000000 +0000
18985@@ -0,0 +1,18 @@
18986+#
18987+# Makefile for the Linux vserver routines.
18988+#
18989+
18990+
18991+obj-y += vserver.o
18992+
18993+vserver-y := switch.o context.o space.o sched.o network.o inode.o \
18994+ limit.o cvirt.o cacct.o signal.o helper.o init.o \
18995+ dlimit.o tag.o
18996+
18997+vserver-$(CONFIG_INET) += inet.o
18998+vserver-$(CONFIG_PROC_FS) += proc.o
18999+vserver-$(CONFIG_VSERVER_DEBUG) += sysctl.o debug.o
19000+vserver-$(CONFIG_VSERVER_HISTORY) += history.o
19001+vserver-$(CONFIG_VSERVER_MONITOR) += monitor.o
19002+vserver-$(CONFIG_VSERVER_DEVICE) += device.o
19003+
19004diff -NurpP --minimal linux-4.9.207/kernel/vserver/network.c linux-4.9.207-vs2.3.9.11/kernel/vserver/network.c
19005--- linux-4.9.207/kernel/vserver/network.c 1970-01-01 00:00:00.000000000 +0000
19006+++ linux-4.9.207-vs2.3.9.11/kernel/vserver/network.c 2018-10-20 04:58:15.000000000 +0000
5cb1760b 19007@@ -0,0 +1,1053 @@
d337f35e 19008+/*
4bf69007 19009+ * linux/kernel/vserver/network.c
d337f35e 19010+ *
4bf69007
AM
19011+ * Virtual Server: Network Support
19012+ *
cc23e853 19013+ * Copyright (C) 2003-2007 Herbert P?tzl
4bf69007
AM
19014+ *
19015+ * V0.01 broken out from vcontext V0.05
19016+ * V0.02 cleaned up implementation
19017+ * V0.03 added equiv nx commands
19018+ * V0.04 switch to RCU based hash
19019+ * V0.05 and back to locking again
19020+ * V0.06 changed vcmds to nxi arg
19021+ * V0.07 have __create claim() the nxi
d337f35e 19022+ *
d337f35e 19023+ */
d337f35e 19024+
4bf69007
AM
19025+#include <linux/err.h>
19026+#include <linux/slab.h>
19027+#include <linux/rcupdate.h>
19028+#include <net/ipv6.h>
d337f35e 19029+
4bf69007
AM
19030+#include <linux/vs_network.h>
19031+#include <linux/vs_pid.h>
19032+#include <linux/vserver/network_cmd.h>
d337f35e
JR
19033+
19034+
4bf69007
AM
19035+atomic_t nx_global_ctotal = ATOMIC_INIT(0);
19036+atomic_t nx_global_cactive = ATOMIC_INIT(0);
d337f35e 19037+
4bf69007
AM
19038+static struct kmem_cache *nx_addr_v4_cachep = NULL;
19039+static struct kmem_cache *nx_addr_v6_cachep = NULL;
d337f35e 19040+
d337f35e 19041+
4bf69007 19042+static int __init init_network(void)
d337f35e 19043+{
4bf69007
AM
19044+ nx_addr_v4_cachep = kmem_cache_create("nx_v4_addr_cache",
19045+ sizeof(struct nx_addr_v4), 0,
19046+ SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL);
19047+ nx_addr_v6_cachep = kmem_cache_create("nx_v6_addr_cache",
19048+ sizeof(struct nx_addr_v6), 0,
19049+ SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL);
d337f35e
JR
19050+ return 0;
19051+}
19052+
19053+
4bf69007 19054+/* __alloc_nx_addr_v4() */
d337f35e 19055+
4bf69007 19056+static inline struct nx_addr_v4 *__alloc_nx_addr_v4(void)
d337f35e 19057+{
4bf69007
AM
19058+ struct nx_addr_v4 *nxa = kmem_cache_alloc(
19059+ nx_addr_v4_cachep, GFP_KERNEL);
92598135 19060+
4bf69007
AM
19061+ if (!IS_ERR(nxa))
19062+ memset(nxa, 0, sizeof(*nxa));
19063+ return nxa;
d337f35e
JR
19064+}
19065+
4bf69007 19066+/* __dealloc_nx_addr_v4() */
d337f35e 19067+
4bf69007
AM
19068+static inline void __dealloc_nx_addr_v4(struct nx_addr_v4 *nxa)
19069+{
19070+ kmem_cache_free(nx_addr_v4_cachep, nxa);
19071+}
d337f35e 19072+
4bf69007 19073+/* __dealloc_nx_addr_v4_all() */
d337f35e 19074+
4bf69007 19075+static inline void __dealloc_nx_addr_v4_all(struct nx_addr_v4 *nxa)
d337f35e 19076+{
4bf69007
AM
19077+ while (nxa) {
19078+ struct nx_addr_v4 *next = nxa->next;
d337f35e 19079+
4bf69007
AM
19080+ __dealloc_nx_addr_v4(nxa);
19081+ nxa = next;
19082+ }
19083+}
d337f35e 19084+
d337f35e 19085+
4bf69007 19086+#ifdef CONFIG_IPV6
d337f35e 19087+
4bf69007 19088+/* __alloc_nx_addr_v6() */
d337f35e 19089+
4bf69007
AM
19090+static inline struct nx_addr_v6 *__alloc_nx_addr_v6(void)
19091+{
19092+ struct nx_addr_v6 *nxa = kmem_cache_alloc(
19093+ nx_addr_v6_cachep, GFP_KERNEL);
d337f35e 19094+
4bf69007
AM
19095+ if (!IS_ERR(nxa))
19096+ memset(nxa, 0, sizeof(*nxa));
19097+ return nxa;
d337f35e
JR
19098+}
19099+
4bf69007
AM
19100+/* __dealloc_nx_addr_v6() */
19101+
19102+static inline void __dealloc_nx_addr_v6(struct nx_addr_v6 *nxa)
d337f35e 19103+{
4bf69007
AM
19104+ kmem_cache_free(nx_addr_v6_cachep, nxa);
19105+}
d337f35e 19106+
4bf69007 19107+/* __dealloc_nx_addr_v6_all() */
d337f35e 19108+
4bf69007
AM
19109+static inline void __dealloc_nx_addr_v6_all(struct nx_addr_v6 *nxa)
19110+{
19111+ while (nxa) {
19112+ struct nx_addr_v6 *next = nxa->next;
d337f35e 19113+
4bf69007
AM
19114+ __dealloc_nx_addr_v6(nxa);
19115+ nxa = next;
19116+ }
19117+}
d337f35e 19118+
4bf69007 19119+#endif /* CONFIG_IPV6 */
d337f35e 19120+
4bf69007 19121+/* __alloc_nx_info()
d337f35e 19122+
4bf69007
AM
19123+ * allocate an initialized nx_info struct
19124+ * doesn't make it visible (hash) */
d337f35e 19125+
61333608 19126+static struct nx_info *__alloc_nx_info(vnid_t nid)
d337f35e 19127+{
4bf69007 19128+ struct nx_info *new = NULL;
d337f35e 19129+
4bf69007 19130+ vxdprintk(VXD_CBIT(nid, 1), "alloc_nx_info(%d)*", nid);
d337f35e 19131+
4bf69007
AM
19132+ /* would this benefit from a slab cache? */
19133+ new = kmalloc(sizeof(struct nx_info), GFP_KERNEL);
19134+ if (!new)
19135+ return 0;
d337f35e 19136+
4bf69007
AM
19137+ memset(new, 0, sizeof(struct nx_info));
19138+ new->nx_id = nid;
19139+ INIT_HLIST_NODE(&new->nx_hlist);
19140+ atomic_set(&new->nx_usecnt, 0);
19141+ atomic_set(&new->nx_tasks, 0);
19142+ spin_lock_init(&new->addr_lock);
19143+ new->nx_state = 0;
d337f35e 19144+
4bf69007 19145+ new->nx_flags = NXF_INIT_SET;
d337f35e 19146+
4bf69007 19147+ /* rest of init goes here */
d337f35e 19148+
4bf69007
AM
19149+ new->v4_lback.s_addr = htonl(INADDR_LOOPBACK);
19150+ new->v4_bcast.s_addr = htonl(INADDR_BROADCAST);
19151+
19152+ vxdprintk(VXD_CBIT(nid, 0),
19153+ "alloc_nx_info(%d) = %p", nid, new);
19154+ atomic_inc(&nx_global_ctotal);
19155+ return new;
d337f35e
JR
19156+}
19157+
4bf69007 19158+/* __dealloc_nx_info()
d337f35e 19159+
4bf69007 19160+ * final disposal of nx_info */
d337f35e 19161+
4bf69007
AM
19162+static void __dealloc_nx_info(struct nx_info *nxi)
19163+{
19164+ vxdprintk(VXD_CBIT(nid, 0),
19165+ "dealloc_nx_info(%p)", nxi);
d337f35e 19166+
4bf69007
AM
19167+ nxi->nx_hlist.next = LIST_POISON1;
19168+ nxi->nx_id = -1;
d337f35e 19169+
4bf69007
AM
19170+ BUG_ON(atomic_read(&nxi->nx_usecnt));
19171+ BUG_ON(atomic_read(&nxi->nx_tasks));
19172+
19173+ __dealloc_nx_addr_v4_all(nxi->v4.next);
19174+#ifdef CONFIG_IPV6
19175+ __dealloc_nx_addr_v6_all(nxi->v6.next);
19176+#endif
19177+
19178+ nxi->nx_state |= NXS_RELEASED;
19179+ kfree(nxi);
19180+ atomic_dec(&nx_global_ctotal);
d337f35e
JR
19181+}
19182+
4bf69007
AM
19183+static void __shutdown_nx_info(struct nx_info *nxi)
19184+{
19185+ nxi->nx_state |= NXS_SHUTDOWN;
19186+ vs_net_change(nxi, VSC_NETDOWN);
19187+}
d337f35e 19188+
4bf69007 19189+/* exported stuff */
d337f35e 19190+
4bf69007
AM
19191+void free_nx_info(struct nx_info *nxi)
19192+{
19193+ /* context shutdown is mandatory */
19194+ BUG_ON(nxi->nx_state != NXS_SHUTDOWN);
d337f35e 19195+
4bf69007
AM
19196+ /* context must not be hashed */
19197+ BUG_ON(nxi->nx_state & NXS_HASHED);
d337f35e 19198+
4bf69007
AM
19199+ BUG_ON(atomic_read(&nxi->nx_usecnt));
19200+ BUG_ON(atomic_read(&nxi->nx_tasks));
d337f35e 19201+
4bf69007
AM
19202+ __dealloc_nx_info(nxi);
19203+}
d337f35e 19204+
d337f35e 19205+
4bf69007
AM
19206+void __nx_set_lback(struct nx_info *nxi)
19207+{
19208+ int nid = nxi->nx_id;
19209+ __be32 lback = htonl(INADDR_LOOPBACK ^ ((nid & 0xFFFF) << 8));
d337f35e 19210+
4bf69007
AM
19211+ nxi->v4_lback.s_addr = lback;
19212+}
d337f35e 19213+
4bf69007
AM
19214+extern int __nx_inet_add_lback(__be32 addr);
19215+extern int __nx_inet_del_lback(__be32 addr);
d337f35e
JR
19216+
19217+
4bf69007 19218+/* hash table for nx_info hash */
d337f35e 19219+
4bf69007 19220+#define NX_HASH_SIZE 13
d337f35e 19221+
4bf69007
AM
19222+struct hlist_head nx_info_hash[NX_HASH_SIZE];
19223+
19224+static DEFINE_SPINLOCK(nx_info_hash_lock);
19225+
19226+
61333608 19227+static inline unsigned int __hashval(vnid_t nid)
d337f35e 19228+{
4bf69007 19229+ return (nid % NX_HASH_SIZE);
d337f35e
JR
19230+}
19231+
d337f35e 19232+
d337f35e 19233+
4bf69007 19234+/* __hash_nx_info()
d337f35e 19235+
4bf69007
AM
19236+ * add the nxi to the global hash table
19237+ * requires the hash_lock to be held */
19238+
19239+static inline void __hash_nx_info(struct nx_info *nxi)
d337f35e 19240+{
4bf69007 19241+ struct hlist_head *head;
d337f35e 19242+
4bf69007
AM
19243+ vxd_assert_lock(&nx_info_hash_lock);
19244+ vxdprintk(VXD_CBIT(nid, 4),
19245+ "__hash_nx_info: %p[#%d]", nxi, nxi->nx_id);
d337f35e 19246+
4bf69007
AM
19247+ /* context must not be hashed */
19248+ BUG_ON(nx_info_state(nxi, NXS_HASHED));
d337f35e 19249+
4bf69007
AM
19250+ nxi->nx_state |= NXS_HASHED;
19251+ head = &nx_info_hash[__hashval(nxi->nx_id)];
19252+ hlist_add_head(&nxi->nx_hlist, head);
19253+ atomic_inc(&nx_global_cactive);
19254+}
d337f35e 19255+
4bf69007 19256+/* __unhash_nx_info()
d337f35e 19257+
4bf69007
AM
19258+ * remove the nxi from the global hash table
19259+ * requires the hash_lock to be held */
d337f35e 19260+
4bf69007
AM
19261+static inline void __unhash_nx_info(struct nx_info *nxi)
19262+{
19263+ vxd_assert_lock(&nx_info_hash_lock);
19264+ vxdprintk(VXD_CBIT(nid, 4),
19265+ "__unhash_nx_info: %p[#%d.%d.%d]", nxi, nxi->nx_id,
19266+ atomic_read(&nxi->nx_usecnt), atomic_read(&nxi->nx_tasks));
d337f35e 19267+
4bf69007
AM
19268+ /* context must be hashed */
19269+ BUG_ON(!nx_info_state(nxi, NXS_HASHED));
19270+ /* but without tasks */
19271+ BUG_ON(atomic_read(&nxi->nx_tasks));
d337f35e 19272+
4bf69007
AM
19273+ nxi->nx_state &= ~NXS_HASHED;
19274+ hlist_del(&nxi->nx_hlist);
19275+ atomic_dec(&nx_global_cactive);
d337f35e
JR
19276+}
19277+
d337f35e 19278+
4bf69007 19279+/* __lookup_nx_info()
d337f35e 19280+
4bf69007
AM
19281+ * requires the hash_lock to be held
19282+ * doesn't increment the nx_refcnt */
d337f35e 19283+
61333608 19284+static inline struct nx_info *__lookup_nx_info(vnid_t nid)
d337f35e 19285+{
4bf69007
AM
19286+ struct hlist_head *head = &nx_info_hash[__hashval(nid)];
19287+ struct hlist_node *pos;
19288+ struct nx_info *nxi;
d337f35e 19289+
4bf69007
AM
19290+ vxd_assert_lock(&nx_info_hash_lock);
19291+ hlist_for_each(pos, head) {
19292+ nxi = hlist_entry(pos, struct nx_info, nx_hlist);
19293+
19294+ if (nxi->nx_id == nid)
19295+ goto found;
d337f35e 19296+ }
4bf69007
AM
19297+ nxi = NULL;
19298+found:
19299+ vxdprintk(VXD_CBIT(nid, 0),
19300+ "__lookup_nx_info(#%u): %p[#%u]",
19301+ nid, nxi, nxi ? nxi->nx_id : 0);
19302+ return nxi;
d337f35e
JR
19303+}
19304+
19305+
4bf69007 19306+/* __create_nx_info()
d337f35e 19307+
4bf69007
AM
19308+ * create the requested context
19309+ * get(), claim() and hash it */
d337f35e 19310+
4bf69007
AM
19311+static struct nx_info *__create_nx_info(int id)
19312+{
19313+ struct nx_info *new, *nxi = NULL;
d337f35e 19314+
4bf69007 19315+ vxdprintk(VXD_CBIT(nid, 1), "create_nx_info(%d)*", id);
d337f35e 19316+
4bf69007
AM
19317+ if (!(new = __alloc_nx_info(id)))
19318+ return ERR_PTR(-ENOMEM);
d337f35e 19319+
4bf69007
AM
19320+ /* required to make dynamic xids unique */
19321+ spin_lock(&nx_info_hash_lock);
d337f35e 19322+
4bf69007
AM
19323+ /* static context requested */
19324+ if ((nxi = __lookup_nx_info(id))) {
19325+ vxdprintk(VXD_CBIT(nid, 0),
19326+ "create_nx_info(%d) = %p (already there)", id, nxi);
19327+ if (nx_info_flags(nxi, NXF_STATE_SETUP, 0))
19328+ nxi = ERR_PTR(-EBUSY);
19329+ else
19330+ nxi = ERR_PTR(-EEXIST);
19331+ goto out_unlock;
19332+ }
19333+ /* new context */
19334+ vxdprintk(VXD_CBIT(nid, 0),
19335+ "create_nx_info(%d) = %p (new)", id, new);
19336+ claim_nx_info(new, NULL);
19337+ __nx_set_lback(new);
19338+ __hash_nx_info(get_nx_info(new));
19339+ nxi = new, new = NULL;
d337f35e 19340+
4bf69007
AM
19341+out_unlock:
19342+ spin_unlock(&nx_info_hash_lock);
19343+ if (new)
19344+ __dealloc_nx_info(new);
19345+ return nxi;
19346+}
d337f35e
JR
19347+
19348+
d337f35e 19349+
4bf69007 19350+/* exported stuff */
d337f35e 19351+
d337f35e 19352+
4bf69007
AM
19353+void unhash_nx_info(struct nx_info *nxi)
19354+{
19355+ __shutdown_nx_info(nxi);
19356+ spin_lock(&nx_info_hash_lock);
19357+ __unhash_nx_info(nxi);
19358+ spin_unlock(&nx_info_hash_lock);
d337f35e
JR
19359+}
19360+
4bf69007 19361+/* lookup_nx_info()
d337f35e 19362+
4bf69007
AM
19363+ * search for a nx_info and get() it
19364+ * negative id means current */
d337f35e 19365+
4bf69007 19366+struct nx_info *lookup_nx_info(int id)
d337f35e 19367+{
4bf69007 19368+ struct nx_info *nxi = NULL;
d337f35e 19369+
4bf69007
AM
19370+ if (id < 0) {
19371+ nxi = get_nx_info(current_nx_info());
19372+ } else if (id > 1) {
19373+ spin_lock(&nx_info_hash_lock);
19374+ nxi = get_nx_info(__lookup_nx_info(id));
19375+ spin_unlock(&nx_info_hash_lock);
d337f35e 19376+ }
4bf69007
AM
19377+ return nxi;
19378+}
d337f35e 19379+
4bf69007 19380+/* nid_is_hashed()
d337f35e 19381+
4bf69007
AM
19382+ * verify that nid is still hashed */
19383+
61333608 19384+int nid_is_hashed(vnid_t nid)
4bf69007
AM
19385+{
19386+ int hashed;
19387+
19388+ spin_lock(&nx_info_hash_lock);
19389+ hashed = (__lookup_nx_info(nid) != NULL);
19390+ spin_unlock(&nx_info_hash_lock);
19391+ return hashed;
d337f35e
JR
19392+}
19393+
19394+
4bf69007 19395+#ifdef CONFIG_PROC_FS
d337f35e 19396+
4bf69007
AM
19397+/* get_nid_list()
19398+
19399+ * get a subset of hashed nids for proc
19400+ * assumes size is at least one */
19401+
19402+int get_nid_list(int index, unsigned int *nids, int size)
d337f35e 19403+{
4bf69007 19404+ int hindex, nr_nids = 0;
d337f35e 19405+
4bf69007
AM
19406+ /* only show current and children */
19407+ if (!nx_check(0, VS_ADMIN | VS_WATCH)) {
19408+ if (index > 0)
19409+ return 0;
19410+ nids[nr_nids] = nx_current_nid();
19411+ return 1;
19412+ }
d337f35e 19413+
4bf69007
AM
19414+ for (hindex = 0; hindex < NX_HASH_SIZE; hindex++) {
19415+ struct hlist_head *head = &nx_info_hash[hindex];
19416+ struct hlist_node *pos;
d337f35e 19417+
4bf69007
AM
19418+ spin_lock(&nx_info_hash_lock);
19419+ hlist_for_each(pos, head) {
19420+ struct nx_info *nxi;
19421+
19422+ if (--index > 0)
19423+ continue;
19424+
19425+ nxi = hlist_entry(pos, struct nx_info, nx_hlist);
19426+ nids[nr_nids] = nxi->nx_id;
19427+ if (++nr_nids >= size) {
19428+ spin_unlock(&nx_info_hash_lock);
d337f35e 19429+ goto out;
4bf69007 19430+ }
d337f35e 19431+ }
4bf69007
AM
19432+ /* keep the lock time short */
19433+ spin_unlock(&nx_info_hash_lock);
d337f35e
JR
19434+ }
19435+out:
4bf69007 19436+ return nr_nids;
d337f35e 19437+}
4bf69007 19438+#endif
d337f35e 19439+
4bf69007
AM
19440+
19441+/*
19442+ * migrate task to new network
19443+ * gets nxi, puts old_nxi on change
19444+ */
19445+
19446+int nx_migrate_task(struct task_struct *p, struct nx_info *nxi)
2380c486 19447+{
4bf69007
AM
19448+ struct nx_info *old_nxi;
19449+ int ret = 0;
2380c486 19450+
4bf69007
AM
19451+ if (!p || !nxi)
19452+ BUG();
d337f35e 19453+
4bf69007
AM
19454+ vxdprintk(VXD_CBIT(nid, 5),
19455+ "nx_migrate_task(%p,%p[#%d.%d.%d])",
19456+ p, nxi, nxi->nx_id,
19457+ atomic_read(&nxi->nx_usecnt),
19458+ atomic_read(&nxi->nx_tasks));
d337f35e 19459+
4bf69007
AM
19460+ if (nx_info_flags(nxi, NXF_INFO_PRIVATE, 0) &&
19461+ !nx_info_flags(nxi, NXF_STATE_SETUP, 0))
19462+ return -EACCES;
d337f35e 19463+
4bf69007
AM
19464+ if (nx_info_state(nxi, NXS_SHUTDOWN))
19465+ return -EFAULT;
d337f35e 19466+
4bf69007
AM
19467+ /* maybe disallow this completely? */
19468+ old_nxi = task_get_nx_info(p);
19469+ if (old_nxi == nxi)
19470+ goto out;
d337f35e 19471+
4bf69007
AM
19472+ task_lock(p);
19473+ if (old_nxi)
19474+ clr_nx_info(&p->nx_info);
19475+ claim_nx_info(nxi, p);
19476+ set_nx_info(&p->nx_info, nxi);
19477+ p->nid = nxi->nx_id;
19478+ task_unlock(p);
d337f35e 19479+
4bf69007
AM
19480+ vxdprintk(VXD_CBIT(nid, 5),
19481+ "moved task %p into nxi:%p[#%d]",
19482+ p, nxi, nxi->nx_id);
d337f35e 19483+
4bf69007
AM
19484+ if (old_nxi)
19485+ release_nx_info(old_nxi, p);
19486+ ret = 0;
19487+out:
19488+ put_nx_info(old_nxi);
19489+ return ret;
19490+}
d337f35e 19491+
d337f35e 19492+
4bf69007
AM
19493+void nx_set_persistent(struct nx_info *nxi)
19494+{
19495+ vxdprintk(VXD_CBIT(nid, 6),
19496+ "nx_set_persistent(%p[#%d])", nxi, nxi->nx_id);
d337f35e 19497+
4bf69007
AM
19498+ get_nx_info(nxi);
19499+ claim_nx_info(nxi, NULL);
d337f35e
JR
19500+}
19501+
4bf69007 19502+void nx_clear_persistent(struct nx_info *nxi)
2380c486 19503+{
4bf69007
AM
19504+ vxdprintk(VXD_CBIT(nid, 6),
19505+ "nx_clear_persistent(%p[#%d])", nxi, nxi->nx_id);
2380c486 19506+
4bf69007
AM
19507+ release_nx_info(nxi, NULL);
19508+ put_nx_info(nxi);
2380c486 19509+}
d337f35e 19510+
4bf69007
AM
19511+void nx_update_persistent(struct nx_info *nxi)
19512+{
19513+ if (nx_info_flags(nxi, NXF_PERSISTENT, 0))
19514+ nx_set_persistent(nxi);
19515+ else
19516+ nx_clear_persistent(nxi);
19517+}
d337f35e 19518+
4bf69007
AM
19519+/* vserver syscall commands below here */
19520+
19521+/* taks nid and nx_info functions */
d337f35e 19522+
4bf69007 19523+#include <asm/uaccess.h>
d337f35e
JR
19524+
19525+
4bf69007 19526+int vc_task_nid(uint32_t id)
d337f35e 19527+{
61333608 19528+ vnid_t nid;
d337f35e 19529+
4bf69007
AM
19530+ if (id) {
19531+ struct task_struct *tsk;
d337f35e 19532+
4bf69007
AM
19533+ rcu_read_lock();
19534+ tsk = find_task_by_real_pid(id);
19535+ nid = (tsk) ? tsk->nid : -ESRCH;
19536+ rcu_read_unlock();
19537+ } else
19538+ nid = nx_current_nid();
19539+ return nid;
d337f35e
JR
19540+}
19541+
19542+
4bf69007
AM
19543+int vc_nx_info(struct nx_info *nxi, void __user *data)
19544+{
19545+ struct vcmd_nx_info_v0 vc_data;
d337f35e 19546+
4bf69007 19547+ vc_data.nid = nxi->nx_id;
d337f35e 19548+
4bf69007
AM
19549+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
19550+ return -EFAULT;
19551+ return 0;
19552+}
d337f35e 19553+
d337f35e 19554+
4bf69007 19555+/* network functions */
d337f35e 19556+
4bf69007
AM
19557+int vc_net_create(uint32_t nid, void __user *data)
19558+{
19559+ struct vcmd_net_create vc_data = { .flagword = NXF_INIT_SET };
19560+ struct nx_info *new_nxi;
19561+ int ret;
d337f35e 19562+
4bf69007
AM
19563+ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
19564+ return -EFAULT;
d337f35e 19565+
4bf69007
AM
19566+ if ((nid > MAX_S_CONTEXT) || (nid < 2))
19567+ return -EINVAL;
d337f35e 19568+
4bf69007
AM
19569+ new_nxi = __create_nx_info(nid);
19570+ if (IS_ERR(new_nxi))
19571+ return PTR_ERR(new_nxi);
d337f35e 19572+
4bf69007
AM
19573+ /* initial flags */
19574+ new_nxi->nx_flags = vc_data.flagword;
d337f35e 19575+
4bf69007
AM
19576+ ret = -ENOEXEC;
19577+ if (vs_net_change(new_nxi, VSC_NETUP))
19578+ goto out;
d337f35e 19579+
4bf69007
AM
19580+ ret = nx_migrate_task(current, new_nxi);
19581+ if (ret)
d337f35e
JR
19582+ goto out;
19583+
4bf69007
AM
19584+ /* return context id on success */
19585+ ret = new_nxi->nx_id;
d337f35e 19586+
4bf69007
AM
19587+ /* get a reference for persistent contexts */
19588+ if ((vc_data.flagword & NXF_PERSISTENT))
19589+ nx_set_persistent(new_nxi);
d337f35e 19590+out:
4bf69007
AM
19591+ release_nx_info(new_nxi, NULL);
19592+ put_nx_info(new_nxi);
19593+ return ret;
d337f35e
JR
19594+}
19595+
d337f35e 19596+
4bf69007
AM
19597+int vc_net_migrate(struct nx_info *nxi, void __user *data)
19598+{
19599+ return nx_migrate_task(current, nxi);
19600+}
d337f35e 19601+
2380c486 19602+
4bf69007
AM
19603+static inline
19604+struct nx_addr_v4 *__find_v4_addr(struct nx_info *nxi,
19605+ __be32 ip, __be32 ip2, __be32 mask, uint16_t type, uint16_t flags,
19606+ struct nx_addr_v4 **prev)
d337f35e 19607+{
4bf69007
AM
19608+ struct nx_addr_v4 *nxa = &nxi->v4;
19609+
19610+ for (; nxa; nxa = nxa->next) {
19611+ if ((nxa->ip[0].s_addr == ip) &&
19612+ (nxa->ip[1].s_addr == ip2) &&
19613+ (nxa->mask.s_addr == mask) &&
19614+ (nxa->type == type) &&
19615+ (nxa->flags == flags))
19616+ return nxa;
19617+
19618+ /* save previous entry */
19619+ if (prev)
19620+ *prev = nxa;
19621+ }
19622+ return NULL;
2380c486
JR
19623+}
19624+
4bf69007
AM
19625+int do_add_v4_addr(struct nx_info *nxi, __be32 ip, __be32 ip2, __be32 mask,
19626+ uint16_t type, uint16_t flags)
d337f35e 19627+{
4bf69007
AM
19628+ struct nx_addr_v4 *nxa = NULL;
19629+ struct nx_addr_v4 *new = __alloc_nx_addr_v4();
5cb1760b 19630+ unsigned long irqflags;
4bf69007 19631+ int ret = -EEXIST;
d337f35e 19632+
4bf69007
AM
19633+ if (IS_ERR(new))
19634+ return PTR_ERR(new);
d337f35e 19635+
5cb1760b 19636+ spin_lock_irqsave(&nxi->addr_lock, irqflags);
4bf69007
AM
19637+ if (__find_v4_addr(nxi, ip, ip2, mask, type, flags, &nxa))
19638+ goto out_unlock;
2380c486 19639+
4bf69007
AM
19640+ if (NX_IPV4(nxi)) {
19641+ nxa->next = new;
19642+ nxa = new;
19643+ new = NULL;
19644+
19645+ /* remove single ip for ip list */
19646+ nxi->nx_flags &= ~NXF_SINGLE_IP;
19647+ }
19648+
19649+ nxa->ip[0].s_addr = ip;
19650+ nxa->ip[1].s_addr = ip2;
19651+ nxa->mask.s_addr = mask;
19652+ nxa->type = type;
19653+ nxa->flags = flags;
19654+ ret = 0;
19655+out_unlock:
5cb1760b 19656+ spin_unlock_irqrestore(&nxi->addr_lock, irqflags);
4bf69007
AM
19657+ if (new)
19658+ __dealloc_nx_addr_v4(new);
19659+ return ret;
d337f35e
JR
19660+}
19661+
4bf69007
AM
19662+int do_remove_v4_addr(struct nx_info *nxi, __be32 ip, __be32 ip2, __be32 mask,
19663+ uint16_t type, uint16_t flags)
2380c486 19664+{
4bf69007
AM
19665+ struct nx_addr_v4 *nxa = NULL;
19666+ struct nx_addr_v4 *old = NULL;
5cb1760b 19667+ unsigned long irqflags;
4bf69007 19668+ int ret = 0;
2380c486 19669+
5cb1760b 19670+ spin_lock_irqsave(&nxi->addr_lock, irqflags);
4bf69007
AM
19671+ switch (type) {
19672+ case NXA_TYPE_ADDR:
19673+ old = __find_v4_addr(nxi, ip, ip2, mask, type, flags, &nxa);
19674+ if (old) {
19675+ if (nxa) {
19676+ nxa->next = old->next;
19677+ old->next = NULL;
19678+ } else {
19679+ if (old->next) {
19680+ nxa = old;
19681+ old = old->next;
19682+ *nxa = *old;
19683+ old->next = NULL;
19684+ } else {
19685+ memset(old, 0, sizeof(*old));
19686+ old = NULL;
19687+ }
19688+ }
19689+ } else
19690+ ret = -ESRCH;
19691+ break;
2380c486 19692+
4bf69007
AM
19693+ case NXA_TYPE_ANY:
19694+ nxa = &nxi->v4;
19695+ old = nxa->next;
19696+ memset(nxa, 0, sizeof(*nxa));
19697+ break;
19698+
19699+ default:
19700+ ret = -EINVAL;
19701+ }
5cb1760b 19702+ spin_unlock_irqrestore(&nxi->addr_lock, irqflags);
4bf69007
AM
19703+ __dealloc_nx_addr_v4_all(old);
19704+ return ret;
2380c486
JR
19705+}
19706+
4bf69007
AM
19707+
19708+int vc_net_add(struct nx_info *nxi, void __user *data)
2380c486 19709+{
4bf69007
AM
19710+ struct vcmd_net_addr_v0 vc_data;
19711+ int index, ret = 0;
2380c486 19712+
4bf69007 19713+ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
2380c486
JR
19714+ return -EFAULT;
19715+
4bf69007
AM
19716+ switch (vc_data.type) {
19717+ case NXA_TYPE_IPV4:
19718+ if ((vc_data.count < 1) || (vc_data.count > 4))
19719+ return -EINVAL;
adc1caaa 19720+
4bf69007
AM
19721+ index = 0;
19722+ while (index < vc_data.count) {
19723+ ret = do_add_v4_addr(nxi, vc_data.ip[index].s_addr, 0,
19724+ vc_data.mask[index].s_addr, NXA_TYPE_ADDR, 0);
19725+ if (ret)
19726+ return ret;
19727+ index++;
19728+ }
19729+ ret = index;
19730+ break;
2380c486 19731+
4bf69007
AM
19732+ case NXA_TYPE_IPV4|NXA_MOD_BCAST:
19733+ nxi->v4_bcast = vc_data.ip[0];
19734+ ret = 1;
19735+ break;
2380c486 19736+
4bf69007
AM
19737+ case NXA_TYPE_IPV4|NXA_MOD_LBACK:
19738+ nxi->v4_lback = vc_data.ip[0];
19739+ ret = 1;
19740+ break;
19741+
19742+ default:
19743+ ret = -EINVAL;
19744+ break;
19745+ }
19746+ return ret;
19747+}
19748+
19749+int vc_net_remove(struct nx_info *nxi, void __user *data)
19750+{
19751+ struct vcmd_net_addr_v0 vc_data;
19752+
19753+ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
2380c486 19754+ return -EFAULT;
4bf69007
AM
19755+
19756+ switch (vc_data.type) {
19757+ case NXA_TYPE_ANY:
19758+ return do_remove_v4_addr(nxi, 0, 0, 0, vc_data.type, 0);
19759+ default:
19760+ return -EINVAL;
19761+ }
2380c486
JR
19762+ return 0;
19763+}
19764+
d337f35e 19765+
4bf69007 19766+int vc_net_add_ipv4_v1(struct nx_info *nxi, void __user *data)
d337f35e 19767+{
4bf69007
AM
19768+ struct vcmd_net_addr_ipv4_v1 vc_data;
19769+
19770+ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
19771+ return -EFAULT;
19772+
19773+ switch (vc_data.type) {
19774+ case NXA_TYPE_ADDR:
19775+ case NXA_TYPE_MASK:
19776+ return do_add_v4_addr(nxi, vc_data.ip.s_addr, 0,
19777+ vc_data.mask.s_addr, vc_data.type, vc_data.flags);
19778+
19779+ case NXA_TYPE_ADDR | NXA_MOD_BCAST:
19780+ nxi->v4_bcast = vc_data.ip;
19781+ break;
19782+
19783+ case NXA_TYPE_ADDR | NXA_MOD_LBACK:
19784+ nxi->v4_lback = vc_data.ip;
19785+ break;
19786+
19787+ default:
19788+ return -EINVAL;
19789+ }
19790+ return 0;
d337f35e
JR
19791+}
19792+
4bf69007 19793+int vc_net_add_ipv4(struct nx_info *nxi, void __user *data)
d337f35e 19794+{
4bf69007 19795+ struct vcmd_net_addr_ipv4_v2 vc_data;
d337f35e 19796+
4bf69007
AM
19797+ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
19798+ return -EFAULT;
19799+
19800+ switch (vc_data.type) {
19801+ case NXA_TYPE_ADDR:
19802+ case NXA_TYPE_MASK:
19803+ case NXA_TYPE_RANGE:
19804+ return do_add_v4_addr(nxi, vc_data.ip.s_addr, vc_data.ip2.s_addr,
19805+ vc_data.mask.s_addr, vc_data.type, vc_data.flags);
19806+
19807+ case NXA_TYPE_ADDR | NXA_MOD_BCAST:
19808+ nxi->v4_bcast = vc_data.ip;
19809+ break;
19810+
19811+ case NXA_TYPE_ADDR | NXA_MOD_LBACK:
19812+ nxi->v4_lback = vc_data.ip;
19813+ break;
19814+
19815+ default:
19816+ return -EINVAL;
19817+ }
19818+ return 0;
d337f35e
JR
19819+}
19820+
4bf69007 19821+int vc_net_rem_ipv4_v1(struct nx_info *nxi, void __user *data)
d337f35e 19822+{
4bf69007
AM
19823+ struct vcmd_net_addr_ipv4_v1 vc_data;
19824+
19825+ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
19826+ return -EFAULT;
19827+
19828+ return do_remove_v4_addr(nxi, vc_data.ip.s_addr, 0,
19829+ vc_data.mask.s_addr, vc_data.type, vc_data.flags);
d337f35e
JR
19830+}
19831+
4bf69007 19832+int vc_net_rem_ipv4(struct nx_info *nxi, void __user *data)
d337f35e 19833+{
4bf69007
AM
19834+ struct vcmd_net_addr_ipv4_v2 vc_data;
19835+
19836+ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
19837+ return -EFAULT;
19838+
19839+ return do_remove_v4_addr(nxi, vc_data.ip.s_addr, vc_data.ip2.s_addr,
19840+ vc_data.mask.s_addr, vc_data.type, vc_data.flags);
d337f35e 19841+}
d337f35e 19842+
4bf69007 19843+#ifdef CONFIG_IPV6
d337f35e
JR
19844+
19845+static inline
4bf69007
AM
19846+struct nx_addr_v6 *__find_v6_addr(struct nx_info *nxi,
19847+ struct in6_addr *ip, struct in6_addr *mask,
19848+ uint32_t prefix, uint16_t type, uint16_t flags,
19849+ struct nx_addr_v6 **prev)
d337f35e 19850+{
4bf69007 19851+ struct nx_addr_v6 *nxa = &nxi->v6;
d337f35e 19852+
4bf69007
AM
19853+ for (; nxa; nxa = nxa->next) {
19854+ if (ipv6_addr_equal(&nxa->ip, ip) &&
19855+ ipv6_addr_equal(&nxa->mask, mask) &&
19856+ (nxa->prefix == prefix) &&
19857+ (nxa->type == type) &&
19858+ (nxa->flags == flags))
19859+ return nxa;
19860+
19861+ /* save previous entry */
19862+ if (prev)
19863+ *prev = nxa;
19864+ }
19865+ return NULL;
d337f35e
JR
19866+}
19867+
d337f35e 19868+
4bf69007
AM
19869+int do_add_v6_addr(struct nx_info *nxi,
19870+ struct in6_addr *ip, struct in6_addr *mask,
19871+ uint32_t prefix, uint16_t type, uint16_t flags)
19872+{
19873+ struct nx_addr_v6 *nxa = NULL;
19874+ struct nx_addr_v6 *new = __alloc_nx_addr_v6();
5cb1760b 19875+ unsigned long irqflags;
4bf69007 19876+ int ret = -EEXIST;
d337f35e 19877+
4bf69007
AM
19878+ if (IS_ERR(new))
19879+ return PTR_ERR(new);
d337f35e 19880+
5cb1760b 19881+ spin_lock_irqsave(&nxi->addr_lock, irqflags);
4bf69007
AM
19882+ if (__find_v6_addr(nxi, ip, mask, prefix, type, flags, &nxa))
19883+ goto out_unlock;
d337f35e 19884+
4bf69007
AM
19885+ if (NX_IPV6(nxi)) {
19886+ nxa->next = new;
19887+ nxa = new;
19888+ new = NULL;
19889+ }
d337f35e 19890+
4bf69007
AM
19891+ nxa->ip = *ip;
19892+ nxa->mask = *mask;
19893+ nxa->prefix = prefix;
19894+ nxa->type = type;
19895+ nxa->flags = flags;
19896+ ret = 0;
19897+out_unlock:
5cb1760b 19898+ spin_unlock_irqrestore(&nxi->addr_lock, irqflags);
4bf69007
AM
19899+ if (new)
19900+ __dealloc_nx_addr_v6(new);
19901+ return ret;
19902+}
d337f35e 19903+
4bf69007
AM
19904+int do_remove_v6_addr(struct nx_info *nxi,
19905+ struct in6_addr *ip, struct in6_addr *mask,
19906+ uint32_t prefix, uint16_t type, uint16_t flags)
d337f35e 19907+{
4bf69007
AM
19908+ struct nx_addr_v6 *nxa = NULL;
19909+ struct nx_addr_v6 *old = NULL;
5cb1760b 19910+ unsigned long irqflags;
4bf69007 19911+ int ret = 0;
d337f35e 19912+
5cb1760b 19913+ spin_lock_irqsave(&nxi->addr_lock, irqflags);
4bf69007
AM
19914+ switch (type) {
19915+ case NXA_TYPE_ADDR:
19916+ old = __find_v6_addr(nxi, ip, mask, prefix, type, flags, &nxa);
19917+ if (old) {
19918+ if (nxa) {
19919+ nxa->next = old->next;
19920+ old->next = NULL;
19921+ } else {
19922+ if (old->next) {
19923+ nxa = old;
19924+ old = old->next;
19925+ *nxa = *old;
19926+ old->next = NULL;
19927+ } else {
19928+ memset(old, 0, sizeof(*old));
19929+ old = NULL;
19930+ }
19931+ }
19932+ } else
19933+ ret = -ESRCH;
19934+ break;
d337f35e 19935+
4bf69007
AM
19936+ case NXA_TYPE_ANY:
19937+ nxa = &nxi->v6;
19938+ old = nxa->next;
19939+ memset(nxa, 0, sizeof(*nxa));
d337f35e
JR
19940+ break;
19941+
d337f35e 19942+ default:
4bf69007 19943+ ret = -EINVAL;
d337f35e 19944+ }
5cb1760b 19945+ spin_unlock_irqrestore(&nxi->addr_lock, irqflags);
4bf69007
AM
19946+ __dealloc_nx_addr_v6_all(old);
19947+ return ret;
d337f35e
JR
19948+}
19949+
4bf69007 19950+int vc_net_add_ipv6(struct nx_info *nxi, void __user *data)
d337f35e 19951+{
4bf69007 19952+ struct vcmd_net_addr_ipv6_v1 vc_data;
d337f35e 19953+
4bf69007 19954+ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
d337f35e
JR
19955+ return -EFAULT;
19956+
4bf69007
AM
19957+ switch (vc_data.type) {
19958+ case NXA_TYPE_ADDR:
19959+ memset(&vc_data.mask, ~0, sizeof(vc_data.mask));
19960+ /* fallthrough */
19961+ case NXA_TYPE_MASK:
19962+ return do_add_v6_addr(nxi, &vc_data.ip, &vc_data.mask,
19963+ vc_data.prefix, vc_data.type, vc_data.flags);
19964+ default:
19965+ return -EINVAL;
19966+ }
19967+ return 0;
19968+}
d337f35e 19969+
4bf69007
AM
19970+int vc_net_remove_ipv6(struct nx_info *nxi, void __user *data)
19971+{
19972+ struct vcmd_net_addr_ipv6_v1 vc_data;
19973+
19974+ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
19975+ return -EFAULT;
19976+
19977+ switch (vc_data.type) {
19978+ case NXA_TYPE_ADDR:
19979+ memset(&vc_data.mask, ~0, sizeof(vc_data.mask));
19980+ /* fallthrough */
19981+ case NXA_TYPE_MASK:
19982+ return do_remove_v6_addr(nxi, &vc_data.ip, &vc_data.mask,
19983+ vc_data.prefix, vc_data.type, vc_data.flags);
19984+ case NXA_TYPE_ANY:
19985+ return do_remove_v6_addr(nxi, NULL, NULL, 0, vc_data.type, 0);
19986+ default:
19987+ return -EINVAL;
19988+ }
19989+ return 0;
d337f35e
JR
19990+}
19991+
4bf69007 19992+#endif /* CONFIG_IPV6 */
d337f35e 19993+
4bf69007
AM
19994+
19995+int vc_get_nflags(struct nx_info *nxi, void __user *data)
d337f35e 19996+{
4bf69007 19997+ struct vcmd_net_flags_v0 vc_data;
d337f35e 19998+
4bf69007 19999+ vc_data.flagword = nxi->nx_flags;
d337f35e 20000+
4bf69007
AM
20001+ /* special STATE flag handling */
20002+ vc_data.mask = vs_mask_flags(~0ULL, nxi->nx_flags, NXF_ONE_TIME);
d337f35e 20003+
4bf69007
AM
20004+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
20005+ return -EFAULT;
20006+ return 0;
d337f35e
JR
20007+}
20008+
4bf69007
AM
20009+int vc_set_nflags(struct nx_info *nxi, void __user *data)
20010+{
20011+ struct vcmd_net_flags_v0 vc_data;
20012+ uint64_t mask, trigger;
20013+
20014+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
20015+ return -EFAULT;
d337f35e 20016+
4bf69007
AM
20017+ /* special STATE flag handling */
20018+ mask = vs_mask_mask(vc_data.mask, nxi->nx_flags, NXF_ONE_TIME);
20019+ trigger = (mask & nxi->nx_flags) ^ (mask & vc_data.flagword);
d337f35e 20020+
4bf69007
AM
20021+ nxi->nx_flags = vs_mask_flags(nxi->nx_flags,
20022+ vc_data.flagword, mask);
20023+ if (trigger & NXF_PERSISTENT)
20024+ nx_update_persistent(nxi);
20025+
20026+ return 0;
20027+}
20028+
20029+int vc_get_ncaps(struct nx_info *nxi, void __user *data)
d337f35e 20030+{
4bf69007 20031+ struct vcmd_net_caps_v0 vc_data;
d337f35e 20032+
4bf69007
AM
20033+ vc_data.ncaps = nxi->nx_ncaps;
20034+ vc_data.cmask = ~0ULL;
d337f35e 20035+
2380c486 20036+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
4bf69007
AM
20037+ return -EFAULT;
20038+ return 0;
d337f35e
JR
20039+}
20040+
4bf69007
AM
20041+int vc_set_ncaps(struct nx_info *nxi, void __user *data)
20042+{
20043+ struct vcmd_net_caps_v0 vc_data;
20044+
20045+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
20046+ return -EFAULT;
20047+
20048+ nxi->nx_ncaps = vs_mask_flags(nxi->nx_ncaps,
20049+ vc_data.ncaps, vc_data.cmask);
20050+ return 0;
20051+}
20052+
20053+
20054+#include <linux/module.h>
20055+
20056+module_init(init_network);
20057+
20058+EXPORT_SYMBOL_GPL(free_nx_info);
20059+EXPORT_SYMBOL_GPL(unhash_nx_info);
20060+
3261cfd5
AM
20061diff -NurpP --minimal linux-4.9.207/kernel/vserver/proc.c linux-4.9.207-vs2.3.9.11/kernel/vserver/proc.c
20062--- linux-4.9.207/kernel/vserver/proc.c 1970-01-01 00:00:00.000000000 +0000
20063+++ linux-4.9.207-vs2.3.9.11/kernel/vserver/proc.c 2018-10-20 04:58:15.000000000 +0000
cc23e853 20064@@ -0,0 +1,1040 @@
d337f35e 20065+/*
4bf69007 20066+ * linux/kernel/vserver/proc.c
d337f35e 20067+ *
4bf69007 20068+ * Virtual Context Support
d337f35e 20069+ *
cc23e853 20070+ * Copyright (C) 2003-2011 Herbert P?tzl
d337f35e 20071+ *
4bf69007
AM
20072+ * V0.01 basic structure
20073+ * V0.02 adaptation vs1.3.0
20074+ * V0.03 proc permissions
20075+ * V0.04 locking/generic
20076+ * V0.05 next generation procfs
20077+ * V0.06 inode validation
20078+ * V0.07 generic rewrite vid
20079+ * V0.08 remove inode type
20080+ * V0.09 added u/wmask info
d337f35e
JR
20081+ *
20082+ */
20083+
4bf69007 20084+#include <linux/proc_fs.h>
ec22aa5c 20085+#include <linux/fs_struct.h>
4bf69007
AM
20086+#include <linux/mount.h>
20087+#include <linux/namei.h>
20088+#include <asm/unistd.h>
2380c486 20089+
d337f35e 20090+#include <linux/vs_context.h>
4bf69007
AM
20091+#include <linux/vs_network.h>
20092+#include <linux/vs_cvirt.h>
d337f35e 20093+
4bf69007
AM
20094+#include <linux/in.h>
20095+#include <linux/inetdevice.h>
20096+#include <linux/vs_inet.h>
20097+#include <linux/vs_inet6.h>
d337f35e 20098+
4bf69007 20099+#include <linux/vserver/global.h>
d337f35e 20100+
4bf69007
AM
20101+#include "cvirt_proc.h"
20102+#include "cacct_proc.h"
20103+#include "limit_proc.h"
20104+#include "sched_proc.h"
20105+#include "vci_config.h"
d337f35e 20106+
09be7631
JR
20107+#include <../../fs/proc/internal.h>
20108+
2380c486 20109+
4bf69007
AM
20110+static inline char *print_cap_t(char *buffer, kernel_cap_t *c)
20111+{
20112+ unsigned __capi;
2380c486 20113+
4bf69007
AM
20114+ CAP_FOR_EACH_U32(__capi) {
20115+ buffer += sprintf(buffer, "%08x",
20116+ c->cap[(_KERNEL_CAPABILITY_U32S-1) - __capi]);
20117+ }
20118+ return buffer;
20119+}
2380c486 20120+
d337f35e 20121+
4bf69007 20122+static struct proc_dir_entry *proc_virtual;
d337f35e 20123+
4bf69007 20124+static struct proc_dir_entry *proc_virtnet;
d337f35e 20125+
d337f35e 20126+
4bf69007 20127+/* first the actual feeds */
d337f35e 20128+
d337f35e 20129+
4bf69007
AM
20130+static int proc_vci(char *buffer)
20131+{
20132+ return sprintf(buffer,
20133+ "VCIVersion:\t%04x:%04x\n"
20134+ "VCISyscall:\t%d\n"
20135+ "VCIKernel:\t%08x\n",
20136+ VCI_VERSION >> 16,
20137+ VCI_VERSION & 0xFFFF,
20138+ __NR_vserver,
20139+ vci_kernel_config());
20140+}
d337f35e 20141+
4bf69007
AM
20142+static int proc_virtual_info(char *buffer)
20143+{
20144+ return proc_vci(buffer);
d337f35e
JR
20145+}
20146+
4bf69007
AM
20147+static int proc_virtual_status(char *buffer)
20148+{
20149+ return sprintf(buffer,
20150+ "#CTotal:\t%d\n"
20151+ "#CActive:\t%d\n"
20152+ "#NSProxy:\t%d\t%d %d %d %d %d %d\n"
20153+ "#InitTask:\t%d\t%d %d\n",
20154+ atomic_read(&vx_global_ctotal),
20155+ atomic_read(&vx_global_cactive),
20156+ atomic_read(&vs_global_nsproxy),
20157+ atomic_read(&vs_global_fs),
20158+ atomic_read(&vs_global_mnt_ns),
20159+ atomic_read(&vs_global_uts_ns),
cc23e853 20160+ atomic_read(&vs_global_ipc_ns),
4bf69007
AM
20161+ atomic_read(&vs_global_user_ns),
20162+ atomic_read(&vs_global_pid_ns),
20163+ atomic_read(&init_task.usage),
20164+ atomic_read(&init_task.nsproxy->count),
20165+ init_task.fs->users);
20166+}
2380c486 20167+
2380c486 20168+
4bf69007 20169+int proc_vxi_info(struct vx_info *vxi, char *buffer)
d337f35e 20170+{
4bf69007 20171+ int length;
d337f35e 20172+
4bf69007
AM
20173+ length = sprintf(buffer,
20174+ "ID:\t%d\n"
20175+ "Info:\t%p\n"
20176+ "Init:\t%d\n"
20177+ "OOM:\t%lld\n",
20178+ vxi->vx_id,
20179+ vxi,
20180+ vxi->vx_initpid,
20181+ vxi->vx_badness_bias);
20182+ return length;
d337f35e
JR
20183+}
20184+
4bf69007 20185+int proc_vxi_status(struct vx_info *vxi, char *buffer)
d337f35e 20186+{
4bf69007 20187+ char *orig = buffer;
d337f35e 20188+
4bf69007
AM
20189+ buffer += sprintf(buffer,
20190+ "UseCnt:\t%d\n"
20191+ "Tasks:\t%d\n"
20192+ "Flags:\t%016llx\n",
20193+ atomic_read(&vxi->vx_usecnt),
20194+ atomic_read(&vxi->vx_tasks),
20195+ (unsigned long long)vxi->vx_flags);
d337f35e 20196+
4bf69007
AM
20197+ buffer += sprintf(buffer, "BCaps:\t");
20198+ buffer = print_cap_t(buffer, &vxi->vx_bcaps);
20199+ buffer += sprintf(buffer, "\n");
ab30d09f 20200+
4bf69007
AM
20201+ buffer += sprintf(buffer,
20202+ "CCaps:\t%016llx\n"
20203+ "Umask:\t%16llx\n"
20204+ "Wmask:\t%16llx\n"
20205+ "Spaces:\t%08lx %08lx\n",
20206+ (unsigned long long)vxi->vx_ccaps,
20207+ (unsigned long long)vxi->vx_umask,
20208+ (unsigned long long)vxi->vx_wmask,
20209+ vxi->space[0].vx_nsmask, vxi->space[1].vx_nsmask);
20210+ return buffer - orig;
20211+}
ab30d09f 20212+
4bf69007
AM
20213+int proc_vxi_limit(struct vx_info *vxi, char *buffer)
20214+{
20215+ return vx_info_proc_limit(&vxi->limit, buffer);
20216+}
d337f35e 20217+
4bf69007
AM
20218+int proc_vxi_sched(struct vx_info *vxi, char *buffer)
20219+{
20220+ int cpu, length;
d337f35e 20221+
4bf69007
AM
20222+ length = vx_info_proc_sched(&vxi->sched, buffer);
20223+ for_each_online_cpu(cpu) {
20224+ length += vx_info_proc_sched_pc(
20225+ &vx_per_cpu(vxi, sched_pc, cpu),
20226+ buffer + length, cpu);
ec22aa5c 20227+ }
4bf69007
AM
20228+ return length;
20229+}
ec22aa5c 20230+
4bf69007
AM
20231+int proc_vxi_nsproxy0(struct vx_info *vxi, char *buffer)
20232+{
20233+ return vx_info_proc_nsproxy(vxi->space[0].vx_nsproxy, buffer);
20234+}
d337f35e 20235+
4bf69007
AM
20236+int proc_vxi_nsproxy1(struct vx_info *vxi, char *buffer)
20237+{
20238+ return vx_info_proc_nsproxy(vxi->space[1].vx_nsproxy, buffer);
20239+}
ec22aa5c 20240+
4bf69007
AM
20241+int proc_vxi_cvirt(struct vx_info *vxi, char *buffer)
20242+{
20243+ int cpu, length;
d33d7b00 20244+
4bf69007
AM
20245+ vx_update_load(vxi);
20246+ length = vx_info_proc_cvirt(&vxi->cvirt, buffer);
20247+ for_each_online_cpu(cpu) {
20248+ length += vx_info_proc_cvirt_pc(
20249+ &vx_per_cpu(vxi, cvirt_pc, cpu),
20250+ buffer + length, cpu);
3bac966d 20251+ }
4bf69007
AM
20252+ return length;
20253+}
3bac966d 20254+
4bf69007
AM
20255+int proc_vxi_cacct(struct vx_info *vxi, char *buffer)
20256+{
20257+ return vx_info_proc_cacct(&vxi->cacct, buffer);
d337f35e
JR
20258+}
20259+
20260+
4bf69007 20261+static int proc_virtnet_info(char *buffer)
d337f35e 20262+{
4bf69007
AM
20263+ return proc_vci(buffer);
20264+}
ab30d09f 20265+
4bf69007
AM
20266+static int proc_virtnet_status(char *buffer)
20267+{
20268+ return sprintf(buffer,
20269+ "#CTotal:\t%d\n"
20270+ "#CActive:\t%d\n",
20271+ atomic_read(&nx_global_ctotal),
20272+ atomic_read(&nx_global_cactive));
20273+}
d337f35e 20274+
4bf69007
AM
20275+int proc_nxi_info(struct nx_info *nxi, char *buffer)
20276+{
20277+ struct nx_addr_v4 *v4a;
20278+#ifdef CONFIG_IPV6
20279+ struct nx_addr_v6 *v6a;
20280+#endif
20281+ int length, i;
ab30d09f 20282+
4bf69007
AM
20283+ length = sprintf(buffer,
20284+ "ID:\t%d\n"
20285+ "Info:\t%p\n"
20286+ "Bcast:\t" NIPQUAD_FMT "\n"
20287+ "Lback:\t" NIPQUAD_FMT "\n",
20288+ nxi->nx_id,
20289+ nxi,
20290+ NIPQUAD(nxi->v4_bcast.s_addr),
20291+ NIPQUAD(nxi->v4_lback.s_addr));
ab30d09f 20292+
4bf69007
AM
20293+ if (!NX_IPV4(nxi))
20294+ goto skip_v4;
20295+ for (i = 0, v4a = &nxi->v4; v4a; i++, v4a = v4a->next)
20296+ length += sprintf(buffer + length, "%d:\t" NXAV4_FMT "\n",
20297+ i, NXAV4(v4a));
20298+skip_v4:
20299+#ifdef CONFIG_IPV6
20300+ if (!NX_IPV6(nxi))
20301+ goto skip_v6;
20302+ for (i = 0, v6a = &nxi->v6; v6a; i++, v6a = v6a->next)
20303+ length += sprintf(buffer + length, "%d:\t" NXAV6_FMT "\n",
20304+ i, NXAV6(v6a));
20305+skip_v6:
20306+#endif
20307+ return length;
20308+}
2380c486 20309+
4bf69007
AM
20310+int proc_nxi_status(struct nx_info *nxi, char *buffer)
20311+{
20312+ int length;
ec22aa5c 20313+
4bf69007
AM
20314+ length = sprintf(buffer,
20315+ "UseCnt:\t%d\n"
20316+ "Tasks:\t%d\n"
20317+ "Flags:\t%016llx\n"
20318+ "NCaps:\t%016llx\n",
20319+ atomic_read(&nxi->nx_usecnt),
20320+ atomic_read(&nxi->nx_tasks),
20321+ (unsigned long long)nxi->nx_flags,
20322+ (unsigned long long)nxi->nx_ncaps);
20323+ return length;
20324+}
ec22aa5c 20325+
ec22aa5c 20326+
d337f35e 20327+
4bf69007 20328+/* here the inode helpers */
d337f35e 20329+
4bf69007
AM
20330+struct vs_entry {
20331+ int len;
20332+ char *name;
20333+ mode_t mode;
20334+ struct inode_operations *iop;
20335+ struct file_operations *fop;
20336+ union proc_op op;
20337+};
d337f35e 20338+
4bf69007
AM
20339+static struct inode *vs_proc_make_inode(struct super_block *sb, struct vs_entry *p)
20340+{
20341+ struct inode *inode = new_inode(sb);
3bac966d 20342+
4bf69007
AM
20343+ if (!inode)
20344+ goto out;
3bac966d 20345+
4bf69007
AM
20346+ inode->i_mode = p->mode;
20347+ if (p->iop)
20348+ inode->i_op = p->iop;
20349+ if (p->fop)
20350+ inode->i_fop = p->fop;
3bac966d 20351+
4bf69007
AM
20352+ set_nlink(inode, (p->mode & S_IFDIR) ? 2 : 1);
20353+ inode->i_flags |= S_IMMUTABLE;
3bac966d 20354+
4bf69007 20355+ inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
2380c486 20356+
8ce283e1
AM
20357+ i_uid_write(inode, 0);
20358+ i_gid_write(inode, 0);
20359+ i_tag_write(inode, 0);
4bf69007
AM
20360+out:
20361+ return inode;
d337f35e
JR
20362+}
20363+
4bf69007
AM
20364+static struct dentry *vs_proc_instantiate(struct inode *dir,
20365+ struct dentry *dentry, int id, void *ptr)
2380c486 20366+{
4bf69007
AM
20367+ struct vs_entry *p = ptr;
20368+ struct inode *inode = vs_proc_make_inode(dir->i_sb, p);
20369+ struct dentry *error = ERR_PTR(-EINVAL);
2380c486 20370+
4bf69007
AM
20371+ if (!inode)
20372+ goto out;
2380c486 20373+
4bf69007
AM
20374+ PROC_I(inode)->op = p->op;
20375+ PROC_I(inode)->fd = id;
20376+ d_add(dentry, inode);
20377+ error = NULL;
20378+out:
20379+ return error;
2380c486
JR
20380+}
20381+
4bf69007 20382+/* Lookups */
2380c486 20383+
09be7631
JR
20384+typedef struct dentry *vx_instantiate_t(struct inode *, struct dentry *, int, void *);
20385+
2380c486 20386+
4bf69007
AM
20387+/*
20388+ * Fill a directory entry.
20389+ *
20390+ * If possible create the dcache entry and derive our inode number and
20391+ * file type from dcache entry.
20392+ *
20393+ * Since all of the proc inode numbers are dynamically generated, the inode
20394+ * numbers do not exist until the inode is cache. This means creating the
c2e5f7c8
JR
20395+ * the dcache entry in iterate is necessary to keep the inode numbers
20396+ * reported by iterate in sync with the inode numbers reported
4bf69007
AM
20397+ * by stat.
20398+ */
c2e5f7c8 20399+static int vx_proc_fill_cache(struct file *filp, struct dir_context *ctx,
09be7631 20400+ char *name, int len, vx_instantiate_t instantiate, int id, void *ptr)
2380c486 20401+{
cc23e853 20402+ struct dentry *child, *dir = filp->f_path.dentry;
4bf69007
AM
20403+ struct inode *inode;
20404+ struct qstr qname;
20405+ ino_t ino = 0;
20406+ unsigned type = DT_UNKNOWN;
d337f35e 20407+
4bf69007
AM
20408+ qname.name = name;
20409+ qname.len = len;
cc23e853 20410+ qname.hash = full_name_hash(NULL, name, len);
d337f35e 20411+
4bf69007
AM
20412+ child = d_lookup(dir, &qname);
20413+ if (!child) {
20414+ struct dentry *new;
20415+ new = d_alloc(dir, &qname);
20416+ if (new) {
20417+ child = instantiate(dir->d_inode, new, id, ptr);
20418+ if (child)
20419+ dput(new);
20420+ else
20421+ child = new;
20422+ }
20423+ }
20424+ if (!child || IS_ERR(child) || !child->d_inode)
20425+ goto end_instantiate;
20426+ inode = child->d_inode;
20427+ if (inode) {
20428+ ino = inode->i_ino;
20429+ type = inode->i_mode >> 12;
20430+ }
20431+ dput(child);
20432+end_instantiate:
20433+ if (!ino)
4bf69007 20434+ ino = 1;
c2e5f7c8 20435+ return !dir_emit(ctx, name, len, ino, type);
4bf69007 20436+}
d337f35e 20437+
d337f35e 20438+
d337f35e 20439+
4bf69007 20440+/* get and revalidate vx_info/xid */
2380c486 20441+
4bf69007
AM
20442+static inline
20443+struct vx_info *get_proc_vx_info(struct inode *inode)
20444+{
20445+ return lookup_vx_info(PROC_I(inode)->fd);
d337f35e
JR
20446+}
20447+
4bf69007 20448+static int proc_xid_revalidate(struct dentry *dentry, unsigned int flags)
d337f35e 20449+{
4bf69007 20450+ struct inode *inode = dentry->d_inode;
61333608 20451+ vxid_t xid = PROC_I(inode)->fd;
2380c486 20452+
4bf69007
AM
20453+ if (flags & LOOKUP_RCU) /* FIXME: can be dropped? */
20454+ return -ECHILD;
2380c486 20455+
4bf69007
AM
20456+ if (!xid || xid_is_hashed(xid))
20457+ return 1;
20458+ d_drop(dentry);
d337f35e
JR
20459+ return 0;
20460+}
20461+
d337f35e 20462+
4bf69007 20463+/* get and revalidate nx_info/nid */
d337f35e 20464+
4bf69007
AM
20465+static int proc_nid_revalidate(struct dentry *dentry, unsigned int flags)
20466+{
20467+ struct inode *inode = dentry->d_inode;
61333608 20468+ vnid_t nid = PROC_I(inode)->fd;
2380c486 20469+
4bf69007
AM
20470+ if (flags & LOOKUP_RCU) /* FIXME: can be dropped? */
20471+ return -ECHILD;
2380c486 20472+
4bf69007
AM
20473+ if (!nid || nid_is_hashed(nid))
20474+ return 1;
20475+ d_drop(dentry);
20476+ return 0;
d337f35e
JR
20477+}
20478+
4bf69007
AM
20479+
20480+
20481+#define PROC_BLOCK_SIZE (PAGE_SIZE - 1024)
20482+
20483+static ssize_t proc_vs_info_read(struct file *file, char __user *buf,
20484+ size_t count, loff_t *ppos)
d337f35e 20485+{
cc23e853 20486+ struct inode *inode = file->f_path.dentry->d_inode;
4bf69007
AM
20487+ unsigned long page;
20488+ ssize_t length = 0;
20489+
20490+ if (count > PROC_BLOCK_SIZE)
20491+ count = PROC_BLOCK_SIZE;
20492+
20493+ /* fade that out as soon as stable */
20494+ WARN_ON(PROC_I(inode)->fd);
20495+
20496+ if (!(page = __get_free_page(GFP_KERNEL)))
20497+ return -ENOMEM;
20498+
20499+ BUG_ON(!PROC_I(inode)->op.proc_vs_read);
20500+ length = PROC_I(inode)->op.proc_vs_read((char *)page);
20501+
20502+ if (length >= 0)
20503+ length = simple_read_from_buffer(buf, count, ppos,
20504+ (char *)page, length);
20505+
20506+ free_page(page);
20507+ return length;
d337f35e
JR
20508+}
20509+
4bf69007
AM
20510+static ssize_t proc_vx_info_read(struct file *file, char __user *buf,
20511+ size_t count, loff_t *ppos)
20512+{
cc23e853 20513+ struct inode *inode = file->f_path.dentry->d_inode;
4bf69007 20514+ struct vx_info *vxi = NULL;
61333608 20515+ vxid_t xid = PROC_I(inode)->fd;
4bf69007
AM
20516+ unsigned long page;
20517+ ssize_t length = 0;
d337f35e 20518+
4bf69007
AM
20519+ if (count > PROC_BLOCK_SIZE)
20520+ count = PROC_BLOCK_SIZE;
20521+
20522+ /* fade that out as soon as stable */
20523+ WARN_ON(!xid);
20524+ vxi = lookup_vx_info(xid);
20525+ if (!vxi)
20526+ goto out;
d337f35e 20527+
4bf69007
AM
20528+ length = -ENOMEM;
20529+ if (!(page = __get_free_page(GFP_KERNEL)))
20530+ goto out_put;
d337f35e 20531+
4bf69007
AM
20532+ BUG_ON(!PROC_I(inode)->op.proc_vxi_read);
20533+ length = PROC_I(inode)->op.proc_vxi_read(vxi, (char *)page);
d337f35e 20534+
4bf69007
AM
20535+ if (length >= 0)
20536+ length = simple_read_from_buffer(buf, count, ppos,
20537+ (char *)page, length);
d337f35e 20538+
4bf69007
AM
20539+ free_page(page);
20540+out_put:
20541+ put_vx_info(vxi);
20542+out:
20543+ return length;
20544+}
20545+
20546+static ssize_t proc_nx_info_read(struct file *file, char __user *buf,
20547+ size_t count, loff_t *ppos)
d337f35e 20548+{
cc23e853 20549+ struct inode *inode = file->f_path.dentry->d_inode;
4bf69007 20550+ struct nx_info *nxi = NULL;
61333608 20551+ vnid_t nid = PROC_I(inode)->fd;
4bf69007
AM
20552+ unsigned long page;
20553+ ssize_t length = 0;
d337f35e 20554+
4bf69007
AM
20555+ if (count > PROC_BLOCK_SIZE)
20556+ count = PROC_BLOCK_SIZE;
d337f35e 20557+
4bf69007
AM
20558+ /* fade that out as soon as stable */
20559+ WARN_ON(!nid);
20560+ nxi = lookup_nx_info(nid);
20561+ if (!nxi)
20562+ goto out;
d337f35e 20563+
4bf69007
AM
20564+ length = -ENOMEM;
20565+ if (!(page = __get_free_page(GFP_KERNEL)))
20566+ goto out_put;
d337f35e 20567+
4bf69007
AM
20568+ BUG_ON(!PROC_I(inode)->op.proc_nxi_read);
20569+ length = PROC_I(inode)->op.proc_nxi_read(nxi, (char *)page);
2380c486 20570+
4bf69007
AM
20571+ if (length >= 0)
20572+ length = simple_read_from_buffer(buf, count, ppos,
20573+ (char *)page, length);
d337f35e 20574+
4bf69007
AM
20575+ free_page(page);
20576+out_put:
20577+ put_nx_info(nxi);
20578+out:
20579+ return length;
20580+}
2380c486 20581+
d337f35e 20582+
763640ca 20583+
4bf69007 20584+/* here comes the lower level */
763640ca 20585+
265d6dcc 20586+
4bf69007
AM
20587+#define NOD(NAME, MODE, IOP, FOP, OP) { \
20588+ .len = sizeof(NAME) - 1, \
20589+ .name = (NAME), \
20590+ .mode = MODE, \
20591+ .iop = IOP, \
20592+ .fop = FOP, \
20593+ .op = OP, \
20594+}
d337f35e 20595+
d337f35e 20596+
4bf69007
AM
20597+#define DIR(NAME, MODE, OTYPE) \
20598+ NOD(NAME, (S_IFDIR | (MODE)), \
20599+ &proc_ ## OTYPE ## _inode_operations, \
20600+ &proc_ ## OTYPE ## _file_operations, { } )
d337f35e 20601+
4bf69007
AM
20602+#define INF(NAME, MODE, OTYPE) \
20603+ NOD(NAME, (S_IFREG | (MODE)), NULL, \
20604+ &proc_vs_info_file_operations, \
20605+ { .proc_vs_read = &proc_##OTYPE } )
d337f35e 20606+
4bf69007
AM
20607+#define VINF(NAME, MODE, OTYPE) \
20608+ NOD(NAME, (S_IFREG | (MODE)), NULL, \
20609+ &proc_vx_info_file_operations, \
20610+ { .proc_vxi_read = &proc_##OTYPE } )
2380c486 20611+
4bf69007
AM
20612+#define NINF(NAME, MODE, OTYPE) \
20613+ NOD(NAME, (S_IFREG | (MODE)), NULL, \
20614+ &proc_nx_info_file_operations, \
20615+ { .proc_nxi_read = &proc_##OTYPE } )
d337f35e 20616+
d337f35e 20617+
4bf69007
AM
20618+static struct file_operations proc_vs_info_file_operations = {
20619+ .read = proc_vs_info_read,
20620+};
d337f35e 20621+
4bf69007
AM
20622+static struct file_operations proc_vx_info_file_operations = {
20623+ .read = proc_vx_info_read,
20624+};
d337f35e 20625+
4bf69007
AM
20626+static struct dentry_operations proc_xid_dentry_operations = {
20627+ .d_revalidate = proc_xid_revalidate,
20628+};
d337f35e 20629+
4bf69007
AM
20630+static struct vs_entry vx_base_stuff[] = {
20631+ VINF("info", S_IRUGO, vxi_info),
20632+ VINF("status", S_IRUGO, vxi_status),
20633+ VINF("limit", S_IRUGO, vxi_limit),
20634+ VINF("sched", S_IRUGO, vxi_sched),
20635+ VINF("nsproxy", S_IRUGO, vxi_nsproxy0),
20636+ VINF("nsproxy1",S_IRUGO, vxi_nsproxy1),
20637+ VINF("cvirt", S_IRUGO, vxi_cvirt),
20638+ VINF("cacct", S_IRUGO, vxi_cacct),
20639+ {}
20640+};
2380c486 20641+
d337f35e 20642+
d337f35e 20643+
d337f35e 20644+
4bf69007
AM
20645+static struct dentry *proc_xid_instantiate(struct inode *dir,
20646+ struct dentry *dentry, int id, void *ptr)
20647+{
20648+ dentry->d_op = &proc_xid_dentry_operations;
20649+ return vs_proc_instantiate(dir, dentry, id, ptr);
20650+}
2380c486 20651+
4bf69007
AM
20652+static struct dentry *proc_xid_lookup(struct inode *dir,
20653+ struct dentry *dentry, unsigned int flags)
20654+{
20655+ struct vs_entry *p = vx_base_stuff;
20656+ struct dentry *error = ERR_PTR(-ENOENT);
2380c486 20657+
4bf69007
AM
20658+ for (; p->name; p++) {
20659+ if (p->len != dentry->d_name.len)
20660+ continue;
20661+ if (!memcmp(dentry->d_name.name, p->name, p->len))
20662+ break;
20663+ }
20664+ if (!p->name)
20665+ goto out;
d337f35e 20666+
4bf69007
AM
20667+ error = proc_xid_instantiate(dir, dentry, PROC_I(dir)->fd, p);
20668+out:
20669+ return error;
20670+}
9f7054f1 20671+
c2e5f7c8 20672+static int proc_xid_iterate(struct file *filp, struct dir_context *ctx)
4bf69007 20673+{
cc23e853 20674+ struct dentry *dentry = filp->f_path.dentry;
4bf69007
AM
20675+ struct inode *inode = dentry->d_inode;
20676+ struct vs_entry *p = vx_base_stuff;
20677+ int size = sizeof(vx_base_stuff) / sizeof(struct vs_entry);
c2e5f7c8 20678+ int index;
2380c486 20679+
cc23e853
AM
20680+ if (!dir_emit_dots(filp, ctx))
20681+ return 0;
20682+
20683+ index = ctx->pos - 2;
20684+ if (index < size) {
4bf69007 20685+ for (p += index; p->name; p++) {
c2e5f7c8 20686+ if (vx_proc_fill_cache(filp, ctx, p->name, p->len,
4bf69007 20687+ vs_proc_instantiate, PROC_I(inode)->fd, p))
cc23e853 20688+ return 0;
c2e5f7c8 20689+ ctx->pos++;
4bf69007 20690+ }
d337f35e 20691+ }
4bf69007 20692+ return 1;
d337f35e
JR
20693+}
20694+
20695+
d337f35e 20696+
4bf69007
AM
20697+static struct file_operations proc_nx_info_file_operations = {
20698+ .read = proc_nx_info_read,
20699+};
d337f35e 20700+
4bf69007
AM
20701+static struct dentry_operations proc_nid_dentry_operations = {
20702+ .d_revalidate = proc_nid_revalidate,
20703+};
d337f35e 20704+
4bf69007
AM
20705+static struct vs_entry nx_base_stuff[] = {
20706+ NINF("info", S_IRUGO, nxi_info),
20707+ NINF("status", S_IRUGO, nxi_status),
20708+ {}
20709+};
2380c486 20710+
d337f35e 20711+
4bf69007
AM
20712+static struct dentry *proc_nid_instantiate(struct inode *dir,
20713+ struct dentry *dentry, int id, void *ptr)
d337f35e 20714+{
4bf69007
AM
20715+ dentry->d_op = &proc_nid_dentry_operations;
20716+ return vs_proc_instantiate(dir, dentry, id, ptr);
20717+}
d337f35e 20718+
4bf69007
AM
20719+static struct dentry *proc_nid_lookup(struct inode *dir,
20720+ struct dentry *dentry, unsigned int flags)
20721+{
20722+ struct vs_entry *p = nx_base_stuff;
20723+ struct dentry *error = ERR_PTR(-ENOENT);
d337f35e 20724+
4bf69007
AM
20725+ for (; p->name; p++) {
20726+ if (p->len != dentry->d_name.len)
20727+ continue;
20728+ if (!memcmp(dentry->d_name.name, p->name, p->len))
20729+ break;
20730+ }
20731+ if (!p->name)
20732+ goto out;
d337f35e 20733+
4bf69007
AM
20734+ error = proc_nid_instantiate(dir, dentry, PROC_I(dir)->fd, p);
20735+out:
20736+ return error;
20737+}
d337f35e 20738+
c2e5f7c8 20739+static int proc_nid_iterate(struct file *filp, struct dir_context *ctx)
4bf69007 20740+{
cc23e853 20741+ struct dentry *dentry = filp->f_path.dentry;
4bf69007
AM
20742+ struct inode *inode = dentry->d_inode;
20743+ struct vs_entry *p = nx_base_stuff;
20744+ int size = sizeof(nx_base_stuff) / sizeof(struct vs_entry);
c2e5f7c8 20745+ int index;
d337f35e 20746+
cc23e853
AM
20747+ if (!dir_emit_dots(filp, ctx))
20748+ return 0;
20749+
20750+ index = ctx->pos - 2;
20751+ if (index < size) {
4bf69007 20752+ for (p += index; p->name; p++) {
c2e5f7c8 20753+ if (vx_proc_fill_cache(filp, ctx, p->name, p->len,
4bf69007 20754+ vs_proc_instantiate, PROC_I(inode)->fd, p))
cc23e853 20755+ return 0;
c2e5f7c8 20756+ ctx->pos++;
4bf69007
AM
20757+ }
20758+ }
4bf69007
AM
20759+ return 1;
20760+}
2380c486 20761+
d337f35e 20762+
4bf69007 20763+#define MAX_MULBY10 ((~0U - 9) / 10)
d337f35e 20764+
4bf69007
AM
20765+static inline int atovid(const char *str, int len)
20766+{
20767+ int vid, c;
d337f35e 20768+
4bf69007
AM
20769+ vid = 0;
20770+ while (len-- > 0) {
20771+ c = *str - '0';
20772+ str++;
20773+ if (c > 9)
20774+ return -1;
20775+ if (vid >= MAX_MULBY10)
20776+ return -1;
20777+ vid *= 10;
20778+ vid += c;
20779+ if (!vid)
20780+ return -1;
20781+ }
20782+ return vid;
20783+}
2380c486 20784+
4bf69007 20785+/* now the upper level (virtual) */
2380c486 20786+
2380c486 20787+
4bf69007
AM
20788+static struct file_operations proc_xid_file_operations = {
20789+ .read = generic_read_dir,
c2e5f7c8 20790+ .iterate = proc_xid_iterate,
4bf69007 20791+};
2380c486 20792+
4bf69007
AM
20793+static struct inode_operations proc_xid_inode_operations = {
20794+ .lookup = proc_xid_lookup,
20795+};
d337f35e 20796+
4bf69007
AM
20797+static struct vs_entry vx_virtual_stuff[] = {
20798+ INF("info", S_IRUGO, virtual_info),
20799+ INF("status", S_IRUGO, virtual_status),
20800+ DIR(NULL, S_IRUGO | S_IXUGO, xid),
20801+};
2380c486 20802+
d337f35e 20803+
4bf69007
AM
20804+static struct dentry *proc_virtual_lookup(struct inode *dir,
20805+ struct dentry *dentry, unsigned int flags)
20806+{
20807+ struct vs_entry *p = vx_virtual_stuff;
20808+ struct dentry *error = ERR_PTR(-ENOENT);
20809+ int id = 0;
d337f35e 20810+
4bf69007
AM
20811+ for (; p->name; p++) {
20812+ if (p->len != dentry->d_name.len)
20813+ continue;
20814+ if (!memcmp(dentry->d_name.name, p->name, p->len))
20815+ break;
20816+ }
20817+ if (p->name)
20818+ goto instantiate;
d337f35e 20819+
4bf69007
AM
20820+ id = atovid(dentry->d_name.name, dentry->d_name.len);
20821+ if ((id < 0) || !xid_is_hashed(id))
d337f35e
JR
20822+ goto out;
20823+
4bf69007
AM
20824+instantiate:
20825+ error = proc_xid_instantiate(dir, dentry, id, p);
20826+out:
20827+ return error;
20828+}
d337f35e 20829+
4bf69007
AM
20830+static struct file_operations proc_nid_file_operations = {
20831+ .read = generic_read_dir,
c2e5f7c8 20832+ .iterate = proc_nid_iterate,
4bf69007 20833+};
d337f35e 20834+
4bf69007
AM
20835+static struct inode_operations proc_nid_inode_operations = {
20836+ .lookup = proc_nid_lookup,
20837+};
d337f35e 20838+
4bf69007
AM
20839+static struct vs_entry nx_virtnet_stuff[] = {
20840+ INF("info", S_IRUGO, virtnet_info),
20841+ INF("status", S_IRUGO, virtnet_status),
20842+ DIR(NULL, S_IRUGO | S_IXUGO, nid),
20843+};
d337f35e 20844+
d337f35e 20845+
4bf69007
AM
20846+static struct dentry *proc_virtnet_lookup(struct inode *dir,
20847+ struct dentry *dentry, unsigned int flags)
20848+{
20849+ struct vs_entry *p = nx_virtnet_stuff;
20850+ struct dentry *error = ERR_PTR(-ENOENT);
20851+ int id = 0;
d337f35e 20852+
4bf69007
AM
20853+ for (; p->name; p++) {
20854+ if (p->len != dentry->d_name.len)
20855+ continue;
20856+ if (!memcmp(dentry->d_name.name, p->name, p->len))
20857+ break;
20858+ }
20859+ if (p->name)
20860+ goto instantiate;
d337f35e 20861+
4bf69007
AM
20862+ id = atovid(dentry->d_name.name, dentry->d_name.len);
20863+ if ((id < 0) || !nid_is_hashed(id))
d337f35e
JR
20864+ goto out;
20865+
4bf69007
AM
20866+instantiate:
20867+ error = proc_nid_instantiate(dir, dentry, id, p);
20868+out:
20869+ return error;
20870+}
2380c486 20871+
d337f35e 20872+
4bf69007
AM
20873+#define PROC_MAXVIDS 32
20874+
c2e5f7c8 20875+int proc_virtual_iterate(struct file *filp, struct dir_context *ctx)
4bf69007 20876+{
4bf69007
AM
20877+ struct vs_entry *p = vx_virtual_stuff;
20878+ int size = sizeof(vx_virtual_stuff) / sizeof(struct vs_entry);
c2e5f7c8 20879+ int index;
4bf69007
AM
20880+ unsigned int xid_array[PROC_MAXVIDS];
20881+ char buf[PROC_NUMBUF];
20882+ unsigned int nr_xids, i;
4bf69007 20883+
cc23e853
AM
20884+ if (!dir_emit_dots(filp, ctx))
20885+ return 0;
20886+
20887+ index = ctx->pos - 2;
20888+ if (index < size) {
4bf69007 20889+ for (p += index; p->name; p++) {
c2e5f7c8 20890+ if (vx_proc_fill_cache(filp, ctx, p->name, p->len,
4bf69007 20891+ vs_proc_instantiate, 0, p))
cc23e853 20892+ return 0;
c2e5f7c8 20893+ ctx->pos++;
d337f35e
JR
20894+ }
20895+ }
cc23e853
AM
20896+
20897+ index = ctx->pos - size;
20898+ p = &vx_virtual_stuff[size - 1];
20899+ nr_xids = get_xid_list(index, xid_array, PROC_MAXVIDS);
20900+ for (i = 0; i < nr_xids; i++) {
20901+ int n, xid = xid_array[i];
20902+ unsigned int j = PROC_NUMBUF;
20903+
20904+ n = xid;
20905+ do
20906+ buf[--j] = '0' + (n % 10);
20907+ while (n /= 10);
20908+
20909+ if (vx_proc_fill_cache(filp, ctx,
20910+ buf + j, PROC_NUMBUF - j,
20911+ vs_proc_instantiate, xid, p))
20912+ return 0;
20913+ ctx->pos++;
20914+ }
4bf69007 20915+ return 0;
d337f35e
JR
20916+}
20917+
4bf69007
AM
20918+static int proc_virtual_getattr(struct vfsmount *mnt,
20919+ struct dentry *dentry, struct kstat *stat)
d337f35e 20920+{
4bf69007 20921+ struct inode *inode = dentry->d_inode;
d337f35e 20922+
4bf69007
AM
20923+ generic_fillattr(inode, stat);
20924+ stat->nlink = 2 + atomic_read(&vx_global_cactive);
20925+ return 0;
d337f35e
JR
20926+}
20927+
4bf69007
AM
20928+static struct file_operations proc_virtual_dir_operations = {
20929+ .read = generic_read_dir,
c2e5f7c8 20930+ .iterate = proc_virtual_iterate,
d337f35e
JR
20931+};
20932+
4bf69007
AM
20933+static struct inode_operations proc_virtual_dir_inode_operations = {
20934+ .getattr = proc_virtual_getattr,
20935+ .lookup = proc_virtual_lookup,
20936+};
d337f35e 20937+
d337f35e
JR
20938+
20939+
c2e5f7c8 20940+int proc_virtnet_iterate(struct file *filp, struct dir_context *ctx)
d337f35e 20941+{
4bf69007
AM
20942+ struct vs_entry *p = nx_virtnet_stuff;
20943+ int size = sizeof(nx_virtnet_stuff) / sizeof(struct vs_entry);
c2e5f7c8 20944+ int index;
4bf69007
AM
20945+ unsigned int nid_array[PROC_MAXVIDS];
20946+ char buf[PROC_NUMBUF];
20947+ unsigned int nr_nids, i;
d337f35e 20948+
cc23e853
AM
20949+ if (!dir_emit_dots(filp, ctx))
20950+ return 0;
20951+
20952+ index = ctx->pos - 2;
20953+ if (index < size) {
4bf69007 20954+ for (p += index; p->name; p++) {
c2e5f7c8 20955+ if (vx_proc_fill_cache(filp, ctx, p->name, p->len,
4bf69007 20956+ vs_proc_instantiate, 0, p))
cc23e853 20957+ return 0;
c2e5f7c8 20958+ ctx->pos++;
d337f35e
JR
20959+ }
20960+ }
cc23e853
AM
20961+
20962+ index = ctx->pos - size;
20963+ p = &nx_virtnet_stuff[size - 1];
20964+ nr_nids = get_nid_list(index, nid_array, PROC_MAXVIDS);
20965+ for (i = 0; i < nr_nids; i++) {
20966+ int n, nid = nid_array[i];
20967+ unsigned int j = PROC_NUMBUF;
20968+
20969+ n = nid;
20970+ do
20971+ buf[--j] = '0' + (n % 10);
20972+ while (n /= 10);
20973+
20974+ if (vx_proc_fill_cache(filp, ctx,
20975+ buf + j, PROC_NUMBUF - j,
20976+ vs_proc_instantiate, nid, p))
20977+ return 0;
20978+ ctx->pos++;
20979+ }
d337f35e
JR
20980+ return 0;
20981+}
20982+
4bf69007
AM
20983+static int proc_virtnet_getattr(struct vfsmount *mnt,
20984+ struct dentry *dentry, struct kstat *stat)
20985+{
20986+ struct inode *inode = dentry->d_inode;
d337f35e 20987+
4bf69007
AM
20988+ generic_fillattr(inode, stat);
20989+ stat->nlink = 2 + atomic_read(&nx_global_cactive);
20990+ return 0;
20991+}
d337f35e 20992+
4bf69007
AM
20993+static struct file_operations proc_virtnet_dir_operations = {
20994+ .read = generic_read_dir,
c2e5f7c8 20995+ .iterate = proc_virtnet_iterate,
d337f35e
JR
20996+};
20997+
4bf69007
AM
20998+static struct inode_operations proc_virtnet_dir_inode_operations = {
20999+ .getattr = proc_virtnet_getattr,
21000+ .lookup = proc_virtnet_lookup,
d337f35e
JR
21001+};
21002+
d337f35e
JR
21003+
21004+
4bf69007 21005+void proc_vx_init(void)
d337f35e 21006+{
4bf69007 21007+ struct proc_dir_entry *ent;
d337f35e 21008+
4bf69007
AM
21009+ ent = proc_mkdir("virtual", 0);
21010+ if (ent) {
21011+ ent->proc_fops = &proc_virtual_dir_operations;
21012+ ent->proc_iops = &proc_virtual_dir_inode_operations;
21013+ }
21014+ proc_virtual = ent;
d337f35e 21015+
4bf69007
AM
21016+ ent = proc_mkdir("virtnet", 0);
21017+ if (ent) {
21018+ ent->proc_fops = &proc_virtnet_dir_operations;
21019+ ent->proc_iops = &proc_virtnet_dir_inode_operations;
d337f35e 21020+ }
4bf69007 21021+ proc_virtnet = ent;
d337f35e
JR
21022+}
21023+
d337f35e 21024+
2380c486 21025+
2380c486 21026+
4bf69007 21027+/* per pid info */
2380c486 21028+
bb20add7
AM
21029+void render_cap_t(struct seq_file *, const char *,
21030+ struct vx_info *, kernel_cap_t *);
21031+
2380c486 21032+
bb20add7
AM
21033+int proc_pid_vx_info(
21034+ struct seq_file *m,
21035+ struct pid_namespace *ns,
21036+ struct pid *pid,
21037+ struct task_struct *p)
2380c486 21038+{
4bf69007 21039+ struct vx_info *vxi;
2380c486 21040+
bb20add7 21041+ seq_printf(m, "XID:\t%d\n", vx_task_xid(p));
2380c486 21042+
4bf69007
AM
21043+ vxi = task_get_vx_info(p);
21044+ if (!vxi)
bb20add7 21045+ return 0;
2380c486 21046+
bb20add7
AM
21047+ render_cap_t(m, "BCaps:\t", vxi, &vxi->vx_bcaps);
21048+ seq_printf(m, "CCaps:\t%016llx\n",
4bf69007 21049+ (unsigned long long)vxi->vx_ccaps);
bb20add7 21050+ seq_printf(m, "CFlags:\t%016llx\n",
4bf69007 21051+ (unsigned long long)vxi->vx_flags);
bb20add7 21052+ seq_printf(m, "CIPid:\t%d\n", vxi->vx_initpid);
4bf69007
AM
21053+
21054+ put_vx_info(vxi);
bb20add7 21055+ return 0;
2380c486
JR
21056+}
21057+
2380c486 21058+
bb20add7
AM
21059+int proc_pid_nx_info(
21060+ struct seq_file *m,
21061+ struct pid_namespace *ns,
21062+ struct pid *pid,
21063+ struct task_struct *p)
4bf69007
AM
21064+{
21065+ struct nx_info *nxi;
21066+ struct nx_addr_v4 *v4a;
21067+#ifdef CONFIG_IPV6
21068+ struct nx_addr_v6 *v6a;
21069+#endif
4bf69007 21070+ int i;
2380c486 21071+
bb20add7 21072+ seq_printf(m, "NID:\t%d\n", nx_task_nid(p));
2380c486 21073+
4bf69007
AM
21074+ nxi = task_get_nx_info(p);
21075+ if (!nxi)
bb20add7 21076+ return 0;
2380c486 21077+
bb20add7 21078+ seq_printf(m, "NCaps:\t%016llx\n",
4bf69007 21079+ (unsigned long long)nxi->nx_ncaps);
bb20add7 21080+ seq_printf(m, "NFlags:\t%016llx\n",
4bf69007
AM
21081+ (unsigned long long)nxi->nx_flags);
21082+
bb20add7 21083+ seq_printf(m, "V4Root[bcast]:\t" NIPQUAD_FMT "\n",
4bf69007 21084+ NIPQUAD(nxi->v4_bcast.s_addr));
bb20add7 21085+ seq_printf(m, "V4Root[lback]:\t" NIPQUAD_FMT "\n",
4bf69007
AM
21086+ NIPQUAD(nxi->v4_lback.s_addr));
21087+ if (!NX_IPV4(nxi))
21088+ goto skip_v4;
21089+ for (i = 0, v4a = &nxi->v4; v4a; i++, v4a = v4a->next)
bb20add7 21090+ seq_printf(m, "V4Root[%d]:\t" NXAV4_FMT "\n",
4bf69007
AM
21091+ i, NXAV4(v4a));
21092+skip_v4:
21093+#ifdef CONFIG_IPV6
21094+ if (!NX_IPV6(nxi))
21095+ goto skip_v6;
21096+ for (i = 0, v6a = &nxi->v6; v6a; i++, v6a = v6a->next)
bb20add7 21097+ seq_printf(m, "V6Root[%d]:\t" NXAV6_FMT "\n",
4bf69007
AM
21098+ i, NXAV6(v6a));
21099+skip_v6:
21100+#endif
21101+ put_nx_info(nxi);
bb20add7 21102+ return 0;
2380c486
JR
21103+}
21104+
3261cfd5
AM
21105diff -NurpP --minimal linux-4.9.207/kernel/vserver/sched.c linux-4.9.207-vs2.3.9.11/kernel/vserver/sched.c
21106--- linux-4.9.207/kernel/vserver/sched.c 1970-01-01 00:00:00.000000000 +0000
21107+++ linux-4.9.207-vs2.3.9.11/kernel/vserver/sched.c 2018-10-20 04:58:15.000000000 +0000
4bf69007
AM
21108@@ -0,0 +1,83 @@
21109+/*
21110+ * linux/kernel/vserver/sched.c
21111+ *
21112+ * Virtual Server: Scheduler Support
21113+ *
cc23e853 21114+ * Copyright (C) 2004-2010 Herbert P?tzl
4bf69007
AM
21115+ *
21116+ * V0.01 adapted Sam Vilains version to 2.6.3
21117+ * V0.02 removed legacy interface
21118+ * V0.03 changed vcmds to vxi arg
21119+ * V0.04 removed older and legacy interfaces
21120+ * V0.05 removed scheduler code/commands
21121+ *
21122+ */
21123+
21124+#include <linux/vs_context.h>
21125+#include <linux/vs_sched.h>
21126+#include <linux/cpumask.h>
21127+#include <linux/vserver/sched_cmd.h>
2380c486 21128+
4bf69007
AM
21129+#include <asm/uaccess.h>
21130+
21131+
21132+void vx_update_sched_param(struct _vx_sched *sched,
21133+ struct _vx_sched_pc *sched_pc)
2380c486 21134+{
4bf69007 21135+ sched_pc->prio_bias = sched->prio_bias;
2380c486
JR
21136+}
21137+
4bf69007
AM
21138+static int do_set_prio_bias(struct vx_info *vxi, struct vcmd_prio_bias *data)
21139+{
21140+ int cpu;
2380c486 21141+
4bf69007
AM
21142+ if (data->prio_bias > MAX_PRIO_BIAS)
21143+ data->prio_bias = MAX_PRIO_BIAS;
21144+ if (data->prio_bias < MIN_PRIO_BIAS)
21145+ data->prio_bias = MIN_PRIO_BIAS;
2380c486 21146+
4bf69007 21147+ if (data->cpu_id != ~0) {
cc23e853 21148+ vxi->sched.update = *get_cpu_mask(data->cpu_id);
4bf69007
AM
21149+ cpumask_and(&vxi->sched.update, &vxi->sched.update,
21150+ cpu_online_mask);
21151+ } else
21152+ cpumask_copy(&vxi->sched.update, cpu_online_mask);
2380c486 21153+
cc23e853 21154+ for ((cpu) = 0; (cpu) < 1; (cpu)++, (void)vxi->sched.update)
4bf69007
AM
21155+ vx_update_sched_param(&vxi->sched,
21156+ &vx_per_cpu(vxi, sched_pc, cpu));
21157+ return 0;
21158+}
2380c486 21159+
4bf69007
AM
21160+int vc_set_prio_bias(struct vx_info *vxi, void __user *data)
21161+{
21162+ struct vcmd_prio_bias vc_data;
d337f35e 21163+
4bf69007
AM
21164+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
21165+ return -EFAULT;
d337f35e 21166+
4bf69007
AM
21167+ return do_set_prio_bias(vxi, &vc_data);
21168+}
d337f35e 21169+
4bf69007
AM
21170+int vc_get_prio_bias(struct vx_info *vxi, void __user *data)
21171+{
21172+ struct vcmd_prio_bias vc_data;
21173+ struct _vx_sched_pc *pcd;
21174+ int cpu;
d337f35e 21175+
4bf69007
AM
21176+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
21177+ return -EFAULT;
2380c486 21178+
4bf69007 21179+ cpu = vc_data.cpu_id;
d337f35e 21180+
4bf69007
AM
21181+ if (!cpu_possible(cpu))
21182+ return -EINVAL;
d337f35e 21183+
4bf69007
AM
21184+ pcd = &vx_per_cpu(vxi, sched_pc, cpu);
21185+ vc_data.prio_bias = pcd->prio_bias;
d337f35e 21186+
4bf69007
AM
21187+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
21188+ return -EFAULT;
21189+ return 0;
21190+}
d337f35e 21191+
3261cfd5
AM
21192diff -NurpP --minimal linux-4.9.207/kernel/vserver/sched_init.h linux-4.9.207-vs2.3.9.11/kernel/vserver/sched_init.h
21193--- linux-4.9.207/kernel/vserver/sched_init.h 1970-01-01 00:00:00.000000000 +0000
21194+++ linux-4.9.207-vs2.3.9.11/kernel/vserver/sched_init.h 2018-10-20 04:58:15.000000000 +0000
4bf69007 21195@@ -0,0 +1,27 @@
2380c486 21196+
4bf69007
AM
21197+static inline void vx_info_init_sched(struct _vx_sched *sched)
21198+{
21199+ /* scheduling; hard code starting values as constants */
21200+ sched->prio_bias = 0;
d337f35e
JR
21201+}
21202+
4bf69007
AM
21203+static inline
21204+void vx_info_init_sched_pc(struct _vx_sched_pc *sched_pc, int cpu)
e3afe727 21205+{
4bf69007
AM
21206+ sched_pc->prio_bias = 0;
21207+
21208+ sched_pc->user_ticks = 0;
21209+ sched_pc->sys_ticks = 0;
21210+ sched_pc->hold_ticks = 0;
e3afe727
AM
21211+}
21212+
4bf69007 21213+static inline void vx_info_exit_sched(struct _vx_sched *sched)
e3afe727 21214+{
4bf69007 21215+ return;
e3afe727
AM
21216+}
21217+
4bf69007
AM
21218+static inline
21219+void vx_info_exit_sched_pc(struct _vx_sched_pc *sched_pc, int cpu)
e3afe727 21220+{
4bf69007 21221+ return;
e3afe727 21222+}
3261cfd5
AM
21223diff -NurpP --minimal linux-4.9.207/kernel/vserver/sched_proc.h linux-4.9.207-vs2.3.9.11/kernel/vserver/sched_proc.h
21224--- linux-4.9.207/kernel/vserver/sched_proc.h 1970-01-01 00:00:00.000000000 +0000
21225+++ linux-4.9.207-vs2.3.9.11/kernel/vserver/sched_proc.h 2018-10-20 04:58:15.000000000 +0000
4bf69007
AM
21226@@ -0,0 +1,32 @@
21227+#ifndef _VX_SCHED_PROC_H
21228+#define _VX_SCHED_PROC_H
e3afe727 21229+
4bf69007
AM
21230+
21231+static inline
21232+int vx_info_proc_sched(struct _vx_sched *sched, char *buffer)
e3afe727 21233+{
4bf69007
AM
21234+ int length = 0;
21235+
21236+ length += sprintf(buffer,
21237+ "PrioBias:\t%8d\n",
21238+ sched->prio_bias);
21239+ return length;
e3afe727
AM
21240+}
21241+
4bf69007
AM
21242+static inline
21243+int vx_info_proc_sched_pc(struct _vx_sched_pc *sched_pc,
21244+ char *buffer, int cpu)
e3afe727 21245+{
4bf69007 21246+ int length = 0;
e3afe727 21247+
4bf69007
AM
21248+ length += sprintf(buffer + length,
21249+ "cpu %d: %lld %lld %lld", cpu,
21250+ (unsigned long long)sched_pc->user_ticks,
21251+ (unsigned long long)sched_pc->sys_ticks,
21252+ (unsigned long long)sched_pc->hold_ticks);
21253+ length += sprintf(buffer + length,
21254+ " %d\n", sched_pc->prio_bias);
21255+ return length;
21256+}
93de0823 21257+
4bf69007 21258+#endif /* _VX_SCHED_PROC_H */
3261cfd5
AM
21259diff -NurpP --minimal linux-4.9.207/kernel/vserver/signal.c linux-4.9.207-vs2.3.9.11/kernel/vserver/signal.c
21260--- linux-4.9.207/kernel/vserver/signal.c 1970-01-01 00:00:00.000000000 +0000
21261+++ linux-4.9.207-vs2.3.9.11/kernel/vserver/signal.c 2018-10-20 04:58:15.000000000 +0000
4bf69007
AM
21262@@ -0,0 +1,134 @@
21263+/*
21264+ * linux/kernel/vserver/signal.c
21265+ *
21266+ * Virtual Server: Signal Support
21267+ *
cc23e853 21268+ * Copyright (C) 2003-2007 Herbert P?tzl
4bf69007
AM
21269+ *
21270+ * V0.01 broken out from vcontext V0.05
21271+ * V0.02 changed vcmds to vxi arg
21272+ * V0.03 adjusted siginfo for kill
21273+ *
21274+ */
99a884b4 21275+
4bf69007 21276+#include <asm/uaccess.h>
93de0823 21277+
4bf69007
AM
21278+#include <linux/vs_context.h>
21279+#include <linux/vs_pid.h>
21280+#include <linux/vserver/signal_cmd.h>
d337f35e 21281+
d337f35e 21282+
4bf69007
AM
21283+int vx_info_kill(struct vx_info *vxi, int pid, int sig)
21284+{
21285+ int retval, count = 0;
21286+ struct task_struct *p;
21287+ struct siginfo *sip = SEND_SIG_PRIV;
d33d7b00 21288+
4bf69007
AM
21289+ retval = -ESRCH;
21290+ vxdprintk(VXD_CBIT(misc, 4),
21291+ "vx_info_kill(%p[#%d],%d,%d)*",
21292+ vxi, vxi->vx_id, pid, sig);
21293+ read_lock(&tasklist_lock);
21294+ switch (pid) {
21295+ case 0:
21296+ case -1:
21297+ for_each_process(p) {
21298+ int err = 0;
d337f35e 21299+
4bf69007
AM
21300+ if (vx_task_xid(p) != vxi->vx_id || p->pid <= 1 ||
21301+ (pid && vxi->vx_initpid == p->pid))
21302+ continue;
d337f35e 21303+
4bf69007
AM
21304+ err = group_send_sig_info(sig, sip, p);
21305+ ++count;
21306+ if (err != -EPERM)
21307+ retval = err;
21308+ }
21309+ break;
d337f35e 21310+
4bf69007
AM
21311+ case 1:
21312+ if (vxi->vx_initpid) {
21313+ pid = vxi->vx_initpid;
21314+ /* for now, only SIGINT to private init ... */
21315+ if (!vx_info_flags(vxi, VXF_STATE_ADMIN, 0) &&
21316+ /* ... as long as there are tasks left */
21317+ (atomic_read(&vxi->vx_tasks) > 1))
21318+ sig = SIGINT;
21319+ }
21320+ /* fallthrough */
21321+ default:
21322+ rcu_read_lock();
21323+ p = find_task_by_real_pid(pid);
21324+ rcu_read_unlock();
21325+ if (p) {
21326+ if (vx_task_xid(p) == vxi->vx_id)
21327+ retval = group_send_sig_info(sig, sip, p);
21328+ }
21329+ break;
21330+ }
21331+ read_unlock(&tasklist_lock);
21332+ vxdprintk(VXD_CBIT(misc, 4),
21333+ "vx_info_kill(%p[#%d],%d,%d,%ld) = %d",
21334+ vxi, vxi->vx_id, pid, sig, (long)sip, retval);
21335+ return retval;
21336+}
d337f35e 21337+
4bf69007 21338+int vc_ctx_kill(struct vx_info *vxi, void __user *data)
d337f35e 21339+{
4bf69007 21340+ struct vcmd_ctx_kill_v0 vc_data;
d337f35e 21341+
4bf69007
AM
21342+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
21343+ return -EFAULT;
d337f35e 21344+
4bf69007
AM
21345+ /* special check to allow guest shutdown */
21346+ if (!vx_info_flags(vxi, VXF_STATE_ADMIN, 0) &&
21347+ /* forbid killall pid=0 when init is present */
21348+ (((vc_data.pid < 1) && vxi->vx_initpid) ||
21349+ (vc_data.pid > 1)))
21350+ return -EACCES;
21351+
21352+ return vx_info_kill(vxi, vc_data.pid, vc_data.sig);
d337f35e
JR
21353+}
21354+
4bf69007
AM
21355+
21356+static int __wait_exit(struct vx_info *vxi)
d337f35e 21357+{
4bf69007
AM
21358+ DECLARE_WAITQUEUE(wait, current);
21359+ int ret = 0;
d337f35e 21360+
4bf69007
AM
21361+ add_wait_queue(&vxi->vx_wait, &wait);
21362+ set_current_state(TASK_INTERRUPTIBLE);
d337f35e 21363+
4bf69007
AM
21364+wait:
21365+ if (vx_info_state(vxi,
21366+ VXS_SHUTDOWN | VXS_HASHED | VXS_HELPER) == VXS_SHUTDOWN)
21367+ goto out;
21368+ if (signal_pending(current)) {
21369+ ret = -ERESTARTSYS;
21370+ goto out;
21371+ }
21372+ schedule();
21373+ goto wait;
21374+
21375+out:
21376+ set_current_state(TASK_RUNNING);
21377+ remove_wait_queue(&vxi->vx_wait, &wait);
21378+ return ret;
d337f35e
JR
21379+}
21380+
4a036bed 21381+
7b17263b 21382+
4bf69007 21383+int vc_wait_exit(struct vx_info *vxi, void __user *data)
7b17263b 21384+{
4bf69007
AM
21385+ struct vcmd_wait_exit_v0 vc_data;
21386+ int ret;
7b17263b 21387+
4bf69007
AM
21388+ ret = __wait_exit(vxi);
21389+ vc_data.reboot_cmd = vxi->reboot_cmd;
21390+ vc_data.exit_code = vxi->exit_code;
21391+
21392+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
21393+ ret = -EFAULT;
21394+ return ret;
7b17263b 21395+}
2380c486 21396+
3261cfd5
AM
21397diff -NurpP --minimal linux-4.9.207/kernel/vserver/space.c linux-4.9.207-vs2.3.9.11/kernel/vserver/space.c
21398--- linux-4.9.207/kernel/vserver/space.c 1970-01-01 00:00:00.000000000 +0000
21399+++ linux-4.9.207-vs2.3.9.11/kernel/vserver/space.c 2018-10-20 04:58:15.000000000 +0000
cc23e853 21400@@ -0,0 +1,437 @@
4bf69007
AM
21401+/*
21402+ * linux/kernel/vserver/space.c
21403+ *
21404+ * Virtual Server: Context Space Support
21405+ *
cc23e853 21406+ * Copyright (C) 2003-2010 Herbert P?tzl
4bf69007
AM
21407+ *
21408+ * V0.01 broken out from context.c 0.07
21409+ * V0.02 added task locking for namespace
21410+ * V0.03 broken out vx_enter_namespace
21411+ * V0.04 added *space support and commands
21412+ * V0.05 added credential support
21413+ *
21414+ */
21415+
21416+#include <linux/utsname.h>
21417+#include <linux/nsproxy.h>
21418+#include <linux/err.h>
21419+#include <linux/fs_struct.h>
21420+#include <linux/cred.h>
21421+#include <asm/uaccess.h>
d337f35e 21422+
d337f35e 21423+#include <linux/vs_context.h>
4bf69007
AM
21424+#include <linux/vserver/space.h>
21425+#include <linux/vserver/space_cmd.h>
2380c486 21426+
4bf69007
AM
21427+atomic_t vs_global_nsproxy = ATOMIC_INIT(0);
21428+atomic_t vs_global_fs = ATOMIC_INIT(0);
21429+atomic_t vs_global_mnt_ns = ATOMIC_INIT(0);
21430+atomic_t vs_global_uts_ns = ATOMIC_INIT(0);
cc23e853 21431+atomic_t vs_global_ipc_ns = ATOMIC_INIT(0);
4bf69007
AM
21432+atomic_t vs_global_user_ns = ATOMIC_INIT(0);
21433+atomic_t vs_global_pid_ns = ATOMIC_INIT(0);
d337f35e 21434+
2380c486 21435+
4bf69007 21436+/* namespace functions */
2380c486 21437+
4bf69007
AM
21438+#include <linux/mnt_namespace.h>
21439+#include <linux/user_namespace.h>
21440+#include <linux/pid_namespace.h>
21441+#include <linux/ipc_namespace.h>
21442+#include <net/net_namespace.h>
21443+#include "../fs/mount.h"
2380c486 21444+
2380c486 21445+
4bf69007
AM
21446+static const struct vcmd_space_mask_v1 space_mask_v0 = {
21447+ .mask = CLONE_FS |
21448+ CLONE_NEWNS |
21449+#ifdef CONFIG_UTS_NS
21450+ CLONE_NEWUTS |
21451+#endif
21452+#ifdef CONFIG_IPC_NS
21453+ CLONE_NEWIPC |
21454+#endif
21455+#ifdef CONFIG_USER_NS
21456+ CLONE_NEWUSER |
21457+#endif
21458+ 0
21459+};
2380c486 21460+
4bf69007
AM
21461+static const struct vcmd_space_mask_v1 space_mask = {
21462+ .mask = CLONE_FS |
21463+ CLONE_NEWNS |
21464+#ifdef CONFIG_UTS_NS
21465+ CLONE_NEWUTS |
21466+#endif
21467+#ifdef CONFIG_IPC_NS
21468+ CLONE_NEWIPC |
21469+#endif
21470+#ifdef CONFIG_USER_NS
21471+ CLONE_NEWUSER |
21472+#endif
21473+#ifdef CONFIG_PID_NS
21474+ CLONE_NEWPID |
21475+#endif
21476+#ifdef CONFIG_NET_NS
21477+ CLONE_NEWNET |
21478+#endif
21479+ 0
21480+};
2380c486 21481+
4bf69007
AM
21482+static const struct vcmd_space_mask_v1 default_space_mask = {
21483+ .mask = CLONE_FS |
21484+ CLONE_NEWNS |
21485+#ifdef CONFIG_UTS_NS
21486+ CLONE_NEWUTS |
21487+#endif
21488+#ifdef CONFIG_IPC_NS
21489+ CLONE_NEWIPC |
21490+#endif
21491+#ifdef CONFIG_USER_NS
bb20add7 21492+// CLONE_NEWUSER |
4bf69007
AM
21493+#endif
21494+#ifdef CONFIG_PID_NS
21495+// CLONE_NEWPID |
21496+#endif
21497+ 0
21498+};
2380c486 21499+
4bf69007
AM
21500+/*
21501+ * build a new nsproxy mix
21502+ * assumes that both proxies are 'const'
21503+ * does not touch nsproxy refcounts
21504+ * will hold a reference on the result.
21505+ */
7b17263b 21506+
4bf69007
AM
21507+struct nsproxy *vs_mix_nsproxy(struct nsproxy *old_nsproxy,
21508+ struct nsproxy *new_nsproxy, unsigned long mask)
21509+{
21510+ struct mnt_namespace *old_ns;
21511+ struct uts_namespace *old_uts;
21512+ struct ipc_namespace *old_ipc;
21513+#ifdef CONFIG_PID_NS
21514+ struct pid_namespace *old_pid;
21515+#endif
21516+#ifdef CONFIG_NET_NS
21517+ struct net *old_net;
21518+#endif
21519+ struct nsproxy *nsproxy;
d337f35e 21520+
4bf69007
AM
21521+ nsproxy = copy_nsproxy(old_nsproxy);
21522+ if (!nsproxy)
21523+ goto out;
bd0a9c15 21524+
4bf69007
AM
21525+ if (mask & CLONE_NEWNS) {
21526+ old_ns = nsproxy->mnt_ns;
21527+ nsproxy->mnt_ns = new_nsproxy->mnt_ns;
21528+ if (nsproxy->mnt_ns)
21529+ get_mnt_ns(nsproxy->mnt_ns);
21530+ } else
21531+ old_ns = NULL;
d337f35e 21532+
4bf69007
AM
21533+ if (mask & CLONE_NEWUTS) {
21534+ old_uts = nsproxy->uts_ns;
21535+ nsproxy->uts_ns = new_nsproxy->uts_ns;
21536+ if (nsproxy->uts_ns)
21537+ get_uts_ns(nsproxy->uts_ns);
21538+ } else
21539+ old_uts = NULL;
2380c486 21540+
4bf69007
AM
21541+ if (mask & CLONE_NEWIPC) {
21542+ old_ipc = nsproxy->ipc_ns;
21543+ nsproxy->ipc_ns = new_nsproxy->ipc_ns;
21544+ if (nsproxy->ipc_ns)
21545+ get_ipc_ns(nsproxy->ipc_ns);
21546+ } else
21547+ old_ipc = NULL;
ec22aa5c 21548+
4bf69007
AM
21549+#ifdef CONFIG_PID_NS
21550+ if (mask & CLONE_NEWPID) {
5f23d63e
AM
21551+ old_pid = nsproxy->pid_ns_for_children;
21552+ nsproxy->pid_ns_for_children = new_nsproxy->pid_ns_for_children;
21553+ if (nsproxy->pid_ns_for_children)
21554+ get_pid_ns(nsproxy->pid_ns_for_children);
4bf69007
AM
21555+ } else
21556+ old_pid = NULL;
21557+#endif
21558+#ifdef CONFIG_NET_NS
21559+ if (mask & CLONE_NEWNET) {
21560+ old_net = nsproxy->net_ns;
21561+ nsproxy->net_ns = new_nsproxy->net_ns;
21562+ if (nsproxy->net_ns)
21563+ get_net(nsproxy->net_ns);
21564+ } else
21565+ old_net = NULL;
21566+#endif
21567+ if (old_ns)
21568+ put_mnt_ns(old_ns);
21569+ if (old_uts)
21570+ put_uts_ns(old_uts);
21571+ if (old_ipc)
21572+ put_ipc_ns(old_ipc);
21573+#ifdef CONFIG_PID_NS
21574+ if (old_pid)
21575+ put_pid_ns(old_pid);
21576+#endif
21577+#ifdef CONFIG_NET_NS
21578+ if (old_net)
21579+ put_net(old_net);
21580+#endif
21581+out:
21582+ return nsproxy;
21583+}
2380c486 21584+
bd0a9c15 21585+
4bf69007
AM
21586+/*
21587+ * merge two nsproxy structs into a new one.
21588+ * will hold a reference on the result.
21589+ */
d337f35e 21590+
4bf69007
AM
21591+static inline
21592+struct nsproxy *__vs_merge_nsproxy(struct nsproxy *old,
21593+ struct nsproxy *proxy, unsigned long mask)
21594+{
21595+ struct nsproxy null_proxy = { .mnt_ns = NULL };
2380c486 21596+
4bf69007
AM
21597+ if (!proxy)
21598+ return NULL;
d337f35e 21599+
4bf69007
AM
21600+ if (mask) {
21601+ /* vs_mix_nsproxy returns with reference */
21602+ return vs_mix_nsproxy(old ? old : &null_proxy,
21603+ proxy, mask);
21604+ }
21605+ get_nsproxy(proxy);
21606+ return proxy;
21607+}
2380c486 21608+
ec22aa5c 21609+
4bf69007
AM
21610+int vx_enter_space(struct vx_info *vxi, unsigned long mask, unsigned index)
21611+{
21612+ struct nsproxy *proxy, *proxy_cur, *proxy_new;
21613+ struct fs_struct *fs_cur, *fs = NULL;
21614+ struct _vx_space *space;
21615+ int ret, kill = 0;
2380c486 21616+
4bf69007
AM
21617+ vxdprintk(VXD_CBIT(space, 8), "vx_enter_space(%p[#%u],0x%08lx,%d)",
21618+ vxi, vxi->vx_id, mask, index);
2380c486 21619+
4bf69007
AM
21620+ if (vx_info_flags(vxi, VXF_INFO_PRIVATE, 0))
21621+ return -EACCES;
2380c486 21622+
4bf69007
AM
21623+ if (index >= VX_SPACES)
21624+ return -EINVAL;
2380c486 21625+
4bf69007
AM
21626+ space = &vxi->space[index];
21627+
21628+ if (!mask)
21629+ mask = space->vx_nsmask;
21630+
21631+ if ((mask & space->vx_nsmask) != mask)
21632+ return -EINVAL;
21633+
21634+ if (mask & CLONE_FS) {
21635+ fs = copy_fs_struct(space->vx_fs);
21636+ if (!fs)
21637+ return -ENOMEM;
2380c486 21638+ }
4bf69007
AM
21639+ proxy = space->vx_nsproxy;
21640+
21641+ vxdprintk(VXD_CBIT(space, 9),
21642+ "vx_enter_space(%p[#%u],0x%08lx,%d) -> (%p,%p)",
21643+ vxi, vxi->vx_id, mask, index, proxy, fs);
21644+
21645+ task_lock(current);
21646+ fs_cur = current->fs;
21647+
21648+ if (mask & CLONE_FS) {
21649+ spin_lock(&fs_cur->lock);
21650+ current->fs = fs;
21651+ kill = !--fs_cur->users;
21652+ spin_unlock(&fs_cur->lock);
ec22aa5c 21653+ }
ec22aa5c 21654+
4bf69007
AM
21655+ proxy_cur = current->nsproxy;
21656+ get_nsproxy(proxy_cur);
21657+ task_unlock(current);
21658+
21659+ if (kill)
21660+ free_fs_struct(fs_cur);
21661+
21662+ proxy_new = __vs_merge_nsproxy(proxy_cur, proxy, mask);
21663+ if (IS_ERR(proxy_new)) {
21664+ ret = PTR_ERR(proxy_new);
21665+ goto out_put;
eab5a9a6 21666+ }
4bf69007
AM
21667+
21668+ proxy_new = xchg(&current->nsproxy, proxy_new);
21669+
21670+ if (mask & CLONE_NEWUSER) {
21671+ struct cred *cred;
21672+
21673+ vxdprintk(VXD_CBIT(space, 10),
21674+ "vx_enter_space(%p[#%u],%p) cred (%p,%p)",
21675+ vxi, vxi->vx_id, space->vx_cred,
21676+ current->real_cred, current->cred);
21677+
21678+ if (space->vx_cred) {
21679+ cred = __prepare_creds(space->vx_cred);
21680+ if (cred)
21681+ commit_creds(cred);
21682+ }
d337f35e 21683+ }
4bf69007
AM
21684+
21685+ ret = 0;
21686+
21687+ if (proxy_new)
21688+ put_nsproxy(proxy_new);
21689+out_put:
21690+ if (proxy_cur)
21691+ put_nsproxy(proxy_cur);
21692+ return ret;
21693+}
21694+
21695+
21696+int vx_set_space(struct vx_info *vxi, unsigned long mask, unsigned index)
21697+{
21698+ struct nsproxy *proxy_vxi, *proxy_cur, *proxy_new;
21699+ struct fs_struct *fs_vxi, *fs = NULL;
21700+ struct _vx_space *space;
21701+ int ret, kill = 0;
21702+
21703+ vxdprintk(VXD_CBIT(space, 8), "vx_set_space(%p[#%u],0x%08lx,%d)",
21704+ vxi, vxi->vx_id, mask, index);
21705+
21706+ if ((mask & space_mask.mask) != mask)
21707+ return -EINVAL;
21708+
21709+ if (index >= VX_SPACES)
21710+ return -EINVAL;
21711+
21712+ space = &vxi->space[index];
21713+
21714+ proxy_vxi = space->vx_nsproxy;
21715+ fs_vxi = space->vx_fs;
21716+
21717+ if (mask & CLONE_FS) {
21718+ fs = copy_fs_struct(current->fs);
21719+ if (!fs)
21720+ return -ENOMEM;
2380c486 21721+ }
d337f35e 21722+
4bf69007 21723+ task_lock(current);
2ba6f0dd 21724+
4bf69007
AM
21725+ if (mask & CLONE_FS) {
21726+ spin_lock(&fs_vxi->lock);
21727+ space->vx_fs = fs;
21728+ kill = !--fs_vxi->users;
21729+ spin_unlock(&fs_vxi->lock);
21730+ }
2ba6f0dd 21731+
4bf69007
AM
21732+ proxy_cur = current->nsproxy;
21733+ get_nsproxy(proxy_cur);
21734+ task_unlock(current);
2ba6f0dd 21735+
4bf69007
AM
21736+ if (kill)
21737+ free_fs_struct(fs_vxi);
2ba6f0dd 21738+
4bf69007
AM
21739+ proxy_new = __vs_merge_nsproxy(proxy_vxi, proxy_cur, mask);
21740+ if (IS_ERR(proxy_new)) {
21741+ ret = PTR_ERR(proxy_new);
21742+ goto out_put;
21743+ }
2ba6f0dd 21744+
4bf69007
AM
21745+ proxy_new = xchg(&space->vx_nsproxy, proxy_new);
21746+ space->vx_nsmask |= mask;
2ba6f0dd 21747+
4bf69007
AM
21748+ if (mask & CLONE_NEWUSER) {
21749+ struct cred *cred;
2ba6f0dd 21750+
4bf69007
AM
21751+ vxdprintk(VXD_CBIT(space, 10),
21752+ "vx_set_space(%p[#%u],%p) cred (%p,%p)",
21753+ vxi, vxi->vx_id, space->vx_cred,
21754+ current->real_cred, current->cred);
2ba6f0dd 21755+
4bf69007
AM
21756+ cred = prepare_creds();
21757+ cred = (struct cred *)xchg(&space->vx_cred, cred);
21758+ if (cred)
21759+ abort_creds(cred);
21760+ }
2ba6f0dd 21761+
4bf69007 21762+ ret = 0;
2ba6f0dd 21763+
4bf69007
AM
21764+ if (proxy_new)
21765+ put_nsproxy(proxy_new);
21766+out_put:
21767+ if (proxy_cur)
21768+ put_nsproxy(proxy_cur);
21769+ return ret;
21770+}
2ba6f0dd
AM
21771+
21772+
4bf69007
AM
21773+int vc_enter_space_v1(struct vx_info *vxi, void __user *data)
21774+{
21775+ struct vcmd_space_mask_v1 vc_data = { .mask = 0 };
2ba6f0dd 21776+
4bf69007
AM
21777+ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
21778+ return -EFAULT;
2ba6f0dd 21779+
4bf69007
AM
21780+ return vx_enter_space(vxi, vc_data.mask, 0);
21781+}
2ba6f0dd 21782+
4bf69007
AM
21783+int vc_enter_space(struct vx_info *vxi, void __user *data)
21784+{
21785+ struct vcmd_space_mask_v2 vc_data = { .mask = 0 };
2ba6f0dd 21786+
4bf69007
AM
21787+ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
21788+ return -EFAULT;
2ba6f0dd 21789+
4bf69007
AM
21790+ if (vc_data.index >= VX_SPACES)
21791+ return -EINVAL;
2ba6f0dd 21792+
4bf69007
AM
21793+ return vx_enter_space(vxi, vc_data.mask, vc_data.index);
21794+}
2ba6f0dd 21795+
4bf69007
AM
21796+int vc_set_space_v1(struct vx_info *vxi, void __user *data)
21797+{
21798+ struct vcmd_space_mask_v1 vc_data = { .mask = 0 };
2ba6f0dd 21799+
4bf69007
AM
21800+ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
21801+ return -EFAULT;
2ba6f0dd 21802+
4bf69007
AM
21803+ return vx_set_space(vxi, vc_data.mask, 0);
21804+}
2ba6f0dd 21805+
4bf69007
AM
21806+int vc_set_space(struct vx_info *vxi, void __user *data)
21807+{
21808+ struct vcmd_space_mask_v2 vc_data = { .mask = 0 };
2ba6f0dd 21809+
4bf69007
AM
21810+ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
21811+ return -EFAULT;
2ba6f0dd 21812+
4bf69007
AM
21813+ if (vc_data.index >= VX_SPACES)
21814+ return -EINVAL;
2ba6f0dd 21815+
4bf69007
AM
21816+ return vx_set_space(vxi, vc_data.mask, vc_data.index);
21817+}
2ba6f0dd 21818+
4bf69007
AM
21819+int vc_get_space_mask(void __user *data, int type)
21820+{
21821+ const struct vcmd_space_mask_v1 *mask;
2ba6f0dd 21822+
4bf69007
AM
21823+ if (type == 0)
21824+ mask = &space_mask_v0;
21825+ else if (type == 1)
21826+ mask = &space_mask;
21827+ else
21828+ mask = &default_space_mask;
2ba6f0dd 21829+
4bf69007
AM
21830+ vxdprintk(VXD_CBIT(space, 10),
21831+ "vc_get_space_mask(%d) = %08llx", type, mask->mask);
2ba6f0dd 21832+
4bf69007
AM
21833+ if (copy_to_user(data, mask, sizeof(*mask)))
21834+ return -EFAULT;
21835+ return 0;
21836+}
2ba6f0dd 21837+
3261cfd5
AM
21838diff -NurpP --minimal linux-4.9.207/kernel/vserver/switch.c linux-4.9.207-vs2.3.9.11/kernel/vserver/switch.c
21839--- linux-4.9.207/kernel/vserver/switch.c 1970-01-01 00:00:00.000000000 +0000
21840+++ linux-4.9.207-vs2.3.9.11/kernel/vserver/switch.c 2018-10-20 04:58:15.000000000 +0000
4bf69007
AM
21841@@ -0,0 +1,556 @@
21842+/*
21843+ * linux/kernel/vserver/switch.c
21844+ *
21845+ * Virtual Server: Syscall Switch
21846+ *
cc23e853 21847+ * Copyright (C) 2003-2011 Herbert P?tzl
4bf69007
AM
21848+ *
21849+ * V0.01 syscall switch
21850+ * V0.02 added signal to context
21851+ * V0.03 added rlimit functions
21852+ * V0.04 added iattr, task/xid functions
21853+ * V0.05 added debug/history stuff
21854+ * V0.06 added compat32 layer
21855+ * V0.07 vcmd args and perms
21856+ * V0.08 added status commands
21857+ * V0.09 added tag commands
21858+ * V0.10 added oom bias
21859+ * V0.11 added device commands
21860+ * V0.12 added warn mask
21861+ *
21862+ */
2ba6f0dd 21863+
4bf69007
AM
21864+#include <linux/vs_context.h>
21865+#include <linux/vs_network.h>
21866+#include <linux/vserver/switch.h>
2ba6f0dd 21867+
4bf69007 21868+#include "vci_config.h"
2ba6f0dd 21869+
2ba6f0dd 21870+
4bf69007
AM
21871+static inline
21872+int vc_get_version(uint32_t id)
21873+{
21874+ return VCI_VERSION;
21875+}
2ba6f0dd 21876+
4bf69007
AM
21877+static inline
21878+int vc_get_vci(uint32_t id)
21879+{
21880+ return vci_kernel_config();
21881+}
2ba6f0dd 21882+
4bf69007
AM
21883+#include <linux/vserver/context_cmd.h>
21884+#include <linux/vserver/cvirt_cmd.h>
21885+#include <linux/vserver/cacct_cmd.h>
21886+#include <linux/vserver/limit_cmd.h>
21887+#include <linux/vserver/network_cmd.h>
21888+#include <linux/vserver/sched_cmd.h>
21889+#include <linux/vserver/debug_cmd.h>
21890+#include <linux/vserver/inode_cmd.h>
21891+#include <linux/vserver/dlimit_cmd.h>
21892+#include <linux/vserver/signal_cmd.h>
21893+#include <linux/vserver/space_cmd.h>
21894+#include <linux/vserver/tag_cmd.h>
21895+#include <linux/vserver/device_cmd.h>
2ba6f0dd 21896+
4bf69007
AM
21897+#include <linux/vserver/inode.h>
21898+#include <linux/vserver/dlimit.h>
2ba6f0dd 21899+
2ba6f0dd 21900+
4bf69007
AM
21901+#ifdef CONFIG_COMPAT
21902+#define __COMPAT(name, id, data, compat) \
21903+ (compat) ? name ## _x32(id, data) : name(id, data)
21904+#define __COMPAT_NO_ID(name, data, compat) \
21905+ (compat) ? name ## _x32(data) : name(data)
21906+#else
21907+#define __COMPAT(name, id, data, compat) \
21908+ name(id, data)
21909+#define __COMPAT_NO_ID(name, data, compat) \
21910+ name(data)
21911+#endif
2ba6f0dd 21912+
2ba6f0dd 21913+
4bf69007
AM
21914+static inline
21915+long do_vcmd(uint32_t cmd, uint32_t id,
21916+ struct vx_info *vxi, struct nx_info *nxi,
21917+ void __user *data, int compat)
21918+{
21919+ switch (cmd) {
2ba6f0dd 21920+
4bf69007
AM
21921+ case VCMD_get_version:
21922+ return vc_get_version(id);
21923+ case VCMD_get_vci:
21924+ return vc_get_vci(id);
2ba6f0dd 21925+
4bf69007
AM
21926+ case VCMD_task_xid:
21927+ return vc_task_xid(id);
21928+ case VCMD_vx_info:
21929+ return vc_vx_info(vxi, data);
2ba6f0dd 21930+
4bf69007
AM
21931+ case VCMD_task_nid:
21932+ return vc_task_nid(id);
21933+ case VCMD_nx_info:
21934+ return vc_nx_info(nxi, data);
2ba6f0dd 21935+
4bf69007
AM
21936+ case VCMD_task_tag:
21937+ return vc_task_tag(id);
2ba6f0dd 21938+
4bf69007
AM
21939+ case VCMD_set_space_v1:
21940+ return vc_set_space_v1(vxi, data);
21941+ /* this is version 2 */
21942+ case VCMD_set_space:
21943+ return vc_set_space(vxi, data);
2ba6f0dd 21944+
4bf69007
AM
21945+ case VCMD_get_space_mask_v0:
21946+ return vc_get_space_mask(data, 0);
21947+ /* this is version 1 */
21948+ case VCMD_get_space_mask:
21949+ return vc_get_space_mask(data, 1);
2ba6f0dd 21950+
4bf69007
AM
21951+ case VCMD_get_space_default:
21952+ return vc_get_space_mask(data, -1);
2ba6f0dd 21953+
4bf69007
AM
21954+ case VCMD_set_umask:
21955+ return vc_set_umask(vxi, data);
2ba6f0dd 21956+
4bf69007
AM
21957+ case VCMD_get_umask:
21958+ return vc_get_umask(vxi, data);
2ba6f0dd 21959+
4bf69007
AM
21960+ case VCMD_set_wmask:
21961+ return vc_set_wmask(vxi, data);
2ba6f0dd 21962+
4bf69007
AM
21963+ case VCMD_get_wmask:
21964+ return vc_get_wmask(vxi, data);
21965+#ifdef CONFIG_IA32_EMULATION
21966+ case VCMD_get_rlimit:
21967+ return __COMPAT(vc_get_rlimit, vxi, data, compat);
21968+ case VCMD_set_rlimit:
21969+ return __COMPAT(vc_set_rlimit, vxi, data, compat);
21970+#else
21971+ case VCMD_get_rlimit:
21972+ return vc_get_rlimit(vxi, data);
21973+ case VCMD_set_rlimit:
21974+ return vc_set_rlimit(vxi, data);
21975+#endif
21976+ case VCMD_get_rlimit_mask:
21977+ return vc_get_rlimit_mask(id, data);
21978+ case VCMD_reset_hits:
21979+ return vc_reset_hits(vxi, data);
21980+ case VCMD_reset_minmax:
21981+ return vc_reset_minmax(vxi, data);
2ba6f0dd 21982+
4bf69007
AM
21983+ case VCMD_get_vhi_name:
21984+ return vc_get_vhi_name(vxi, data);
21985+ case VCMD_set_vhi_name:
21986+ return vc_set_vhi_name(vxi, data);
2ba6f0dd 21987+
4bf69007
AM
21988+ case VCMD_ctx_stat:
21989+ return vc_ctx_stat(vxi, data);
21990+ case VCMD_virt_stat:
21991+ return vc_virt_stat(vxi, data);
21992+ case VCMD_sock_stat:
21993+ return vc_sock_stat(vxi, data);
21994+ case VCMD_rlimit_stat:
21995+ return vc_rlimit_stat(vxi, data);
2ba6f0dd 21996+
4bf69007
AM
21997+ case VCMD_set_cflags:
21998+ return vc_set_cflags(vxi, data);
21999+ case VCMD_get_cflags:
22000+ return vc_get_cflags(vxi, data);
2ba6f0dd 22001+
4bf69007
AM
22002+ /* this is version 1 */
22003+ case VCMD_set_ccaps:
22004+ return vc_set_ccaps(vxi, data);
22005+ /* this is version 1 */
22006+ case VCMD_get_ccaps:
22007+ return vc_get_ccaps(vxi, data);
22008+ case VCMD_set_bcaps:
22009+ return vc_set_bcaps(vxi, data);
22010+ case VCMD_get_bcaps:
22011+ return vc_get_bcaps(vxi, data);
2ba6f0dd 22012+
4bf69007
AM
22013+ case VCMD_set_badness:
22014+ return vc_set_badness(vxi, data);
22015+ case VCMD_get_badness:
22016+ return vc_get_badness(vxi, data);
2ba6f0dd 22017+
4bf69007
AM
22018+ case VCMD_set_nflags:
22019+ return vc_set_nflags(nxi, data);
22020+ case VCMD_get_nflags:
22021+ return vc_get_nflags(nxi, data);
2ba6f0dd 22022+
4bf69007
AM
22023+ case VCMD_set_ncaps:
22024+ return vc_set_ncaps(nxi, data);
22025+ case VCMD_get_ncaps:
22026+ return vc_get_ncaps(nxi, data);
2ba6f0dd 22027+
4bf69007
AM
22028+ case VCMD_set_prio_bias:
22029+ return vc_set_prio_bias(vxi, data);
22030+ case VCMD_get_prio_bias:
22031+ return vc_get_prio_bias(vxi, data);
22032+ case VCMD_add_dlimit:
22033+ return __COMPAT(vc_add_dlimit, id, data, compat);
22034+ case VCMD_rem_dlimit:
22035+ return __COMPAT(vc_rem_dlimit, id, data, compat);
22036+ case VCMD_set_dlimit:
22037+ return __COMPAT(vc_set_dlimit, id, data, compat);
22038+ case VCMD_get_dlimit:
22039+ return __COMPAT(vc_get_dlimit, id, data, compat);
2ba6f0dd 22040+
4bf69007
AM
22041+ case VCMD_ctx_kill:
22042+ return vc_ctx_kill(vxi, data);
2ba6f0dd 22043+
4bf69007
AM
22044+ case VCMD_wait_exit:
22045+ return vc_wait_exit(vxi, data);
2ba6f0dd 22046+
4bf69007
AM
22047+ case VCMD_get_iattr:
22048+ return __COMPAT_NO_ID(vc_get_iattr, data, compat);
22049+ case VCMD_set_iattr:
22050+ return __COMPAT_NO_ID(vc_set_iattr, data, compat);
2ba6f0dd 22051+
4bf69007
AM
22052+ case VCMD_fget_iattr:
22053+ return vc_fget_iattr(id, data);
22054+ case VCMD_fset_iattr:
22055+ return vc_fset_iattr(id, data);
2ba6f0dd 22056+
4bf69007
AM
22057+ case VCMD_enter_space_v0:
22058+ return vc_enter_space_v1(vxi, NULL);
22059+ case VCMD_enter_space_v1:
22060+ return vc_enter_space_v1(vxi, data);
22061+ /* this is version 2 */
22062+ case VCMD_enter_space:
22063+ return vc_enter_space(vxi, data);
2ba6f0dd 22064+
4bf69007
AM
22065+ case VCMD_ctx_create_v0:
22066+ return vc_ctx_create(id, NULL);
22067+ case VCMD_ctx_create:
22068+ return vc_ctx_create(id, data);
22069+ case VCMD_ctx_migrate_v0:
22070+ return vc_ctx_migrate(vxi, NULL);
22071+ case VCMD_ctx_migrate:
22072+ return vc_ctx_migrate(vxi, data);
2ba6f0dd 22073+
4bf69007
AM
22074+ case VCMD_net_create_v0:
22075+ return vc_net_create(id, NULL);
22076+ case VCMD_net_create:
22077+ return vc_net_create(id, data);
22078+ case VCMD_net_migrate:
22079+ return vc_net_migrate(nxi, data);
2ba6f0dd 22080+
4bf69007
AM
22081+ case VCMD_tag_migrate:
22082+ return vc_tag_migrate(id);
2ba6f0dd 22083+
4bf69007
AM
22084+ case VCMD_net_add:
22085+ return vc_net_add(nxi, data);
22086+ case VCMD_net_remove:
22087+ return vc_net_remove(nxi, data);
2ba6f0dd 22088+
4bf69007
AM
22089+ case VCMD_net_add_ipv4_v1:
22090+ return vc_net_add_ipv4_v1(nxi, data);
22091+ /* this is version 2 */
22092+ case VCMD_net_add_ipv4:
22093+ return vc_net_add_ipv4(nxi, data);
2ba6f0dd 22094+
4bf69007
AM
22095+ case VCMD_net_rem_ipv4_v1:
22096+ return vc_net_rem_ipv4_v1(nxi, data);
22097+ /* this is version 2 */
22098+ case VCMD_net_rem_ipv4:
22099+ return vc_net_rem_ipv4(nxi, data);
22100+#ifdef CONFIG_IPV6
22101+ case VCMD_net_add_ipv6:
22102+ return vc_net_add_ipv6(nxi, data);
22103+ case VCMD_net_remove_ipv6:
22104+ return vc_net_remove_ipv6(nxi, data);
22105+#endif
22106+/* case VCMD_add_match_ipv4:
22107+ return vc_add_match_ipv4(nxi, data);
22108+ case VCMD_get_match_ipv4:
22109+ return vc_get_match_ipv4(nxi, data);
22110+#ifdef CONFIG_IPV6
22111+ case VCMD_add_match_ipv6:
22112+ return vc_add_match_ipv6(nxi, data);
22113+ case VCMD_get_match_ipv6:
22114+ return vc_get_match_ipv6(nxi, data);
22115+#endif */
2ba6f0dd 22116+
4bf69007
AM
22117+#ifdef CONFIG_VSERVER_DEVICE
22118+ case VCMD_set_mapping:
22119+ return __COMPAT(vc_set_mapping, vxi, data, compat);
22120+ case VCMD_unset_mapping:
22121+ return __COMPAT(vc_unset_mapping, vxi, data, compat);
22122+#endif
22123+#ifdef CONFIG_VSERVER_HISTORY
22124+ case VCMD_dump_history:
22125+ return vc_dump_history(id);
22126+ case VCMD_read_history:
22127+ return __COMPAT(vc_read_history, id, data, compat);
22128+#endif
22129+ default:
22130+ vxwprintk_task(1, "unimplemented VCMD_%02d_%d[%d]",
22131+ VC_CATEGORY(cmd), VC_COMMAND(cmd), VC_VERSION(cmd));
22132+ }
22133+ return -ENOSYS;
22134+}
2ba6f0dd 22135+
2ba6f0dd 22136+
4bf69007
AM
22137+#define __VCMD(vcmd, _perm, _args, _flags) \
22138+ case VCMD_ ## vcmd: perm = _perm; \
22139+ args = _args; flags = _flags; break
2ba6f0dd 22140+
2ba6f0dd 22141+
4bf69007
AM
22142+#define VCA_NONE 0x00
22143+#define VCA_VXI 0x01
22144+#define VCA_NXI 0x02
2ba6f0dd 22145+
4bf69007
AM
22146+#define VCF_NONE 0x00
22147+#define VCF_INFO 0x01
22148+#define VCF_ADMIN 0x02
22149+#define VCF_ARES 0x06 /* includes admin */
22150+#define VCF_SETUP 0x08
2ba6f0dd 22151+
4bf69007 22152+#define VCF_ZIDOK 0x10 /* zero id okay */
2ba6f0dd 22153+
2ba6f0dd
AM
22154+
22155+static inline
4bf69007 22156+long do_vserver(uint32_t cmd, uint32_t id, void __user *data, int compat)
2ba6f0dd 22157+{
4bf69007
AM
22158+ long ret;
22159+ int permit = -1, state = 0;
22160+ int perm = -1, args = 0, flags = 0;
22161+ struct vx_info *vxi = NULL;
22162+ struct nx_info *nxi = NULL;
2ba6f0dd 22163+
4bf69007
AM
22164+ switch (cmd) {
22165+ /* unpriviledged commands */
22166+ __VCMD(get_version, 0, VCA_NONE, 0);
22167+ __VCMD(get_vci, 0, VCA_NONE, 0);
22168+ __VCMD(get_rlimit_mask, 0, VCA_NONE, 0);
22169+ __VCMD(get_space_mask_v0,0, VCA_NONE, 0);
22170+ __VCMD(get_space_mask, 0, VCA_NONE, 0);
22171+ __VCMD(get_space_default,0, VCA_NONE, 0);
2ba6f0dd 22172+
4bf69007
AM
22173+ /* info commands */
22174+ __VCMD(task_xid, 2, VCA_NONE, 0);
22175+ __VCMD(reset_hits, 2, VCA_VXI, 0);
22176+ __VCMD(reset_minmax, 2, VCA_VXI, 0);
22177+ __VCMD(vx_info, 3, VCA_VXI, VCF_INFO);
22178+ __VCMD(get_bcaps, 3, VCA_VXI, VCF_INFO);
22179+ __VCMD(get_ccaps, 3, VCA_VXI, VCF_INFO);
22180+ __VCMD(get_cflags, 3, VCA_VXI, VCF_INFO);
22181+ __VCMD(get_umask, 3, VCA_VXI, VCF_INFO);
22182+ __VCMD(get_wmask, 3, VCA_VXI, VCF_INFO);
22183+ __VCMD(get_badness, 3, VCA_VXI, VCF_INFO);
22184+ __VCMD(get_vhi_name, 3, VCA_VXI, VCF_INFO);
22185+ __VCMD(get_rlimit, 3, VCA_VXI, VCF_INFO);
2ba6f0dd 22186+
4bf69007
AM
22187+ __VCMD(ctx_stat, 3, VCA_VXI, VCF_INFO);
22188+ __VCMD(virt_stat, 3, VCA_VXI, VCF_INFO);
22189+ __VCMD(sock_stat, 3, VCA_VXI, VCF_INFO);
22190+ __VCMD(rlimit_stat, 3, VCA_VXI, VCF_INFO);
2ba6f0dd 22191+
4bf69007
AM
22192+ __VCMD(task_nid, 2, VCA_NONE, 0);
22193+ __VCMD(nx_info, 3, VCA_NXI, VCF_INFO);
22194+ __VCMD(get_ncaps, 3, VCA_NXI, VCF_INFO);
22195+ __VCMD(get_nflags, 3, VCA_NXI, VCF_INFO);
2ba6f0dd 22196+
4bf69007 22197+ __VCMD(task_tag, 2, VCA_NONE, 0);
2ba6f0dd 22198+
4bf69007
AM
22199+ __VCMD(get_iattr, 2, VCA_NONE, 0);
22200+ __VCMD(fget_iattr, 2, VCA_NONE, 0);
22201+ __VCMD(get_dlimit, 3, VCA_NONE, VCF_INFO);
22202+ __VCMD(get_prio_bias, 3, VCA_VXI, VCF_INFO);
2ba6f0dd 22203+
4bf69007
AM
22204+ /* lower admin commands */
22205+ __VCMD(wait_exit, 4, VCA_VXI, VCF_INFO);
22206+ __VCMD(ctx_create_v0, 5, VCA_NONE, 0);
22207+ __VCMD(ctx_create, 5, VCA_NONE, 0);
22208+ __VCMD(ctx_migrate_v0, 5, VCA_VXI, VCF_ADMIN);
22209+ __VCMD(ctx_migrate, 5, VCA_VXI, VCF_ADMIN);
22210+ __VCMD(enter_space_v0, 5, VCA_VXI, VCF_ADMIN);
22211+ __VCMD(enter_space_v1, 5, VCA_VXI, VCF_ADMIN);
22212+ __VCMD(enter_space, 5, VCA_VXI, VCF_ADMIN);
2ba6f0dd 22213+
4bf69007
AM
22214+ __VCMD(net_create_v0, 5, VCA_NONE, 0);
22215+ __VCMD(net_create, 5, VCA_NONE, 0);
22216+ __VCMD(net_migrate, 5, VCA_NXI, VCF_ADMIN);
2ba6f0dd 22217+
4bf69007 22218+ __VCMD(tag_migrate, 5, VCA_NONE, VCF_ADMIN);
2ba6f0dd 22219+
4bf69007
AM
22220+ /* higher admin commands */
22221+ __VCMD(ctx_kill, 6, VCA_VXI, VCF_ARES);
22222+ __VCMD(set_space_v1, 7, VCA_VXI, VCF_ARES | VCF_SETUP);
22223+ __VCMD(set_space, 7, VCA_VXI, VCF_ARES | VCF_SETUP);
2ba6f0dd 22224+
4bf69007
AM
22225+ __VCMD(set_ccaps, 7, VCA_VXI, VCF_ARES | VCF_SETUP);
22226+ __VCMD(set_bcaps, 7, VCA_VXI, VCF_ARES | VCF_SETUP);
22227+ __VCMD(set_cflags, 7, VCA_VXI, VCF_ARES | VCF_SETUP);
22228+ __VCMD(set_umask, 7, VCA_VXI, VCF_ARES | VCF_SETUP);
22229+ __VCMD(set_wmask, 7, VCA_VXI, VCF_ARES | VCF_SETUP);
22230+ __VCMD(set_badness, 7, VCA_VXI, VCF_ARES | VCF_SETUP);
2ba6f0dd 22231+
4bf69007
AM
22232+ __VCMD(set_vhi_name, 7, VCA_VXI, VCF_ARES | VCF_SETUP);
22233+ __VCMD(set_rlimit, 7, VCA_VXI, VCF_ARES | VCF_SETUP);
22234+ __VCMD(set_prio_bias, 7, VCA_VXI, VCF_ARES | VCF_SETUP);
2ba6f0dd 22235+
4bf69007
AM
22236+ __VCMD(set_ncaps, 7, VCA_NXI, VCF_ARES | VCF_SETUP);
22237+ __VCMD(set_nflags, 7, VCA_NXI, VCF_ARES | VCF_SETUP);
22238+ __VCMD(net_add, 8, VCA_NXI, VCF_ARES | VCF_SETUP);
22239+ __VCMD(net_remove, 8, VCA_NXI, VCF_ARES | VCF_SETUP);
22240+ __VCMD(net_add_ipv4_v1, 8, VCA_NXI, VCF_ARES | VCF_SETUP);
22241+ __VCMD(net_rem_ipv4_v1, 8, VCA_NXI, VCF_ARES | VCF_SETUP);
22242+ __VCMD(net_add_ipv4, 8, VCA_NXI, VCF_ARES | VCF_SETUP);
22243+ __VCMD(net_rem_ipv4, 8, VCA_NXI, VCF_ARES | VCF_SETUP);
22244+#ifdef CONFIG_IPV6
22245+ __VCMD(net_add_ipv6, 8, VCA_NXI, VCF_ARES | VCF_SETUP);
22246+ __VCMD(net_remove_ipv6, 8, VCA_NXI, VCF_ARES | VCF_SETUP);
22247+#endif
22248+ __VCMD(set_iattr, 7, VCA_NONE, 0);
22249+ __VCMD(fset_iattr, 7, VCA_NONE, 0);
22250+ __VCMD(set_dlimit, 7, VCA_NONE, VCF_ARES);
22251+ __VCMD(add_dlimit, 8, VCA_NONE, VCF_ARES);
22252+ __VCMD(rem_dlimit, 8, VCA_NONE, VCF_ARES);
2ba6f0dd 22253+
4bf69007
AM
22254+#ifdef CONFIG_VSERVER_DEVICE
22255+ __VCMD(set_mapping, 8, VCA_VXI, VCF_ARES|VCF_ZIDOK);
22256+ __VCMD(unset_mapping, 8, VCA_VXI, VCF_ARES|VCF_ZIDOK);
22257+#endif
22258+ /* debug level admin commands */
22259+#ifdef CONFIG_VSERVER_HISTORY
22260+ __VCMD(dump_history, 9, VCA_NONE, 0);
22261+ __VCMD(read_history, 9, VCA_NONE, 0);
22262+#endif
2ba6f0dd 22263+
4bf69007
AM
22264+ default:
22265+ perm = -1;
22266+ }
2ba6f0dd 22267+
4bf69007
AM
22268+ vxdprintk(VXD_CBIT(switch, 0),
22269+ "vc: VCMD_%02d_%d[%d], %d,%p [%d,%d,%x,%x]",
22270+ VC_CATEGORY(cmd), VC_COMMAND(cmd),
22271+ VC_VERSION(cmd), id, data, compat,
22272+ perm, args, flags);
2ba6f0dd 22273+
4bf69007
AM
22274+ ret = -ENOSYS;
22275+ if (perm < 0)
22276+ goto out;
2ba6f0dd 22277+
4bf69007
AM
22278+ state = 1;
22279+ if (!capable(CAP_CONTEXT))
22280+ goto out;
2ba6f0dd 22281+
4bf69007
AM
22282+ state = 2;
22283+ /* moved here from the individual commands */
22284+ ret = -EPERM;
22285+ if ((perm > 1) && !capable(CAP_SYS_ADMIN))
22286+ goto out;
2ba6f0dd 22287+
4bf69007
AM
22288+ state = 3;
22289+ /* vcmd involves resource management */
22290+ ret = -EPERM;
22291+ if ((flags & VCF_ARES) && !capable(CAP_SYS_RESOURCE))
22292+ goto out;
2ba6f0dd 22293+
4bf69007
AM
22294+ state = 4;
22295+ /* various legacy exceptions */
22296+ switch (cmd) {
22297+ /* will go away when spectator is a cap */
22298+ case VCMD_ctx_migrate_v0:
22299+ case VCMD_ctx_migrate:
22300+ if (id == 1) {
22301+ current->xid = 1;
22302+ ret = 1;
22303+ goto out;
22304+ }
22305+ break;
2ba6f0dd 22306+
4bf69007
AM
22307+ /* will go away when spectator is a cap */
22308+ case VCMD_net_migrate:
22309+ if (id == 1) {
22310+ current->nid = 1;
22311+ ret = 1;
22312+ goto out;
22313+ }
22314+ break;
22315+ }
2ba6f0dd 22316+
4bf69007
AM
22317+ /* vcmds are fine by default */
22318+ permit = 1;
2ba6f0dd 22319+
4bf69007
AM
22320+ /* admin type vcmds require admin ... */
22321+ if (flags & VCF_ADMIN)
22322+ permit = vx_check(0, VS_ADMIN) ? 1 : 0;
2ba6f0dd 22323+
4bf69007
AM
22324+ /* ... but setup type vcmds override that */
22325+ if (!permit && (flags & VCF_SETUP))
22326+ permit = vx_flags(VXF_STATE_SETUP, 0) ? 2 : 0;
2ba6f0dd 22327+
4bf69007
AM
22328+ state = 5;
22329+ ret = -EPERM;
22330+ if (!permit)
22331+ goto out;
2ba6f0dd 22332+
4bf69007
AM
22333+ state = 6;
22334+ if (!id && (flags & VCF_ZIDOK))
22335+ goto skip_id;
2ba6f0dd 22336+
4bf69007
AM
22337+ ret = -ESRCH;
22338+ if (args & VCA_VXI) {
22339+ vxi = lookup_vx_info(id);
22340+ if (!vxi)
22341+ goto out;
2ba6f0dd 22342+
4bf69007
AM
22343+ if ((flags & VCF_ADMIN) &&
22344+ /* special case kill for shutdown */
22345+ (cmd != VCMD_ctx_kill) &&
22346+ /* can context be administrated? */
22347+ !vx_info_flags(vxi, VXF_STATE_ADMIN, 0)) {
22348+ ret = -EACCES;
22349+ goto out_vxi;
22350+ }
22351+ }
22352+ state = 7;
22353+ if (args & VCA_NXI) {
22354+ nxi = lookup_nx_info(id);
22355+ if (!nxi)
22356+ goto out_vxi;
2ba6f0dd 22357+
4bf69007
AM
22358+ if ((flags & VCF_ADMIN) &&
22359+ /* can context be administrated? */
22360+ !nx_info_flags(nxi, NXF_STATE_ADMIN, 0)) {
22361+ ret = -EACCES;
22362+ goto out_nxi;
22363+ }
22364+ }
22365+skip_id:
22366+ state = 8;
22367+ ret = do_vcmd(cmd, id, vxi, nxi, data, compat);
2ba6f0dd 22368+
4bf69007
AM
22369+out_nxi:
22370+ if ((args & VCA_NXI) && nxi)
22371+ put_nx_info(nxi);
22372+out_vxi:
22373+ if ((args & VCA_VXI) && vxi)
22374+ put_vx_info(vxi);
22375+out:
22376+ vxdprintk(VXD_CBIT(switch, 1),
22377+ "vc: VCMD_%02d_%d[%d] = %08lx(%ld) [%d,%d]",
22378+ VC_CATEGORY(cmd), VC_COMMAND(cmd),
22379+ VC_VERSION(cmd), ret, ret, state, permit);
22380+ return ret;
22381+}
2ba6f0dd 22382+
4bf69007
AM
22383+asmlinkage long
22384+sys_vserver(uint32_t cmd, uint32_t id, void __user *data)
22385+{
22386+ return do_vserver(cmd, id, data, 0);
22387+}
2ba6f0dd 22388+
4bf69007 22389+#ifdef CONFIG_COMPAT
2ba6f0dd 22390+
4bf69007
AM
22391+asmlinkage long
22392+sys32_vserver(uint32_t cmd, uint32_t id, void __user *data)
22393+{
22394+ return do_vserver(cmd, id, data, 1);
22395+}
2ba6f0dd 22396+
4bf69007 22397+#endif /* CONFIG_COMPAT */
3261cfd5
AM
22398diff -NurpP --minimal linux-4.9.207/kernel/vserver/sysctl.c linux-4.9.207-vs2.3.9.11/kernel/vserver/sysctl.c
22399--- linux-4.9.207/kernel/vserver/sysctl.c 1970-01-01 00:00:00.000000000 +0000
22400+++ linux-4.9.207-vs2.3.9.11/kernel/vserver/sysctl.c 2018-10-20 04:58:15.000000000 +0000
cc23e853 22401@@ -0,0 +1,249 @@
4bf69007
AM
22402+/*
22403+ * kernel/vserver/sysctl.c
22404+ *
22405+ * Virtual Context Support
22406+ *
cc23e853 22407+ * Copyright (C) 2004-2007 Herbert P?tzl
4bf69007
AM
22408+ *
22409+ * V0.01 basic structure
22410+ *
22411+ */
2ba6f0dd 22412+
4bf69007
AM
22413+#include <linux/module.h>
22414+#include <linux/ctype.h>
22415+#include <linux/sysctl.h>
22416+#include <linux/parser.h>
cc23e853
AM
22417+#include <linux/utsname.h>
22418+
4bf69007 22419+#include <asm/uaccess.h>
cc23e853 22420+#include <asm/sections.h>
2ba6f0dd 22421+
4bf69007
AM
22422+enum {
22423+ CTL_DEBUG_ERROR = 0,
22424+ CTL_DEBUG_SWITCH = 1,
22425+ CTL_DEBUG_XID,
22426+ CTL_DEBUG_NID,
22427+ CTL_DEBUG_TAG,
22428+ CTL_DEBUG_NET,
22429+ CTL_DEBUG_LIMIT,
22430+ CTL_DEBUG_CRES,
22431+ CTL_DEBUG_DLIM,
22432+ CTL_DEBUG_QUOTA,
22433+ CTL_DEBUG_CVIRT,
22434+ CTL_DEBUG_SPACE,
22435+ CTL_DEBUG_PERM,
22436+ CTL_DEBUG_MISC,
2ba6f0dd
AM
22437+};
22438+
2ba6f0dd 22439+
4bf69007
AM
22440+unsigned int vs_debug_switch = 0;
22441+unsigned int vs_debug_xid = 0;
22442+unsigned int vs_debug_nid = 0;
22443+unsigned int vs_debug_tag = 0;
22444+unsigned int vs_debug_net = 0;
22445+unsigned int vs_debug_limit = 0;
22446+unsigned int vs_debug_cres = 0;
22447+unsigned int vs_debug_dlim = 0;
22448+unsigned int vs_debug_quota = 0;
22449+unsigned int vs_debug_cvirt = 0;
22450+unsigned int vs_debug_space = 0;
22451+unsigned int vs_debug_perm = 0;
22452+unsigned int vs_debug_misc = 0;
2ba6f0dd 22453+
2ba6f0dd 22454+
4bf69007 22455+static struct ctl_table_header *vserver_table_header;
bb20add7 22456+static struct ctl_table vserver_root_table[];
4bf69007 22457+
2ba6f0dd 22458+
4bf69007
AM
22459+void vserver_register_sysctl(void)
22460+{
22461+ if (!vserver_table_header) {
22462+ vserver_table_header = register_sysctl_table(vserver_root_table);
22463+ }
2ba6f0dd 22464+
4bf69007 22465+}
2ba6f0dd 22466+
4bf69007
AM
22467+void vserver_unregister_sysctl(void)
22468+{
22469+ if (vserver_table_header) {
22470+ unregister_sysctl_table(vserver_table_header);
22471+ vserver_table_header = NULL;
22472+ }
22473+}
2ba6f0dd 22474+
bb20add7 22475+static int proc_dodebug(struct ctl_table *table, int write,
4bf69007
AM
22476+ void __user *buffer, size_t *lenp, loff_t *ppos)
22477+{
22478+ char tmpbuf[20], *p, c;
22479+ unsigned int value;
22480+ size_t left, len;
2ba6f0dd 22481+
4bf69007
AM
22482+ if ((*ppos && !write) || !*lenp) {
22483+ *lenp = 0;
22484+ return 0;
22485+ }
2ba6f0dd 22486+
4bf69007 22487+ left = *lenp;
2ba6f0dd 22488+
4bf69007
AM
22489+ if (write) {
22490+ if (!access_ok(VERIFY_READ, buffer, left))
22491+ return -EFAULT;
22492+ p = (char *)buffer;
22493+ while (left && __get_user(c, p) >= 0 && isspace(c))
22494+ left--, p++;
22495+ if (!left)
22496+ goto done;
2ba6f0dd 22497+
4bf69007
AM
22498+ if (left > sizeof(tmpbuf) - 1)
22499+ return -EINVAL;
22500+ if (copy_from_user(tmpbuf, p, left))
22501+ return -EFAULT;
22502+ tmpbuf[left] = '\0';
2ba6f0dd 22503+
4bf69007
AM
22504+ for (p = tmpbuf, value = 0; '0' <= *p && *p <= '9'; p++, left--)
22505+ value = 10 * value + (*p - '0');
22506+ if (*p && !isspace(*p))
22507+ return -EINVAL;
22508+ while (left && isspace(*p))
22509+ left--, p++;
22510+ *(unsigned int *)table->data = value;
22511+ } else {
22512+ if (!access_ok(VERIFY_WRITE, buffer, left))
22513+ return -EFAULT;
22514+ len = sprintf(tmpbuf, "%d", *(unsigned int *)table->data);
22515+ if (len > left)
22516+ len = left;
22517+ if (__copy_to_user(buffer, tmpbuf, len))
22518+ return -EFAULT;
22519+ if ((left -= len) > 0) {
22520+ if (put_user('\n', (char *)buffer + len))
22521+ return -EFAULT;
22522+ left--;
22523+ }
22524+ }
2ba6f0dd 22525+
4bf69007
AM
22526+done:
22527+ *lenp -= left;
22528+ *ppos += *lenp;
22529+ return 0;
22530+}
2ba6f0dd 22531+
4bf69007 22532+static int zero;
2ba6f0dd 22533+
4bf69007
AM
22534+#define CTL_ENTRY(ctl, name) \
22535+ { \
22536+ .procname = #name, \
22537+ .data = &vs_ ## name, \
22538+ .maxlen = sizeof(int), \
22539+ .mode = 0644, \
22540+ .proc_handler = &proc_dodebug, \
22541+ .extra1 = &zero, \
22542+ .extra2 = &zero, \
22543+ }
2ba6f0dd 22544+
bb20add7 22545+static struct ctl_table vserver_debug_table[] = {
4bf69007
AM
22546+ CTL_ENTRY(CTL_DEBUG_SWITCH, debug_switch),
22547+ CTL_ENTRY(CTL_DEBUG_XID, debug_xid),
22548+ CTL_ENTRY(CTL_DEBUG_NID, debug_nid),
22549+ CTL_ENTRY(CTL_DEBUG_TAG, debug_tag),
22550+ CTL_ENTRY(CTL_DEBUG_NET, debug_net),
22551+ CTL_ENTRY(CTL_DEBUG_LIMIT, debug_limit),
22552+ CTL_ENTRY(CTL_DEBUG_CRES, debug_cres),
22553+ CTL_ENTRY(CTL_DEBUG_DLIM, debug_dlim),
22554+ CTL_ENTRY(CTL_DEBUG_QUOTA, debug_quota),
22555+ CTL_ENTRY(CTL_DEBUG_CVIRT, debug_cvirt),
22556+ CTL_ENTRY(CTL_DEBUG_SPACE, debug_space),
22557+ CTL_ENTRY(CTL_DEBUG_PERM, debug_perm),
22558+ CTL_ENTRY(CTL_DEBUG_MISC, debug_misc),
22559+ { 0 }
22560+};
2ba6f0dd 22561+
bb20add7 22562+static struct ctl_table vserver_root_table[] = {
4bf69007
AM
22563+ {
22564+ .procname = "vserver",
22565+ .mode = 0555,
22566+ .child = vserver_debug_table
22567+ },
22568+ { 0 }
22569+};
2ba6f0dd 22570+
2ba6f0dd 22571+
4bf69007
AM
22572+static match_table_t tokens = {
22573+ { CTL_DEBUG_SWITCH, "switch=%x" },
22574+ { CTL_DEBUG_XID, "xid=%x" },
22575+ { CTL_DEBUG_NID, "nid=%x" },
22576+ { CTL_DEBUG_TAG, "tag=%x" },
22577+ { CTL_DEBUG_NET, "net=%x" },
22578+ { CTL_DEBUG_LIMIT, "limit=%x" },
22579+ { CTL_DEBUG_CRES, "cres=%x" },
22580+ { CTL_DEBUG_DLIM, "dlim=%x" },
22581+ { CTL_DEBUG_QUOTA, "quota=%x" },
22582+ { CTL_DEBUG_CVIRT, "cvirt=%x" },
22583+ { CTL_DEBUG_SPACE, "space=%x" },
22584+ { CTL_DEBUG_PERM, "perm=%x" },
22585+ { CTL_DEBUG_MISC, "misc=%x" },
22586+ { CTL_DEBUG_ERROR, NULL }
22587+};
2ba6f0dd 22588+
4bf69007
AM
22589+#define HANDLE_CASE(id, name, val) \
22590+ case CTL_DEBUG_ ## id: \
22591+ vs_debug_ ## name = val; \
22592+ printk("vs_debug_" #name "=0x%x\n", val); \
22593+ break
2ba6f0dd 22594+
2ba6f0dd 22595+
4bf69007
AM
22596+static int __init vs_debug_setup(char *str)
22597+{
22598+ char *p;
22599+ int token;
2ba6f0dd 22600+
4bf69007
AM
22601+ printk("vs_debug_setup(%s)\n", str);
22602+ while ((p = strsep(&str, ",")) != NULL) {
22603+ substring_t args[MAX_OPT_ARGS];
22604+ unsigned int value;
2ba6f0dd 22605+
4bf69007
AM
22606+ if (!*p)
22607+ continue;
2ba6f0dd 22608+
4bf69007
AM
22609+ token = match_token(p, tokens, args);
22610+ value = (token > 0) ? simple_strtoul(args[0].from, NULL, 0) : 0;
2ba6f0dd 22611+
4bf69007
AM
22612+ switch (token) {
22613+ HANDLE_CASE(SWITCH, switch, value);
22614+ HANDLE_CASE(XID, xid, value);
22615+ HANDLE_CASE(NID, nid, value);
22616+ HANDLE_CASE(TAG, tag, value);
22617+ HANDLE_CASE(NET, net, value);
22618+ HANDLE_CASE(LIMIT, limit, value);
22619+ HANDLE_CASE(CRES, cres, value);
22620+ HANDLE_CASE(DLIM, dlim, value);
22621+ HANDLE_CASE(QUOTA, quota, value);
22622+ HANDLE_CASE(CVIRT, cvirt, value);
22623+ HANDLE_CASE(SPACE, space, value);
22624+ HANDLE_CASE(PERM, perm, value);
22625+ HANDLE_CASE(MISC, misc, value);
22626+ default:
22627+ return -EINVAL;
22628+ break;
22629+ }
22630+ }
22631+ return 1;
22632+}
2ba6f0dd 22633+
4bf69007 22634+__setup("vsdebug=", vs_debug_setup);
2ba6f0dd 22635+
2ba6f0dd 22636+
2ba6f0dd 22637+
4bf69007
AM
22638+EXPORT_SYMBOL_GPL(vs_debug_switch);
22639+EXPORT_SYMBOL_GPL(vs_debug_xid);
22640+EXPORT_SYMBOL_GPL(vs_debug_nid);
22641+EXPORT_SYMBOL_GPL(vs_debug_net);
22642+EXPORT_SYMBOL_GPL(vs_debug_limit);
22643+EXPORT_SYMBOL_GPL(vs_debug_cres);
22644+EXPORT_SYMBOL_GPL(vs_debug_dlim);
22645+EXPORT_SYMBOL_GPL(vs_debug_quota);
22646+EXPORT_SYMBOL_GPL(vs_debug_cvirt);
22647+EXPORT_SYMBOL_GPL(vs_debug_space);
22648+EXPORT_SYMBOL_GPL(vs_debug_perm);
22649+EXPORT_SYMBOL_GPL(vs_debug_misc);
2ba6f0dd 22650+
3261cfd5
AM
22651diff -NurpP --minimal linux-4.9.207/kernel/vserver/tag.c linux-4.9.207-vs2.3.9.11/kernel/vserver/tag.c
22652--- linux-4.9.207/kernel/vserver/tag.c 1970-01-01 00:00:00.000000000 +0000
22653+++ linux-4.9.207-vs2.3.9.11/kernel/vserver/tag.c 2018-10-20 04:58:15.000000000 +0000
4bf69007
AM
22654@@ -0,0 +1,63 @@
22655+/*
22656+ * linux/kernel/vserver/tag.c
22657+ *
22658+ * Virtual Server: Shallow Tag Space
22659+ *
cc23e853 22660+ * Copyright (C) 2007 Herbert P?tzl
4bf69007
AM
22661+ *
22662+ * V0.01 basic implementation
22663+ *
22664+ */
2ba6f0dd 22665+
4bf69007
AM
22666+#include <linux/sched.h>
22667+#include <linux/vserver/debug.h>
22668+#include <linux/vs_pid.h>
22669+#include <linux/vs_tag.h>
2ba6f0dd 22670+
4bf69007 22671+#include <linux/vserver/tag_cmd.h>
2ba6f0dd 22672+
2ba6f0dd 22673+
61333608 22674+int dx_migrate_task(struct task_struct *p, vtag_t tag)
4bf69007
AM
22675+{
22676+ if (!p)
22677+ BUG();
2ba6f0dd 22678+
4bf69007
AM
22679+ vxdprintk(VXD_CBIT(tag, 5),
22680+ "dx_migrate_task(%p[#%d],#%d)", p, p->tag, tag);
2ba6f0dd 22681+
4bf69007
AM
22682+ task_lock(p);
22683+ p->tag = tag;
22684+ task_unlock(p);
2ba6f0dd 22685+
4bf69007
AM
22686+ vxdprintk(VXD_CBIT(tag, 5),
22687+ "moved task %p into [#%d]", p, tag);
22688+ return 0;
22689+}
2ba6f0dd 22690+
4bf69007 22691+/* vserver syscall commands below here */
2ba6f0dd 22692+
4bf69007 22693+/* taks xid and vx_info functions */
2ba6f0dd 22694+
2ba6f0dd 22695+
4bf69007
AM
22696+int vc_task_tag(uint32_t id)
22697+{
61333608 22698+ vtag_t tag;
2ba6f0dd 22699+
4bf69007
AM
22700+ if (id) {
22701+ struct task_struct *tsk;
22702+ rcu_read_lock();
22703+ tsk = find_task_by_real_pid(id);
22704+ tag = (tsk) ? tsk->tag : -ESRCH;
22705+ rcu_read_unlock();
22706+ } else
22707+ tag = dx_current_tag();
22708+ return tag;
22709+}
2ba6f0dd 22710+
2ba6f0dd 22711+
4bf69007
AM
22712+int vc_tag_migrate(uint32_t tag)
22713+{
22714+ return dx_migrate_task(current, tag & 0xFFFF);
22715+}
2ba6f0dd 22716+
2ba6f0dd 22717+
3261cfd5
AM
22718diff -NurpP --minimal linux-4.9.207/kernel/vserver/vci_config.h linux-4.9.207-vs2.3.9.11/kernel/vserver/vci_config.h
22719--- linux-4.9.207/kernel/vserver/vci_config.h 1970-01-01 00:00:00.000000000 +0000
22720+++ linux-4.9.207-vs2.3.9.11/kernel/vserver/vci_config.h 2018-10-20 04:58:15.000000000 +0000
4bf69007 22721@@ -0,0 +1,80 @@
2ba6f0dd 22722+
4bf69007 22723+/* interface version */
2ba6f0dd 22724+
4bf69007 22725+#define VCI_VERSION 0x00020308
2ba6f0dd 22726+
2ba6f0dd 22727+
4bf69007
AM
22728+enum {
22729+ VCI_KCBIT_NO_DYNAMIC = 0,
2ba6f0dd 22730+
4bf69007
AM
22731+ VCI_KCBIT_PROC_SECURE = 4,
22732+ /* VCI_KCBIT_HARDCPU = 5, */
22733+ /* VCI_KCBIT_IDLELIMIT = 6, */
22734+ /* VCI_KCBIT_IDLETIME = 7, */
2ba6f0dd 22735+
4bf69007
AM
22736+ VCI_KCBIT_COWBL = 8,
22737+ VCI_KCBIT_FULLCOWBL = 9,
22738+ VCI_KCBIT_SPACES = 10,
22739+ VCI_KCBIT_NETV2 = 11,
22740+ VCI_KCBIT_MEMCG = 12,
22741+ VCI_KCBIT_MEMCG_SWAP = 13,
2ba6f0dd 22742+
4bf69007
AM
22743+ VCI_KCBIT_DEBUG = 16,
22744+ VCI_KCBIT_HISTORY = 20,
22745+ VCI_KCBIT_TAGGED = 24,
22746+ VCI_KCBIT_PPTAG = 28,
2ba6f0dd 22747+
4bf69007 22748+ VCI_KCBIT_MORE = 31,
2ba6f0dd
AM
22749+};
22750+
2ba6f0dd 22751+
4bf69007
AM
22752+static inline uint32_t vci_kernel_config(void)
22753+{
22754+ return
22755+ (1 << VCI_KCBIT_NO_DYNAMIC) |
2ba6f0dd 22756+
4bf69007
AM
22757+ /* configured features */
22758+#ifdef CONFIG_VSERVER_PROC_SECURE
22759+ (1 << VCI_KCBIT_PROC_SECURE) |
22760+#endif
22761+#ifdef CONFIG_VSERVER_COWBL
22762+ (1 << VCI_KCBIT_COWBL) |
22763+ (1 << VCI_KCBIT_FULLCOWBL) |
22764+#endif
22765+ (1 << VCI_KCBIT_SPACES) |
22766+ (1 << VCI_KCBIT_NETV2) |
22767+#ifdef CONFIG_MEMCG
22768+ (1 << VCI_KCBIT_MEMCG) |
22769+#endif
22770+#ifdef CONFIG_MEMCG_SWAP
22771+ (1 << VCI_KCBIT_MEMCG_SWAP) |
22772+#endif
2ba6f0dd 22773+
4bf69007
AM
22774+ /* debug options */
22775+#ifdef CONFIG_VSERVER_DEBUG
22776+ (1 << VCI_KCBIT_DEBUG) |
22777+#endif
22778+#ifdef CONFIG_VSERVER_HISTORY
22779+ (1 << VCI_KCBIT_HISTORY) |
22780+#endif
2ba6f0dd 22781+
4bf69007
AM
22782+ /* inode context tagging */
22783+#if defined(CONFIG_TAGGING_NONE)
22784+ (0 << VCI_KCBIT_TAGGED) |
22785+#elif defined(CONFIG_TAGGING_UID16)
22786+ (1 << VCI_KCBIT_TAGGED) |
22787+#elif defined(CONFIG_TAGGING_GID16)
22788+ (2 << VCI_KCBIT_TAGGED) |
22789+#elif defined(CONFIG_TAGGING_ID24)
22790+ (3 << VCI_KCBIT_TAGGED) |
22791+#elif defined(CONFIG_TAGGING_INTERN)
22792+ (4 << VCI_KCBIT_TAGGED) |
22793+#elif defined(CONFIG_TAGGING_RUNTIME)
22794+ (5 << VCI_KCBIT_TAGGED) |
22795+#else
22796+ (7 << VCI_KCBIT_TAGGED) |
22797+#endif
22798+ (1 << VCI_KCBIT_PPTAG) |
22799+ 0;
22800+}
2ba6f0dd 22801+
3261cfd5
AM
22802diff -NurpP --minimal linux-4.9.207/mm/memcontrol.c linux-4.9.207-vs2.3.9.11/mm/memcontrol.c
22803--- linux-4.9.207/mm/memcontrol.c 2019-12-25 15:28:44.407201863 +0000
22804+++ linux-4.9.207-vs2.3.9.11/mm/memcontrol.c 2019-12-25 15:37:52.838415659 +0000
22805@@ -2854,6 +2854,41 @@ static u64 mem_cgroup_read_u64(struct cg
cc23e853 22806 }
4bf69007
AM
22807 }
22808
369dbd59
AM
22809+unsigned long mem_cgroup_mem_usage_pages(struct mem_cgroup *memcg)
22810+{
22811+ return mem_cgroup_usage(memcg, false);
22812+}
22813+
22814+unsigned long mem_cgroup_mem_limit_pages(struct mem_cgroup *memcg)
4bf69007 22815+{
369dbd59 22816+ return memcg->memory.limit;
4bf69007 22817+}
2ba6f0dd 22818+
369dbd59 22819+unsigned long mem_cgroup_memsw_usage_pages(struct mem_cgroup *memcg)
4bf69007 22820+{
369dbd59 22821+ return mem_cgroup_usage(memcg, true);
4bf69007 22822+}
2ba6f0dd 22823+
369dbd59 22824+unsigned long mem_cgroup_memsw_limit_pages(struct mem_cgroup *memcg)
4bf69007 22825+{
369dbd59 22826+ return memcg->memsw.limit;
4bf69007 22827+}
2ba6f0dd 22828+
369dbd59 22829+void dump_mem_cgroup(struct mem_cgroup *memcg)
4bf69007 22830+{
369dbd59
AM
22831+ printk(KERN_INFO "memcg: %p/%d:\n"
22832+ "\tmemory:\t%lu/%lu %lu/%lu\n"
22833+ "\tmemsw:\t%lu/%lu %lu/%lu\n"
22834+ "\tkmem:\t%lu/%lu %lu/%lu\n",
22835+ memcg, memcg->id.id,
22836+ page_counter_read(&memcg->memory), memcg->memory.limit,
22837+ memcg->memory.watermark, memcg->memory.failcnt,
22838+ page_counter_read(&memcg->memsw), memcg->memsw.limit,
22839+ memcg->memsw.watermark, memcg->memsw.failcnt,
22840+ page_counter_read(&memcg->kmem), memcg->kmem.limit,
22841+ memcg->kmem.watermark, memcg->kmem.failcnt);
4bf69007 22842+}
2ba6f0dd 22843+
cc23e853
AM
22844 #ifndef CONFIG_SLOB
22845 static int memcg_online_kmem(struct mem_cgroup *memcg)
22846 {
3261cfd5
AM
22847diff -NurpP --minimal linux-4.9.207/mm/oom_kill.c linux-4.9.207-vs2.3.9.11/mm/oom_kill.c
22848--- linux-4.9.207/mm/oom_kill.c 2019-12-25 15:28:44.447201214 +0000
22849+++ linux-4.9.207-vs2.3.9.11/mm/oom_kill.c 2019-02-22 08:37:56.143042249 +0000
cc23e853
AM
22850@@ -38,6 +38,8 @@
22851 #include <linux/kthread.h>
22852 #include <linux/init.h>
22853 #include <linux/mmu_notifier.h>
4bf69007
AM
22854+#include <linux/reboot.h>
22855+#include <linux/vs_context.h>
22856
cc23e853
AM
22857 #include <asm/tlb.h>
22858 #include "internal.h"
22859@@ -142,11 +144,18 @@ static inline bool is_memcg_oom(struct o
4bf69007 22860 static bool oom_unkillable_task(struct task_struct *p,
cc23e853 22861 struct mem_cgroup *memcg, const nodemask_t *nodemask)
4bf69007
AM
22862 {
22863- if (is_global_init(p))
22864+ unsigned xid = vx_current_xid();
2ba6f0dd 22865+
4bf69007
AM
22866+ /* skip the init task, global and per guest */
22867+ if (task_is_init(p))
22868 return true;
22869 if (p->flags & PF_KTHREAD)
22870 return true;
22871
22872+ /* skip other guest and host processes if oom in guest */
22873+ if (xid && vx_task_xid(p) != xid)
22874+ return true;
2ba6f0dd 22875+
4bf69007
AM
22876 /* When mem_cgroup_out_of_memory() and p is not member of the group */
22877 if (memcg && !task_in_mem_cgroup(p, memcg))
22878 return true;
cc23e853
AM
22879@@ -851,8 +860,8 @@ static void oom_kill_process(struct oom_
22880 if (__ratelimit(&oom_rs))
22881 dump_header(oc, p);
4bf69007 22882
cc23e853 22883- pr_err("%s: Kill process %d (%s) score %u or sacrifice child\n",
4bf69007
AM
22884- message, task_pid_nr(p), p->comm, points);
22885+ pr_err("%s: Kill process %d:#%u (%s) score %d or sacrifice child\n",
22886+ message, task_pid_nr(p), p->xid, p->comm, points);
4bf69007
AM
22887
22888 /*
cc23e853 22889 * If any of p's children has a different mm and is eligible for kill,
3261cfd5 22890@@ -910,8 +919,8 @@ static void oom_kill_process(struct oom_
cc23e853
AM
22891 */
22892 do_send_sig_info(SIGKILL, SEND_SIG_FORCED, victim, true);
22893 mark_oom_victim(victim);
22894- pr_err("Killed process %d (%s) total-vm:%lukB, anon-rss:%lukB, file-rss:%lukB, shmem-rss:%lukB\n",
4bf69007 22895- task_pid_nr(victim), victim->comm, K(victim->mm->total_vm),
cc23e853 22896+ pr_err("Killed process %d:%u (%s) total-vm:%lukB, anon-rss:%lukB, file-rss:%lukB, shmem-rss:%lukB\n",
4bf69007
AM
22897+ task_pid_nr(victim), victim->xid, victim->comm, K(victim->mm->total_vm),
22898 K(get_mm_counter(victim->mm, MM_ANONPAGES)),
cc23e853
AM
22899 K(get_mm_counter(victim->mm, MM_FILEPAGES)),
22900 K(get_mm_counter(victim->mm, MM_SHMEMPAGES)));
3261cfd5 22901@@ -958,6 +967,8 @@ static void oom_kill_process(struct oom_
4bf69007 22902 }
cc23e853 22903 #undef K
4bf69007
AM
22904
22905+long vs_oom_action(unsigned int);
2ba6f0dd 22906+
4bf69007 22907 /*
cc23e853
AM
22908 * Determines whether the kernel must panic because of the panic_on_oom sysctl.
22909 */
3261cfd5 22910@@ -1063,7 +1074,12 @@ bool out_of_memory(struct oom_control *o
4bf69007 22911 /* Found nothing?!?! Either we hang forever, or we panic. */
cc23e853
AM
22912 if (!oc->chosen && !is_sysrq_oom(oc) && !is_memcg_oom(oc)) {
22913 dump_header(oc, NULL);
4bf69007 22914- panic("Out of memory and no killable processes...\n");
2ba6f0dd 22915+
4bf69007
AM
22916+ /* avoid panic for guest OOM */
22917+ if (vx_current_xid())
22918+ vs_oom_action(LINUX_REBOOT_CMD_OOM);
22919+ else
22920+ panic("Out of memory and no killable processes...\n");
22921 }
cc23e853
AM
22922 if (oc->chosen && oc->chosen != (void *)-1UL) {
22923 oom_kill_process(oc, !is_memcg_oom(oc) ? "Out of memory" :
3261cfd5
AM
22924diff -NurpP --minimal linux-4.9.207/mm/page_alloc.c linux-4.9.207-vs2.3.9.11/mm/page_alloc.c
22925--- linux-4.9.207/mm/page_alloc.c 2019-12-25 15:28:44.447201214 +0000
22926+++ linux-4.9.207-vs2.3.9.11/mm/page_alloc.c 2019-10-05 14:58:46.190299248 +0000
cc23e853
AM
22927@@ -64,6 +64,8 @@
22928 #include <linux/page_owner.h>
22929 #include <linux/kthread.h>
22930 #include <linux/memcontrol.h>
4bf69007
AM
22931+#include <linux/vs_base.h>
22932+#include <linux/vs_limit.h>
22933
c2e5f7c8 22934 #include <asm/sections.h>
4bf69007 22935 #include <asm/tlbflush.h>
3261cfd5 22936@@ -4188,6 +4190,9 @@ void si_meminfo(struct sysinfo *val)
4bf69007
AM
22937 val->totalhigh = totalhigh_pages;
22938 val->freehigh = nr_free_highpages();
22939 val->mem_unit = PAGE_SIZE;
2ba6f0dd 22940+
4bf69007
AM
22941+ if (vx_flags(VXF_VIRT_MEM, 0))
22942+ vx_vsi_meminfo(val);
22943 }
22944
22945 EXPORT_SYMBOL(si_meminfo);
3261cfd5 22946@@ -4222,6 +4227,9 @@ void si_meminfo_node(struct sysinfo *val
cc23e853 22947 val->freehigh = free_highpages;
4bf69007
AM
22948 #endif
22949 val->mem_unit = PAGE_SIZE;
2ba6f0dd 22950+
4bf69007
AM
22951+ if (vx_flags(VXF_VIRT_MEM, 0))
22952+ vx_vsi_meminfo(val);
22953 }
22954 #endif
22955
3261cfd5
AM
22956diff -NurpP --minimal linux-4.9.207/mm/pgtable-generic.c linux-4.9.207-vs2.3.9.11/mm/pgtable-generic.c
22957--- linux-4.9.207/mm/pgtable-generic.c 2016-12-11 19:17:54.000000000 +0000
22958+++ linux-4.9.207-vs2.3.9.11/mm/pgtable-generic.c 2018-10-20 04:58:15.000000000 +0000
4bf69007
AM
22959@@ -6,6 +6,8 @@
22960 * Copyright (C) 2010 Linus Torvalds
22961 */
22962
22963+#include <linux/mm.h>
2ba6f0dd 22964+
4bf69007
AM
22965 #include <linux/pagemap.h>
22966 #include <asm/tlb.h>
22967 #include <asm-generic/pgtable.h>
3261cfd5
AM
22968diff -NurpP --minimal linux-4.9.207/mm/shmem.c linux-4.9.207-vs2.3.9.11/mm/shmem.c
22969--- linux-4.9.207/mm/shmem.c 2019-12-25 15:28:44.477200729 +0000
22970+++ linux-4.9.207-vs2.3.9.11/mm/shmem.c 2019-12-25 15:37:52.838415659 +0000
22971@@ -2803,7 +2803,7 @@ static int shmem_statfs(struct dentry *d
4bf69007
AM
22972 {
22973 struct shmem_sb_info *sbinfo = SHMEM_SB(dentry->d_sb);
22974
22975- buf->f_type = TMPFS_MAGIC;
22976+ buf->f_type = TMPFS_SUPER_MAGIC;
cc23e853 22977 buf->f_bsize = PAGE_SIZE;
4bf69007
AM
22978 buf->f_namelen = NAME_MAX;
22979 if (sbinfo->max_blocks) {
3261cfd5 22980@@ -3628,7 +3628,7 @@ int shmem_fill_super(struct super_block
4bf69007 22981 sb->s_maxbytes = MAX_LFS_FILESIZE;
cc23e853
AM
22982 sb->s_blocksize = PAGE_SIZE;
22983 sb->s_blocksize_bits = PAGE_SHIFT;
4bf69007
AM
22984- sb->s_magic = TMPFS_MAGIC;
22985+ sb->s_magic = TMPFS_SUPER_MAGIC;
22986 sb->s_op = &shmem_ops;
22987 sb->s_time_gran = 1;
22988 #ifdef CONFIG_TMPFS_XATTR
3261cfd5
AM
22989diff -NurpP --minimal linux-4.9.207/mm/slab.c linux-4.9.207-vs2.3.9.11/mm/slab.c
22990--- linux-4.9.207/mm/slab.c 2019-12-25 15:28:44.477200729 +0000
22991+++ linux-4.9.207-vs2.3.9.11/mm/slab.c 2019-10-05 14:58:46.200299086 +0000
cc23e853 22992@@ -307,6 +307,8 @@ static void kmem_cache_node_init(struct
4bf69007
AM
22993 #define STATS_INC_FREEMISS(x) do { } while (0)
22994 #endif
22995
22996+#include "slab_vs.h"
2ba6f0dd 22997+
4bf69007
AM
22998 #if DEBUG
22999
23000 /*
3261cfd5 23001@@ -3344,6 +3346,7 @@ slab_alloc_node(struct kmem_cache *cache
4bf69007
AM
23002 /* ___cache_alloc_node can fall back to other nodes */
23003 ptr = ____cache_alloc_node(cachep, flags, nodeid);
23004 out:
23005+ vx_slab_alloc(cachep, flags);
23006 local_irq_restore(save_flags);
23007 ptr = cache_alloc_debugcheck_after(cachep, flags, ptr, caller);
cc23e853 23008
3261cfd5 23009@@ -3525,6 +3528,7 @@ void ___cache_free(struct kmem_cache *ca
4bf69007
AM
23010 check_irq_off();
23011 kmemleak_free_recursive(objp, cachep->flags);
23012 objp = cache_free_debugcheck(cachep, objp, caller);
23013+ vx_slab_free(cachep);
23014
23015 kmemcheck_slab_free(cachep, objp, cachep->object_size);
23016
3261cfd5
AM
23017diff -NurpP --minimal linux-4.9.207/mm/slab_vs.h linux-4.9.207-vs2.3.9.11/mm/slab_vs.h
23018--- linux-4.9.207/mm/slab_vs.h 1970-01-01 00:00:00.000000000 +0000
23019+++ linux-4.9.207-vs2.3.9.11/mm/slab_vs.h 2018-10-20 04:58:15.000000000 +0000
4bf69007 23020@@ -0,0 +1,29 @@
2ba6f0dd 23021+
4bf69007 23022+#include <linux/vserver/context.h>
2ba6f0dd 23023+
4bf69007 23024+#include <linux/vs_context.h>
2ba6f0dd 23025+
4bf69007
AM
23026+static inline
23027+void vx_slab_alloc(struct kmem_cache *cachep, gfp_t flags)
23028+{
23029+ int what = gfp_zone(cachep->allocflags);
23030+ struct vx_info *vxi = current_vx_info();
2ba6f0dd 23031+
4bf69007
AM
23032+ if (!vxi)
23033+ return;
2ba6f0dd 23034+
4bf69007
AM
23035+ atomic_add(cachep->size, &vxi->cacct.slab[what]);
23036+}
2ba6f0dd 23037+
4bf69007
AM
23038+static inline
23039+void vx_slab_free(struct kmem_cache *cachep)
23040+{
23041+ int what = gfp_zone(cachep->allocflags);
23042+ struct vx_info *vxi = current_vx_info();
2ba6f0dd 23043+
4bf69007
AM
23044+ if (!vxi)
23045+ return;
2ba6f0dd 23046+
4bf69007
AM
23047+ atomic_sub(cachep->size, &vxi->cacct.slab[what]);
23048+}
2ba6f0dd 23049+
3261cfd5
AM
23050diff -NurpP --minimal linux-4.9.207/mm/swapfile.c linux-4.9.207-vs2.3.9.11/mm/swapfile.c
23051--- linux-4.9.207/mm/swapfile.c 2019-12-25 15:28:44.477200729 +0000
23052+++ linux-4.9.207-vs2.3.9.11/mm/swapfile.c 2018-10-20 05:55:43.000000000 +0000
4bf69007
AM
23053@@ -39,6 +39,7 @@
23054 #include <asm/tlbflush.h>
23055 #include <linux/swapops.h>
cc23e853 23056 #include <linux/swap_cgroup.h>
4bf69007
AM
23057+#include <linux/vs_base.h>
23058
23059 static bool swap_count_continued(struct swap_info_struct *, pgoff_t,
23060 unsigned char);
cc23e853 23061@@ -2083,6 +2084,16 @@ static int swap_show(struct seq_file *sw
4bf69007
AM
23062
23063 if (si == SEQ_START_TOKEN) {
23064 seq_puts(swap,"Filename\t\t\t\tType\t\tSize\tUsed\tPriority\n");
23065+ if (vx_flags(VXF_VIRT_MEM, 0)) {
cc23e853 23066+ struct sysinfo si = { 0 };
2ba6f0dd 23067+
4bf69007
AM
23068+ vx_vsi_swapinfo(&si);
23069+ if (si.totalswap < (1 << 10))
23070+ return 0;
23071+ seq_printf(swap, "%s\t\t\t\t\t%s\t%lu\t%lu\t%d\n",
23072+ "hdv0", "partition", si.totalswap >> 10,
23073+ (si.totalswap - si.freeswap) >> 10, -1);
23074+ }
23075 return 0;
23076 }
23077
09a55596 23078@@ -2630,6 +2641,8 @@ void si_swapinfo(struct sysinfo *val)
b00e13aa 23079 val->freeswap = atomic_long_read(&nr_swap_pages) + nr_to_be_unused;
4bf69007
AM
23080 val->totalswap = total_swap_pages + nr_to_be_unused;
23081 spin_unlock(&swap_lock);
23082+ if (vx_flags(VXF_VIRT_MEM, 0))
23083+ vx_vsi_swapinfo(val);
23084 }
23085
23086 /*
3261cfd5
AM
23087diff -NurpP --minimal linux-4.9.207/net/bridge/br_multicast.c linux-4.9.207-vs2.3.9.11/net/bridge/br_multicast.c
23088--- linux-4.9.207/net/bridge/br_multicast.c 2019-12-25 15:28:44.897193938 +0000
23089+++ linux-4.9.207-vs2.3.9.11/net/bridge/br_multicast.c 2019-10-05 14:58:46.250298288 +0000
cc23e853 23090@@ -465,7 +465,7 @@ static struct sk_buff *br_ip6_multicast_
4bf69007
AM
23091 ip6h->hop_limit = 1;
23092 ipv6_addr_set(&ip6h->daddr, htonl(0xff020000), 0, 0, htonl(1));
23093 if (ipv6_dev_get_saddr(dev_net(br->dev), br->dev, &ip6h->daddr, 0,
23094- &ip6h->saddr)) {
23095+ &ip6h->saddr, NULL)) {
23096 kfree_skb(skb);
cc23e853 23097 br->has_ipv6_addr = 0;
4bf69007 23098 return NULL;
3261cfd5
AM
23099diff -NurpP --minimal linux-4.9.207/net/core/dev.c linux-4.9.207-vs2.3.9.11/net/core/dev.c
23100--- linux-4.9.207/net/core/dev.c 2019-12-25 15:28:44.977192647 +0000
23101+++ linux-4.9.207-vs2.3.9.11/net/core/dev.c 2019-12-25 15:37:52.958413722 +0000
cc23e853 23102@@ -126,6 +126,7 @@
4bf69007
AM
23103 #include <linux/in.h>
23104 #include <linux/jhash.h>
23105 #include <linux/random.h>
23106+#include <linux/vs_inet.h>
23107 #include <trace/events/napi.h>
23108 #include <trace/events/net.h>
23109 #include <trace/events/skb.h>
cc23e853 23110@@ -730,7 +731,8 @@ struct net_device *__dev_get_by_name(str
4bf69007
AM
23111 struct hlist_head *head = dev_name_hash(net, name);
23112
b00e13aa 23113 hlist_for_each_entry(dev, head, name_hlist)
4bf69007
AM
23114- if (!strncmp(dev->name, name, IFNAMSIZ))
23115+ if (!strncmp(dev->name, name, IFNAMSIZ) &&
23116+ nx_dev_visible(current_nx_info(), dev))
23117 return dev;
23118
23119 return NULL;
cc23e853 23120@@ -755,7 +757,8 @@ struct net_device *dev_get_by_name_rcu(s
4bf69007
AM
23121 struct hlist_head *head = dev_name_hash(net, name);
23122
b00e13aa 23123 hlist_for_each_entry_rcu(dev, head, name_hlist)
4bf69007
AM
23124- if (!strncmp(dev->name, name, IFNAMSIZ))
23125+ if (!strncmp(dev->name, name, IFNAMSIZ) &&
23126+ nx_dev_visible(current_nx_info(), dev))
23127 return dev;
23128
23129 return NULL;
cc23e853 23130@@ -805,7 +808,8 @@ struct net_device *__dev_get_by_index(st
4bf69007
AM
23131 struct hlist_head *head = dev_index_hash(net, ifindex);
23132
b00e13aa 23133 hlist_for_each_entry(dev, head, index_hlist)
4bf69007
AM
23134- if (dev->ifindex == ifindex)
23135+ if ((dev->ifindex == ifindex) &&
23136+ nx_dev_visible(current_nx_info(), dev))
23137 return dev;
23138
23139 return NULL;
cc23e853 23140@@ -823,7 +827,7 @@ EXPORT_SYMBOL(__dev_get_by_index);
4bf69007
AM
23141 * about locking. The caller must hold RCU lock.
23142 */
23143
23144-struct net_device *dev_get_by_index_rcu(struct net *net, int ifindex)
23145+struct net_device *dev_get_by_index_real_rcu(struct net *net, int ifindex)
23146 {
4bf69007 23147 struct net_device *dev;
b00e13aa 23148 struct hlist_head *head = dev_index_hash(net, ifindex);
cc23e853 23149@@ -834,6 +838,16 @@ struct net_device *dev_get_by_index_rcu(
4bf69007
AM
23150
23151 return NULL;
23152 }
23153+EXPORT_SYMBOL(dev_get_by_index_real_rcu);
2ba6f0dd 23154+
4bf69007
AM
23155+struct net_device *dev_get_by_index_rcu(struct net *net, int ifindex)
23156+{
23157+ struct net_device *dev = dev_get_by_index_real_rcu(net, ifindex);
2ba6f0dd 23158+
4bf69007
AM
23159+ if (nx_dev_visible(current_nx_info(), dev))
23160+ return dev;
23161+ return NULL;
23162+}
23163 EXPORT_SYMBOL(dev_get_by_index_rcu);
23164
23165
cc23e853 23166@@ -916,7 +930,8 @@ struct net_device *dev_getbyhwaddr_rcu(s
4bf69007
AM
23167
23168 for_each_netdev_rcu(net, dev)
23169 if (dev->type == type &&
23170- !memcmp(dev->dev_addr, ha, dev->addr_len))
23171+ !memcmp(dev->dev_addr, ha, dev->addr_len) &&
23172+ nx_dev_visible(current_nx_info(), dev))
23173 return dev;
23174
23175 return NULL;
cc23e853 23176@@ -928,9 +943,11 @@ struct net_device *__dev_getfirstbyhwtyp
4bf69007
AM
23177 struct net_device *dev;
23178
23179 ASSERT_RTNL();
23180- for_each_netdev(net, dev)
23181- if (dev->type == type)
23182+ for_each_netdev(net, dev) {
23183+ if ((dev->type == type) &&
23184+ nx_dev_visible(current_nx_info(), dev))
23185 return dev;
23186+ }
23187
23188 return NULL;
23189 }
cc23e853 23190@@ -942,7 +959,8 @@ struct net_device *dev_getfirstbyhwtype(
b00e13aa
AM
23191
23192 rcu_read_lock();
23193 for_each_netdev_rcu(net, dev)
23194- if (dev->type == type) {
23195+ if ((dev->type == type) &&
23196+ nx_dev_visible(current_nx_info(), dev)) {
23197 dev_hold(dev);
23198 ret = dev;
23199 break;
cc23e853 23200@@ -972,7 +990,8 @@ struct net_device *__dev_get_by_flags(st
b00e13aa
AM
23201
23202 ret = NULL;
bb20add7 23203 for_each_netdev(net, dev) {
b00e13aa
AM
23204- if (((dev->flags ^ if_flags) & mask) == 0) {
23205+ if ((((dev->flags ^ if_flags) & mask) == 0) &&
23206+ nx_dev_visible(current_nx_info(), dev)) {
23207 ret = dev;
23208 break;
23209 }
cc23e853 23210@@ -1050,6 +1069,8 @@ static int __dev_alloc_name(struct net *
4bf69007
AM
23211 continue;
23212 if (i < 0 || i >= max_netdevices)
23213 continue;
23214+ if (!nx_dev_visible(current_nx_info(), d))
23215+ continue;
23216
23217 /* avoid cases where sscanf is not exact inverse of printf */
23218 snprintf(buf, IFNAMSIZ, name, i);
3261cfd5
AM
23219diff -NurpP --minimal linux-4.9.207/net/core/net-procfs.c linux-4.9.207-vs2.3.9.11/net/core/net-procfs.c
23220--- linux-4.9.207/net/core/net-procfs.c 2016-12-11 19:17:54.000000000 +0000
23221+++ linux-4.9.207-vs2.3.9.11/net/core/net-procfs.c 2018-10-20 04:58:15.000000000 +0000
8ce283e1
AM
23222@@ -1,6 +1,7 @@
23223 #include <linux/netdevice.h>
23224 #include <linux/proc_fs.h>
23225 #include <linux/seq_file.h>
23226+#include <linux/vs_inet.h>
23227 #include <net/wext.h>
23228
23229 #define BUCKET_SPACE (32 - NETDEV_HASHBITS - 1)
23230@@ -77,8 +78,13 @@ static void dev_seq_stop(struct seq_file
23231 static void dev_seq_printf_stats(struct seq_file *seq, struct net_device *dev)
23232 {
23233 struct rtnl_link_stats64 temp;
23234- const struct rtnl_link_stats64 *stats = dev_get_stats(dev, &temp);
23235+ const struct rtnl_link_stats64 *stats;
23236+
23237+ /* device visible inside network context? */
23238+ if (!nx_dev_visible(current_nx_info(), dev))
23239+ return;
23240
23241+ stats = dev_get_stats(dev, &temp);
23242 seq_printf(seq, "%6s: %7llu %7llu %4llu %4llu %4llu %5llu %10llu %9llu "
23243 "%8llu %7llu %4llu %4llu %4llu %5llu %7llu %10llu\n",
23244 dev->name, stats->rx_bytes, stats->rx_packets,
3261cfd5
AM
23245diff -NurpP --minimal linux-4.9.207/net/core/rtnetlink.c linux-4.9.207-vs2.3.9.11/net/core/rtnetlink.c
23246--- linux-4.9.207/net/core/rtnetlink.c 2019-12-25 15:28:44.997192322 +0000
23247+++ linux-4.9.207-vs2.3.9.11/net/core/rtnetlink.c 2019-12-25 15:37:52.958413722 +0000
cc23e853
AM
23248@@ -1615,6 +1615,8 @@ static int rtnl_dump_ifinfo(struct sk_bu
23249 goto cont;
4bf69007
AM
23250 if (idx < s_idx)
23251 goto cont;
23252+ if (!nx_dev_visible(skb->sk->sk_nx_info, dev))
23253+ continue;
7ed51edd
JR
23254 err = rtnl_fill_ifinfo(skb, dev, RTM_NEWLINK,
23255 NETLINK_CB(cb->skb).portid,
23256 cb->nlh->nlmsg_seq, 0,
3261cfd5 23257@@ -2841,6 +2843,9 @@ void rtmsg_ifinfo(int type, struct net_d
cc23e853
AM
23258 {
23259 struct sk_buff *skb;
4bf69007
AM
23260
23261+ if (!nx_dev_visible(current_nx_info(), dev))
23262+ return;
2ba6f0dd 23263+
cc23e853
AM
23264 if (dev->reg_state != NETREG_REGISTERED)
23265 return;
23266
3261cfd5
AM
23267diff -NurpP --minimal linux-4.9.207/net/core/sock.c linux-4.9.207-vs2.3.9.11/net/core/sock.c
23268--- linux-4.9.207/net/core/sock.c 2019-12-25 15:28:44.997192322 +0000
23269+++ linux-4.9.207-vs2.3.9.11/net/core/sock.c 2019-12-25 15:37:52.958413722 +0000
cc23e853 23270@@ -135,6 +135,10 @@
4bf69007
AM
23271
23272 #include <linux/filter.h>
cc23e853 23273 #include <net/sock_reuseport.h>
4bf69007
AM
23274+#include <linux/vs_socket.h>
23275+#include <linux/vs_limit.h>
23276+#include <linux/vs_context.h>
23277+#include <linux/vs_network.h>
23278
23279 #include <trace/events/sock.h>
23280
3261cfd5 23281@@ -1340,6 +1344,8 @@ static struct sock *sk_prot_alloc(struct
4bf69007
AM
23282 goto out_free_sec;
23283 sk_tx_queue_clear(sk);
23284 }
23285+ sock_vx_init(sk);
23286+ sock_nx_init(sk);
23287
23288 return sk;
23289
3261cfd5 23290@@ -1443,6 +1449,11 @@ static void __sk_destruct(struct rcu_hea
4bf69007 23291 put_pid(sk->sk_peer_pid);
cc23e853
AM
23292 if (likely(sk->sk_net_refcnt))
23293 put_net(sock_net(sk));
4bf69007
AM
23294+ vx_sock_dec(sk);
23295+ clr_vx_info(&sk->sk_vx_info);
23296+ sk->sk_xid = -1;
23297+ clr_nx_info(&sk->sk_nx_info);
23298+ sk->sk_nid = -1;
23299 sk_prot_free(sk->sk_prot_creator, sk);
23300 }
23301
3261cfd5 23302@@ -1504,6 +1515,8 @@ struct sock *sk_clone_lock(const struct
4bf69007 23303 /* SANITY */
cc23e853
AM
23304 if (likely(newsk->sk_net_refcnt))
23305 get_net(sock_net(newsk));
4bf69007
AM
23306+ sock_vx_init(newsk);
23307+ sock_nx_init(newsk);
23308 sk_node_init(&newsk->sk_node);
23309 sock_lock_init(newsk);
23310 bh_lock_sock(newsk);
3261cfd5 23311@@ -1574,6 +1587,12 @@ struct sock *sk_clone_lock(const struct
4bf69007
AM
23312 smp_wmb();
23313 atomic_set(&newsk->sk_refcnt, 2);
23314
23315+ set_vx_info(&newsk->sk_vx_info, sk->sk_vx_info);
23316+ newsk->sk_xid = sk->sk_xid;
23317+ vx_sock_inc(newsk);
23318+ set_nx_info(&newsk->sk_nx_info, sk->sk_nx_info);
23319+ newsk->sk_nid = sk->sk_nid;
2ba6f0dd 23320+
4bf69007
AM
23321 /*
23322 * Increment the counter in the same struct proto as the master
23323 * sock (sk_refcnt_debug_inc uses newsk->sk_prot->socks, that
3261cfd5
AM
23324@@ -2477,6 +2496,12 @@ void sock_init_data(struct socket *sock,
23325 seqlock_init(&sk->sk_stamp_seq);
23326 #endif
4bf69007
AM
23327
23328+ set_vx_info(&sk->sk_vx_info, current_vx_info());
23329+ sk->sk_xid = vx_current_xid();
23330+ vx_sock_inc(sk);
23331+ set_nx_info(&sk->sk_nx_info, current_nx_info());
23332+ sk->sk_nid = nx_current_nid();
2ba6f0dd 23333+
c2e5f7c8
JR
23334 #ifdef CONFIG_NET_RX_BUSY_POLL
23335 sk->sk_napi_id = 0;
23336 sk->sk_ll_usec = sysctl_net_busy_read;
3261cfd5
AM
23337diff -NurpP --minimal linux-4.9.207/net/ipv4/af_inet.c linux-4.9.207-vs2.3.9.11/net/ipv4/af_inet.c
23338--- linux-4.9.207/net/ipv4/af_inet.c 2019-12-25 15:28:45.207188929 +0000
23339+++ linux-4.9.207-vs2.3.9.11/net/ipv4/af_inet.c 2018-10-20 05:55:44.000000000 +0000
cc23e853 23340@@ -303,10 +303,15 @@ lookup_protocol:
4bf69007
AM
23341 }
23342
23343 err = -EPERM;
23344+ if ((protocol == IPPROTO_ICMP) &&
23345+ nx_capable(CAP_NET_RAW, NXC_RAW_ICMP))
23346+ goto override;
cc23e853 23347+
b00e13aa
AM
23348 if (sock->type == SOCK_RAW && !kern &&
23349 !ns_capable(net->user_ns, CAP_NET_RAW))
4bf69007 23350 goto out_rcu_unlock;
cc23e853 23351
a4a22af8
AM
23352+override:
23353 sock->ops = answer->ops;
23354 answer_prot = answer->prot;
bb20add7 23355 answer_flags = answer->flags;
cc23e853 23356@@ -424,6 +429,7 @@ int inet_bind(struct socket *sock, struc
4bf69007
AM
23357 struct sock *sk = sock->sk;
23358 struct inet_sock *inet = inet_sk(sk);
b00e13aa 23359 struct net *net = sock_net(sk);
cc23e853 23360+ struct nx_v4_sock_addr nsa;
4bf69007
AM
23361 unsigned short snum;
23362 int chk_addr_ret;
cc23e853
AM
23363 u32 tb_id = RT_TABLE_LOCAL;
23364@@ -449,7 +455,11 @@ int inet_bind(struct socket *sock, struc
4bf69007
AM
23365 }
23366
cc23e853
AM
23367 tb_id = l3mdev_fib_table_by_index(net, sk->sk_bound_dev_if) ? : tb_id;
23368- chk_addr_ret = inet_addr_type_table(net, addr->sin_addr.s_addr, tb_id);
4bf69007
AM
23369+ err = v4_map_sock_addr(inet, addr, &nsa);
23370+ if (err)
23371+ goto out;
2ba6f0dd 23372+
cc23e853 23373+ chk_addr_ret = inet_addr_type_table(net, nsa.saddr, tb_id);
4bf69007
AM
23374
23375 /* Not specified by any standard per-se, however it breaks too
23376 * many applications when removed. It is unfortunate since
cc23e853 23377@@ -461,7 +471,7 @@ int inet_bind(struct socket *sock, struc
4bf69007 23378 err = -EADDRNOTAVAIL;
bb20add7 23379 if (!net->ipv4.sysctl_ip_nonlocal_bind &&
4bf69007
AM
23380 !(inet->freebind || inet->transparent) &&
23381- addr->sin_addr.s_addr != htonl(INADDR_ANY) &&
23382+ nsa.saddr != htonl(INADDR_ANY) &&
23383 chk_addr_ret != RTN_LOCAL &&
23384 chk_addr_ret != RTN_MULTICAST &&
23385 chk_addr_ret != RTN_BROADCAST)
cc23e853 23386@@ -487,7 +497,7 @@ int inet_bind(struct socket *sock, struc
4bf69007
AM
23387 if (sk->sk_state != TCP_CLOSE || inet->inet_num)
23388 goto out_release_sock;
23389
23390- inet->inet_rcv_saddr = inet->inet_saddr = addr->sin_addr.s_addr;
23391+ v4_set_sock_addr(inet, &nsa);
23392 if (chk_addr_ret == RTN_MULTICAST || chk_addr_ret == RTN_BROADCAST)
23393 inet->inet_saddr = 0; /* Use device */
23394
cc23e853 23395@@ -706,11 +716,13 @@ int inet_getname(struct socket *sock, st
4bf69007
AM
23396 peer == 1))
23397 return -ENOTCONN;
23398 sin->sin_port = inet->inet_dport;
23399- sin->sin_addr.s_addr = inet->inet_daddr;
23400+ sin->sin_addr.s_addr =
23401+ nx_map_sock_lback(sk->sk_nx_info, inet->inet_daddr);
23402 } else {
23403 __be32 addr = inet->inet_rcv_saddr;
23404 if (!addr)
23405 addr = inet->inet_saddr;
23406+ addr = nx_map_sock_lback(sk->sk_nx_info, addr);
23407 sin->sin_port = inet->inet_sport;
23408 sin->sin_addr.s_addr = addr;
23409 }
cc23e853
AM
23410@@ -894,6 +906,7 @@ static int inet_compat_ioctl(struct sock
23411 return err;
23412 }
23413 #endif
23414+#include <linux/vs_limit.h>
23415
23416 const struct proto_ops inet_stream_ops = {
23417 .family = PF_INET,
3261cfd5
AM
23418diff -NurpP --minimal linux-4.9.207/net/ipv4/arp.c linux-4.9.207-vs2.3.9.11/net/ipv4/arp.c
23419--- linux-4.9.207/net/ipv4/arp.c 2019-12-25 15:28:45.207188929 +0000
23420+++ linux-4.9.207-vs2.3.9.11/net/ipv4/arp.c 2018-10-20 04:58:15.000000000 +0000
09a55596 23421@@ -1320,6 +1320,7 @@ static void arp_format_neigh_entry(struc
4bf69007
AM
23422 struct net_device *dev = n->dev;
23423 int hatype = dev->type;
23424
23425+ /* FIXME: check for network context */
23426 read_lock(&n->lock);
23427 /* Convert hardware address to XX:XX:XX:XX ... form. */
23428 #if IS_ENABLED(CONFIG_AX25)
09a55596 23429@@ -1351,6 +1352,7 @@ static void arp_format_pneigh_entry(stru
4bf69007
AM
23430 int hatype = dev ? dev->type : 0;
23431 char tbuf[16];
23432
23433+ /* FIXME: check for network context */
23434 sprintf(tbuf, "%pI4", n->key);
23435 seq_printf(seq, "%-16s 0x%-10x0x%-10x%s * %s\n",
23436 tbuf, hatype, ATF_PUBL | ATF_PERM, "00:00:00:00:00:00",
3261cfd5
AM
23437diff -NurpP --minimal linux-4.9.207/net/ipv4/devinet.c linux-4.9.207-vs2.3.9.11/net/ipv4/devinet.c
23438--- linux-4.9.207/net/ipv4/devinet.c 2019-12-25 15:28:45.207188929 +0000
23439+++ linux-4.9.207-vs2.3.9.11/net/ipv4/devinet.c 2019-12-25 15:37:52.998413076 +0000
23440@@ -546,6 +546,7 @@ struct in_device *inetdev_by_index(struc
4bf69007
AM
23441 }
23442 EXPORT_SYMBOL(inetdev_by_index);
23443
2ba6f0dd 23444+
4bf69007
AM
23445 /* Called only from RTNL semaphored context. No locks. */
23446
23447 struct in_ifaddr *inet_ifa_byprefix(struct in_device *in_dev, __be32 prefix,
3261cfd5 23448@@ -1000,6 +1001,8 @@ int devinet_ioctl(struct net *net, unsig
4bf69007
AM
23449
23450 in_dev = __in_dev_get_rtnl(dev);
23451 if (in_dev) {
23452+ struct nx_info *nxi = current_nx_info();
2ba6f0dd 23453+
4bf69007
AM
23454 if (tryaddrmatch) {
23455 /* Matthias Andree */
23456 /* compare label and address (4.4BSD style) */
3261cfd5 23457@@ -1008,6 +1011,8 @@ int devinet_ioctl(struct net *net, unsig
4bf69007
AM
23458 This is checked above. */
23459 for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
23460 ifap = &ifa->ifa_next) {
23461+ if (!nx_v4_ifa_visible(nxi, ifa))
23462+ continue;
23463 if (!strcmp(ifr.ifr_name, ifa->ifa_label) &&
23464 sin_orig.sin_addr.s_addr ==
23465 ifa->ifa_local) {
3261cfd5 23466@@ -1020,9 +1025,12 @@ int devinet_ioctl(struct net *net, unsig
4bf69007
AM
23467 comparing just the label */
23468 if (!ifa) {
23469 for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
23470- ifap = &ifa->ifa_next)
23471+ ifap = &ifa->ifa_next) {
23472+ if (!nx_v4_ifa_visible(nxi, ifa))
23473+ continue;
23474 if (!strcmp(ifr.ifr_name, ifa->ifa_label))
23475 break;
23476+ }
23477 }
23478 }
23479
3261cfd5 23480@@ -1176,6 +1184,8 @@ static int inet_gifconf(struct net_devic
4bf69007
AM
23481 goto out;
23482
23483 for (ifa = in_dev->ifa_list; ifa; ifa = ifa->ifa_next) {
23484+ if (!nx_v4_ifa_visible(current_nx_info(), ifa))
23485+ continue;
23486 if (!buf) {
23487 done += sizeof(ifr);
23488 continue;
3261cfd5 23489@@ -1598,6 +1608,7 @@ static int inet_dump_ifaddr(struct sk_bu
4bf69007
AM
23490 struct net_device *dev;
23491 struct in_device *in_dev;
23492 struct in_ifaddr *ifa;
23493+ struct sock *sk = skb->sk;
23494 struct hlist_head *head;
4bf69007 23495
b00e13aa 23496 s_h = cb->args[0];
3261cfd5 23497@@ -1621,6 +1632,8 @@ static int inet_dump_ifaddr(struct sk_bu
4bf69007
AM
23498
23499 for (ifa = in_dev->ifa_list, ip_idx = 0; ifa;
23500 ifa = ifa->ifa_next, ip_idx++) {
23501+ if (sk && !nx_v4_ifa_visible(sk->sk_nx_info, ifa))
23502+ continue;
23503 if (ip_idx < s_ip_idx)
23504 continue;
23505 if (inet_fill_ifaddr(skb, ifa,
3261cfd5
AM
23506diff -NurpP --minimal linux-4.9.207/net/ipv4/fib_trie.c linux-4.9.207-vs2.3.9.11/net/ipv4/fib_trie.c
23507--- linux-4.9.207/net/ipv4/fib_trie.c 2019-12-25 15:28:45.207188929 +0000
23508+++ linux-4.9.207-vs2.3.9.11/net/ipv4/fib_trie.c 2019-02-22 08:37:56.413037657 +0000
23509@@ -2627,6 +2627,7 @@ static int fib_route_seq_show(struct seq
cc23e853
AM
23510
23511 seq_setwidth(seq, 127);
23512
23513+ /* FIXME: check for network context? */
23514 if (fi)
23515 seq_printf(seq,
23516 "%s\t%08X\t%08X\t%04X\t%d\t%u\t"
3261cfd5
AM
23517diff -NurpP --minimal linux-4.9.207/net/ipv4/inet_connection_sock.c linux-4.9.207-vs2.3.9.11/net/ipv4/inet_connection_sock.c
23518--- linux-4.9.207/net/ipv4/inet_connection_sock.c 2019-12-25 15:28:45.217188765 +0000
23519+++ linux-4.9.207-vs2.3.9.11/net/ipv4/inet_connection_sock.c 2019-10-05 14:58:46.260298130 +0000
cc23e853
AM
23520@@ -16,6 +16,7 @@
23521 #include <linux/module.h>
23522 #include <linux/jhash.h>
23523
23524+#include <net/addrconf.h>
23525 #include <net/inet_connection_sock.h>
23526 #include <net/inet_hashtables.h>
23527 #include <net/inet_timewait_sock.h>
23528@@ -44,6 +45,7 @@ void inet_get_local_port_range(struct ne
4bf69007
AM
23529 }
23530 EXPORT_SYMBOL(inet_get_local_port_range);
23531
2ba6f0dd 23532+
4bf69007
AM
23533 int inet_csk_bind_conflict(const struct sock *sk,
23534 const struct inet_bind_bucket *tb, bool relax)
23535 {
cc23e853
AM
23536@@ -72,15 +74,13 @@ int inet_csk_bind_conflict(const struct
23537 (sk2->sk_state != TCP_TIME_WAIT &&
b00e13aa 23538 !uid_eq(uid, sock_i_uid(sk2))))) {
c2e5f7c8
JR
23539
23540- if (!sk2->sk_rcv_saddr || !sk->sk_rcv_saddr ||
23541- sk2->sk_rcv_saddr == sk->sk_rcv_saddr)
cc23e853 23542+ if (ipv4_rcv_saddr_equal(sk, sk2, true))
4bf69007
AM
23543 break;
23544 }
23545 if (!relax && reuse && sk2->sk_reuse &&
b00e13aa 23546 sk2->sk_state != TCP_LISTEN) {
c2e5f7c8
JR
23547
23548- if (!sk2->sk_rcv_saddr || !sk->sk_rcv_saddr ||
23549- sk2->sk_rcv_saddr == sk->sk_rcv_saddr)
cc23e853 23550+ if (ipv4_rcv_saddr_equal(sk, sk2, true))
b00e13aa
AM
23551 break;
23552 }
23553 }
3261cfd5
AM
23554diff -NurpP --minimal linux-4.9.207/net/ipv4/inet_diag.c linux-4.9.207-vs2.3.9.11/net/ipv4/inet_diag.c
23555--- linux-4.9.207/net/ipv4/inet_diag.c 2016-12-11 19:17:54.000000000 +0000
23556+++ linux-4.9.207-vs2.3.9.11/net/ipv4/inet_diag.c 2018-10-20 06:33:52.000000000 +0000
4bf69007
AM
23557@@ -31,6 +31,8 @@
23558
23559 #include <linux/inet.h>
23560 #include <linux/stddef.h>
23561+#include <linux/vs_network.h>
23562+#include <linux/vs_inet.h>
23563
23564 #include <linux/inet_diag.h>
23565 #include <linux/sock_diag.h>
09a55596
AM
23566@@ -87,8 +89,8 @@ void inet_diag_msg_common_fill(struct in
23567 memset(&r->id.idiag_src, 0, sizeof(r->id.idiag_src));
23568 memset(&r->id.idiag_dst, 0, sizeof(r->id.idiag_dst));
23569
23570- r->id.idiag_src[0] = sk->sk_rcv_saddr;
23571- r->id.idiag_dst[0] = sk->sk_daddr;
23572+ r->id.idiag_src[0] = nx_map_sock_lback(sk->sk_nx_info, sk->sk_rcv_saddr);
23573+ r->id.idiag_dst[0] = nx_map_sock_lback(sk->sk_nx_info, sk->sk_daddr);
23574 }
23575 }
23576 EXPORT_SYMBOL_GPL(inet_diag_msg_common_fill);
23577@@ -879,6 +881,9 @@ void inet_diag_dump_icsk(struct inet_has
4bf69007
AM
23578 if (!net_eq(sock_net(sk), net))
23579 continue;
23580
23581+ if (!nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT))
23582+ continue;
09a55596 23583+
4bf69007
AM
23584 if (num < s_num) {
23585 num++;
23586 continue;
09a55596 23587@@ -941,6 +946,8 @@ skip_listen_ht:
4bf69007
AM
23588
23589 if (!net_eq(sock_net(sk), net))
23590 continue;
23591+ if (!nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT))
23592+ continue;
23593 if (num < s_num)
23594 goto next_normal;
c2e5f7c8 23595 state = (sk->sk_state == TCP_TIME_WAIT) ?
3261cfd5
AM
23596diff -NurpP --minimal linux-4.9.207/net/ipv4/inet_hashtables.c linux-4.9.207-vs2.3.9.11/net/ipv4/inet_hashtables.c
23597--- linux-4.9.207/net/ipv4/inet_hashtables.c 2019-12-25 15:28:45.217188765 +0000
23598+++ linux-4.9.207-vs2.3.9.11/net/ipv4/inet_hashtables.c 2018-10-20 04:58:15.000000000 +0000
cc23e853 23599@@ -24,6 +24,7 @@
4bf69007
AM
23600 #include <net/inet_connection_sock.h>
23601 #include <net/inet_hashtables.h>
23602 #include <net/secure_seq.h>
23603+#include <net/route.h>
23604 #include <net/ip.h>
cc23e853
AM
23605 #include <net/tcp.h>
23606 #include <net/sock_reuseport.h>
23607@@ -186,6 +187,11 @@ static inline int compute_score(struct s
4bf69007
AM
23608 if (rcv_saddr != daddr)
23609 return -1;
b00e13aa 23610 score += 4;
4bf69007
AM
23611+ } else {
23612+ /* block non nx_info ips */
23613+ if (!v4_addr_in_nx_info(sk->sk_nx_info,
23614+ daddr, NXA_MASK_BIND))
23615+ return -1;
23616 }
cc23e853 23617 if (sk->sk_bound_dev_if || exact_dif) {
4bf69007 23618 if (sk->sk_bound_dev_if != dif)
cc23e853
AM
23619@@ -300,6 +306,7 @@ begin:
23620 goto found;
4bf69007
AM
23621 }
23622 }
2ba6f0dd 23623+
4bf69007
AM
23624 /*
23625 * if the nulls value we got at the end of this lookup is
23626 * not the expected one, we must restart lookup.
3261cfd5
AM
23627diff -NurpP --minimal linux-4.9.207/net/ipv4/netfilter.c linux-4.9.207-vs2.3.9.11/net/ipv4/netfilter.c
23628--- linux-4.9.207/net/ipv4/netfilter.c 2019-12-25 15:28:45.267187958 +0000
23629+++ linux-4.9.207-vs2.3.9.11/net/ipv4/netfilter.c 2018-10-20 04:58:15.000000000 +0000
09be7631 23630@@ -11,7 +11,7 @@
4bf69007
AM
23631 #include <linux/skbuff.h>
23632 #include <linux/gfp.h>
23633 #include <linux/export.h>
23634-#include <net/route.h>
23635+// #include <net/route.h>
23636 #include <net/xfrm.h>
23637 #include <net/ip.h>
23638 #include <net/netfilter/nf_queue.h>
3261cfd5
AM
23639diff -NurpP --minimal linux-4.9.207/net/ipv4/raw.c linux-4.9.207-vs2.3.9.11/net/ipv4/raw.c
23640--- linux-4.9.207/net/ipv4/raw.c 2019-12-25 15:28:45.297187472 +0000
23641+++ linux-4.9.207-vs2.3.9.11/net/ipv4/raw.c 2019-10-05 14:58:46.260298130 +0000
cc23e853 23642@@ -128,7 +128,7 @@ static struct sock *__raw_v4_lookup(stru
4bf69007
AM
23643
23644 if (net_eq(sock_net(sk), net) && inet->inet_num == num &&
23645 !(inet->inet_daddr && inet->inet_daddr != raddr) &&
23646- !(inet->inet_rcv_saddr && inet->inet_rcv_saddr != laddr) &&
23647+ v4_sock_addr_match(sk->sk_nx_info, inet, laddr) &&
23648 !(sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif))
23649 goto found; /* gotcha */
23650 }
cc23e853
AM
23651@@ -418,6 +418,12 @@ static int raw_send_hdrinc(struct sock *
23652 skb_transport_header(skb))->type);
23653 }
4bf69007
AM
23654
23655+ err = -EPERM;
23656+ if (!nx_check(0, VS_ADMIN) && !capable(CAP_NET_RAW) &&
23657+ sk->sk_nx_info &&
23658+ !v4_addr_in_nx_info(sk->sk_nx_info, iph->saddr, NXA_MASK_BIND))
23659+ goto error_free;
2ba6f0dd 23660+
cc23e853
AM
23661 err = NF_HOOK(NFPROTO_IPV4, NF_INET_LOCAL_OUT,
23662 net, sk, skb, NULL, rt->dst.dev,
23663 dst_output);
23664@@ -623,6 +629,16 @@ static int raw_sendmsg(struct sock *sk,
4bf69007
AM
23665 goto done;
23666 }
23667
23668+ if (sk->sk_nx_info) {
23669+ rt = ip_v4_find_src(sock_net(sk), sk->sk_nx_info, &fl4);
23670+ if (IS_ERR(rt)) {
23671+ err = PTR_ERR(rt);
23672+ rt = NULL;
23673+ goto done;
23674+ }
23675+ ip_rt_put(rt);
23676+ }
2ba6f0dd 23677+
4bf69007 23678 security_sk_classify_flow(sk, flowi4_to_flowi(&fl4));
cc23e853 23679 rt = ip_route_output_flow(net, &fl4, sk);
4bf69007 23680 if (IS_ERR(rt)) {
cc23e853 23681@@ -701,17 +717,19 @@ static int raw_bind(struct sock *sk, str
4bf69007
AM
23682 {
23683 struct inet_sock *inet = inet_sk(sk);
23684 struct sockaddr_in *addr = (struct sockaddr_in *) uaddr;
23685+ struct nx_v4_sock_addr nsa = { 0 };
23686 int ret = -EINVAL;
23687 int chk_addr_ret;
23688
23689 if (sk->sk_state != TCP_CLOSE || addr_len < sizeof(struct sockaddr_in))
23690 goto out;
23691- chk_addr_ret = inet_addr_type(sock_net(sk), addr->sin_addr.s_addr);
23692+ v4_map_sock_addr(inet, addr, &nsa);
23693+ chk_addr_ret = inet_addr_type(sock_net(sk), nsa.saddr);
23694 ret = -EADDRNOTAVAIL;
23695- if (addr->sin_addr.s_addr && chk_addr_ret != RTN_LOCAL &&
23696+ if (nsa.saddr && chk_addr_ret != RTN_LOCAL &&
23697 chk_addr_ret != RTN_MULTICAST && chk_addr_ret != RTN_BROADCAST)
23698 goto out;
23699- inet->inet_rcv_saddr = inet->inet_saddr = addr->sin_addr.s_addr;
23700+ v4_set_sock_addr(inet, &nsa);
23701 if (chk_addr_ret == RTN_MULTICAST || chk_addr_ret == RTN_BROADCAST)
23702 inet->inet_saddr = 0; /* Use device */
23703 sk_dst_reset(sk);
cc23e853 23704@@ -760,7 +778,8 @@ static int raw_recvmsg(struct sock *sk,
4bf69007
AM
23705 /* Copy the address. */
23706 if (sin) {
23707 sin->sin_family = AF_INET;
23708- sin->sin_addr.s_addr = ip_hdr(skb)->saddr;
23709+ sin->sin_addr.s_addr =
23710+ nx_map_sock_lback(sk->sk_nx_info, ip_hdr(skb)->saddr);
23711 sin->sin_port = 0;
23712 memset(&sin->sin_zero, 0, sizeof(sin->sin_zero));
c2e5f7c8 23713 *addr_len = sizeof(*sin);
cc23e853 23714@@ -956,7 +975,8 @@ static struct sock *raw_get_first(struct
b00e13aa
AM
23715 for (state->bucket = 0; state->bucket < RAW_HTABLE_SIZE;
23716 ++state->bucket) {
23717 sk_for_each(sk, &state->h->ht[state->bucket])
4bf69007
AM
23718- if (sock_net(sk) == seq_file_net(seq))
23719+ if ((sock_net(sk) == seq_file_net(seq)) &&
b00e13aa 23720+ nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT))
4bf69007
AM
23721 goto found;
23722 }
23723 sk = NULL;
cc23e853 23724@@ -972,7 +992,8 @@ static struct sock *raw_get_next(struct
4bf69007
AM
23725 sk = sk_next(sk);
23726 try_again:
23727 ;
23728- } while (sk && sock_net(sk) != seq_file_net(seq));
23729+ } while (sk && ((sock_net(sk) != seq_file_net(seq)) ||
23730+ !nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT)));
23731
23732 if (!sk && ++state->bucket < RAW_HTABLE_SIZE) {
23733 sk = sk_head(&state->h->ht[state->bucket]);
3261cfd5
AM
23734diff -NurpP --minimal linux-4.9.207/net/ipv4/route.c linux-4.9.207-vs2.3.9.11/net/ipv4/route.c
23735--- linux-4.9.207/net/ipv4/route.c 2019-12-25 15:28:45.297187472 +0000
23736+++ linux-4.9.207-vs2.3.9.11/net/ipv4/route.c 2019-12-25 15:37:52.998413076 +0000
23737@@ -2289,7 +2289,7 @@ struct rtable *__ip_route_output_key_has
4bf69007
AM
23738
23739
23740 if (fl4->flowi4_oif) {
23741- dev_out = dev_get_by_index_rcu(net, fl4->flowi4_oif);
23742+ dev_out = dev_get_by_index_real_rcu(net, fl4->flowi4_oif);
23743 rth = ERR_PTR(-ENODEV);
cc23e853 23744 if (!dev_out)
4bf69007 23745 goto out;
3261cfd5
AM
23746diff -NurpP --minimal linux-4.9.207/net/ipv4/tcp.c linux-4.9.207-vs2.3.9.11/net/ipv4/tcp.c
23747--- linux-4.9.207/net/ipv4/tcp.c 2019-12-25 15:28:45.297187472 +0000
23748+++ linux-4.9.207-vs2.3.9.11/net/ipv4/tcp.c 2019-10-05 14:58:46.260298130 +0000
cc23e853
AM
23749@@ -269,6 +269,7 @@
23750 #include <linux/err.h>
4bf69007
AM
23751 #include <linux/time.h>
23752 #include <linux/slab.h>
23753+#include <linux/in.h>
23754
23755 #include <net/icmp.h>
23756 #include <net/inet_common.h>
3261cfd5
AM
23757diff -NurpP --minimal linux-4.9.207/net/ipv4/tcp_ipv4.c linux-4.9.207-vs2.3.9.11/net/ipv4/tcp_ipv4.c
23758--- linux-4.9.207/net/ipv4/tcp_ipv4.c 2019-12-25 15:28:45.317187148 +0000
23759+++ linux-4.9.207-vs2.3.9.11/net/ipv4/tcp_ipv4.c 2019-12-25 15:37:52.998413076 +0000
23760@@ -1935,8 +1935,12 @@ get_head:
3f7e6b2c 23761 sk = sk_nulls_next(sk);
5ba7a31c 23762 get_sk:
3f7e6b2c 23763 sk_nulls_for_each_from(sk, node) {
5ba7a31c 23764+ vxdprintk(VXD_CBIT(net, 6), "sk: %p [#%d] (from %d)",
3261cfd5 23765+ sk, sk->sk_nid, nx_current_nid());
5ba7a31c
AM
23766 if (!net_eq(sock_net(sk), net))
23767 continue;
23768+ if (!nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT))
23769+ continue;
23770 if (sk->sk_family == st->family)
23771 return sk;
23772 }
3261cfd5 23773@@ -1989,6 +1993,11 @@ static void *established_get_first(struc
4bf69007
AM
23774
23775 spin_lock_bh(lock);
23776 sk_nulls_for_each(sk, node, &tcp_hashinfo.ehash[st->bucket].chain) {
23777+ vxdprintk(VXD_CBIT(net, 6),
23778+ "sk,egf: %p [#%d] (from %d)",
23779+ sk, sk->sk_nid, nx_current_nid());
23780+ if (!nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT))
23781+ continue;
23782 if (sk->sk_family != st->family ||
23783 !net_eq(sock_net(sk), net)) {
23784 continue;
3261cfd5 23785@@ -2015,6 +2024,11 @@ static void *established_get_next(struct
c2e5f7c8 23786 sk = sk_nulls_next(sk);
4bf69007
AM
23787
23788 sk_nulls_for_each_from(sk, node) {
23789+ vxdprintk(VXD_CBIT(net, 6),
23790+ "sk,egn: %p [#%d] (from %d)",
23791+ sk, sk->sk_nid, nx_current_nid());
23792+ if (!nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT))
23793+ continue;
23794 if (sk->sk_family == st->family && net_eq(sock_net(sk), net))
c2e5f7c8 23795 return sk;
4bf69007 23796 }
3261cfd5 23797@@ -2206,9 +2220,9 @@ static void get_openreq4(const struct re
4bf69007 23798 seq_printf(f, "%4d: %08X:%04X %08X:%04X"
c2e5f7c8 23799 " %02X %08X:%08X %02X:%08lX %08X %5u %8d %u %d %pK",
4bf69007 23800 i,
c2e5f7c8
JR
23801- ireq->ir_loc_addr,
23802+ nx_map_sock_lback(current_nx_info(), ireq->ir_loc_addr),
cc23e853 23803 ireq->ir_num,
c2e5f7c8
JR
23804- ireq->ir_rmt_addr,
23805+ nx_map_sock_lback(current_nx_info(), ireq->ir_rmt_addr),
23806 ntohs(ireq->ir_rmt_port),
4bf69007
AM
23807 TCP_SYN_RECV,
23808 0, 0, /* could print option size, but that is af dependent. */
3261cfd5 23809@@ -2231,8 +2245,8 @@ static void get_tcp4_sock(struct sock *s
4bf69007
AM
23810 const struct inet_connection_sock *icsk = inet_csk(sk);
23811 const struct inet_sock *inet = inet_sk(sk);
cc23e853 23812 const struct fastopen_queue *fastopenq = &icsk->icsk_accept_queue.fastopenq;
4bf69007
AM
23813- __be32 dest = inet->inet_daddr;
23814- __be32 src = inet->inet_rcv_saddr;
23815+ __be32 dest = nx_map_sock_lback(current_nx_info(), inet->inet_daddr);
23816+ __be32 src = nx_map_sock_lback(current_nx_info(), inet->inet_rcv_saddr);
23817 __u16 destp = ntohs(inet->inet_dport);
23818 __u16 srcp = ntohs(inet->inet_sport);
23819 int rx_queue;
3261cfd5 23820@@ -2291,8 +2305,8 @@ static void get_timewait4_sock(const str
cc23e853 23821 __be32 dest, src;
4bf69007 23822 __u16 destp, srcp;
4bf69007
AM
23823
23824- dest = tw->tw_daddr;
23825- src = tw->tw_rcv_saddr;
23826+ dest = nx_map_sock_lback(current_nx_info(), tw->tw_daddr);
23827+ src = nx_map_sock_lback(current_nx_info(), tw->tw_rcv_saddr);
23828 destp = ntohs(tw->tw_dport);
23829 srcp = ntohs(tw->tw_sport);
23830
3261cfd5
AM
23831diff -NurpP --minimal linux-4.9.207/net/ipv4/tcp_minisocks.c linux-4.9.207-vs2.3.9.11/net/ipv4/tcp_minisocks.c
23832--- linux-4.9.207/net/ipv4/tcp_minisocks.c 2019-12-25 15:28:45.317187148 +0000
23833+++ linux-4.9.207-vs2.3.9.11/net/ipv4/tcp_minisocks.c 2018-10-20 05:55:44.000000000 +0000
4bf69007
AM
23834@@ -23,6 +23,9 @@
23835 #include <linux/slab.h>
23836 #include <linux/sysctl.h>
23837 #include <linux/workqueue.h>
23838+#include <linux/vs_limit.h>
23839+#include <linux/vs_socket.h>
23840+#include <linux/vs_context.h>
23841 #include <net/tcp.h>
23842 #include <net/inet_common.h>
23843 #include <net/xfrm.h>
09a55596 23844@@ -286,6 +289,11 @@ void tcp_time_wait(struct sock *sk, int
b00e13aa 23845 tcptw->tw_ts_offset = tp->tsoffset;
cc23e853 23846 tcptw->tw_last_oow_ack_time = 0;
4bf69007
AM
23847
23848+ tw->tw_xid = sk->sk_xid;
23849+ tw->tw_vx_info = NULL;
23850+ tw->tw_nid = sk->sk_nid;
23851+ tw->tw_nx_info = NULL;
2ba6f0dd 23852+
4bf69007
AM
23853 #if IS_ENABLED(CONFIG_IPV6)
23854 if (tw->tw_family == PF_INET6) {
23855 struct ipv6_pinfo *np = inet6_sk(sk);
3261cfd5
AM
23856diff -NurpP --minimal linux-4.9.207/net/ipv4/udp.c linux-4.9.207-vs2.3.9.11/net/ipv4/udp.c
23857--- linux-4.9.207/net/ipv4/udp.c 2019-12-25 15:28:45.327186987 +0000
23858+++ linux-4.9.207-vs2.3.9.11/net/ipv4/udp.c 2019-10-05 14:58:46.260298130 +0000
09a55596 23859@@ -361,12 +361,26 @@ int ipv4_rcv_saddr_equal(const struct so
cc23e853
AM
23860 bool match_wildcard)
23861 {
23862 struct inet_sock *inet1 = inet_sk(sk1), *inet2 = inet_sk(sk2);
23863+ __be32 sk1_rcv_saddr = inet1->inet_rcv_saddr,
23864+ sk2_rcv_saddr = inet2->inet_rcv_saddr;
23865
23866- if (!ipv6_only_sock(sk2)) {
23867- if (inet1->inet_rcv_saddr == inet2->inet_rcv_saddr)
23868- return 1;
23869- if (!inet1->inet_rcv_saddr || !inet2->inet_rcv_saddr)
23870- return match_wildcard;
cc23e853
AM
23871+ if (ipv6_only_sock(sk2))
23872+ return 0;
23873+
23874+ if (sk1_rcv_saddr && sk2_rcv_saddr && sk1_rcv_saddr == sk2_rcv_saddr)
23875+ return 1;
23876+
23877+ if (match_wildcard) {
23878+ if (!sk2_rcv_saddr && !sk1_rcv_saddr)
23879+ return nx_v4_addr_conflict(sk1->sk_nx_info, sk2->sk_nx_info);
23880+
23881+ if (!sk2_rcv_saddr && sk1_rcv_saddr)
23882+ return v4_addr_in_nx_info(sk2->sk_nx_info,
23883+ sk1_rcv_saddr, NXA_MASK_BIND);
23884+
23885+ if (!sk1_rcv_saddr && sk2_rcv_saddr)
23886+ return v4_addr_in_nx_info(sk1->sk_nx_info,
23887+ sk2_rcv_saddr, NXA_MASK_BIND);
09a55596 23888 }
cc23e853 23889 return 0;
4bf69007 23890 }
cc23e853
AM
23891@@ -408,6 +422,11 @@ static int compute_score(struct sock *sk
23892 if (inet->inet_rcv_saddr != daddr)
23893 return -1;
23894 score += 4;
4bf69007
AM
23895+ } else {
23896+ /* block non nx_info ips */
23897+ if (!v4_addr_in_nx_info(sk->sk_nx_info,
23898+ daddr, NXA_MASK_BIND))
23899+ return -1;
cc23e853
AM
23900 }
23901
23902 if (inet->inet_daddr) {
23903@@ -483,6 +502,7 @@ static struct sock *udp4_lib_lookup2(str
4bf69007
AM
23904 return result;
23905 }
23906
2ba6f0dd 23907+
4bf69007
AM
23908 /* UDP is nearly always wildcards out the wazoo, it makes no sense to try
23909 * harder than this. -DaveM
23910 */
3261cfd5 23911@@ -607,7 +627,7 @@ static inline bool __udp_is_mcast_sock(s
c2e5f7c8
JR
23912 udp_sk(sk)->udp_port_hash != hnum ||
23913 (inet->inet_daddr && inet->inet_daddr != rmt_addr) ||
23914 (inet->inet_dport != rmt_port && inet->inet_dport) ||
23915- (inet->inet_rcv_saddr && inet->inet_rcv_saddr != loc_addr) ||
23916+ !v4_sock_addr_match(sk->sk_nx_info, inet, loc_addr) ||
23917 ipv6_only_sock(sk) ||
23918 (sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif))
23919 return false;
3261cfd5 23920@@ -1024,6 +1044,16 @@ int udp_sendmsg(struct sock *sk, struct
cc23e853 23921 flow_flags,
4bf69007
AM
23922 faddr, saddr, dport, inet->inet_sport);
23923
23924+ if (sk->sk_nx_info) {
23925+ rt = ip_v4_find_src(net, sk->sk_nx_info, fl4);
23926+ if (IS_ERR(rt)) {
23927+ err = PTR_ERR(rt);
23928+ rt = NULL;
23929+ goto out;
23930+ }
23931+ ip_rt_put(rt);
23932+ }
2ba6f0dd 23933+
4bf69007
AM
23934 security_sk_classify_flow(sk, flowi4_to_flowi(fl4));
23935 rt = ip_route_output_flow(net, fl4, sk);
23936 if (IS_ERR(rt)) {
3261cfd5 23937@@ -1321,7 +1351,8 @@ try_again:
4bf69007
AM
23938 if (sin) {
23939 sin->sin_family = AF_INET;
23940 sin->sin_port = udp_hdr(skb)->source;
23941- sin->sin_addr.s_addr = ip_hdr(skb)->saddr;
23942+ sin->sin_addr.s_addr = nx_map_sock_lback(
23943+ skb->sk->sk_nx_info, ip_hdr(skb)->saddr);
23944 memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
c2e5f7c8 23945 *addr_len = sizeof(*sin);
4bf69007 23946 }
3261cfd5 23947@@ -2291,6 +2322,8 @@ static struct sock *udp_get_first(struct
cc23e853 23948 sk_for_each(sk, &hslot->head) {
4bf69007
AM
23949 if (!net_eq(sock_net(sk), net))
23950 continue;
23951+ if (!nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT))
23952+ continue;
23953 if (sk->sk_family == state->family)
23954 goto found;
23955 }
3261cfd5 23956@@ -2308,7 +2341,9 @@ static struct sock *udp_get_next(struct
4bf69007
AM
23957
23958 do {
cc23e853 23959 sk = sk_next(sk);
4bf69007
AM
23960- } while (sk && (!net_eq(sock_net(sk), net) || sk->sk_family != state->family));
23961+ } while (sk && (!net_eq(sock_net(sk), net) ||
23962+ sk->sk_family != state->family ||
23963+ !nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT)));
23964
23965 if (!sk) {
23966 if (state->bucket <= state->udp_table->mask)
3261cfd5 23967@@ -2404,8 +2439,8 @@ static void udp4_format_sock(struct sock
c2e5f7c8 23968 int bucket)
4bf69007
AM
23969 {
23970 struct inet_sock *inet = inet_sk(sp);
23971- __be32 dest = inet->inet_daddr;
23972- __be32 src = inet->inet_rcv_saddr;
23973+ __be32 dest = nx_map_sock_lback(current_nx_info(), inet->inet_daddr);
23974+ __be32 src = nx_map_sock_lback(current_nx_info(), inet->inet_rcv_saddr);
23975 __u16 destp = ntohs(inet->inet_dport);
23976 __u16 srcp = ntohs(inet->inet_sport);
23977
3261cfd5
AM
23978diff -NurpP --minimal linux-4.9.207/net/ipv4/udp_diag.c linux-4.9.207-vs2.3.9.11/net/ipv4/udp_diag.c
23979--- linux-4.9.207/net/ipv4/udp_diag.c 2016-12-11 19:17:54.000000000 +0000
23980+++ linux-4.9.207-vs2.3.9.11/net/ipv4/udp_diag.c 2018-10-20 06:31:18.000000000 +0000
09a55596
AM
23981@@ -120,6 +120,8 @@ static void udp_dump(struct udp_table *t
23982
23983 if (!net_eq(sock_net(sk), net))
23984 continue;
23985+ if (!nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT))
23986+ continue;
23987 if (num < s_num)
23988 goto next;
23989 if (!(r->idiag_states & (1 << sk->sk_state)))
3261cfd5
AM
23990diff -NurpP --minimal linux-4.9.207/net/ipv6/addrconf.c linux-4.9.207-vs2.3.9.11/net/ipv6/addrconf.c
23991--- linux-4.9.207/net/ipv6/addrconf.c 2019-12-25 15:28:45.367186342 +0000
23992+++ linux-4.9.207-vs2.3.9.11/net/ipv6/addrconf.c 2019-10-22 13:47:05.779626538 +0000
cc23e853 23993@@ -92,6 +92,7 @@
4bf69007
AM
23994 #include <linux/proc_fs.h>
23995 #include <linux/seq_file.h>
23996 #include <linux/export.h>
23997+#include <linux/vs_network.h>
4bf69007
AM
23998
23999 /* Set to 3 to get tracing... */
24000 #define ACONF_DEBUG 2
3261cfd5 24001@@ -1498,7 +1499,8 @@ static int __ipv6_dev_get_saddr(struct n
cc23e853
AM
24002 struct ipv6_saddr_dst *dst,
24003 struct inet6_dev *idev,
24004 struct ipv6_saddr_score *scores,
24005- int hiscore_idx)
24006+ int hiscore_idx,
24007+ struct nx_info *nxi)
24008 {
24009 struct ipv6_saddr_score *score = &scores[1 - hiscore_idx], *hiscore = &scores[hiscore_idx];
24010
3261cfd5 24011@@ -1528,6 +1530,8 @@ static int __ipv6_dev_get_saddr(struct n
cc23e853
AM
24012 idev->dev->name);
24013 continue;
24014 }
24015+ if (!v6_addr_in_nx_info(nxi, &score->ifa->addr, -1))
24016+ continue;
24017
24018 score->rule = -1;
24019 bitmap_zero(score->scorebits, IPV6_SADDR_RULE_MAX);
3261cfd5 24020@@ -1578,26 +1582,27 @@ static int ipv6_get_saddr_master(struct
cc23e853
AM
24021 const struct net_device *master,
24022 struct ipv6_saddr_dst *dst,
24023 struct ipv6_saddr_score *scores,
24024- int hiscore_idx)
24025+ int hiscore_idx,
24026+ struct nx_info *nxi)
24027 {
24028 struct inet6_dev *idev;
24029
24030 idev = __in6_dev_get(dst_dev);
24031 if (idev)
24032- hiscore_idx = __ipv6_dev_get_saddr(net, dst, idev,
24033- scores, hiscore_idx);
24034+ hiscore_idx = __ipv6_dev_get_saddr(net, dst,
24035+ idev, scores, hiscore_idx, nxi);
24036
24037 idev = __in6_dev_get(master);
24038 if (idev)
24039- hiscore_idx = __ipv6_dev_get_saddr(net, dst, idev,
24040- scores, hiscore_idx);
24041+ hiscore_idx = __ipv6_dev_get_saddr(net, dst,
24042+ idev, scores, hiscore_idx, nxi);
24043
24044 return hiscore_idx;
24045 }
4bf69007
AM
24046
24047 int ipv6_dev_get_saddr(struct net *net, const struct net_device *dst_dev,
24048 const struct in6_addr *daddr, unsigned int prefs,
24049- struct in6_addr *saddr)
24050+ struct in6_addr *saddr, struct nx_info *nxi)
24051 {
cc23e853
AM
24052 struct ipv6_saddr_score scores[2], *hiscore;
24053 struct ipv6_saddr_dst dst;
3261cfd5 24054@@ -1646,7 +1651,8 @@ int ipv6_dev_get_saddr(struct net *net,
cc23e853
AM
24055
24056 if (use_oif_addr) {
24057 if (idev)
24058- hiscore_idx = __ipv6_dev_get_saddr(net, &dst, idev, scores, hiscore_idx);
24059+ hiscore_idx = __ipv6_dev_get_saddr(net,
24060+ &dst, idev, scores, hiscore_idx, nxi);
24061 } else {
24062 const struct net_device *master;
24063 int master_idx = 0;
3261cfd5 24064@@ -1660,8 +1666,8 @@ int ipv6_dev_get_saddr(struct net *net,
cc23e853
AM
24065 master_idx = master->ifindex;
24066
24067 hiscore_idx = ipv6_get_saddr_master(net, dst_dev,
24068- master, &dst,
24069- scores, hiscore_idx);
24070+ master, &dst, scores,
24071+ hiscore_idx, nxi);
24072
24073 if (scores[hiscore_idx].ifa)
24074 goto out;
3261cfd5 24075@@ -1676,7 +1682,8 @@ int ipv6_dev_get_saddr(struct net *net,
cc23e853
AM
24076 idev = __in6_dev_get(dev);
24077 if (!idev)
4bf69007 24078 continue;
cc23e853
AM
24079- hiscore_idx = __ipv6_dev_get_saddr(net, &dst, idev, scores, hiscore_idx);
24080+ hiscore_idx = __ipv6_dev_get_saddr(net,
24081+ &dst, idev, scores, hiscore_idx, nxi);
24082 }
24083 }
4bf69007 24084
3261cfd5 24085@@ -4130,7 +4137,10 @@ static void if6_seq_stop(struct seq_file
4bf69007
AM
24086 static int if6_seq_show(struct seq_file *seq, void *v)
24087 {
24088 struct inet6_ifaddr *ifp = (struct inet6_ifaddr *)v;
24089- seq_printf(seq, "%pi6 %02x %02x %02x %02x %8s\n",
2ba6f0dd 24090+
4bf69007
AM
24091+ if (nx_check(0, VS_ADMIN|VS_WATCH) ||
24092+ v6_addr_in_nx_info(current_nx_info(), &ifp->addr, -1))
24093+ seq_printf(seq, "%pi6 %02x %02x %02x %02x %8s\n",
24094 &ifp->addr,
24095 ifp->idev->dev->ifindex,
24096 ifp->prefix_len,
3261cfd5 24097@@ -4714,6 +4724,11 @@ static int in6_dump_addrs(struct inet6_d
4bf69007
AM
24098 struct ifacaddr6 *ifaca;
24099 int err = 1;
24100 int ip_idx = *p_ip_idx;
24101+ struct nx_info *nxi = skb->sk ? skb->sk->sk_nx_info : NULL;
2ba6f0dd 24102+
4bf69007
AM
24103+ /* disable ipv6 on non v6 guests */
24104+ if (nxi && !nx_info_has_v6(nxi))
24105+ return skb->len;
24106
24107 read_lock_bh(&idev->lock);
24108 switch (type) {
3261cfd5 24109@@ -4724,6 +4739,8 @@ static int in6_dump_addrs(struct inet6_d
4bf69007 24110 list_for_each_entry(ifa, &idev->addr_list, if_list) {
b65d880e
JR
24111 if (ip_idx < s_ip_idx)
24112 goto next;
cc23e853 24113+ if (!v6_addr_in_nx_info(nxi, &ifa->addr, -1))
b65d880e 24114+ goto next;
4bf69007
AM
24115 err = inet6_fill_ifaddr(skb, ifa,
24116 NETLINK_CB(cb->skb).portid,
24117 cb->nlh->nlmsg_seq,
3261cfd5 24118@@ -4743,6 +4760,8 @@ next:
4bf69007
AM
24119 ifmca = ifmca->next, ip_idx++) {
24120 if (ip_idx < s_ip_idx)
24121 continue;
cc23e853
AM
24122+ if (!v6_addr_in_nx_info(nxi, &ifmca->mca_addr, -1))
24123+ continue;
4bf69007
AM
24124 err = inet6_fill_ifmcaddr(skb, ifmca,
24125 NETLINK_CB(cb->skb).portid,
24126 cb->nlh->nlmsg_seq,
3261cfd5 24127@@ -4758,6 +4777,8 @@ next:
4bf69007
AM
24128 ifaca = ifaca->aca_next, ip_idx++) {
24129 if (ip_idx < s_ip_idx)
24130 continue;
cc23e853
AM
24131+ if (!v6_addr_in_nx_info(nxi, &ifaca->aca_addr, -1))
24132+ continue;
4bf69007
AM
24133 err = inet6_fill_ifacaddr(skb, ifaca,
24134 NETLINK_CB(cb->skb).portid,
24135 cb->nlh->nlmsg_seq,
3261cfd5 24136@@ -4786,6 +4807,10 @@ static int inet6_dump_addr(struct sk_buf
4bf69007
AM
24137 struct inet6_dev *idev;
24138 struct hlist_head *head;
b00e13aa 24139
4bf69007
AM
24140+ /* FIXME: maybe disable ipv6 on non v6 guests?
24141+ if (skb->sk && skb->sk->sk_vx_info)
24142+ return skb->len; */
b00e13aa
AM
24143+
24144 s_h = cb->args[0];
24145 s_idx = idx = cb->args[1];
24146 s_ip_idx = ip_idx = cb->args[2];
3261cfd5 24147@@ -5304,6 +5329,7 @@ static int inet6_dump_ifinfo(struct sk_b
b00e13aa
AM
24148 struct net_device *dev;
24149 struct inet6_dev *idev;
24150 struct hlist_head *head;
24151+ struct nx_info *nxi = skb->sk ? skb->sk->sk_nx_info : NULL;
4bf69007
AM
24152
24153 s_h = cb->args[0];
24154 s_idx = cb->args[1];
3261cfd5 24155@@ -5315,6 +5341,8 @@ static int inet6_dump_ifinfo(struct sk_b
b00e13aa 24156 hlist_for_each_entry_rcu(dev, head, index_hlist) {
4bf69007
AM
24157 if (idx < s_idx)
24158 goto cont;
24159+ if (!v6_dev_in_nx_info(dev, nxi))
24160+ goto cont;
24161 idev = __in6_dev_get(dev);
24162 if (!idev)
24163 goto cont;
3261cfd5
AM
24164diff -NurpP --minimal linux-4.9.207/net/ipv6/af_inet6.c linux-4.9.207-vs2.3.9.11/net/ipv6/af_inet6.c
24165--- linux-4.9.207/net/ipv6/af_inet6.c 2019-12-25 15:28:45.367186342 +0000
24166+++ linux-4.9.207-vs2.3.9.11/net/ipv6/af_inet6.c 2019-02-22 08:37:56.413037657 +0000
cc23e853 24167@@ -43,6 +43,7 @@
4bf69007
AM
24168 #include <linux/netdevice.h>
24169 #include <linux/icmpv6.h>
24170 #include <linux/netfilter_ipv6.h>
24171+#include <linux/vs_inet.h>
4bf69007
AM
24172
24173 #include <net/ip.h>
24174 #include <net/ipv6.h>
cc23e853 24175@@ -167,10 +168,13 @@ lookup_protocol:
4bf69007
AM
24176 }
24177
24178 err = -EPERM;
24179+ if ((protocol == IPPROTO_ICMPV6) &&
24180+ nx_capable(CAP_NET_RAW, NXC_RAW_ICMP))
24181+ goto override;
b00e13aa
AM
24182 if (sock->type == SOCK_RAW && !kern &&
24183 !ns_capable(net->user_ns, CAP_NET_RAW))
4bf69007
AM
24184 goto out_rcu_unlock;
24185-
24186+override:
24187 sock->ops = answer->ops;
24188 answer_prot = answer->prot;
bb20add7 24189 answer_flags = answer->flags;
cc23e853 24190@@ -272,6 +276,7 @@ int inet6_bind(struct socket *sock, stru
4bf69007
AM
24191 struct inet_sock *inet = inet_sk(sk);
24192 struct ipv6_pinfo *np = inet6_sk(sk);
24193 struct net *net = sock_net(sk);
24194+ struct nx_v6_sock_addr nsa;
24195 __be32 v4addr = 0;
24196 unsigned short snum;
cef7ea10
AM
24197 bool saved_ipv6only;
24198@@ -288,6 +293,10 @@ int inet6_bind(struct socket *sock, stru
4bf69007
AM
24199 if (addr->sin6_family != AF_INET6)
24200 return -EAFNOSUPPORT;
24201
24202+ err = v6_map_sock_addr(inet, addr, &nsa);
24203+ if (err)
24204+ return err;
2ba6f0dd 24205+
4bf69007
AM
24206 addr_type = ipv6_addr_type(&addr->sin6_addr);
24207 if ((addr_type & IPV6_ADDR_MULTICAST) && sock->type == SOCK_STREAM)
24208 return -EINVAL;
3261cfd5 24209@@ -340,6 +349,10 @@ int inet6_bind(struct socket *sock, stru
4bf69007
AM
24210 err = -EADDRNOTAVAIL;
24211 goto out;
24212 }
24213+ if (!v4_addr_in_nx_info(sk->sk_nx_info, v4addr, NXA_MASK_BIND)) {
24214+ err = -EADDRNOTAVAIL;
24215+ goto out;
24216+ }
24217 } else {
24218 if (addr_type != IPV6_ADDR_ANY) {
24219 struct net_device *dev = NULL;
3261cfd5 24220@@ -369,6 +382,11 @@ int inet6_bind(struct socket *sock, stru
4bf69007
AM
24221 }
24222 }
24223
24224+ if (!v6_addr_in_nx_info(sk->sk_nx_info, &addr->sin6_addr, -1)) {
24225+ err = -EADDRNOTAVAIL;
24226+ goto out_unlock;
24227+ }
2ba6f0dd 24228+
4bf69007
AM
24229 /* ipv4 addr of the socket is invalid. Only the
24230 * unspecified and mapped address have a v4 equivalent.
24231 */
3261cfd5 24232@@ -386,6 +404,9 @@ int inet6_bind(struct socket *sock, stru
4bf69007
AM
24233 }
24234 }
24235
24236+ /* what's that for? */
24237+ v6_set_sock_addr(inet, &nsa);
2ba6f0dd 24238+
4bf69007
AM
24239 inet->inet_rcv_saddr = v4addr;
24240 inet->inet_saddr = v4addr;
24241
3261cfd5 24242@@ -492,9 +513,11 @@ int inet6_getname(struct socket *sock, s
4bf69007
AM
24243 return -ENOTCONN;
24244 sin->sin6_port = inet->inet_dport;
c2e5f7c8 24245 sin->sin6_addr = sk->sk_v6_daddr;
4bf69007
AM
24246+ /* FIXME: remap lback? */
24247 if (np->sndflow)
24248 sin->sin6_flowinfo = np->flow_label;
24249 } else {
24250+ /* FIXME: remap lback? */
c2e5f7c8 24251 if (ipv6_addr_any(&sk->sk_v6_rcv_saddr))
4bf69007
AM
24252 sin->sin6_addr = np->saddr;
24253 else
3261cfd5
AM
24254diff -NurpP --minimal linux-4.9.207/net/ipv6/datagram.c linux-4.9.207-vs2.3.9.11/net/ipv6/datagram.c
24255--- linux-4.9.207/net/ipv6/datagram.c 2019-12-25 15:28:45.367186342 +0000
24256+++ linux-4.9.207-vs2.3.9.11/net/ipv6/datagram.c 2019-02-22 08:37:56.423037487 +0000
24257@@ -779,7 +779,7 @@ int ip6_datagram_send_ctl(struct net *ne
4bf69007
AM
24258
24259 rcu_read_lock();
24260 if (fl6->flowi6_oif) {
24261- dev = dev_get_by_index_rcu(net, fl6->flowi6_oif);
24262+ dev = dev_get_by_index_real_rcu(net, fl6->flowi6_oif);
24263 if (!dev) {
24264 rcu_read_unlock();
24265 return -ENODEV;
3261cfd5
AM
24266diff -NurpP --minimal linux-4.9.207/net/ipv6/fib6_rules.c linux-4.9.207-vs2.3.9.11/net/ipv6/fib6_rules.c
24267--- linux-4.9.207/net/ipv6/fib6_rules.c 2019-12-25 15:28:45.387186017 +0000
24268+++ linux-4.9.207-vs2.3.9.11/net/ipv6/fib6_rules.c 2018-10-20 04:58:15.000000000 +0000
cc23e853 24269@@ -102,7 +102,7 @@ static int fib6_rule_action(struct fib_r
4bf69007
AM
24270 ip6_dst_idev(&rt->dst)->dev,
24271 &flp6->daddr,
24272 rt6_flags2srcprefs(flags),
24273- &saddr))
24274+ &saddr, NULL))
24275 goto again;
24276 if (!ipv6_prefix_equal(&saddr, &r->src.addr,
24277 r->src.plen))
3261cfd5
AM
24278diff -NurpP --minimal linux-4.9.207/net/ipv6/inet6_hashtables.c linux-4.9.207-vs2.3.9.11/net/ipv6/inet6_hashtables.c
24279--- linux-4.9.207/net/ipv6/inet6_hashtables.c 2016-12-11 19:17:54.000000000 +0000
24280+++ linux-4.9.207-vs2.3.9.11/net/ipv6/inet6_hashtables.c 2018-10-20 04:58:15.000000000 +0000
4bf69007
AM
24281@@ -16,6 +16,7 @@
24282
24283 #include <linux/module.h>
24284 #include <linux/random.h>
24285+#include <linux/vs_inet6.h>
24286
cc23e853 24287 #include <net/addrconf.h>
4bf69007 24288 #include <net/inet_connection_sock.h>
cc23e853 24289@@ -108,6 +109,9 @@ static inline int compute_score(struct s
c2e5f7c8 24290 if (!ipv6_addr_equal(&sk->sk_v6_rcv_saddr, daddr))
4bf69007
AM
24291 return -1;
24292 score++;
24293+ } else {
24294+ if (!v6_addr_in_nx_info(sk->sk_nx_info, daddr, -1))
24295+ return -1;
24296 }
cc23e853 24297 if (sk->sk_bound_dev_if || exact_dif) {
4bf69007 24298 if (sk->sk_bound_dev_if != dif)
cc23e853
AM
24299@@ -282,39 +286,71 @@ EXPORT_SYMBOL_GPL(inet6_hash);
24300 * IPV6_ADDR_ANY only equals to IPV6_ADDR_ANY,
24301 * and 0.0.0.0 equals to 0.0.0.0 only
24302 */
24303-int ipv6_rcv_saddr_equal(const struct sock *sk, const struct sock *sk2,
24304+int ipv6_rcv_saddr_equal(const struct sock *sk1, const struct sock *sk2,
24305 bool match_wildcard)
24306 {
24307+ const struct in6_addr *sk1_rcv_saddr6 = inet6_rcv_saddr(sk1);
24308 const struct in6_addr *sk2_rcv_saddr6 = inet6_rcv_saddr(sk2);
24309+ __be32 sk1_rcv_saddr = sk1->sk_rcv_saddr;
24310+ __be32 sk2_rcv_saddr = sk2->sk_rcv_saddr;
24311+ int sk1_ipv6only = inet_v6_ipv6only(sk1);
24312 int sk2_ipv6only = inet_v6_ipv6only(sk2);
24313- int addr_type = ipv6_addr_type(&sk->sk_v6_rcv_saddr);
24314+ int addr_type1 = ipv6_addr_type(sk1_rcv_saddr6);
24315 int addr_type2 = sk2_rcv_saddr6 ? ipv6_addr_type(sk2_rcv_saddr6) : IPV6_ADDR_MAPPED;
24316
24317+
24318+ /* if one is mapped and the other is ipv6only exit early */
24319+ if (addr_type1 == IPV6_ADDR_MAPPED && sk2_ipv6only)
24320+ return 0;
24321+
24322+ if (addr_type2 == IPV6_ADDR_MAPPED && sk1_ipv6only)
24323+ return 0;
24324+
24325 /* if both are mapped, treat as IPv4 */
24326- if (addr_type == IPV6_ADDR_MAPPED && addr_type2 == IPV6_ADDR_MAPPED) {
24327- if (!sk2_ipv6only) {
24328- if (sk->sk_rcv_saddr == sk2->sk_rcv_saddr)
24329- return 1;
24330- if (!sk->sk_rcv_saddr || !sk2->sk_rcv_saddr)
24331- return match_wildcard;
24332- }
24333+ if (addr_type1 == IPV6_ADDR_MAPPED && addr_type2 == IPV6_ADDR_MAPPED) {
24334+ if (sk1_rcv_saddr == sk2_rcv_saddr)
24335+ return 1;
24336+ if ((!sk1_rcv_saddr || !sk2_rcv_saddr) && match_wildcard)
24337+ goto vs_v4;
24338 return 0;
24339 }
24340
24341- if (addr_type == IPV6_ADDR_ANY && addr_type2 == IPV6_ADDR_ANY)
24342- return 1;
24343+ /* if both are wildcards, check for overlap */
24344+ if (addr_type1 == IPV6_ADDR_ANY && addr_type2 == IPV6_ADDR_ANY)
24345+ return nx_v6_addr_conflict(sk1->sk_nx_info, sk2->sk_nx_info);
24346
24347- if (addr_type2 == IPV6_ADDR_ANY && match_wildcard &&
24348- !(sk2_ipv6only && addr_type == IPV6_ADDR_MAPPED))
24349+ /* if both are valid ipv6 addresses, mapped handled above */
24350+ if (addr_type1 != IPV6_ADDR_ANY && addr_type2 != IPV6_ADDR_ANY &&
24351+ sk2_rcv_saddr6 && ipv6_addr_equal(sk1_rcv_saddr6, sk2_rcv_saddr6))
24352 return 1;
24353
24354- if (addr_type == IPV6_ADDR_ANY && match_wildcard &&
24355- !(ipv6_only_sock(sk) && addr_type2 == IPV6_ADDR_MAPPED))
24356- return 1;
24357+ if (addr_type1 == IPV6_ADDR_ANY && match_wildcard) {
24358+ /* ipv6only case handled above */
24359+ if (addr_type2 == IPV6_ADDR_MAPPED)
24360+ return v4_addr_in_nx_info(sk1->sk_nx_info, sk2_rcv_saddr, -1);
24361+ else
24362+ return v6_addr_in_nx_info(sk1->sk_nx_info, sk2_rcv_saddr6, -1);
24363+ }
24364
24365- if (sk2_rcv_saddr6 &&
24366- ipv6_addr_equal(&sk->sk_v6_rcv_saddr, sk2_rcv_saddr6))
24367- return 1;
24368+ if (addr_type2 == IPV6_ADDR_ANY && match_wildcard) {
24369+ /* ipv6only case handled above */
24370+ if (addr_type1 == IPV6_ADDR_MAPPED)
24371+ return v4_addr_in_nx_info(sk2->sk_nx_info, sk1_rcv_saddr, -1);
24372+ else
24373+ return v6_addr_in_nx_info(sk2->sk_nx_info, sk1_rcv_saddr6, -1);
24374+ }
24375+
24376+ return 0;
24377+
24378+vs_v4:
24379+ if (!sk1_rcv_saddr && !sk2_rcv_saddr)
24380+ return nx_v4_addr_conflict(sk1->sk_nx_info, sk2->sk_nx_info);
24381+
24382+ if (!sk2_rcv_saddr)
24383+ return v4_addr_in_nx_info(sk1->sk_nx_info, sk2_rcv_saddr, -1);
24384+
24385+ if (!sk1_rcv_saddr)
24386+ return v4_addr_in_nx_info(sk2->sk_nx_info, sk1_rcv_saddr, -1);
24387
24388 return 0;
24389 }
3261cfd5
AM
24390diff -NurpP --minimal linux-4.9.207/net/ipv6/ip6_fib.c linux-4.9.207-vs2.3.9.11/net/ipv6/ip6_fib.c
24391--- linux-4.9.207/net/ipv6/ip6_fib.c 2019-12-25 15:28:45.387186017 +0000
24392+++ linux-4.9.207-vs2.3.9.11/net/ipv6/ip6_fib.c 2018-10-20 04:58:15.000000000 +0000
cc23e853 24393@@ -1976,6 +1976,7 @@ static int ipv6_route_seq_show(struct se
c2e5f7c8
JR
24394 struct rt6_info *rt = v;
24395 struct ipv6_route_iter *iter = seq->private;
24396
24397+ /* FIXME: check for network context? */
24398 seq_printf(seq, "%pi6 %02x ", &rt->rt6i_dst.addr, rt->rt6i_dst.plen);
24399
24400 #ifdef CONFIG_IPV6_SUBTREES
3261cfd5
AM
24401diff -NurpP --minimal linux-4.9.207/net/ipv6/ip6_output.c linux-4.9.207-vs2.3.9.11/net/ipv6/ip6_output.c
24402--- linux-4.9.207/net/ipv6/ip6_output.c 2019-12-25 15:28:45.397185857 +0000
24403+++ linux-4.9.207-vs2.3.9.11/net/ipv6/ip6_output.c 2019-10-05 14:58:46.270297968 +0000
24404@@ -962,7 +962,8 @@ static int ip6_dst_lookup_tail(struct ne
cc23e853 24405 rt = (*dst)->error ? NULL : (struct rt6_info *)*dst;
4bf69007
AM
24406 err = ip6_route_get_saddr(net, rt, &fl6->daddr,
24407 sk ? inet6_sk(sk)->srcprefs : 0,
24408- &fl6->saddr);
24409+ &fl6->saddr,
24410+ sk ? sk->sk_nx_info : NULL);
24411 if (err)
24412 goto out_err_release;
cc23e853 24413
3261cfd5
AM
24414diff -NurpP --minimal linux-4.9.207/net/ipv6/ip6_tunnel.c linux-4.9.207-vs2.3.9.11/net/ipv6/ip6_tunnel.c
24415--- linux-4.9.207/net/ipv6/ip6_tunnel.c 2019-12-25 15:28:45.397185857 +0000
24416+++ linux-4.9.207-vs2.3.9.11/net/ipv6/ip6_tunnel.c 2019-10-05 14:58:46.270297968 +0000
24417@@ -1116,7 +1116,7 @@ route_lookup:
cc23e853
AM
24418 }
24419 if (t->parms.collect_md &&
24420 ipv6_dev_get_saddr(net, ip6_dst_idev(dst)->dev,
24421- &fl6->daddr, 0, &fl6->saddr))
24422+ &fl6->daddr, 0, &fl6->saddr, NULL))
24423 goto tx_err_link_failure;
24424 ndst = dst;
4bf69007 24425 }
3261cfd5
AM
24426diff -NurpP --minimal linux-4.9.207/net/ipv6/ndisc.c linux-4.9.207-vs2.3.9.11/net/ipv6/ndisc.c
24427--- linux-4.9.207/net/ipv6/ndisc.c 2019-12-25 15:28:45.407185693 +0000
24428+++ linux-4.9.207-vs2.3.9.11/net/ipv6/ndisc.c 2019-02-22 08:37:56.423037487 +0000
cc23e853 24429@@ -512,7 +512,7 @@ void ndisc_send_na(struct net_device *de
4bf69007
AM
24430 } else {
24431 if (ipv6_dev_get_saddr(dev_net(dev), dev, daddr,
24432 inet6_sk(dev_net(dev)->ipv6.ndisc_sk)->srcprefs,
24433- &tmpaddr))
24434+ &tmpaddr, NULL))
24435 return;
24436 src_addr = &tmpaddr;
24437 }
3261cfd5
AM
24438diff -NurpP --minimal linux-4.9.207/net/ipv6/netfilter/nf_nat_masquerade_ipv6.c linux-4.9.207-vs2.3.9.11/net/ipv6/netfilter/nf_nat_masquerade_ipv6.c
24439--- linux-4.9.207/net/ipv6/netfilter/nf_nat_masquerade_ipv6.c 2016-12-11 19:17:54.000000000 +0000
24440+++ linux-4.9.207-vs2.3.9.11/net/ipv6/netfilter/nf_nat_masquerade_ipv6.c 2018-10-20 04:58:15.000000000 +0000
cc23e853 24441@@ -39,7 +39,7 @@ nf_nat_masquerade_ipv6(struct sk_buff *s
4bf69007
AM
24442 ctinfo == IP_CT_RELATED_REPLY));
24443
cc23e853 24444 if (ipv6_dev_get_saddr(nf_ct_net(ct), out,
4bf69007
AM
24445- &ipv6_hdr(skb)->daddr, 0, &src) < 0)
24446+ &ipv6_hdr(skb)->daddr, 0, &src, NULL) < 0)
24447 return NF_DROP;
24448
bb20add7 24449 nfct_nat(ct)->masq_index = out->ifindex;
3261cfd5
AM
24450diff -NurpP --minimal linux-4.9.207/net/ipv6/raw.c linux-4.9.207-vs2.3.9.11/net/ipv6/raw.c
24451--- linux-4.9.207/net/ipv6/raw.c 2019-12-25 15:28:45.477184561 +0000
24452+++ linux-4.9.207-vs2.3.9.11/net/ipv6/raw.c 2019-10-05 14:58:46.270297968 +0000
24453@@ -293,6 +293,13 @@ static int rawv6_bind(struct sock *sk, s
4bf69007
AM
24454 goto out_unlock;
24455 }
24456
24457+ if (!v6_addr_in_nx_info(sk->sk_nx_info, &addr->sin6_addr, -1)) {
24458+ err = -EADDRNOTAVAIL;
24459+ if (dev)
24460+ dev_put(dev);
24461+ goto out;
24462+ }
2ba6f0dd 24463+
4bf69007
AM
24464 /* ipv4 addr of the socket is invalid. Only the
24465 * unspecified and mapped address have a v4 equivalent.
24466 */
3261cfd5
AM
24467diff -NurpP --minimal linux-4.9.207/net/ipv6/route.c linux-4.9.207-vs2.3.9.11/net/ipv6/route.c
24468--- linux-4.9.207/net/ipv6/route.c 2019-12-25 15:28:45.477184561 +0000
24469+++ linux-4.9.207-vs2.3.9.11/net/ipv6/route.c 2019-10-05 14:58:46.270297968 +0000
24470@@ -3294,7 +3294,8 @@ static int rt6_fill_node(struct net *net
4bf69007
AM
24471 goto nla_put_failure;
24472 } else if (dst) {
24473 struct in6_addr saddr_buf;
24474- if (ip6_route_get_saddr(net, rt, dst, 0, &saddr_buf) == 0 &&
24475+ if (ip6_route_get_saddr(net, rt, dst, 0, &saddr_buf,
24476+ (skb->sk ? skb->sk->sk_nx_info : NULL)) == 0 &&
cc23e853 24477 nla_put_in6_addr(skb, RTA_PREFSRC, &saddr_buf))
4bf69007
AM
24478 goto nla_put_failure;
24479 }
3261cfd5
AM
24480diff -NurpP --minimal linux-4.9.207/net/ipv6/tcp_ipv6.c linux-4.9.207-vs2.3.9.11/net/ipv6/tcp_ipv6.c
24481--- linux-4.9.207/net/ipv6/tcp_ipv6.c 2019-12-25 15:28:45.477184561 +0000
24482+++ linux-4.9.207-vs2.3.9.11/net/ipv6/tcp_ipv6.c 2019-10-05 14:58:46.270297968 +0000
cc23e853 24483@@ -149,11 +149,18 @@ static int tcp_v6_connect(struct sock *s
4bf69007
AM
24484 */
24485
cc23e853
AM
24486 if (ipv6_addr_any(&usin->sin6_addr)) {
24487- if (ipv6_addr_v4mapped(&sk->sk_v6_rcv_saddr))
24488- ipv6_addr_set_v4mapped(htonl(INADDR_LOOPBACK),
24489- &usin->sin6_addr);
24490- else
24491- usin->sin6_addr = in6addr_loopback;
4bf69007 24492+ struct nx_info *nxi = sk->sk_nx_info;
2ba6f0dd 24493+
4bf69007
AM
24494+ if (nxi && nx_info_has_v6(nxi))
24495+ /* FIXME: remap lback? */
24496+ usin->sin6_addr = nxi->v6.ip;
cc23e853
AM
24497+ else {
24498+ if (ipv6_addr_v4mapped(&sk->sk_v6_rcv_saddr))
24499+ ipv6_addr_set_v4mapped(htonl(INADDR_LOOPBACK),
24500+ &usin->sin6_addr);
24501+ else
24502+ usin->sin6_addr = in6addr_loopback;
24503+ }
24504 }
4bf69007
AM
24505
24506 addr_type = ipv6_addr_type(&usin->sin6_addr);
3261cfd5
AM
24507diff -NurpP --minimal linux-4.9.207/net/ipv6/udp.c linux-4.9.207-vs2.3.9.11/net/ipv6/udp.c
24508--- linux-4.9.207/net/ipv6/udp.c 2019-12-25 15:28:45.487184400 +0000
24509+++ linux-4.9.207-vs2.3.9.11/net/ipv6/udp.c 2019-10-05 14:58:46.270297968 +0000
cc23e853
AM
24510@@ -135,6 +135,10 @@ static int compute_score(struct sock *sk
24511 if (inet->inet_dport != sport)
24512 return -1;
24513 score++;
4bf69007
AM
24514+ } else {
24515+ /* block non nx_info ips */
24516+ if (!v6_addr_in_nx_info(sk->sk_nx_info, daddr, -1))
24517+ return -1;
cc23e853
AM
24518 }
24519
24520 if (!ipv6_addr_any(&sk->sk_v6_rcv_saddr)) {
3261cfd5
AM
24521diff -NurpP --minimal linux-4.9.207/net/ipv6/xfrm6_policy.c linux-4.9.207-vs2.3.9.11/net/ipv6/xfrm6_policy.c
24522--- linux-4.9.207/net/ipv6/xfrm6_policy.c 2019-12-25 15:28:45.507184076 +0000
24523+++ linux-4.9.207-vs2.3.9.11/net/ipv6/xfrm6_policy.c 2018-10-20 04:58:15.000000000 +0000
cc23e853
AM
24524@@ -64,7 +64,8 @@ static int xfrm6_get_saddr(struct net *n
24525 return -EHOSTUNREACH;
24526
4bf69007 24527 dev = ip6_dst_idev(dst)->dev;
cc23e853
AM
24528- ipv6_dev_get_saddr(dev_net(dev), dev, &daddr->in6, 0, &saddr->in6);
24529+ ipv6_dev_get_saddr(dev_net(dev), dev, &daddr->in6,
24530+ 0, &saddr->in6, NULL);
4bf69007
AM
24531 dst_release(dst);
24532 return 0;
24533 }
3261cfd5
AM
24534diff -NurpP --minimal linux-4.9.207/net/netfilter/ipvs/ip_vs_xmit.c linux-4.9.207-vs2.3.9.11/net/netfilter/ipvs/ip_vs_xmit.c
24535--- linux-4.9.207/net/netfilter/ipvs/ip_vs_xmit.c 2016-12-11 19:17:54.000000000 +0000
24536+++ linux-4.9.207-vs2.3.9.11/net/netfilter/ipvs/ip_vs_xmit.c 2018-10-20 04:58:15.000000000 +0000
cc23e853 24537@@ -381,7 +381,7 @@ __ip_vs_route_output_v6(struct net *net,
4bf69007
AM
24538 return dst;
24539 if (ipv6_addr_any(&fl6.saddr) &&
24540 ipv6_dev_get_saddr(net, ip6_dst_idev(dst)->dev,
24541- &fl6.daddr, 0, &fl6.saddr) < 0)
24542+ &fl6.daddr, 0, &fl6.saddr, NULL) < 0)
24543 goto out_err;
24544 if (do_xfrm) {
24545 dst = xfrm_lookup(net, dst, flowi6_to_flowi(&fl6), NULL, 0);
3261cfd5
AM
24546diff -NurpP --minimal linux-4.9.207/net/netlink/af_netlink.c linux-4.9.207-vs2.3.9.11/net/netlink/af_netlink.c
24547--- linux-4.9.207/net/netlink/af_netlink.c 2019-12-25 15:28:46.637165893 +0000
24548+++ linux-4.9.207-vs2.3.9.11/net/netlink/af_netlink.c 2018-10-20 05:56:16.000000000 +0000
09a55596 24549@@ -63,6 +63,8 @@
bb20add7 24550 #include <linux/hash.h>
cc23e853 24551 #include <linux/genetlink.h>
e37b822e 24552 #include <linux/nospec.h>
4bf69007
AM
24553+#include <linux/vs_context.h>
24554+#include <linux/vs_network.h>
4bf69007
AM
24555
24556 #include <net/net_namespace.h>
bb20add7 24557 #include <net/sock.h>
09a55596 24558@@ -2477,7 +2479,8 @@ static void *__netlink_seq_next(struct s
cc23e853
AM
24559 if (err)
24560 return ERR_PTR(err);
24561 }
24562- } while (sock_net(&nlk->sk) != seq_file_net(seq));
24563+ } while ((sock_net(&nlk->sk) != seq_file_net(seq)) ||
24564+ !nx_check(nlk->sk.sk_nid, VS_WATCH_P | VS_IDENT));
bb20add7 24565
cc23e853
AM
24566 return nlk;
24567 }
3261cfd5
AM
24568diff -NurpP --minimal linux-4.9.207/net/packet/diag.c linux-4.9.207-vs2.3.9.11/net/packet/diag.c
24569--- linux-4.9.207/net/packet/diag.c 2016-12-11 19:17:54.000000000 +0000
24570+++ linux-4.9.207-vs2.3.9.11/net/packet/diag.c 2018-10-20 06:31:18.000000000 +0000
09a55596
AM
24571@@ -4,6 +4,7 @@
24572 #include <linux/netdevice.h>
24573 #include <linux/packet_diag.h>
24574 #include <linux/percpu.h>
24575+#include <linux/vs_network.h>
24576 #include <net/net_namespace.h>
24577 #include <net/sock.h>
24578
24579@@ -201,6 +202,8 @@ static int packet_diag_dump(struct sk_bu
24580 sk_for_each(sk, &net->packet.sklist) {
24581 if (!net_eq(sock_net(sk), net))
24582 continue;
24583+ if (!nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT))
24584+ continue;
24585 if (num < s_num)
24586 goto next;
24587
3261cfd5
AM
24588diff -NurpP --minimal linux-4.9.207/net/socket.c linux-4.9.207-vs2.3.9.11/net/socket.c
24589--- linux-4.9.207/net/socket.c 2019-12-25 15:28:49.507119801 +0000
24590+++ linux-4.9.207-vs2.3.9.11/net/socket.c 2019-10-05 14:58:47.230282628 +0000
09a55596 24591@@ -100,10 +100,12 @@
4bf69007
AM
24592
24593 #include <net/sock.h>
24594 #include <linux/netfilter.h>
4bf69007
AM
24595+#include <linux/vs_socket.h>
24596+#include <linux/vs_inet.h>
24597+#include <linux/vs_inet6.h>
24598
24599 #include <linux/if_tun.h>
24600 #include <linux/ipv6_route.h>
cc23e853
AM
24601-#include <linux/route.h>
24602 #include <linux/sockios.h>
24603 #include <linux/atalk.h>
24604 #include <net/busy_poll.h>
09a55596 24605@@ -619,8 +621,24 @@ EXPORT_SYMBOL(__sock_tx_timestamp);
4bf69007 24606
cc23e853
AM
24607 static inline int sock_sendmsg_nosec(struct socket *sock, struct msghdr *msg)
24608 {
24609- int ret = sock->ops->sendmsg(sock, msg, msg_data_left(msg));
24610- BUG_ON(ret == -EIOCBQUEUED);
24611+ size_t size = msg_data_left(msg);
24612+ int ret = sock->ops->sendmsg(sock, msg, size);
24613+#if 0
4bf69007 24614+ if (sock->sk) {
cc23e853 24615+ if (!ret)
4bf69007 24616+ vx_sock_fail(sock->sk, size);
cc23e853
AM
24617+ else
24618+ vx_sock_send(sock->sk, size);
4bf69007 24619+ }
cc23e853 24620+#endif
4bf69007 24621+ vxdprintk(VXD_CBIT(net, 7),
cc23e853 24622+ "sock_sendmsg_nosec: %p[%p,%p,%p;%d/%d]:%zu/%zu",
4bf69007
AM
24623+ sock, sock->sk,
24624+ (sock->sk)?sock->sk->sk_nx_info:0,
24625+ (sock->sk)?sock->sk->sk_vx_info:0,
24626+ (sock->sk)?sock->sk->sk_xid:0,
24627+ (sock->sk)?sock->sk->sk_nid:0,
cc23e853
AM
24628+ size, msg_data_left(msg));
24629 return ret;
4bf69007
AM
24630 }
24631
09a55596 24632@@ -1110,6 +1128,13 @@ int __sock_create(struct net *net, int f
4bf69007
AM
24633 if (type < 0 || type >= SOCK_MAX)
24634 return -EINVAL;
24635
24636+ if (!nx_check(0, VS_ADMIN)) {
24637+ if (family == PF_INET && !current_nx_info_has_v4())
24638+ return -EAFNOSUPPORT;
24639+ if (family == PF_INET6 && !current_nx_info_has_v6())
24640+ return -EAFNOSUPPORT;
24641+ }
2ba6f0dd 24642+
4bf69007
AM
24643 /* Compatibility.
24644
24645 This uglymoron is moved from INET layer to here to avoid
09a55596 24646@@ -1240,6 +1265,7 @@ SYSCALL_DEFINE3(socket, int, family, int
4bf69007
AM
24647 if (retval < 0)
24648 goto out;
24649
24650+ set_bit(SOCK_USER_SOCKET, &sock->flags);
24651 retval = sock_map_fd(sock, flags & (O_CLOEXEC | O_NONBLOCK));
24652 if (retval < 0)
24653 goto out_release;
09a55596 24654@@ -1281,10 +1307,12 @@ SYSCALL_DEFINE4(socketpair, int, family,
4bf69007
AM
24655 err = sock_create(family, type, protocol, &sock1);
24656 if (err < 0)
24657 goto out;
24658+ set_bit(SOCK_USER_SOCKET, &sock1->flags);
24659
24660 err = sock_create(family, type, protocol, &sock2);
24661 if (err < 0)
24662 goto out_release_1;
24663+ set_bit(SOCK_USER_SOCKET, &sock2->flags);
24664
24665 err = sock1->ops->socketpair(sock1, sock2);
24666 if (err < 0)
3261cfd5
AM
24667diff -NurpP --minimal linux-4.9.207/net/sunrpc/auth.c linux-4.9.207-vs2.3.9.11/net/sunrpc/auth.c
24668--- linux-4.9.207/net/sunrpc/auth.c 2016-12-11 19:17:54.000000000 +0000
24669+++ linux-4.9.207-vs2.3.9.11/net/sunrpc/auth.c 2018-10-20 04:58:15.000000000 +0000
4bf69007
AM
24670@@ -15,6 +15,7 @@
24671 #include <linux/sunrpc/clnt.h>
24672 #include <linux/sunrpc/gss_api.h>
24673 #include <linux/spinlock.h>
24674+#include <linux/vs_tag.h>
24675
cc23e853 24676 #if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
4bf69007 24677 # define RPCDBG_FACILITY RPCDBG_AUTH
bb20add7 24678@@ -630,6 +631,7 @@ rpcauth_lookupcred(struct rpc_auth *auth
4bf69007
AM
24679 memset(&acred, 0, sizeof(acred));
24680 acred.uid = cred->fsuid;
24681 acred.gid = cred->fsgid;
a4a22af8 24682+ acred.tag = make_ktag(&init_user_ns, dx_current_tag());
bb20add7 24683 acred.group_info = cred->group_info;
4bf69007 24684 ret = auth->au_ops->lookup_cred(auth, &acred, flags);
bb20add7
AM
24685 return ret;
24686@@ -669,6 +671,7 @@ rpcauth_bind_root_cred(struct rpc_task *
4bf69007 24687 struct auth_cred acred = {
b00e13aa
AM
24688 .uid = GLOBAL_ROOT_UID,
24689 .gid = GLOBAL_ROOT_GID,
a4a22af8 24690+ .tag = KTAGT_INIT(dx_current_tag()),
4bf69007
AM
24691 };
24692
24693 dprintk("RPC: %5u looking up %s cred\n",
3261cfd5
AM
24694diff -NurpP --minimal linux-4.9.207/net/sunrpc/auth_unix.c linux-4.9.207-vs2.3.9.11/net/sunrpc/auth_unix.c
24695--- linux-4.9.207/net/sunrpc/auth_unix.c 2016-12-11 19:17:54.000000000 +0000
24696+++ linux-4.9.207-vs2.3.9.11/net/sunrpc/auth_unix.c 2018-10-20 04:58:15.000000000 +0000
4bf69007
AM
24697@@ -13,11 +13,13 @@
24698 #include <linux/sunrpc/clnt.h>
24699 #include <linux/sunrpc/auth.h>
24700 #include <linux/user_namespace.h>
24701+#include <linux/vs_tag.h>
24702
24703 #define NFS_NGROUPS 16
24704
24705 struct unx_cred {
24706 struct rpc_cred uc_base;
b00e13aa
AM
24707+ ktag_t uc_tag;
24708 kgid_t uc_gid;
24709 kgid_t uc_gids[NFS_NGROUPS];
4bf69007 24710 };
cc23e853 24711@@ -86,6 +88,7 @@ unx_create_cred(struct rpc_auth *auth, s
4bf69007
AM
24712 groups = NFS_NGROUPS;
24713
24714 cred->uc_gid = acred->gid;
24715+ cred->uc_tag = acred->tag;
b00e13aa 24716 for (i = 0; i < groups; i++)
cc23e853 24717 cred->uc_gids[i] = acred->group_info->gid[i];
b00e13aa 24718 if (i < NFS_NGROUPS)
cc23e853 24719@@ -127,7 +130,9 @@ unx_match(struct auth_cred *acred, struc
4bf69007
AM
24720 unsigned int i;
24721
24722
b00e13aa
AM
24723- if (!uid_eq(cred->uc_uid, acred->uid) || !gid_eq(cred->uc_gid, acred->gid))
24724+ if (!uid_eq(cred->uc_uid, acred->uid) ||
24725+ !gid_eq(cred->uc_gid, acred->gid) ||
24726+ !tag_eq(cred->uc_tag, acred->tag))
4bf69007
AM
24727 return 0;
24728
24729 if (acred->group_info != NULL)
cc23e853 24730@@ -152,7 +157,7 @@ unx_marshal(struct rpc_task *task, __be3
4bf69007
AM
24731 struct rpc_clnt *clnt = task->tk_client;
24732 struct unx_cred *cred = container_of(task->tk_rqstp->rq_cred, struct unx_cred, uc_base);
24733 __be32 *base, *hold;
24734- int i;
24735+ int i, tag;
24736
24737 *p++ = htonl(RPC_AUTH_UNIX);
24738 base = p++;
cc23e853 24739@@ -163,8 +168,11 @@ unx_marshal(struct rpc_task *task, __be3
4bf69007
AM
24740 */
24741 p = xdr_encode_array(p, clnt->cl_nodename, clnt->cl_nodelen);
4bf69007 24742
b00e13aa
AM
24743- *p++ = htonl((u32) from_kuid(&init_user_ns, cred->uc_uid));
24744- *p++ = htonl((u32) from_kgid(&init_user_ns, cred->uc_gid));
24745+ tag = task->tk_client->cl_tag;
a4a22af8
AM
24746+ *p++ = htonl((u32) from_kuid(&init_user_ns,
24747+ TAGINO_KUID(tag, cred->uc_uid, cred->uc_tag)));
24748+ *p++ = htonl((u32) from_kgid(&init_user_ns,
24749+ TAGINO_KGID(tag, cred->uc_gid, cred->uc_tag)));
4bf69007 24750 hold = p++;
b00e13aa
AM
24751 for (i = 0; i < 16 && gid_valid(cred->uc_gids[i]); i++)
24752 *p++ = htonl((u32) from_kgid(&init_user_ns, cred->uc_gids[i]));
3261cfd5
AM
24753diff -NurpP --minimal linux-4.9.207/net/sunrpc/clnt.c linux-4.9.207-vs2.3.9.11/net/sunrpc/clnt.c
24754--- linux-4.9.207/net/sunrpc/clnt.c 2019-12-25 15:28:49.887113700 +0000
24755+++ linux-4.9.207-vs2.3.9.11/net/sunrpc/clnt.c 2019-10-05 14:58:47.230282628 +0000
4bf69007 24756@@ -31,6 +31,7 @@
c2e5f7c8 24757 #include <linux/in.h>
4bf69007
AM
24758 #include <linux/in6.h>
24759 #include <linux/un.h>
4bf69007
AM
24760+#include <linux/vs_cvirt.h>
24761
24762 #include <linux/sunrpc/clnt.h>
b00e13aa 24763 #include <linux/sunrpc/addr.h>
cc23e853 24764@@ -496,6 +497,9 @@ static struct rpc_clnt *rpc_create_xprt(
4bf69007
AM
24765 if (!(args->flags & RPC_CLNT_CREATE_QUIET))
24766 clnt->cl_chatty = 1;
24767
24768+ /* TODO: handle RPC_CLNT_CREATE_TAGGED
24769+ if (args->flags & RPC_CLNT_CREATE_TAGGED)
24770+ clnt->cl_tag = 1; */
24771 return clnt;
24772 }
cc23e853 24773
3261cfd5
AM
24774diff -NurpP --minimal linux-4.9.207/net/unix/af_unix.c linux-4.9.207-vs2.3.9.11/net/unix/af_unix.c
24775--- linux-4.9.207/net/unix/af_unix.c 2019-12-25 15:28:50.607102137 +0000
24776+++ linux-4.9.207-vs2.3.9.11/net/unix/af_unix.c 2019-12-25 15:37:53.138410818 +0000
bb20add7 24777@@ -117,6 +117,8 @@
4bf69007
AM
24778 #include <net/checksum.h>
24779 #include <linux/security.h>
c2e5f7c8 24780 #include <linux/freezer.h>
4bf69007
AM
24781+#include <linux/vs_context.h>
24782+#include <linux/vs_limit.h>
24783
24784 struct hlist_head unix_socket_table[2 * UNIX_HASH_SIZE];
24785 EXPORT_SYMBOL_GPL(unix_socket_table);
3261cfd5 24786@@ -284,6 +286,8 @@ static struct sock *__unix_find_socket_b
4bf69007
AM
24787 if (!net_eq(sock_net(s), net))
24788 continue;
24789
24790+ if (!nx_check(s->sk_nid, VS_WATCH_P | VS_IDENT))
24791+ continue;
24792 if (u->addr->len == len &&
24793 !memcmp(u->addr->name, sunname, len))
24794 goto found;
3261cfd5 24795@@ -2744,6 +2748,8 @@ static struct sock *unix_from_bucket(str
4bf69007
AM
24796 for (sk = sk_head(&unix_socket_table[bucket]); sk; sk = sk_next(sk)) {
24797 if (sock_net(sk) != seq_file_net(seq))
24798 continue;
24799+ if (!nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT))
24800+ continue;
24801 if (++count == offset)
24802 break;
24803 }
3261cfd5 24804@@ -2761,6 +2767,8 @@ static struct sock *unix_next_socket(str
4bf69007
AM
24805 sk = sk_next(sk);
24806 if (!sk)
24807 goto next_bucket;
24808+ if (!nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT))
24809+ continue;
24810 if (sock_net(sk) == seq_file_net(seq))
24811 return sk;
24812 }
3261cfd5
AM
24813diff -NurpP --minimal linux-4.9.207/net/unix/diag.c linux-4.9.207-vs2.3.9.11/net/unix/diag.c
24814--- linux-4.9.207/net/unix/diag.c 2019-12-25 15:28:50.607102137 +0000
24815+++ linux-4.9.207-vs2.3.9.11/net/unix/diag.c 2019-10-05 14:58:47.230282628 +0000
09a55596
AM
24816@@ -4,6 +4,7 @@
24817 #include <linux/unix_diag.h>
24818 #include <linux/skbuff.h>
24819 #include <linux/module.h>
24820+#include <linux/vs_network.h>
24821 #include <net/netlink.h>
24822 #include <net/af_unix.h>
24823 #include <net/tcp_states.h>
3261cfd5 24824@@ -200,6 +201,8 @@ static int unix_diag_dump(struct sk_buff
09a55596
AM
24825 sk_for_each(sk, &unix_socket_table[slot]) {
24826 if (!net_eq(sock_net(sk), net))
24827 continue;
24828+ if (!nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT))
24829+ continue;
24830 if (num < s_num)
24831 goto next;
24832 if (!(req->udiag_states & (1 << sk->sk_state)))
3261cfd5
AM
24833diff -NurpP --minimal linux-4.9.207/scripts/checksyscalls.sh linux-4.9.207-vs2.3.9.11/scripts/checksyscalls.sh
24834--- linux-4.9.207/scripts/checksyscalls.sh 2016-12-11 19:17:54.000000000 +0000
24835+++ linux-4.9.207-vs2.3.9.11/scripts/checksyscalls.sh 2018-10-20 04:58:15.000000000 +0000
bb20add7 24836@@ -196,7 +196,6 @@ cat << EOF
4bf69007
AM
24837 #define __IGNORE_afs_syscall
24838 #define __IGNORE_getpmsg
24839 #define __IGNORE_putpmsg
24840-#define __IGNORE_vserver
24841 EOF
24842 }
24843
3261cfd5
AM
24844diff -NurpP --minimal linux-4.9.207/security/commoncap.c linux-4.9.207-vs2.3.9.11/security/commoncap.c
24845--- linux-4.9.207/security/commoncap.c 2016-12-11 19:17:54.000000000 +0000
24846+++ linux-4.9.207-vs2.3.9.11/security/commoncap.c 2018-10-20 04:58:15.000000000 +0000
cc23e853 24847@@ -71,6 +71,7 @@ static void warn_setuid_and_fcaps_mixed(
4bf69007
AM
24848 int cap_capable(const struct cred *cred, struct user_namespace *targ_ns,
24849 int cap, int audit)
24850 {
24851+ struct vx_info *vxi = current_vx_info(); /* FIXME: get vxi from cred? */
b00e13aa 24852 struct user_namespace *ns = targ_ns;
4bf69007 24853
b00e13aa 24854 /* See if cred has the capability in the target user namespace
cc23e853 24855@@ -79,8 +80,12 @@ int cap_capable(const struct cred *cred,
b00e13aa
AM
24856 */
24857 for (;;) {
4bf69007 24858 /* Do we have the necessary capabilities? */
b00e13aa 24859- if (ns == cred->user_ns)
4bf69007 24860- return cap_raised(cred->cap_effective, cap) ? 0 : -EPERM;
b00e13aa 24861+ if (ns == cred->user_ns) {
4bf69007
AM
24862+ if (vx_info_flags(vxi, VXF_STATE_SETUP, 0) &&
24863+ cap_raised(cred->cap_effective, cap))
24864+ return 0;
24865+ return vx_cap_raised(vxi, cred->cap_effective, cap) ? 0 : -EPERM;
24866+ }
24867
24868 /* Have we tried all of the parent namespaces? */
b00e13aa 24869 if (ns == &init_user_ns)
cc23e853 24870@@ -667,7 +672,7 @@ int cap_inode_setxattr(struct dentry *de
4bf69007
AM
24871
24872 if (!strncmp(name, XATTR_SECURITY_PREFIX,
24873 sizeof(XATTR_SECURITY_PREFIX) - 1) &&
24874- !capable(CAP_SYS_ADMIN))
24875+ !vx_capable(CAP_SYS_ADMIN, VXC_FS_SECURITY))
24876 return -EPERM;
24877 return 0;
24878 }
cc23e853 24879@@ -693,7 +698,7 @@ int cap_inode_removexattr(struct dentry
4bf69007
AM
24880
24881 if (!strncmp(name, XATTR_SECURITY_PREFIX,
24882 sizeof(XATTR_SECURITY_PREFIX) - 1) &&
24883- !capable(CAP_SYS_ADMIN))
24884+ !vx_capable(CAP_SYS_ADMIN, VXC_FS_SECURITY))
24885 return -EPERM;
24886 return 0;
24887 }
3261cfd5
AM
24888diff -NurpP --minimal linux-4.9.207/security/selinux/hooks.c linux-4.9.207-vs2.3.9.11/security/selinux/hooks.c
24889--- linux-4.9.207/security/selinux/hooks.c 2019-12-25 15:28:52.047079008 +0000
24890+++ linux-4.9.207-vs2.3.9.11/security/selinux/hooks.c 2019-10-05 14:58:47.310281348 +0000
cc23e853 24891@@ -67,7 +67,6 @@
4bf69007
AM
24892 #include <linux/dccp.h>
24893 #include <linux/quota.h>
24894 #include <linux/un.h> /* for Unix socket types */
24895-#include <net/af_unix.h> /* for Unix socket types */
24896 #include <linux/parser.h>
24897 #include <linux/nfs_mount.h>
24898 #include <net/ipv6.h>
This page took 6.851945 seconds and 4 git commands to generate.