* [PATCH v17 12/15] seccomp: Add SECCOMP_RET_TRAP
From: Will Drewry @ 2012-03-29 20:01 UTC (permalink / raw)
To: linux-kernel
Cc: linux-security-module, linux-arch, linux-doc, kernel-hardening,
netdev, x86, arnd, davem, hpa, mingo, oleg, peterz, rdunlap,
mcgrathr, tglx, luto, eparis, serge.hallyn, djm, scarybeasts,
indan, pmoore, akpm, corbet, eric.dumazet, markus, coreyb,
keescook, jmorris, Will Drewry
In-Reply-To: <1333051320-30872-1-git-send-email-wad@chromium.org>
Adds a new return value to seccomp filters that triggers a SIGSYS to be
delivered with the new SYS_SECCOMP si_code.
This allows in-process system call emulation, including just specifying
an errno or cleanly dumping core, rather than just dying.
v17: - rebase
v16: -
v15: - use audit_seccomp/skip
- pad out error spacing; clean up switch (indan@nul.nu)
v14: - n/a
v13: - rebase on to 88ebdda6159ffc15699f204c33feb3e431bf9bdc
v12: - rebase on to linux-next
v11: - clarify the comment (indan@nul.nu)
- s/sigtrap/sigsys
v10: - use SIGSYS, syscall_get_arch, updates arch/Kconfig
note suggested-by (though original suggestion had other behaviors)
v9: - changes to SIGILL
v8: - clean up based on changes to dependent patches
v7: - introduction
Suggested-by: Markus Gutschke <markus@chromium.org>
Suggested-by: Julien Tinnes <jln@chromium.org>
Signed-off-by: Will Drewry <wad@chromium.org>
---
arch/Kconfig | 14 +++++++++-----
include/asm-generic/siginfo.h | 2 +-
include/linux/seccomp.h | 1 +
kernel/seccomp.c | 26 ++++++++++++++++++++++++++
4 files changed, 37 insertions(+), 6 deletions(-)
diff --git a/arch/Kconfig b/arch/Kconfig
index 9ba3003..a24d213 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -216,11 +216,15 @@ config HAVE_CMPXCHG_DOUBLE
config HAVE_ARCH_SECCOMP_FILTER
bool
help
- This symbol should be selected by an architecure if it provides
- asm/syscall.h, specifically syscall_get_arguments(),
- syscall_get_arch(), and syscall_set_return_value(). Additionally,
- its system call entry path must respect a return value of -1 from
- __secure_computing_int() and/or secure_computing().
+ This symbol should be selected by an architecure if it provides:
+ asm/syscall.h:
+ - syscall_get_arch()
+ - syscall_get_arguments()
+ - syscall_rollback()
+ - syscall_set_return_value()
+ SIGSYS siginfo_t support must be implemented.
+ __secure_computing_int()/secure_computing()'s return value must be
+ checked, with -1 resulting in the syscall being skipped.
config SECCOMP_FILTER
def_bool y
diff --git a/include/asm-generic/siginfo.h b/include/asm-generic/siginfo.h
index 31306f5..af5d035 100644
--- a/include/asm-generic/siginfo.h
+++ b/include/asm-generic/siginfo.h
@@ -93,7 +93,7 @@ typedef struct siginfo {
/* SIGSYS */
struct {
- void __user *_call_addr; /* calling insn */
+ void __user *_call_addr; /* calling user insn */
int _syscall; /* triggering system call number */
unsigned int _arch; /* AUDIT_ARCH_* of syscall */
} _sigsys;
diff --git a/include/linux/seccomp.h b/include/linux/seccomp.h
index 44004df..ecec06c 100644
--- a/include/linux/seccomp.h
+++ b/include/linux/seccomp.h
@@ -19,6 +19,7 @@
* selects the least permissive choice.
*/
#define SECCOMP_RET_KILL 0x00000000U /* kill the task immediately */
+#define SECCOMP_RET_TRAP 0x00030000U /* disallow and force a SIGSYS */
#define SECCOMP_RET_ERRNO 0x00050000U /* returns an errno */
#define SECCOMP_RET_ALLOW 0x7fff0000U /* allow */
diff --git a/kernel/seccomp.c b/kernel/seccomp.c
index 06b97aa..9a59c93 100644
--- a/kernel/seccomp.c
+++ b/kernel/seccomp.c
@@ -327,6 +327,26 @@ void put_seccomp_filter(struct task_struct *tsk)
kfree(freeme);
}
}
+
+/**
+ * seccomp_send_sigsys - signals the task to allow in-process syscall emulation
+ * @syscall: syscall number to send to userland
+ * @reason: filter-supplied reason code to send to userland (via si_errno)
+ *
+ * Forces a SIGSYS with a code of SYS_SECCOMP and related sigsys info.
+ */
+static void seccomp_send_sigsys(int syscall, int reason)
+{
+ struct siginfo info;
+ memset(&info, 0, sizeof(info));
+ info.si_signo = SIGSYS;
+ info.si_code = SYS_SECCOMP;
+ info.si_call_addr = (void __user *)KSTK_EIP(current);
+ info.si_errno = reason;
+ info.si_arch = syscall_get_arch(current, task_pt_regs(current));
+ info.si_syscall = syscall;
+ force_sig_info(SIGSYS, &info, current);
+}
#endif /* CONFIG_SECCOMP_FILTER */
/*
@@ -384,6 +404,12 @@ int __secure_computing_int(int this_syscall)
syscall_set_return_value(current, task_pt_regs(current),
-data, 0);
goto skip;
+ case SECCOMP_RET_TRAP:
+ /* Show the handler the original registers. */
+ syscall_rollback(current, task_pt_regs(current));
+ /* Let the filter pass back 16 bits of data. */
+ seccomp_send_sigsys(this_syscall, data);
+ goto skip;
case SECCOMP_RET_ALLOW:
return 0;
case SECCOMP_RET_KILL:
--
1.7.5.4
^ permalink raw reply related
* [PATCH v17 13/15] ptrace,seccomp: Add PTRACE_SECCOMP support
From: Will Drewry @ 2012-03-29 20:01 UTC (permalink / raw)
To: linux-kernel
Cc: linux-security-module, linux-arch, linux-doc, kernel-hardening,
netdev, x86, arnd, davem, hpa, mingo, oleg, peterz, rdunlap,
mcgrathr, tglx, luto, eparis, serge.hallyn, djm, scarybeasts,
indan, pmoore, akpm, corbet, eric.dumazet, markus, coreyb,
keescook, jmorris, Will Drewry
In-Reply-To: <1333051320-30872-1-git-send-email-wad@chromium.org>
This change adds support for a new ptrace option, PTRACE_O_TRACESECCOMP,
and a new return value for seccomp BPF programs, SECCOMP_RET_TRACE.
When a tracer specifies the PTRACE_O_TRACESECCOMP ptrace option, the
tracer will be notified, via PTRACE_EVENT_SECCOMP, for any syscall that
results in a BPF program returning SECCOMP_RET_TRACE. The 16-bit
SECCOMP_RET_DATA mask of the BPF program return value will be passed as
the ptrace_message and may be retrieved using PTRACE_GETEVENTMSG.
If the subordinate process is not using seccomp filter, then no
system call notifications will occur even if the option is specified.
If there is no tracer with PTRACE_O_TRACESECCOMP when SECCOMP_RET_TRACE
is returned, the system call will not be executed and an -ENOSYS errno
will be returned to userspace.
This change adds a dependency on the system call slow path. Any future
efforts to use the system call fast path for seccomp filter will need to
address this restriction.
v17: - rebase onto refactored ptrace code now in -linus
v16: - update PT_TRACE_MASK to 0xbf4 so that STOP isn't clear on SETOPTIONS call (indan@nul.nu)
[note PT_TRACE_MASK disappears in linux-next]
v15: - add audit support for non-zero return codes
- clean up style (indan@nul.nu)
v14: - rebase/nochanges
v13: - rebase on to 88ebdda6159ffc15699f204c33feb3e431bf9bdc
(Brings back a change to ptrace.c and the masks.)
v12: - rebase to linux-next
- use ptrace_event and update arch/Kconfig to mention slow-path dependency
- drop all tracehook changes and inclusion (oleg@redhat.com)
v11: - invert the logic to just make it a PTRACE_SYSCALL accelerator
(indan@nul.nu)
v10: - moved to PTRACE_O_SECCOMP / PT_TRACE_SECCOMP
v9: - n/a
v8: - guarded PTRACE_SECCOMP use with an ifdef
v7: - introduced
Signed-off-by: Will Drewry <wad@chromium.org>
---
arch/Kconfig | 11 ++++++-----
include/linux/ptrace.h | 5 ++++-
include/linux/seccomp.h | 1 +
kernel/seccomp.c | 12 +++++++++++-
4 files changed, 22 insertions(+), 7 deletions(-)
diff --git a/arch/Kconfig b/arch/Kconfig
index a24d213..fafefe6 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -216,15 +216,16 @@ config HAVE_CMPXCHG_DOUBLE
config HAVE_ARCH_SECCOMP_FILTER
bool
help
- This symbol should be selected by an architecure if it provides:
- asm/syscall.h:
+ An arch should select this symbol if it provides all of these things:
- syscall_get_arch()
- syscall_get_arguments()
- syscall_rollback()
- syscall_set_return_value()
- SIGSYS siginfo_t support must be implemented.
- __secure_computing_int()/secure_computing()'s return value must be
- checked, with -1 resulting in the syscall being skipped.
+ - SIGSYS siginfo_t support
+ - uses __secure_computing_int() or secure_computing()
+ - secure_computing is called from a ptrace_event()-safe context
+ - secure_computing return value is checked and a return value of -1
+ results in the system call being skipped immediately.
config SECCOMP_FILTER
def_bool y
diff --git a/include/linux/ptrace.h b/include/linux/ptrace.h
index 5c71962..597e4fd 100644
--- a/include/linux/ptrace.h
+++ b/include/linux/ptrace.h
@@ -58,6 +58,7 @@
#define PTRACE_EVENT_EXEC 4
#define PTRACE_EVENT_VFORK_DONE 5
#define PTRACE_EVENT_EXIT 6
+#define PTRACE_EVENT_SECCOMP 7
/* Extended result codes which enabled by means other than options. */
#define PTRACE_EVENT_STOP 128
@@ -69,8 +70,9 @@
#define PTRACE_O_TRACEEXEC (1 << PTRACE_EVENT_EXEC)
#define PTRACE_O_TRACEVFORKDONE (1 << PTRACE_EVENT_VFORK_DONE)
#define PTRACE_O_TRACEEXIT (1 << PTRACE_EVENT_EXIT)
+#define PTRACE_O_TRACESECCOMP (1 << PTRACE_EVENT_SECCOMP)
-#define PTRACE_O_MASK 0x0000007f
+#define PTRACE_O_MASK 0x000000ff
#include <asm/ptrace.h>
@@ -98,6 +100,7 @@
#define PT_TRACE_EXEC PT_EVENT_FLAG(PTRACE_EVENT_EXEC)
#define PT_TRACE_VFORK_DONE PT_EVENT_FLAG(PTRACE_EVENT_VFORK_DONE)
#define PT_TRACE_EXIT PT_EVENT_FLAG(PTRACE_EVENT_EXIT)
+#define PT_TRACE_SECCOMP PT_EVENT_FLAG(PTRACE_EVENT_SECCOMP)
/* single stepping state bits (used on ARM and PA-RISC) */
#define PT_SINGLESTEP_BIT 31
diff --git a/include/linux/seccomp.h b/include/linux/seccomp.h
index ecec06c..41ff13b 100644
--- a/include/linux/seccomp.h
+++ b/include/linux/seccomp.h
@@ -21,6 +21,7 @@
#define SECCOMP_RET_KILL 0x00000000U /* kill the task immediately */
#define SECCOMP_RET_TRAP 0x00030000U /* disallow and force a SIGSYS */
#define SECCOMP_RET_ERRNO 0x00050000U /* returns an errno */
+#define SECCOMP_RET_TRACE 0x7ff00000U /* pass to a tracer or disallow */
#define SECCOMP_RET_ALLOW 0x7fff0000U /* allow */
/* Masks for the return value sections. */
diff --git a/kernel/seccomp.c b/kernel/seccomp.c
index 9a59c93..4b5affa 100644
--- a/kernel/seccomp.c
+++ b/kernel/seccomp.c
@@ -24,6 +24,7 @@
#ifdef CONFIG_SECCOMP_FILTER
#include <asm/syscall.h>
#include <linux/filter.h>
+#include <linux/ptrace.h>
#include <linux/security.h>
#include <linux/slab.h>
#include <linux/tracehook.h>
@@ -398,7 +399,7 @@ int __secure_computing_int(int this_syscall)
case SECCOMP_MODE_FILTER:
ret = seccomp_run_filters(this_syscall);
data = ret & SECCOMP_RET_DATA;
- switch (code & SECCOMP_RET_ACTION) {
+ switch (ret & SECCOMP_RET_ACTION) {
case SECCOMP_RET_ERRNO:
/* Set the low-order 16-bits as a errno. */
syscall_set_return_value(current, task_pt_regs(current),
@@ -410,6 +411,15 @@ int __secure_computing_int(int this_syscall)
/* Let the filter pass back 16 bits of data. */
seccomp_send_sigsys(this_syscall, data);
goto skip;
+ case SECCOMP_RET_TRACE:
+ /* Skip these calls if there is no tracer. */
+ if (!ptrace_event_enabled(current, PTRACE_EVENT_SECCOMP))
+ goto skip;
+ /* Allow the BPF to provide the event message */
+ ptrace_event(PTRACE_EVENT_SECCOMP, data);
+ if (fatal_signal_pending(current))
+ break;
+ return 0;
case SECCOMP_RET_ALLOW:
return 0;
case SECCOMP_RET_KILL:
--
1.7.5.4
^ permalink raw reply related
* [PATCH v17 14/15] x86: Enable HAVE_ARCH_SECCOMP_FILTER
From: Will Drewry @ 2012-03-29 20:01 UTC (permalink / raw)
To: linux-kernel
Cc: linux-security-module, linux-arch, linux-doc, kernel-hardening,
netdev, x86, arnd, davem, hpa, mingo, oleg, peterz, rdunlap,
mcgrathr, tglx, luto, eparis, serge.hallyn, djm, scarybeasts,
indan, pmoore, akpm, corbet, eric.dumazet, markus, coreyb,
keescook, jmorris, Will Drewry
In-Reply-To: <1333051320-30872-1-git-send-email-wad@chromium.org>
Enable support for seccomp filter on x86:
- asm/tracehook.h exists
- syscall_get_arguments() works
- syscall_rollback() works
- ptrace_report_syscall() works
- secure_computing() return value is honored (see below)
This also adds support for honoring the return
value from secure_computing().
SECCOMP_RET_TRACE and SECCOMP_RET_TRAP may result in seccomp needing to
skip a system call without killing the process. This is done by
returning a non-zero (-1) value from secure_computing. This change
makes x86 respect that return value.
To ensure that minimal kernel code is exposed, a non-zero return value
results in an immediate return to user space (with an invalid syscall
number).
v17: added reviewed by and rebased
v..: all rebases since original introduction.
Reviewed-by: H. Peter Anvin <hpa@zytor.com>
Signed-off-by: Will Drewry <wad@chromium.org>
---
arch/x86/Kconfig | 1 +
arch/x86/kernel/ptrace.c | 7 ++++++-
2 files changed, 7 insertions(+), 1 deletions(-)
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 3ad653d..1f23136 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -83,6 +83,7 @@ config X86
select ARCH_HAVE_NMI_SAFE_CMPXCHG
select GENERIC_IOMAP
select DCACHE_WORD_ACCESS if !DEBUG_PAGEALLOC
+ select HAVE_ARCH_SECCOMP_FILTER
config INSTRUCTION_DECODER
def_bool (KPROBES || PERF_EVENTS)
diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c
index 8a634c8..a8d3cf9 100644
--- a/arch/x86/kernel/ptrace.c
+++ b/arch/x86/kernel/ptrace.c
@@ -1380,7 +1380,11 @@ long syscall_trace_enter(struct pt_regs *regs)
regs->flags |= X86_EFLAGS_TF;
/* do the secure computing check first */
- secure_computing(regs->orig_ax);
+ if (secure_computing(regs->orig_ax)) {
+ /* seccomp failures shouldn't expose any additional code. */
+ ret = -1L;
+ goto out;
+ }
if (unlikely(test_thread_flag(TIF_SYSCALL_EMU)))
ret = -1L;
@@ -1405,6 +1409,7 @@ long syscall_trace_enter(struct pt_regs *regs)
regs->dx, regs->r10);
#endif
+out:
return ret ?: regs->orig_ax;
}
--
1.7.5.4
^ permalink raw reply related
* [PATCH v17 15/15] Documentation: prctl/seccomp_filter
From: Will Drewry @ 2012-03-29 20:02 UTC (permalink / raw)
To: linux-kernel
Cc: linux-security-module, linux-arch, linux-doc, kernel-hardening,
netdev, x86, arnd, davem, hpa, mingo, oleg, peterz, rdunlap,
mcgrathr, tglx, luto, eparis, serge.hallyn, djm, scarybeasts,
indan, pmoore, akpm, corbet, eric.dumazet, markus, coreyb,
keescook, jmorris, Will Drewry
In-Reply-To: <1333051320-30872-1-git-send-email-wad@chromium.org>
Documents how system call filtering using Berkeley Packet
Filter programs works and how it may be used.
Includes an example for x86 and a semi-generic
example using a macro-based code generator.
v17: - remove @compat note and add Pitfalls section for arch checking
(keescook@chromium.org)
- rebase
v14...v16: - rebase/nochanges
v13: - rebase on to 88ebdda6159ffc15699f204c33feb3e431bf9bdc
v12: - comment on the ptrace_event use
- update arch support comment
- note the behavior of SECCOMP_RET_DATA when there are multiple filters
(keescook@chromium.org)
- lots of samples/ clean up incl 64-bit bpf-direct support
(markus@chromium.org)
- rebase to linux-next
v11: - overhaul return value language, updates (keescook@chromium.org)
- comment on do_exit(SIGSYS)
v10: - update for SIGSYS
- update for new seccomp_data layout
- update for ptrace option use
v9: - updated bpf-direct.c for SIGILL
v8: - add PR_SET_NO_NEW_PRIVS to the samples.
v7: - updated for all the new stuff in v7: TRAP, TRACE
- only talk about PR_SET_SECCOMP now
- fixed bad JLE32 check (coreyb@linux.vnet.ibm.com)
- adds dropper.c: a simple system call disabler
v6: - tweak the language to note the requirement of
PR_SET_NO_NEW_PRIVS being called prior to use. (luto@mit.edu)
v5: - update sample to use system call arguments
- adds a "fancy" example using a macro-based generator
- cleaned up bpf in the sample
- update docs to mention arguments
- fix prctl value (eparis@redhat.com)
- language cleanup (rdunlap@xenotime.net)
v4: - update for no_new_privs use
- minor tweaks
v3: - call out BPF <-> Berkeley Packet Filter (rdunlap@xenotime.net)
- document use of tentative always-unprivileged
- guard sample compilation for i386 and x86_64
v2: - move code to samples (corbet@lwn.net)
Signed-off-by: Will Drewry <wad@chromium.org>
---
Documentation/prctl/seccomp_filter.txt | 163 ++++++++++++++++++++++
samples/Makefile | 2 +-
samples/seccomp/Makefile | 38 +++++
samples/seccomp/bpf-direct.c | 176 +++++++++++++++++++++++
samples/seccomp/bpf-fancy.c | 102 ++++++++++++++
samples/seccomp/bpf-helper.c | 89 ++++++++++++
samples/seccomp/bpf-helper.h | 238 ++++++++++++++++++++++++++++++++
samples/seccomp/dropper.c | 68 +++++++++
8 files changed, 875 insertions(+), 1 deletions(-)
create mode 100644 Documentation/prctl/seccomp_filter.txt
create mode 100644 samples/seccomp/Makefile
create mode 100644 samples/seccomp/bpf-direct.c
create mode 100644 samples/seccomp/bpf-fancy.c
create mode 100644 samples/seccomp/bpf-helper.c
create mode 100644 samples/seccomp/bpf-helper.h
create mode 100644 samples/seccomp/dropper.c
diff --git a/Documentation/prctl/seccomp_filter.txt b/Documentation/prctl/seccomp_filter.txt
new file mode 100644
index 0000000..597c3c5
--- /dev/null
+++ b/Documentation/prctl/seccomp_filter.txt
@@ -0,0 +1,163 @@
+ SECure COMPuting with filters
+ =============================
+
+Introduction
+------------
+
+A large number of system calls are exposed to every userland process
+with many of them going unused for the entire lifetime of the process.
+As system calls change and mature, bugs are found and eradicated. A
+certain subset of userland applications benefit by having a reduced set
+of available system calls. The resulting set reduces the total kernel
+surface exposed to the application. System call filtering is meant for
+use with those applications.
+
+Seccomp filtering provides a means for a process to specify a filter for
+incoming system calls. The filter is expressed as a Berkeley Packet
+Filter (BPF) program, as with socket filters, except that the data
+operated on is related to the system call being made: system call
+number and the system call arguments. This allows for expressive
+filtering of system calls using a filter program language with a long
+history of being exposed to userland and a straightforward data set.
+
+Additionally, BPF makes it impossible for users of seccomp to fall prey
+to time-of-check-time-of-use (TOCTOU) attacks that are common in system
+call interposition frameworks. BPF programs may not dereference
+pointers which constrains all filters to solely evaluating the system
+call arguments directly.
+
+What it isn't
+-------------
+
+System call filtering isn't a sandbox. It provides a clearly defined
+mechanism for minimizing the exposed kernel surface. It is meant to be
+a tool for sandbox developers to use. Beyond that, policy for logical
+behavior and information flow should be managed with a combination of
+other system hardening techniques and, potentially, an LSM of your
+choosing. Expressive, dynamic filters provide further options down this
+path (avoiding pathological sizes or selecting which of the multiplexed
+system calls in socketcall() is allowed, for instance) which could be
+construed, incorrectly, as a more complete sandboxing solution.
+
+Usage
+-----
+
+An additional seccomp mode is added and is enabled using the same
+prctl(2) call as the strict seccomp. If the architecture has
+CONFIG_HAVE_ARCH_SECCOMP_FILTER, then filters may be added as below:
+
+PR_SET_SECCOMP:
+ Now takes an additional argument which specifies a new filter
+ using a BPF program.
+ The BPF program will be executed over struct seccomp_data
+ reflecting the system call number, arguments, and other
+ metadata. The BPF program must then return one of the
+ acceptable values to inform the kernel which action should be
+ taken.
+
+ Usage:
+ prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, prog);
+
+ The 'prog' argument is a pointer to a struct sock_fprog which
+ will contain the filter program. If the program is invalid, the
+ call will return -1 and set errno to EINVAL.
+
+ If fork/clone and execve are allowed by @prog, any child
+ processes will be constrained to the same filters and system
+ call ABI as the parent.
+
+ Prior to use, the task must call prctl(PR_SET_NO_NEW_PRIVS, 1) or
+ run with CAP_SYS_ADMIN privileges in its namespace. If these are not
+ true, -EACCES will be returned. This requirement ensures that filter
+ programs cannot be applied to child processes with greater privileges
+ than the task that installed them.
+
+ Additionally, if prctl(2) is allowed by the attached filter,
+ additional filters may be layered on which will increase evaluation
+ time, but allow for further decreasing the attack surface during
+ execution of a process.
+
+The above call returns 0 on success and non-zero on error.
+
+Return values
+-------------
+A seccomp filter may return any of the following values. If multiple
+filters exist, the return value for the evaluation of a given system
+call will always use the highest precedent value. (For example,
+SECCOMP_RET_KILL will always take precedence.)
+
+In precedence order, they are:
+
+SECCOMP_RET_KILL:
+ Results in the task exiting immediately without executing the
+ system call. The exit status of the task (status & 0x7f) will
+ be SIGSYS, not SIGKILL.
+
+SECCOMP_RET_TRAP:
+ Results in the kernel sending a SIGSYS signal to the triggering
+ task without executing the system call. The kernel will
+ rollback the register state to just before the system call
+ entry such that a signal handler in the task will be able to
+ inspect the ucontext_t->uc_mcontext registers and emulate
+ system call success or failure upon return from the signal
+ handler.
+
+ The SECCOMP_RET_DATA portion of the return value will be passed
+ as si_errno.
+
+ SIGSYS triggered by seccomp will have a si_code of SYS_SECCOMP.
+
+SECCOMP_RET_ERRNO:
+ Results in the lower 16-bits of the return value being passed
+ to userland as the errno without executing the system call.
+
+SECCOMP_RET_TRACE:
+ When returned, this value will cause the kernel to attempt to
+ notify a ptrace()-based tracer prior to executing the system
+ call. If there is no tracer present, -ENOSYS is returned to
+ userland and the system call is not executed.
+
+ A tracer will be notified if it requests PTRACE_O_TRACESECCOMP
+ using ptrace(PTRACE_SETOPTIONS). The tracer will be notified
+ of a PTRACE_EVENT_SECCOMP and the SECCOMP_RET_DATA portion of
+ the BPF program return value will be available to the tracer
+ via PTRACE_GETEVENTMSG.
+
+SECCOMP_RET_ALLOW:
+ Results in the system call being executed.
+
+If multiple filters exist, the return value for the evaluation of a
+given system call will always use the highest precedent value.
+
+Precedence is only determined using the SECCOMP_RET_ACTION mask. When
+multiple filters return values of the same precedence, only the
+SECCOMP_RET_DATA from the most recently installed filter will be
+returned.
+
+Pitfalls
+--------
+
+The biggest pitfall to avoid during use is filtering on system call
+number without checking the architecture value. Why? On any
+architecture that supports multiple system call invocation conventions,
+the system call numbers may vary based on the specific invocation. If
+the numbers in the different calling conventions overlap, then checks in
+the filters may be abused. Always check the arch value!
+
+Example
+-------
+
+The samples/seccomp/ directory contains both an x86-specific example
+and a more generic example of a higher level macro interface for BPF
+program generation.
+
+
+
+Adding architecture support
+-----------------------
+
+See arch/Kconfig for the authoritative requirements. In general, if an
+architecture supports both ptrace_event and seccomp, it will be able to
+support seccomp filter with minor fixup: SIGSYS support and seccomp return
+value checking. Then it must just add CONFIG_HAVE_ARCH_SECCOMP_FILTER
+to its arch-specific Kconfig.
diff --git a/samples/Makefile b/samples/Makefile
index 2f75851..5ef08bb 100644
--- a/samples/Makefile
+++ b/samples/Makefile
@@ -1,4 +1,4 @@
# Makefile for Linux samples code
obj-$(CONFIG_SAMPLES) += kobject/ kprobes/ tracepoints/ trace_events/ \
- hw_breakpoint/ kfifo/ kdb/ hidraw/ rpmsg/
+ hw_breakpoint/ kfifo/ kdb/ hidraw/ rpmsg/ seccomp/
diff --git a/samples/seccomp/Makefile b/samples/seccomp/Makefile
new file mode 100644
index 0000000..e8fe0f5
--- /dev/null
+++ b/samples/seccomp/Makefile
@@ -0,0 +1,38 @@
+# kbuild trick to avoid linker error. Can be omitted if a module is built.
+obj- := dummy.o
+
+hostprogs-$(CONFIG_SECCOMP) := bpf-fancy dropper
+bpf-fancy-objs := bpf-fancy.o bpf-helper.o
+
+HOSTCFLAGS_bpf-fancy.o += -I$(objtree)/usr/include
+HOSTCFLAGS_bpf-fancy.o += -idirafter $(objtree)/include
+HOSTCFLAGS_bpf-helper.o += -I$(objtree)/usr/include
+HOSTCFLAGS_bpf-helper.o += -idirafter $(objtree)/include
+
+HOSTCFLAGS_dropper.o += -I$(objtree)/usr/include
+HOSTCFLAGS_dropper.o += -idirafter $(objtree)/include
+dropper-objs := dropper.o
+
+# bpf-direct.c is x86-only.
+ifeq ($(SRCARCH),x86)
+# List of programs to build
+hostprogs-$(CONFIG_SECCOMP) += bpf-direct
+bpf-direct-objs := bpf-direct.o
+endif
+
+HOSTCFLAGS_bpf-direct.o += -I$(objtree)/usr/include
+HOSTCFLAGS_bpf-direct.o += -idirafter $(objtree)/include
+
+# Try to match the kernel target.
+ifeq ($(CONFIG_64BIT),)
+HOSTCFLAGS_bpf-direct.o += -m32
+HOSTCFLAGS_dropper.o += -m32
+HOSTCFLAGS_bpf-helper.o += -m32
+HOSTCFLAGS_bpf-fancy.o += -m32
+HOSTLOADLIBES_bpf-direct += -m32
+HOSTLOADLIBES_bpf-fancy += -m32
+HOSTLOADLIBES_dropper += -m32
+endif
+
+# Tell kbuild to always build the programs
+always := $(hostprogs-y)
diff --git a/samples/seccomp/bpf-direct.c b/samples/seccomp/bpf-direct.c
new file mode 100644
index 0000000..f1567ad
--- /dev/null
+++ b/samples/seccomp/bpf-direct.c
@@ -0,0 +1,176 @@
+/*
+ * Seccomp filter example for x86 (32-bit and 64-bit) with BPF macros
+ *
+ * Copyright (c) 2012 The Chromium OS Authors <chromium-os-dev@chromium.org>
+ * Author: Will Drewry <wad@chromium.org>
+ *
+ * The code may be used by anyone for any purpose,
+ * and can serve as a starting point for developing
+ * applications using prctl(PR_SET_SECCOMP, 2, ...).
+ */
+#define __USE_GNU 1
+#define _GNU_SOURCE 1
+
+#include <linux/types.h>
+#include <linux/filter.h>
+#include <linux/seccomp.h>
+#include <linux/unistd.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stddef.h>
+#include <string.h>
+#include <sys/prctl.h>
+#include <unistd.h>
+
+#define syscall_arg(_n) (offsetof(struct seccomp_data, args[_n]))
+#define syscall_nr (offsetof(struct seccomp_data, nr))
+
+#if defined(__i386__)
+#define REG_RESULT REG_EAX
+#define REG_SYSCALL REG_EAX
+#define REG_ARG0 REG_EBX
+#define REG_ARG1 REG_ECX
+#define REG_ARG2 REG_EDX
+#define REG_ARG3 REG_ESI
+#define REG_ARG4 REG_EDI
+#define REG_ARG5 REG_EBP
+#elif defined(__x86_64__)
+#define REG_RESULT REG_RAX
+#define REG_SYSCALL REG_RAX
+#define REG_ARG0 REG_RDI
+#define REG_ARG1 REG_RSI
+#define REG_ARG2 REG_RDX
+#define REG_ARG3 REG_R10
+#define REG_ARG4 REG_R8
+#define REG_ARG5 REG_R9
+#else
+#error Unsupported platform
+#endif
+
+#ifndef PR_SET_NO_NEW_PRIVS
+#define PR_SET_NO_NEW_PRIVS 36
+#endif
+
+#ifndef SYS_SECCOMP
+#define SYS_SECCOMP 1
+#endif
+
+static void emulator(int nr, siginfo_t *info, void *void_context)
+{
+ ucontext_t *ctx = (ucontext_t *)(void_context);
+ int syscall;
+ char *buf;
+ ssize_t bytes;
+ size_t len;
+ if (info->si_code != SYS_SECCOMP)
+ return;
+ if (!ctx)
+ return;
+ syscall = ctx->uc_mcontext.gregs[REG_SYSCALL];
+ buf = (char *) ctx->uc_mcontext.gregs[REG_ARG1];
+ len = (size_t) ctx->uc_mcontext.gregs[REG_ARG2];
+
+ if (syscall != __NR_write)
+ return;
+ if (ctx->uc_mcontext.gregs[REG_ARG0] != STDERR_FILENO)
+ return;
+ /* Redirect stderr messages to stdout. Doesn't handle EINTR, etc */
+ ctx->uc_mcontext.gregs[REG_RESULT] = -1;
+ if (write(STDOUT_FILENO, "[ERR] ", 6) > 0) {
+ bytes = write(STDOUT_FILENO, buf, len);
+ ctx->uc_mcontext.gregs[REG_RESULT] = bytes;
+ }
+ return;
+}
+
+static int install_emulator(void)
+{
+ struct sigaction act;
+ sigset_t mask;
+ memset(&act, 0, sizeof(act));
+ sigemptyset(&mask);
+ sigaddset(&mask, SIGSYS);
+
+ act.sa_sigaction = &emulator;
+ act.sa_flags = SA_SIGINFO;
+ if (sigaction(SIGSYS, &act, NULL) < 0) {
+ perror("sigaction");
+ return -1;
+ }
+ if (sigprocmask(SIG_UNBLOCK, &mask, NULL)) {
+ perror("sigprocmask");
+ return -1;
+ }
+ return 0;
+}
+
+static int install_filter(void)
+{
+ struct sock_filter filter[] = {
+ /* Grab the system call number */
+ BPF_STMT(BPF_LD+BPF_W+BPF_ABS, syscall_nr),
+ /* Jump table for the allowed syscalls */
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_rt_sigreturn, 0, 1),
+ BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW),
+#ifdef __NR_sigreturn
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_sigreturn, 0, 1),
+ BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW),
+#endif
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_exit_group, 0, 1),
+ BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_exit, 0, 1),
+ BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_read, 1, 0),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_write, 3, 2),
+
+ /* Check that read is only using stdin. */
+ BPF_STMT(BPF_LD+BPF_W+BPF_ABS, syscall_arg(0)),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, STDIN_FILENO, 4, 0),
+ BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_KILL),
+
+ /* Check that write is only using stdout */
+ BPF_STMT(BPF_LD+BPF_W+BPF_ABS, syscall_arg(0)),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, STDOUT_FILENO, 1, 0),
+ /* Trap attempts to write to stderr */
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, STDERR_FILENO, 1, 2),
+
+ BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW),
+ BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_TRAP),
+ BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_KILL),
+ };
+ struct sock_fprog prog = {
+ .len = (unsigned short)(sizeof(filter)/sizeof(filter[0])),
+ .filter = filter,
+ };
+
+ if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {
+ perror("prctl(NO_NEW_PRIVS)");
+ return 1;
+ }
+
+
+ if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog)) {
+ perror("prctl");
+ return 1;
+ }
+ return 0;
+}
+
+#define payload(_c) (_c), sizeof((_c))
+int main(int argc, char **argv)
+{
+ char buf[4096];
+ ssize_t bytes = 0;
+ if (install_emulator())
+ return 1;
+ if (install_filter())
+ return 1;
+ syscall(__NR_write, STDOUT_FILENO,
+ payload("OHAI! WHAT IS YOUR NAME? "));
+ bytes = syscall(__NR_read, STDIN_FILENO, buf, sizeof(buf));
+ syscall(__NR_write, STDOUT_FILENO, payload("HELLO, "));
+ syscall(__NR_write, STDOUT_FILENO, buf, bytes);
+ syscall(__NR_write, STDERR_FILENO,
+ payload("Error message going to STDERR\n"));
+ return 0;
+}
diff --git a/samples/seccomp/bpf-fancy.c b/samples/seccomp/bpf-fancy.c
new file mode 100644
index 0000000..bf1f6b5
--- /dev/null
+++ b/samples/seccomp/bpf-fancy.c
@@ -0,0 +1,102 @@
+/*
+ * Seccomp BPF example using a macro-based generator.
+ *
+ * Copyright (c) 2012 The Chromium OS Authors <chromium-os-dev@chromium.org>
+ * Author: Will Drewry <wad@chromium.org>
+ *
+ * The code may be used by anyone for any purpose,
+ * and can serve as a starting point for developing
+ * applications using prctl(PR_ATTACH_SECCOMP_FILTER).
+ */
+
+#include <linux/filter.h>
+#include <linux/seccomp.h>
+#include <linux/unistd.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/prctl.h>
+#include <unistd.h>
+
+#include "bpf-helper.h"
+
+#ifndef PR_SET_NO_NEW_PRIVS
+#define PR_SET_NO_NEW_PRIVS 36
+#endif
+
+int main(int argc, char **argv)
+{
+ struct bpf_labels l;
+ static const char msg1[] = "Please type something: ";
+ static const char msg2[] = "You typed: ";
+ char buf[256];
+ struct sock_filter filter[] = {
+ /* TODO: LOAD_SYSCALL_NR(arch) and enforce an arch */
+ LOAD_SYSCALL_NR,
+ SYSCALL(__NR_exit, ALLOW),
+ SYSCALL(__NR_exit_group, ALLOW),
+ SYSCALL(__NR_write, JUMP(&l, write_fd)),
+ SYSCALL(__NR_read, JUMP(&l, read)),
+ DENY, /* Don't passthrough into a label */
+
+ LABEL(&l, read),
+ ARG(0),
+ JNE(STDIN_FILENO, DENY),
+ ARG(1),
+ JNE((unsigned long)buf, DENY),
+ ARG(2),
+ JGE(sizeof(buf), DENY),
+ ALLOW,
+
+ LABEL(&l, write_fd),
+ ARG(0),
+ JEQ(STDOUT_FILENO, JUMP(&l, write_buf)),
+ JEQ(STDERR_FILENO, JUMP(&l, write_buf)),
+ DENY,
+
+ LABEL(&l, write_buf),
+ ARG(1),
+ JEQ((unsigned long)msg1, JUMP(&l, msg1_len)),
+ JEQ((unsigned long)msg2, JUMP(&l, msg2_len)),
+ JEQ((unsigned long)buf, JUMP(&l, buf_len)),
+ DENY,
+
+ LABEL(&l, msg1_len),
+ ARG(2),
+ JLT(sizeof(msg1), ALLOW),
+ DENY,
+
+ LABEL(&l, msg2_len),
+ ARG(2),
+ JLT(sizeof(msg2), ALLOW),
+ DENY,
+
+ LABEL(&l, buf_len),
+ ARG(2),
+ JLT(sizeof(buf), ALLOW),
+ DENY,
+ };
+ struct sock_fprog prog = {
+ .filter = filter,
+ .len = (unsigned short)(sizeof(filter)/sizeof(filter[0])),
+ };
+ ssize_t bytes;
+ bpf_resolve_jumps(&l, filter, sizeof(filter)/sizeof(*filter));
+
+ if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {
+ perror("prctl(NO_NEW_PRIVS)");
+ return 1;
+ }
+
+ if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog)) {
+ perror("prctl(SECCOMP)");
+ return 1;
+ }
+ syscall(__NR_write, STDOUT_FILENO, msg1, strlen(msg1));
+ bytes = syscall(__NR_read, STDIN_FILENO, buf, sizeof(buf)-1);
+ bytes = (bytes > 0 ? bytes : 0);
+ syscall(__NR_write, STDERR_FILENO, msg2, strlen(msg2));
+ syscall(__NR_write, STDERR_FILENO, buf, bytes);
+ /* Now get killed */
+ syscall(__NR_write, STDERR_FILENO, msg2, strlen(msg2)+2);
+ return 0;
+}
diff --git a/samples/seccomp/bpf-helper.c b/samples/seccomp/bpf-helper.c
new file mode 100644
index 0000000..579cfe3
--- /dev/null
+++ b/samples/seccomp/bpf-helper.c
@@ -0,0 +1,89 @@
+/*
+ * Seccomp BPF helper functions
+ *
+ * Copyright (c) 2012 The Chromium OS Authors <chromium-os-dev@chromium.org>
+ * Author: Will Drewry <wad@chromium.org>
+ *
+ * The code may be used by anyone for any purpose,
+ * and can serve as a starting point for developing
+ * applications using prctl(PR_ATTACH_SECCOMP_FILTER).
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include "bpf-helper.h"
+
+int bpf_resolve_jumps(struct bpf_labels *labels,
+ struct sock_filter *filter, size_t count)
+{
+ struct sock_filter *begin = filter;
+ __u8 insn = count - 1;
+
+ if (count < 1)
+ return -1;
+ /*
+ * Walk it once, backwards, to build the label table and do fixups.
+ * Since backward jumps are disallowed by BPF, this is easy.
+ */
+ filter += insn;
+ for (; filter >= begin; --insn, --filter) {
+ if (filter->code != (BPF_JMP+BPF_JA))
+ continue;
+ switch ((filter->jt<<8)|filter->jf) {
+ case (JUMP_JT<<8)|JUMP_JF:
+ if (labels->labels[filter->k].location == 0xffffffff) {
+ fprintf(stderr, "Unresolved label: '%s'\n",
+ labels->labels[filter->k].label);
+ return 1;
+ }
+ filter->k = labels->labels[filter->k].location -
+ (insn + 1);
+ filter->jt = 0;
+ filter->jf = 0;
+ continue;
+ case (LABEL_JT<<8)|LABEL_JF:
+ if (labels->labels[filter->k].location != 0xffffffff) {
+ fprintf(stderr, "Duplicate label use: '%s'\n",
+ labels->labels[filter->k].label);
+ return 1;
+ }
+ labels->labels[filter->k].location = insn;
+ filter->k = 0; /* fall through */
+ filter->jt = 0;
+ filter->jf = 0;
+ continue;
+ }
+ }
+ return 0;
+}
+
+/* Simple lookup table for labels. */
+__u32 seccomp_bpf_label(struct bpf_labels *labels, const char *label)
+{
+ struct __bpf_label *begin = labels->labels, *end;
+ int id;
+ if (labels->count == 0) {
+ begin->label = label;
+ begin->location = 0xffffffff;
+ labels->count++;
+ return 0;
+ }
+ end = begin + labels->count;
+ for (id = 0; begin < end; ++begin, ++id) {
+ if (!strcmp(label, begin->label))
+ return id;
+ }
+ begin->label = label;
+ begin->location = 0xffffffff;
+ labels->count++;
+ return id;
+}
+
+void seccomp_bpf_print(struct sock_filter *filter, size_t count)
+{
+ struct sock_filter *end = filter + count;
+ for ( ; filter < end; ++filter)
+ printf("{ code=%u,jt=%u,jf=%u,k=%u },\n",
+ filter->code, filter->jt, filter->jf, filter->k);
+}
diff --git a/samples/seccomp/bpf-helper.h b/samples/seccomp/bpf-helper.h
new file mode 100644
index 0000000..643279d
--- /dev/null
+++ b/samples/seccomp/bpf-helper.h
@@ -0,0 +1,238 @@
+/*
+ * Example wrapper around BPF macros.
+ *
+ * Copyright (c) 2012 The Chromium OS Authors <chromium-os-dev@chromium.org>
+ * Author: Will Drewry <wad@chromium.org>
+ *
+ * The code may be used by anyone for any purpose,
+ * and can serve as a starting point for developing
+ * applications using prctl(PR_SET_SECCOMP, 2, ...).
+ *
+ * No guarantees are provided with respect to the correctness
+ * or functionality of this code.
+ */
+#ifndef __BPF_HELPER_H__
+#define __BPF_HELPER_H__
+
+#include <asm/bitsperlong.h> /* for __BITS_PER_LONG */
+#include <endian.h>
+#include <linux/filter.h>
+#include <linux/seccomp.h> /* for seccomp_data */
+#include <linux/types.h>
+#include <linux/unistd.h>
+#include <stddef.h>
+
+#define BPF_LABELS_MAX 256
+struct bpf_labels {
+ int count;
+ struct __bpf_label {
+ const char *label;
+ __u32 location;
+ } labels[BPF_LABELS_MAX];
+};
+
+int bpf_resolve_jumps(struct bpf_labels *labels,
+ struct sock_filter *filter, size_t count);
+__u32 seccomp_bpf_label(struct bpf_labels *labels, const char *label);
+void seccomp_bpf_print(struct sock_filter *filter, size_t count);
+
+#define JUMP_JT 0xff
+#define JUMP_JF 0xff
+#define LABEL_JT 0xfe
+#define LABEL_JF 0xfe
+
+#define ALLOW \
+ BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW)
+#define DENY \
+ BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_KILL)
+#define JUMP(labels, label) \
+ BPF_JUMP(BPF_JMP+BPF_JA, FIND_LABEL((labels), (label)), \
+ JUMP_JT, JUMP_JF)
+#define LABEL(labels, label) \
+ BPF_JUMP(BPF_JMP+BPF_JA, FIND_LABEL((labels), (label)), \
+ LABEL_JT, LABEL_JF)
+#define SYSCALL(nr, jt) \
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (nr), 0, 1), \
+ jt
+
+/* Lame, but just an example */
+#define FIND_LABEL(labels, label) seccomp_bpf_label((labels), #label)
+
+#define EXPAND(...) __VA_ARGS__
+/* Map all width-sensitive operations */
+#if __BITS_PER_LONG == 32
+
+#define JEQ(x, jt) JEQ32(x, EXPAND(jt))
+#define JNE(x, jt) JNE32(x, EXPAND(jt))
+#define JGT(x, jt) JGT32(x, EXPAND(jt))
+#define JLT(x, jt) JLT32(x, EXPAND(jt))
+#define JGE(x, jt) JGE32(x, EXPAND(jt))
+#define JLE(x, jt) JLE32(x, EXPAND(jt))
+#define JA(x, jt) JA32(x, EXPAND(jt))
+#define ARG(i) ARG_32(i)
+#define LO_ARG(idx) offsetof(struct seccomp_data, args[(idx)])
+
+#elif __BITS_PER_LONG == 64
+
+/* Ensure that we load the logically correct offset. */
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+#define ENDIAN(_lo, _hi) _lo, _hi
+#define LO_ARG(idx) offsetof(struct seccomp_data, args[(idx)])
+#define HI_ARG(idx) offsetof(struct seccomp_data, args[(idx)]) + sizeof(__u32)
+#elif __BYTE_ORDER == __BIG_ENDIAN
+#define ENDIAN(_lo, _hi) _hi, _lo
+#define LO_ARG(idx) offsetof(struct seccomp_data, args[(idx)]) + sizeof(__u32)
+#define HI_ARG(idx) offsetof(struct seccomp_data, args[(idx)])
+#else
+#error "Unknown endianness"
+#endif
+
+union arg64 {
+ struct {
+ __u32 ENDIAN(lo32, hi32);
+ };
+ __u64 u64;
+};
+
+#define JEQ(x, jt) \
+ JEQ64(((union arg64){.u64 = (x)}).lo32, \
+ ((union arg64){.u64 = (x)}).hi32, \
+ EXPAND(jt))
+#define JGT(x, jt) \
+ JGT64(((union arg64){.u64 = (x)}).lo32, \
+ ((union arg64){.u64 = (x)}).hi32, \
+ EXPAND(jt))
+#define JGE(x, jt) \
+ JGE64(((union arg64){.u64 = (x)}).lo32, \
+ ((union arg64){.u64 = (x)}).hi32, \
+ EXPAND(jt))
+#define JNE(x, jt) \
+ JNE64(((union arg64){.u64 = (x)}).lo32, \
+ ((union arg64){.u64 = (x)}).hi32, \
+ EXPAND(jt))
+#define JLT(x, jt) \
+ JLT64(((union arg64){.u64 = (x)}).lo32, \
+ ((union arg64){.u64 = (x)}).hi32, \
+ EXPAND(jt))
+#define JLE(x, jt) \
+ JLE64(((union arg64){.u64 = (x)}).lo32, \
+ ((union arg64){.u64 = (x)}).hi32, \
+ EXPAND(jt))
+
+#define JA(x, jt) \
+ JA64(((union arg64){.u64 = (x)}).lo32, \
+ ((union arg64){.u64 = (x)}).hi32, \
+ EXPAND(jt))
+#define ARG(i) ARG_64(i)
+
+#else
+#error __BITS_PER_LONG value unusable.
+#endif
+
+/* Loads the arg into A */
+#define ARG_32(idx) \
+ BPF_STMT(BPF_LD+BPF_W+BPF_ABS, LO_ARG(idx))
+
+/* Loads hi into A and lo in X */
+#define ARG_64(idx) \
+ BPF_STMT(BPF_LD+BPF_W+BPF_ABS, LO_ARG(idx)), \
+ BPF_STMT(BPF_ST, 0), /* lo -> M[0] */ \
+ BPF_STMT(BPF_LD+BPF_W+BPF_ABS, HI_ARG(idx)), \
+ BPF_STMT(BPF_ST, 1) /* hi -> M[1] */
+
+#define JEQ32(value, jt) \
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (value), 0, 1), \
+ jt
+
+#define JNE32(value, jt) \
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (value), 1, 0), \
+ jt
+
+/* Checks the lo, then swaps to check the hi. A=lo,X=hi */
+#define JEQ64(lo, hi, jt) \
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (hi), 0, 5), \
+ BPF_STMT(BPF_LD+BPF_MEM, 0), /* swap in lo */ \
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (lo), 0, 2), \
+ BPF_STMT(BPF_LD+BPF_MEM, 1), /* passed: swap hi back in */ \
+ jt, \
+ BPF_STMT(BPF_LD+BPF_MEM, 1) /* failed: swap hi back in */
+
+#define JNE64(lo, hi, jt) \
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (hi), 5, 0), \
+ BPF_STMT(BPF_LD+BPF_MEM, 0), /* swap in lo */ \
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (lo), 2, 0), \
+ BPF_STMT(BPF_LD+BPF_MEM, 1), /* passed: swap hi back in */ \
+ jt, \
+ BPF_STMT(BPF_LD+BPF_MEM, 1) /* failed: swap hi back in */
+
+#define JA32(value, jt) \
+ BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, (value), 0, 1), \
+ jt
+
+#define JA64(lo, hi, jt) \
+ BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, (hi), 3, 0), \
+ BPF_STMT(BPF_LD+BPF_MEM, 0), /* swap in lo */ \
+ BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, (lo), 0, 2), \
+ BPF_STMT(BPF_LD+BPF_MEM, 1), /* passed: swap hi back in */ \
+ jt, \
+ BPF_STMT(BPF_LD+BPF_MEM, 1) /* failed: swap hi back in */
+
+#define JGE32(value, jt) \
+ BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, (value), 0, 1), \
+ jt
+
+#define JLT32(value, jt) \
+ BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, (value), 1, 0), \
+ jt
+
+/* Shortcut checking if hi > arg.hi. */
+#define JGE64(lo, hi, jt) \
+ BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, (hi), 4, 0), \
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (hi), 0, 5), \
+ BPF_STMT(BPF_LD+BPF_MEM, 0), /* swap in lo */ \
+ BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, (lo), 0, 2), \
+ BPF_STMT(BPF_LD+BPF_MEM, 1), /* passed: swap hi back in */ \
+ jt, \
+ BPF_STMT(BPF_LD+BPF_MEM, 1) /* failed: swap hi back in */
+
+#define JLT64(lo, hi, jt) \
+ BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, (hi), 0, 4), \
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (hi), 0, 5), \
+ BPF_STMT(BPF_LD+BPF_MEM, 0), /* swap in lo */ \
+ BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, (lo), 2, 0), \
+ BPF_STMT(BPF_LD+BPF_MEM, 1), /* passed: swap hi back in */ \
+ jt, \
+ BPF_STMT(BPF_LD+BPF_MEM, 1) /* failed: swap hi back in */
+
+#define JGT32(value, jt) \
+ BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, (value), 0, 1), \
+ jt
+
+#define JLE32(value, jt) \
+ BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, (value), 1, 0), \
+ jt
+
+/* Check hi > args.hi first, then do the GE checking */
+#define JGT64(lo, hi, jt) \
+ BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, (hi), 4, 0), \
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (hi), 0, 5), \
+ BPF_STMT(BPF_LD+BPF_MEM, 0), /* swap in lo */ \
+ BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, (lo), 0, 2), \
+ BPF_STMT(BPF_LD+BPF_MEM, 1), /* passed: swap hi back in */ \
+ jt, \
+ BPF_STMT(BPF_LD+BPF_MEM, 1) /* failed: swap hi back in */
+
+#define JLE64(lo, hi, jt) \
+ BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, (hi), 6, 0), \
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (hi), 0, 3), \
+ BPF_STMT(BPF_LD+BPF_MEM, 0), /* swap in lo */ \
+ BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, (lo), 2, 0), \
+ BPF_STMT(BPF_LD+BPF_MEM, 1), /* passed: swap hi back in */ \
+ jt, \
+ BPF_STMT(BPF_LD+BPF_MEM, 1) /* failed: swap hi back in */
+
+#define LOAD_SYSCALL_NR \
+ BPF_STMT(BPF_LD+BPF_W+BPF_ABS, \
+ offsetof(struct seccomp_data, nr))
+
+#endif /* __BPF_HELPER_H__ */
diff --git a/samples/seccomp/dropper.c b/samples/seccomp/dropper.c
new file mode 100644
index 0000000..c69c347
--- /dev/null
+++ b/samples/seccomp/dropper.c
@@ -0,0 +1,68 @@
+/*
+ * Naive system call dropper built on seccomp_filter.
+ *
+ * Copyright (c) 2012 The Chromium OS Authors <chromium-os-dev@chromium.org>
+ * Author: Will Drewry <wad@chromium.org>
+ *
+ * The code may be used by anyone for any purpose,
+ * and can serve as a starting point for developing
+ * applications using prctl(PR_SET_SECCOMP, 2, ...).
+ *
+ * When run, returns the specified errno for the specified
+ * system call number against the given architecture.
+ *
+ * Run this one as root as PR_SET_NO_NEW_PRIVS is not called.
+ */
+
+#include <errno.h>
+#include <linux/audit.h>
+#include <linux/filter.h>
+#include <linux/seccomp.h>
+#include <linux/unistd.h>
+#include <stdio.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <sys/prctl.h>
+#include <unistd.h>
+
+static int install_filter(int nr, int arch, int error)
+{
+ struct sock_filter filter[] = {
+ BPF_STMT(BPF_LD+BPF_W+BPF_ABS,
+ (offsetof(struct seccomp_data, arch))),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, arch, 0, 3),
+ BPF_STMT(BPF_LD+BPF_W+BPF_ABS,
+ (offsetof(struct seccomp_data, nr))),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, nr, 0, 1),
+ BPF_STMT(BPF_RET+BPF_K,
+ SECCOMP_RET_ERRNO|(error & SECCOMP_RET_DATA)),
+ BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW),
+ };
+ struct sock_fprog prog = {
+ .len = (unsigned short)(sizeof(filter)/sizeof(filter[0])),
+ .filter = filter,
+ };
+ if (prctl(PR_SET_SECCOMP, 2, &prog)) {
+ perror("prctl");
+ return 1;
+ }
+ return 0;
+}
+
+int main(int argc, char **argv)
+{
+ if (argc < 5) {
+ fprintf(stderr, "Usage:\n"
+ "dropper <syscall_nr> <arch> <errno> <prog> [<args>]\n"
+ "Hint: AUDIT_ARCH_I386: 0x%X\n"
+ " AUDIT_ARCH_X86_64: 0x%X\n"
+ "\n", AUDIT_ARCH_I386, AUDIT_ARCH_X86_64);
+ return 1;
+ }
+ if (install_filter(strtol(argv[1], NULL, 0), strtol(argv[2], NULL, 0),
+ strtol(argv[3], NULL, 0)))
+ return 1;
+ execv(argv[4], &argv[4]);
+ printf("Failed to execv\n");
+ return 255;
+}
--
1.7.5.4
^ permalink raw reply related
* Re: [PATCH V4 8/8] net/mlx4_en: Set max rate-limit for a TC
From: Eric Dumazet @ 2012-03-29 21:04 UTC (permalink / raw)
To: Amir Vadai
Cc: David S. Miller, netdev, Roland Dreier, Yevgeny Petrilin,
Oren Duer, Amir Vadai
In-Reply-To: <4F74A988.1020103@mellanox.com>
Le jeudi 29 mars 2012 à 20:27 +0200, Amir Vadai a écrit :
> I was in a rush to send it on time and missed it (of course I tested
> only tc 0 so didn't see it in my tests too).
> Anyway, will fix it.
Not sure what you mean by "on time".
Take your time, linux wont freeze today nor next week.
^ permalink raw reply
* [PATCH 00/17] mark const init data with __initconst instead of __initdata
From: Uwe Kleine-König @ 2012-03-29 21:11 UTC (permalink / raw)
To: linux-kernel, Andrew Morton
Cc: Andrew Lunn, Christoph Lameter, linux-mips, Tony Lindgren,
Benjamin Herrenschmidt, Linus Walleij, Matt Porter, Nicolas Ferre,
Matthew Garrett, platform-driver-x86, Grant Likely,
ibm-acpi-devel, Randy Dunlap, linux-mtd, Sekhar Nori,
Daniel Walker, lm-sensors, Klaus Kudielka, Guenter Roeck,
Kevin Hilman, linux-ia64, Kukjin Kim, Russell King, Samuel Ortiz
Hello,
this series fixes a common error to use __initdata to mark const
variables. Most of the time this works well enough to go unnoticed
(though I wonder why the linker doesn't warn about that).
Just try adding something like
int something __initdata;
to one of the patched files and compile to see the error.
While touching these annotations I also corrected the position where it
was wrong to go between the variable name and the =.
Note this series is not compile tested.
Best regards
Uwe
--
Pengutronix e.K. | Uwe Kleine-König |
Industrial Linux Solutions | http://www.pengutronix.de/ |
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/
^ permalink raw reply
* [PATCH 05/17] net: mark const init data with __initconst instead of __initdata
From: Uwe Kleine-König @ 2012-03-29 21:12 UTC (permalink / raw)
To: linux-kernel, Andrew Morton
Cc: kernel, Andreas Koensgen, Klaus Kudielka, Joerg Reuter,
Jean-Paul Roubelat, netdev, linux-hams
In-Reply-To: <20120329211131.GA31250@pengutronix.de>
As long as there is no other non-const variable marked __initdata in the
same compilation unit it doesn't hurt. If there were one however
compilation would fail with
error: $variablename causes a section type conflict
because a section containing const variables is marked read only and so
cannot contain non-const variables.
Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Cc: Andreas Koensgen <ajk@comnets.uni-bremen.de>
Cc: Klaus Kudielka <klaus.kudielka@ieee.org>
Cc: Joerg Reuter <jreuter@yaina.de>
Cc: Jean-Paul Roubelat <jpr@f6fbb.org>
Cc: netdev@vger.kernel.org
Cc: linux-hams@vger.kernel.org
---
drivers/net/ethernet/8390/ne3210.c | 2 +-
drivers/net/hamradio/6pack.c | 4 ++--
drivers/net/hamradio/bpqether.c | 2 +-
drivers/net/hamradio/mkiss.c | 4 ++--
drivers/net/hamradio/scc.c | 2 +-
drivers/net/hamradio/yam.c | 2 +-
drivers/net/tokenring/smctr.c | 2 +-
drivers/net/wan/z85230.c | 2 +-
8 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/drivers/net/ethernet/8390/ne3210.c b/drivers/net/ethernet/8390/ne3210.c
index a2f8b2b..f826e74 100644
--- a/drivers/net/ethernet/8390/ne3210.c
+++ b/drivers/net/ethernet/8390/ne3210.c
@@ -81,7 +81,7 @@ static void ne3210_block_output(struct net_device *dev, int count, const unsigne
static unsigned char irq_map[] __initdata = {15, 12, 11, 10, 9, 7, 5, 3};
static unsigned int shmem_map[] __initdata = {0xff0, 0xfe0, 0xfff0, 0xd8, 0xffe0, 0xffc0, 0xd0, 0x0};
-static const char *ifmap[] __initdata = {"UTP", "?", "BNC", "AUI"};
+static const char *ifmap[] __initconst = {"UTP", "?", "BNC", "AUI"};
static int ifmap_val[] __initdata = {
IF_PORT_10BASET,
IF_PORT_UNKNOWN,
diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c
index 64783a0..d225a2a 100644
--- a/drivers/net/hamradio/6pack.c
+++ b/drivers/net/hamradio/6pack.c
@@ -811,9 +811,9 @@ static struct tty_ldisc_ops sp_ldisc = {
/* Initialize 6pack control device -- register 6pack line discipline */
-static const char msg_banner[] __initdata = KERN_INFO \
+static const char msg_banner[] __initconst = KERN_INFO \
"AX.25: 6pack driver, " SIXPACK_VERSION "\n";
-static const char msg_regfail[] __initdata = KERN_ERR \
+static const char msg_regfail[] __initconst = KERN_ERR \
"6pack: can't register line discipline (err = %d)\n";
static int __init sixpack_init_driver(void)
diff --git a/drivers/net/hamradio/bpqether.c b/drivers/net/hamradio/bpqether.c
index 76d5477..c2e5497 100644
--- a/drivers/net/hamradio/bpqether.c
+++ b/drivers/net/hamradio/bpqether.c
@@ -87,7 +87,7 @@
#include <linux/bpqether.h>
-static const char banner[] __initdata = KERN_INFO \
+static const char banner[] __initconst = KERN_INFO \
"AX.25: bpqether driver version 004\n";
static char bcast_addr[6]={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c
index aed1a61..d694215 100644
--- a/drivers/net/hamradio/mkiss.c
+++ b/drivers/net/hamradio/mkiss.c
@@ -997,9 +997,9 @@ static struct tty_ldisc_ops ax_ldisc = {
.write_wakeup = mkiss_write_wakeup
};
-static const char banner[] __initdata = KERN_INFO \
+static const char banner[] __initconst = KERN_INFO \
"mkiss: AX.25 Multikiss, Hans Albas PE1AYX\n";
-static const char msg_regfail[] __initdata = KERN_ERR \
+static const char msg_regfail[] __initconst = KERN_ERR \
"mkiss: can't register line discipline (err = %d)\n";
static int __init mkiss_init_driver(void)
diff --git a/drivers/net/hamradio/scc.c b/drivers/net/hamradio/scc.c
index efc6c97..1b4a47b 100644
--- a/drivers/net/hamradio/scc.c
+++ b/drivers/net/hamradio/scc.c
@@ -182,7 +182,7 @@
#include "z8530.h"
-static const char banner[] __initdata = KERN_INFO \
+static const char banner[] __initconst = KERN_INFO \
"AX.25: Z8530 SCC driver version "VERSION".dl1bke\n";
static void t_dwait(unsigned long);
diff --git a/drivers/net/hamradio/yam.c b/drivers/net/hamradio/yam.c
index 5a6412e..c6645f1 100644
--- a/drivers/net/hamradio/yam.c
+++ b/drivers/net/hamradio/yam.c
@@ -76,7 +76,7 @@
/* --------------------------------------------------------------------- */
static const char yam_drvname[] = "yam";
-static const char yam_drvinfo[] __initdata = KERN_INFO \
+static const char yam_drvinfo[] __initconst = KERN_INFO \
"YAM driver version 0.8 by F1OAT/F6FBB\n";
/* --------------------------------------------------------------------- */
diff --git a/drivers/net/tokenring/smctr.c b/drivers/net/tokenring/smctr.c
index cb35fb7..90b5f1e 100644
--- a/drivers/net/tokenring/smctr.c
+++ b/drivers/net/tokenring/smctr.c
@@ -59,7 +59,7 @@
#include "smctr.h" /* Our Stuff */
-static const char version[] __initdata =
+static const char version[] __initconst =
KERN_INFO "smctr.c: v1.4 7/12/00 by jschlst@samba.org\n";
static const char cardname[] = "smctr";
diff --git a/drivers/net/wan/z85230.c b/drivers/net/wan/z85230.c
index 0e57690..feacc3b 100644
--- a/drivers/net/wan/z85230.c
+++ b/drivers/net/wan/z85230.c
@@ -1775,7 +1775,7 @@ EXPORT_SYMBOL(z8530_queue_xmit);
/*
* Module support
*/
-static const char banner[] __initdata =
+static const char banner[] __initconst =
KERN_INFO "Generic Z85C30/Z85230 interface driver v0.02\n";
static int __init z85230_init_driver(void)
--
1.7.9.1
--
To unsubscribe from this list: send the line "unsubscribe linux-hams" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* Re: 3.2.8/amd64 full interrupt hangs and deadlocks under big network copies (page allocation failure)
From: Marc MERLIN @ 2012-03-29 21:19 UTC (permalink / raw)
To: Ben Hutchings
Cc: linux-wireless-u79uwXL29TY76Z2rM5mHXA,
netdev-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1333044575.2656.1.camel-/LGg1Z1CJKReKY3V0RtoKmatzQS1i7+A3tAM5lWOD0I@public.gmane.org>
On Thu, Mar 29, 2012 at 07:09:35PM +0100, Ben Hutchings wrote:
> On Thu, 2012-03-29 at 09:38 -0700, Marc MERLIN wrote:
> [...]
> > Below are some sysreq dumps I took (syslog to local disk was still
> > working fine). I know I have Tainted 'G', and I have no idea where that
> > came from, sorry :-/
> [...]
>
> 'G' isn't a taint flag, but the following 'O' is; it means you have one
> or more out-of-tree modules loaded. Care to tell us what they are?
All I can think of is virtualbox, but I'm almost certain I did not have
virtualbox loaded (i.e. modules disabled so they wouldn't load) for my first
test with wired ethernet (yes, I know that virtualbox modules are known
for causing problems).
Ah, yes, I had another out of tree module:
http://www.thinkwiki.org/wiki/Tp_smapi
(on thinkpad W500)
Module Size Used by
hdaps 13616 1
tp_smapi 23531 0
thinkpad_ec 12857 2 hdaps,tp_smapi
So, I suppose the next step is to reproduce without those modules loaded,
which I'll do next.
Thanks,
Marc
--
"A mouse is a device used to point at the xterm you want to type in" - A.S.R.
Microsoft is to operating systems ....
.... what McDonalds is to gourmet cooking
Home page: http://marc.merlins.org/
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH V4 8/8] net/mlx4_en: Set max rate-limit for a TC
From: David Miller @ 2012-03-29 21:25 UTC (permalink / raw)
To: amirv; +Cc: eric.dumazet, netdev, roland, yevgenyp, oren, amirv
In-Reply-To: <4F74A988.1020103@mellanox.com>
From: Amir Vadai <amirv@mellanox.com>
Date: Thu, 29 Mar 2012 20:27:20 +0200
> I was in a rush to send it on time and missed it (of course I tested
> only tc 0 so didn't see it in my tests too).
Being in a rush when you expect others to spend time reviewing your
code is an extremely selfish act.
^ permalink raw reply
* Re: [RFC PATCH] macvlan: add FDB bridge ops
From: Roopa Prabhu @ 2012-03-29 21:26 UTC (permalink / raw)
To: John Fastabend, Michael S. Tsirkin; +Cc: netdev
In-Reply-To: <4F733539.9040106@intel.com>
On 3/28/12 8:58 AM, "John Fastabend" <john.r.fastabend@intel.com> wrote:
> On 3/28/2012 8:52 AM, Michael S. Tsirkin wrote:
>> On Wed, Mar 28, 2012 at 08:43:56AM -0700, Roopa Prabhu wrote:
>>> On 3/20/12 5:26 PM, "John Fastabend" <john.r.fastabend@intel.com> wrote:
>>>
>>>> Add support to add/del and dump the forwarding database
>>>> for macvlan passthru mode. The macvlan driver acts like
>>>> a Two Port Mac Relay (TPMR 802.1Q-2011) in the passthru
>>>> case so adding forwarding rules is just adding the addr
>>>> to the uc or mc lists.
>>>>
>>>> By default the passthru mode puts the lowerdev into a
>>>> promiscuous mode to receive all packets. This behavior
>>>> is not changed by this patch. This is a bit problematic
>>>> and needs to be solved without IMHO breaking existing
>>>> mechanics. Maybe on the first add_fdb we can decrement
>>>> the promisc mode? That seems to work reasonable well and
>>>> keep existing functionality in place... but requires
>>>> an initial add to set things up which is a bit annoying
>>>> so maybe a flag is better. I haven't thought too hard
>>>> about it yet so any ideas welcome
>>
>>
>> ...
>>
>>> Thanks John. Looks good.
>>> I added a few things to your patch below. Yes, I think the promisc check is
>>> required. Made an attempt to add a flag below (I did not get a chance to
>>> think about other approaches there too). Briefly tested it with the br
>>> command.
>>>
>>>
>>> diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
>>> index f975afd..9bc70ad 100644
>>> --- a/drivers/net/macvlan.c
>>> +++ b/drivers/net/macvlan.c
>>> @@ -34,6 +34,9 @@
>>>
>>> #define MACVLAN_HASH_SIZE (1 << BITS_PER_BYTE)
>>>
>>> +/* macvlan port flags */
>>> +#define MACVLAN_FLAG_PROMISC 0x1
>>> +
>>> struct macvlan_port {
>>> struct net_device *dev;
>>> struct hlist_head vlan_hash[MACVLAN_HASH_SIZE];
>>> @@ -41,6 +44,7 @@ struct macvlan_port {
>>> struct rcu_head rcu;
>>> bool passthru;
>>> int count;
>>> + unsigned int flags;
>>> };
>>>
>>> static void macvlan_port_destroy(struct net_device *dev);
>>> @@ -313,6 +317,7 @@ static int macvlan_open(struct net_device *dev)
>>>
>>> if (vlan->port->passthru) {
>>> dev_set_promiscuity(lowerdev, 1);
>>> + vlan->port->flags |= MACVLAN_FLAG_PROMISC;
>>> goto hash_add;
>>> }
>>>
>>> @@ -345,10 +350,14 @@ static int macvlan_stop(struct net_device *dev)
>>> struct net_device *lowerdev = vlan->lowerdev;
>>>
>>> if (vlan->port->passthru) {
>>> - dev_set_promiscuity(lowerdev, -1);
>>> + if (vlan->port->flags & MACVLAN_FLAG_PROMISC) {
>>> + dev_set_promiscuity(lowerdev, -1);
>>> + vlan->port->flags &= ~MACVLAN_FLAG_PROMISC;
>>> + }
>>> goto hash_del;
>>> }
>>>
>>> + dev_uc_unsync(lowerdev, dev);
>>> dev_mc_unsync(lowerdev, dev);
>>> if (dev->flags & IFF_ALLMULTI)
>>> dev_set_allmulti(lowerdev, -1);
>>> @@ -403,6 +412,7 @@ static void macvlan_set_multicast_list(struct net_device
>>> *dev)
>>> {
>>> struct macvlan_dev *vlan = netdev_priv(dev);
>>>
>>> + dev_uc_sync(vlan->lowerdev, dev);
>>> dev_mc_sync(vlan->lowerdev, dev);
>>> }
>>>
>>> @@ -542,6 +552,58 @@ static int macvlan_vlan_rx_kill_vid(struct net_device
>>> *dev,
>>> return 0;
>>> }
>>>
>>> +static int macvlan_fdb_add(struct ndmsg *ndm,
>>> + struct net_device *dev,
>>> + unsigned char *addr,
>>> + u16 flags)
>>> +{
>>> + struct macvlan_dev *vlan = netdev_priv(dev);
>>> + struct net_device *lowerdev = vlan->lowerdev;
>>> + const struct net_device_ops *ops = lowerdev->netdev_ops;
>>> + int err = -EINVAL;
>>> +
>>> + if (!vlan->port->passthru)
>>> + return -EOPNOTSUPP;
>>> +
>>> + if (vlan->port->flags & MACVLAN_FLAG_PROMISC) {
>>> + dev_set_promiscuity (lowerdev, -1);
>>> + vlan->port->flags &= ~MACVLAN_FLAG_PROMISC;
>>> + }
>>> +
>>> + if (ops->ndo_fdb_add)
>>> + return ops->ndo_fdb_add(ndm, lowerdev, addr, flags);
>>> +
>>> + if (is_unicast_ether_addr(addr))
>>> + err = dev_uc_add_excl(lowerdev, addr);
>>> + else if (is_multicast_ether_addr(addr))
>>> + err = dev_mc_add(lowerdev, addr);
>>> +
>>> + return err;
>>> +}
>>> +
>>> +static int macvlan_fdb_del(struct ndmsg *ndm,
>>> + struct net_device *dev,
>>> + unsigned char *addr)
>>> +{
>>> + struct macvlan_dev *vlan = netdev_priv(dev);
>>> + struct net_device *lowerdev = vlan->lowerdev;
>>> + const struct net_device_ops *ops = lowerdev->netdev_ops;
>>> + int err = -EINVAL;
>>> +
>>> + if (!vlan->port->passthru)
>>> + return -EOPNOTSUPP;
>>> +
>>> + if (ops->ndo_fdb_del)
>>> + return ops->ndo_fdb_del(ndm, lowerdev, addr);
>>> +
>>> + if (is_unicast_ether_addr(addr))
>>> + err = dev_uc_del(lowerdev, addr);
>>> + else if (is_multicast_ether_addr(addr))
>>> + err = dev_mc_del(lowerdev, addr);
>>> +
>>> + return err;
>>> +}
>>> +
>>> static void macvlan_ethtool_get_drvinfo(struct net_device *dev,
>>> struct ethtool_drvinfo *drvinfo)
>>> {
>>> @@ -577,6 +639,9 @@ static const struct net_device_ops macvlan_netdev_ops =
>>> {
>>> .ndo_validate_addr = eth_validate_addr,
>>> .ndo_vlan_rx_add_vid = macvlan_vlan_rx_add_vid,
>>> .ndo_vlan_rx_kill_vid = macvlan_vlan_rx_kill_vid,
>>> + .ndo_fdb_add = macvlan_fdb_add,
>>> + .ndo_fdb_del = macvlan_fdb_del,
>>> + .ndo_fdb_dump = ndo_dflt_fdb_dump,
>>> };
>>>
>>> void macvlan_common_setup(struct net_device *dev)
>>>
>>
>>
>> So this clears the promisc on the first add which
>> is a bit annoying. How about a simple flag, set when
>> we create the macvlan?
>>
>
> Agreed. This probably needs a new attrib maybe IFLA_MACVLAN_FLAGS unless
> there already exists a per "kind" (rtnl_link_ops) flags field we can use.
> I scanned the code briefly and didn't see any such thing so likely we need
> the new attribute.
O ok. That makes sense. Unfortunately I am not sure if I will be able to get
back to this anytime in the near future. If anyone wants to rework this
patch please do.
Thanks.
Roopa
^ permalink raw reply
* Re: Crash in __netif_receive_skb
From: Avleen Vig @ 2012-03-29 21:42 UTC (permalink / raw)
To: linux-kernel, netdev
In-Reply-To: <CAMjP1KmDxhOKOGtgKt=OWbcXoJgrbA_rAxdkV4j7Y8XC8yjnuA@mail.gmail.com>
On Wed, Mar 28, 2012 at 10:01 PM, Avleen Vig <avleen@gmail.com> wrote:
> On Wed, Mar 28, 2012 at 8:31 PM, Avleen Vig <avleen@gmail.com> wrote:
>> Hi folks, someone in #kernel recommended I email these two lists. Hope
>> they're the right place.
>>
>> We're running 2.6.32-220.4.1.el6.x86_64 on Centos 6.2, and getting a
>> repeated crash:
>> https://gist.github.com/2231998
>>
>> We can make this happen pretty easily just by passing some network
>> traffic and waiting a while.
>> I couldn't find any references to this particular issue.
>> I have vmcore files and am happy to dig into it if it would help (as
>> long as someone can tell me what to do :))
>
> I hope this debugging is legit, I'm really new to this level of insight.
>
> I think the problem is in include/linux/netpoll.h, at the "if"
> statement at line 86:
> static inline int netpoll_receive_skb(struct sk_buff *skb)
> {
> if (!list_empty(&skb->dev->napi_list))
> return netpoll_rx(skb);
> return 0;
> }
>
>
> This is based on poking around in the crash dump:
> BUG: unable to handle kernel NULL pointer dereference at 0000000000000060
> IP: [<ffffffff8142bb40>] __netif_receive_skb+0x60/0x6e0
> crash> dis -rl ffffffff8142bb40
> ....
> /usr/src/debug/kernel-2.6.32-220.7.1.el6/linux-2.6.32-220.7.1.el6.x86_64/include/linux/netpoll.h:
> 86
> 0xffffffff8142bb33 <__netif_receive_skb+83>: mov 0x20(%rbx),%r12
> 0xffffffff8142bb37 <__netif_receive_skb+87>: mov %r12,-0x38(%rbp)
> 0xffffffff8142bb3b <__netif_receive_skb+91>: lea 0x60(%r12),%rax
> 0xffffffff8142bb40 <__netif_receive_skb+96>: cmp %rax,0x60(%r12)
>
>
>
> I *think* this means that "&skb->dev->napi_list" is null when we're
> trying to compare it, rather than being a list.
>
> If it matters, this is inside LXC containers.
We've traced this to a problem with machines that have multiple hard
drives AND have NAPI enabled for the NIC driver.
We recompiled the e1000e driver with NAPI disabled, with:
make CFLAGS_EXTRA=-DE1000E_NO_NAPI
and everything works great now.
^ permalink raw reply
* Re: [PATCH net] bonding: emit event when bonding changes MAC
From: David Miller @ 2012-03-29 22:12 UTC (permalink / raw)
To: fubar; +Cc: wpan, netdev, andy, lwang, linux-kernel
In-Reply-To: <15892.1333041584@death.nxdomain>
From: Jay Vosburgh <fubar@us.ibm.com>
Date: Thu, 29 Mar 2012 10:19:44 -0700
> Weiping Pan <wpan@redhat.com> wrote:
>
>>When a bonding device is configured with fail_over_mac=active,
>>we expect to see the MAC address of the new active slave as the source MAC
>>address after failover. But we see that the source MAC address is the MAC
>>address of previous active slave.
>>
>>Emit NETDEV_CHANGEADDR event when bonding changes its MAC address, in order
>>to let arp_netdev_event flush neighbour cache and route cache.
>>
>>How to reproduce this bug ?
>>
>> -----------hostB----------------
>>hostA ----- switch ---|-- eth0--bond0(192.168.100.2/24)|
>>(192.168.100.1/24 \--|-- eth1-/ |
>> --------------------------------
>>
>>1 on hostB,
>>modprobe bonding mode=1 miimon=500 fail_over_mac=active downdelay=1000
>>num_grat_arp=1
>>ifconfig bond0 192.168.100.2/24 up
>>ifenslave bond0 eth0
>>ifenslave bond0 eth1
>>
>>then eth0 is the active slave, and MAC of bond0 is MAC of eth0.
>>
>>2 on hostA, ping 192.168.100.2
>>
>>3 on hostB,
>>tcpdump -i bond0 -p icmp -XXX
>>you will see bond0 uses MAC of eth0 as source MAC in icmp reply.
>>
>>4 on hostB,
>>ifconfig eth0 down
>>tcpdump -i bond0 -p icmp -XXX (just keep it running in step 3)
>>you will see first bond0 uses MAC of eth1 as source MAC in icmp
>>reply, then it will use MAC of eth0 as source MAC.
>>
>>Signed-off-by: Weiping Pan <wpan@redhat.com>
>
> Signed-off-by: Jay Vosburgh <fubar@us.ibm.com>
Applied, thanks everyone.
^ permalink raw reply
* Re: [PATCH] fix a bug in emitting the 16-bit immediate operand of AND
From: David Miller @ 2012-03-29 22:13 UTC (permalink / raw)
To: eric.dumazet; +Cc: zhuangfeiran, netdev, linux-kernel
In-Reply-To: <1333021525.3402.22.camel@edumazet-laptop>
From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Thu, 29 Mar 2012 13:45:25 +0200
> Le jeudi 29 mars 2012 à 17:27 +0800, zhuangfeiran@ict.ac.cn a écrit :
>> When K >= 0xFFFF0000, AND needs the two least significant bytes of K as
>> its operand, but EMIT2() gives it the least significant byte of K and
>> 0x2. EMIT() should be used here to replace EMIT2().
>>
>> Signed-off-by: Feiran Zhuang <zhuangfeiran@ict.ac.cn>
>> ---
>> arch/x86/net/bpf_jit_comp.c | 2 +-
>> 1 files changed, 1 insertions(+), 1 deletions(-)
>>
>> diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c
>> index 5671752..5a5b6e4 100644
>> --- a/arch/x86/net/bpf_jit_comp.c
>> +++ b/arch/x86/net/bpf_jit_comp.c
>> @@ -289,7 +289,7 @@ void bpf_jit_compile(struct sk_filter *fp)
>> EMIT2(0x24, K & 0xFF); /* and imm8,%al */
>> } else if (K >= 0xFFFF0000) {
>> EMIT2(0x66, 0x25); /* and imm16,%ax */
>> - EMIT2(K, 2);
>> + EMIT(K, 2);
>> } else {
>> EMIT1_off32(0x25, K); /* and imm32,%eax */
>> }
>
> Good catch, thanks !
>
> Acked-by: Eric Dumazet <eric.dumazet@gmail.com>
Applied.
^ permalink raw reply
* [PATCH v4] e1000: Support RX-ALL flag.
From: greearb @ 2012-03-29 22:47 UTC (permalink / raw)
To: netdev; +Cc: jeffrey.t.kirsher, Ben Greear
From: Ben Greear <greearb@candelatech.com>
This allows the NIC to receive errored frames (bad FCS, etc)
and pass them up the stack. This can be useful when using
sniffers.
Signed-off-by: Ben Greear <greearb@candelatech.com>
---
:100644 100644 a680ee6... ab2f748... M drivers/net/ethernet/intel/e1000/e1000_main.c
drivers/net/ethernet/intel/e1000/e1000_main.c | 22 ++++++++++++++++++++--
1 files changed, 20 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/intel/e1000/e1000_main.c b/drivers/net/ethernet/intel/e1000/e1000_main.c
index a680ee6..ab2f748 100644
--- a/drivers/net/ethernet/intel/e1000/e1000_main.c
+++ b/drivers/net/ethernet/intel/e1000/e1000_main.c
@@ -826,9 +826,10 @@ static int e1000_set_features(struct net_device *netdev,
if (changed & NETIF_F_HW_VLAN_RX)
e1000_vlan_mode(netdev, features);
- if (!(changed & NETIF_F_RXCSUM))
+ if (!(changed & (NETIF_F_RXCSUM | NETIF_F_RXALL)))
return 0;
+ netdev->features = features;
adapter->rx_csum = !!(features & NETIF_F_RXCSUM);
if (netif_running(netdev))
@@ -1074,6 +1075,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
netdev->features |= netdev->hw_features;
netdev->hw_features |= NETIF_F_RXCSUM;
netdev->hw_features |= NETIF_F_RXFCS;
+ netdev->hw_features |= NETIF_F_RXALL;
if (pci_using_dac) {
netdev->features |= NETIF_F_HIGHDMA;
@@ -1807,7 +1809,7 @@ static void e1000_setup_rctl(struct e1000_adapter *adapter)
rctl &= ~(3 << E1000_RCTL_MO_SHIFT);
rctl |= E1000_RCTL_BAM | E1000_RCTL_LBM_NO |
- E1000_RCTL_RDMTS_HALF |
+ E1000_RCTL_RDMTS_HALF | E1000_RCTL_DPF |
(hw->mc_filter_type << E1000_RCTL_MO_SHIFT);
if (hw->tbi_compatibility_on == 1)
@@ -1840,6 +1842,16 @@ static void e1000_setup_rctl(struct e1000_adapter *adapter)
break;
}
+ /* This is useful for sniffing bad packets. */
+ if (adapter->netdev->features & NETIF_F_RXALL) {
+ /* UPE and MPE will be handled by normal PROMISC logic
+ * in e1000e_set_rx_mode */
+ rctl |= (E1000_RCTL_SBP | /* Receive bad packets */
+ E1000_RCTL_PMCF); /* RX All MAC Ctrl Pkts */
+
+ rctl &= ~(E1000_RCTL_DPF); /* Allow filtered pause */
+ }
+
ew32(RCTL, rctl);
}
@@ -3845,6 +3857,8 @@ static bool e1000_clean_jumbo_rx_irq(struct e1000_adapter *adapter,
irq_flags);
length--;
} else {
+ if (netdev->features & NETIF_F_RXALL)
+ goto process_skb;
/* recycle both page and skb */
buffer_info->skb = skb;
/* an error means any chain goes out the window
@@ -3857,6 +3871,7 @@ static bool e1000_clean_jumbo_rx_irq(struct e1000_adapter *adapter,
}
#define rxtop rx_ring->rx_skb_top
+process_skb:
if (!(status & E1000_RXD_STAT_EOP)) {
/* this descriptor is only the beginning (or middle) */
if (!rxtop) {
@@ -4066,12 +4081,15 @@ static bool e1000_clean_rx_irq(struct e1000_adapter *adapter,
flags);
length--;
} else {
+ if (netdev->features & NETIF_F_RXALL)
+ goto process_skb;
/* recycle */
buffer_info->skb = skb;
goto next_desc;
}
}
+process_skb:
total_rx_bytes += (length - 4); /* don't count FCS */
total_rx_packets++;
--
1.7.3.4
^ permalink raw reply related
* [PATCH] net: Report dev->promiscuity in netlink reports.
From: greearb @ 2012-03-29 22:51 UTC (permalink / raw)
To: netdev; +Cc: Ben Greear
From: Ben Greear <greearb@candelatech.com>
The standard ways of probing a device's promiscuity
(ifi_flags, for instance) does not report the actual
state of the device. This patch adds dev->promiscuity
to the netlink netdevice report so that users can know
for certain if the device is acting PROMISC or not.
Signed-off-by: Ben Greear <greearb@candelatech.com>
---
:100644 100644 4b24ff4... 2f4fa93... M include/linux/if_link.h
:100644 100644 f965dce... 6f4983f... M net/core/rtnetlink.c
include/linux/if_link.h | 2 ++
net/core/rtnetlink.c | 3 +++
2 files changed, 5 insertions(+), 0 deletions(-)
diff --git a/include/linux/if_link.h b/include/linux/if_link.h
index 4b24ff4..2f4fa93 100644
--- a/include/linux/if_link.h
+++ b/include/linux/if_link.h
@@ -138,6 +138,8 @@ enum {
IFLA_GROUP, /* Group the device belongs to */
IFLA_NET_NS_FD,
IFLA_EXT_MASK, /* Extended info mask, VFs, etc */
+ IFLA_PROMISCUITY, /* Promiscuity count: > 0 means acts PROMISC */
+#define IFLA_PROMISCUITY IFLA_PROMISCUITY
__IFLA_MAX
};
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index f965dce..6f4983f 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -783,6 +783,7 @@ static noinline size_t if_nlmsg_size(const struct net_device *dev,
+ nla_total_size(4) /* IFLA_MTU */
+ nla_total_size(4) /* IFLA_LINK */
+ nla_total_size(4) /* IFLA_MASTER */
+ + nla_total_size(4) /* IFLA_PROMISCUITY */
+ nla_total_size(1) /* IFLA_OPERSTATE */
+ nla_total_size(1) /* IFLA_LINKMODE */
+ nla_total_size(ext_filter_mask
@@ -899,6 +900,7 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
NLA_PUT_U8(skb, IFLA_LINKMODE, dev->link_mode);
NLA_PUT_U32(skb, IFLA_MTU, dev->mtu);
NLA_PUT_U32(skb, IFLA_GROUP, dev->group);
+ NLA_PUT_U32(skb, IFLA_PROMISCUITY, dev->promiscuity);
if (dev->ifindex != dev->iflink)
NLA_PUT_U32(skb, IFLA_LINK, dev->iflink);
@@ -1114,6 +1116,7 @@ const struct nla_policy ifla_policy[IFLA_MAX+1] = {
[IFLA_PORT_SELF] = { .type = NLA_NESTED },
[IFLA_AF_SPEC] = { .type = NLA_NESTED },
[IFLA_EXT_MASK] = { .type = NLA_U32 },
+ [IFLA_PROMISCUITY] = { .type = NLA_U32 },
};
EXPORT_SYMBOL(ifla_policy);
--
1.7.3.4
^ permalink raw reply related
* RE: [PATCH net V4 2/2] igb: offer a PTP Hardware Clock instead of the timecompare method
From: Keller, Jacob E @ 2012-03-29 23:08 UTC (permalink / raw)
To: chetan loke
Cc: Richard Cochran, netdev@vger.kernel.org,
e1000-devel@lists.sourceforge.net, Kirsher, Jeffrey T,
Ronciak, John, john.stultz@linaro.org, tglx@linutronix.de
In-Reply-To: <CAAsGZS75TStwzTsRnpMGMqPy=h1AoV5uKyguXa92LvAsG4BXOQ@mail.gmail.com>
> -----Original Message-----
> From: chetan loke [mailto:loke.chetan@gmail.com]
> Sent: Tuesday, March 27, 2012 2:55 PM
> To: Keller, Jacob E
> Cc: Richard Cochran; netdev@vger.kernel.org; e1000-
> devel@lists.sourceforge.net; Kirsher, Jeffrey T; Ronciak, John;
> john.stultz@linaro.org; tglx@linutronix.de
> Subject: Re: [PATCH net V4 2/2] igb: offer a PTP Hardware Clock instead of the
> timecompare method
>
> On Tue, Mar 27, 2012 at 4:58 PM, Keller, Jacob E <jacob.e.keller@intel.com>
> wrote:
>
> >
> > I think we could see contention regardless because the spinlock doesn't
> guarantee the ordering of who gets it next.
> >
> > I am not sure. But I will try and set something like this up. However, I do
> think that many get-set calls is pretty high for even a 'highly' loaded
> system. Though the buggy app for sure is possible.
> >
> > Here is what I am thinking as a test case. Linuxptp running normally with a
> higher sync rate than once per second, plus a 'buggy' app which will try to
> infinitely thread the gettime calls. I hope to have something like this
> working soon.
> >
>
> Agreed, we don't know who would grab the lock next. But with just one
> app/process we may not be able to induce the contention because process
> scheduling would come into play. A single process would only get that much
> time slice. With multiple processes, you will be able to schedule them on
> multiple CPUs and hence contend with the driver's completion path because that
> is what a real-exploit would do.
>
> make sure numactl is installed on your system. Within a shell script, launch
> multiple instances of the process as follows:
>
> #!/bin/bash
>
> num_cpus=`cat /proc/cpuinfo |grep -i processor |wc -l`
>
> for ((i=0; i<$num_cpus; i++))
> do
> echo "Launching instance:$(($i+1))"
> numa_cmd="numactl --physcpubind=$i /path/to/buggy-app &"
> echo "executing numa-cmd:$numa_cmd"
> eval $numa_cmd
> done
>
>
> > - Jake
>
> Chetan
I performed this test on my machine. Even with a buggy app that calls clock_gettime
inside a while loop, this does not produce any contention whatsoever with
time stamping. I checked the timestamps returned also, and it appears to be running
more than 20k times a second.
Based on the following factors I do not believe this is an issue:
1) A user requires root to use the ioctl. (Or root user has to grant the user access, which isn't necessary for normal ptp functionality).
2) A root user can already trash the system, therefore we cannot consider this an
exploit as it isn't a method to gain root access or halt a system under a normal
user.
3) A program operating at such a high ioctl rate is flawed design which is not
expected. PTP users should already understand the ioctl has more latency than a
PPS setup.
4) Even running 48 processes (2 per CPU) with a while loop repeatedly calling
clock_gettime, zero contention was observed. The times returned have about a
50us delay between them. This translates to somewhere in the ballpark of 20k
calls per second. This has no effect on network traffic (I can still ssh/ping
over that interface) and has no impact on dropping timestamps of packets. Using
large amounts of traffic is not valid because that is already a known constraint
on ptp. (Too much traffic, especially ptp traffic) results in dropped timestamps
because of the way the hardware stores timestamps for packets in the registers)
If you are not satisfied with this, please provide evidence of a failed test case.
^ permalink raw reply
* Re: [PATCH v17 00/15] seccomp_filter: BPF-based syscall filtering
From: James Morris @ 2012-03-29 23:11 UTC (permalink / raw)
To: Will Drewry
Cc: linux-kernel, linux-security-module, linux-arch, linux-doc,
kernel-hardening, netdev, x86, arnd, davem, hpa, mingo, oleg,
peterz, rdunlap, mcgrathr, tglx, luto, eparis, serge.hallyn, djm,
scarybeasts, indan, pmoore, akpm, corbet, eric.dumazet, markus,
coreyb, keescook
In-Reply-To: <1333051320-30872-1-git-send-email-wad@chromium.org>
On Thu, 29 Mar 2012, Will Drewry wrote:
> Please see prior revisions for a detailed discussion of this patch
> series.
>
> This series is a rebase on to:
> b5174fa3a7f4f8f150bfa3b917c92608953dfa0f
> with very minor changes due to rebasing and tweaks noticed by a few
> initial users. (I will rebase again for v3.4-rc1 when that time comes.)
I've offered to take this via my tree -- if anyone else wants to merge it
via theirs instead, holler.
--
James Morris
<jmorris@namei.org>
^ permalink raw reply
* Re: [BUGFIX][PATCH 2/3] memcg/tcp: remove static_branch_slow_dec() at changing limit
From: KAMEZAWA Hiroyuki @ 2012-03-29 23:51 UTC (permalink / raw)
To: Glauber Costa; +Cc: netdev, David Miller, Andrew Morton
In-Reply-To: <4F744038.1000900@parallels.com>
(2012/03/29 19:58), Glauber Costa wrote:
> On 03/29/2012 09:07 AM, KAMEZAWA Hiroyuki wrote:
>> tcp memcontrol uses static_branch to optimize limit=RESOURCE_MAX case.
>> If all cgroup's limit=RESOUCE_MAX, resource usage is not accounted.
>> But it's buggy now.
>>
>> For example, do following
>> # while sleep 1;do
>> echo 9223372036854775807> /cgroup/memory/A/memory.kmem.tcp.limit_in_bytes;
>> echo 300M> /cgroup/memory/A/memory.kmem.tcp.limit_in_bytes;
>> done
>>
>> and run network application under A. tcp's usage is sometimes accounted
>> and sometimes not accounted because of frequent changes of static_branch.
>> Then, finally, you can see broken tcp.usage_in_bytes.
>> WARN_ON() is printed because res_counter->usage goes below 0.
>> ==
>> kernel: ------------[ cut here ]----------
>> kernel: WARNING: at kernel/res_counter.c:96 res_counter_uncharge_locked+0x37/0x40()
>> <snip>
>> kernel: Pid: 17753, comm: bash Tainted: G W 3.3.0+ #99
>> kernel: Call Trace:
>> kernel:<IRQ> [<ffffffff8104cc9f>] warn_slowpath_common+0x7f/0xc0
>> kernel: [<ffffffff810d7e88>] ? rb_reserve__next_event+0x68/0x470
>> kernel: [<ffffffff8104ccfa>] warn_slowpath_null+0x1a/0x20
>> kernel: [<ffffffff810b4e37>] res_counter_uncharge_locked+0x37/0x40
>> ...
>> ==
>>
>> This patch removes static_branch_slow_dec() at changing res_counter's
>> limit to RESOUCE_MAX. By this, once accounting started, the accountting
>> will continue until the tcp cgroup is destroyed.
>>
>> I think this will not be problem in real use.
>>
>
> So...
>
> Are the warnings still there if you have your other patch in this series?
I wrote patch 3/3 after 2/3 because I found all case cannot be fixed by this.
So, comparing patch 3/3 this fixes is leaking.
Considering following sequence
enable accounting
tcp allocate buffer
disable accounting
tcp free buffer
The accounted usage nerver disappear. This is the probelem which cannot be
covered by patch 3/3. Maybe it's better to change order of patches 3/3 -> 2/3
and describe this explicitly.
> Maybe what we should do is, flush the resource counters so they go back
> to 0 besides decrementing the static branch. This way we get a more
> consistent behavior.
>
set all memcg's usage to be 0 at enable/disable accounting ?
But, there is a problem which static_branch() update is slow. So,
IIUC, we can't catch all cases because of races.
> Another thing to keep in mind, is that the static branch will only be
> inactive if we turn off *all* controllers. You see this happening
> because you are only testing with one.
yes. So, the behavior change by this patch will not affect usual cases.
> So even if we go to the route you're proposing, we could probably try
> doing something on the
> global level, instead of a per-memcg boolean flat.
In global level, static_key's counter handles it.
Thanks,
-Kame
^ permalink raw reply
* Re: [PATCH v4] e1000: Support RX-ALL flag.
From: Jeff Kirsher @ 2012-03-30 0:56 UTC (permalink / raw)
To: greearb; +Cc: netdev
In-Reply-To: <1333061270-4379-1-git-send-email-greearb@candelatech.com>
[-- Attachment #1: Type: text/plain, Size: 783 bytes --]
On Thu, 2012-03-29 at 15:47 -0700, greearb@candelatech.com wrote:
>
> From: Ben Greear <greearb@candelatech.com>
>
> This allows the NIC to receive errored frames (bad FCS, etc)
> and pass them up the stack. This can be useful when using
> sniffers.
>
> Signed-off-by: Ben Greear <greearb@candelatech.com>
> ---
> :100644 100644 a680ee6... ab2f748...
> M drivers/net/ethernet/intel/e1000/e1000_main.c
> drivers/net/ethernet/intel/e1000/e1000_main.c | 22
> ++++++++++++++++++++--
> 1 files changed, 20 insertions(+), 2 deletions(-)
FYI- I was just about to push this upstream :) Thanks Ben!
This is the same patch Aaron has tested in-house.
Tested-by: Aaron Brown <aaron.f.brown@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply
* Re: [RFC PATCH] macvlan: add FDB bridge ops
From: John Fastabend @ 2012-03-30 1:06 UTC (permalink / raw)
To: Roopa Prabhu; +Cc: Michael S. Tsirkin, netdev
In-Reply-To: <CB9A2187.4A989%roprabhu@cisco.com>
On 3/29/2012 2:26 PM, Roopa Prabhu wrote:
>
>
>
> On 3/28/12 8:58 AM, "John Fastabend" <john.r.fastabend@intel.com> wrote:
>
>> On 3/28/2012 8:52 AM, Michael S. Tsirkin wrote:
>>> On Wed, Mar 28, 2012 at 08:43:56AM -0700, Roopa Prabhu wrote:
>>>> On 3/20/12 5:26 PM, "John Fastabend" <john.r.fastabend@intel.com> wrote:
>>>>
>>>>> Add support to add/del and dump the forwarding database
>>>>> for macvlan passthru mode. The macvlan driver acts like
>>>>> a Two Port Mac Relay (TPMR 802.1Q-2011) in the passthru
>>>>> case so adding forwarding rules is just adding the addr
>>>>> to the uc or mc lists.
>>>>>
[...]
>>>
>>>
>>> So this clears the promisc on the first add which
>>> is a bit annoying. How about a simple flag, set when
>>> we create the macvlan?
>>>
>>
>> Agreed. This probably needs a new attrib maybe IFLA_MACVLAN_FLAGS unless
>> there already exists a per "kind" (rtnl_link_ops) flags field we can use.
>> I scanned the code briefly and didn't see any such thing so likely we need
>> the new attribute.
>
> O ok. That makes sense. Unfortunately I am not sure if I will be able to get
> back to this anytime in the near future. If anyone wants to rework this
> patch please do.
>
> Thanks.
> Roopa
>
>
OK I'll fix it up and submit it with the rest of the FDB
patches.
.John
^ permalink raw reply
* [PATCH] memcg/tcp: fix warning caused b res->usage go to negative.
From: KAMEZAWA Hiroyuki @ 2012-03-30 1:44 UTC (permalink / raw)
To: Glauber Costa; +Cc: netdev, David Miller, Andrew Morton
In-Reply-To: <4F742983.1080402@parallels.com>
Maybe what we can do before lsf/mm summit will be this (avoid warning.)
This patch is onto linus's git tree. Patch description is updated.
Thanks.
-Kame
==
>From 4ab80f84bbcb02a790342426c1de84aeb17fcbe9 Mon Sep 17 00:00:00 2001
From: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Date: Thu, 29 Mar 2012 14:59:04 +0900
Subject: [PATCH] memcg/tcp: fix warning caused b res->usage go to negative.
tcp memcontrol starts accouting after res->limit is set. So, if a sockets
starts before setting res->limit, there are already used resource.
At setting res->limit, accounting starts. The resource will be uncharged
and make res_counter below 0 because they are not charged.
This causes warning.
==
kernel: ------------[ cut here ]----------
kernel: WARNING: at kernel/res_counter.c:96 res_counter_uncharge_locked+0x37/0x40()
<snip>
kernel: Pid: 17753, comm: bash Tainted: G W 3.3.0+ #99
kernel: Call Trace:
kernel: <IRQ> [<ffffffff8104cc9f>] warn_slowpath_common+0x7f/0xc0
kernel: [<ffffffff810d7e88>] ? rb_reserve__next_event+0x68/0x470
kernel: [<ffffffff8104ccfa>] warn_slowpath_null+0x1a/0x20
kernel: [<ffffffff810b4e37>] res_counter_uncharge_locked+0x37/0x40
...
==
This patch fixes that by adding res_counter_uncharge_nowarn()
and hide the wrong accounting.
The reason for this fix is :
- For avoid overheads, we don't account tcp usage by a cgroup before
setting limit. So, we cannot know the amount of possible error when
we start accounting. If we have this on/off switch for performance,
this cannot be avoidable.
Consideration:
- As memcg, if some marking to resources as PCG_USED could be used..
...we don't have problems. But it adds overhead.
TODO:
- When enable/disable tcp accounting frequently, we'll see usage accounting
leak. This should be fixed. (still under discussion.)
- sockets_allocated has the same trouble. But it has no warning and never
shows negative value even if it's negative.
Changelog:
- updated patch description.
Acked-by: Glauber Costa <glommer@parallels.com>
Signed-off-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
---
include/linux/res_counter.h | 2 ++
include/net/sock.h | 3 ++-
kernel/res_counter.c | 18 ++++++++++++++++++
3 files changed, 22 insertions(+), 1 deletions(-)
diff --git a/include/linux/res_counter.h b/include/linux/res_counter.h
index da81af0..e081948 100644
--- a/include/linux/res_counter.h
+++ b/include/linux/res_counter.h
@@ -134,6 +134,8 @@ int __must_check res_counter_charge_nofail(struct res_counter *counter,
void res_counter_uncharge_locked(struct res_counter *counter, unsigned long val);
void res_counter_uncharge(struct res_counter *counter, unsigned long val);
+void res_counter_uncharge_nowarn(struct res_counter *counter,
+ unsigned long val);
/**
* res_counter_margin - calculate chargeable space of a counter
diff --git a/include/net/sock.h b/include/net/sock.h
index a6ba1f8..a1b3f4802 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -1048,7 +1048,8 @@ static inline void memcg_memory_allocated_add(struct cg_proto *prot,
static inline void memcg_memory_allocated_sub(struct cg_proto *prot,
unsigned long amt)
{
- res_counter_uncharge(prot->memory_allocated, amt << PAGE_SHIFT);
+ res_counter_uncharge_nowarn(prot->memory_allocated,
+ amt << PAGE_SHIFT);
}
static inline u64 memcg_memory_allocated_read(struct cg_proto *prot)
diff --git a/kernel/res_counter.c b/kernel/res_counter.c
index d508363..2bb01ac 100644
--- a/kernel/res_counter.c
+++ b/kernel/res_counter.c
@@ -113,6 +113,24 @@ void res_counter_uncharge(struct res_counter *counter, unsigned long val)
local_irq_restore(flags);
}
+void res_counter_uncharge_nowarn(struct res_counter *counter,
+ unsigned long val)
+{
+ struct res_counter *c;
+ unsigned long flags;
+
+ local_irq_save(flags);
+
+ for (c = counter; c != NULL; c = c->parent) {
+ spin_lock(&c->lock);
+ if (c->usage < val)
+ val = c->usage;
+ res_counter_uncharge_locked(c, val);
+ spin_unlock(&c->lock);
+ }
+ local_irq_restore(flags);
+}
+
static inline unsigned long long *
res_counter_member(struct res_counter *counter, int member)
--
1.7.4.1
^ permalink raw reply related
* Re: [PATCH v4] e1000: Support RX-ALL flag.
From: Ben Greear @ 2012-03-30 1:56 UTC (permalink / raw)
To: jeffrey.t.kirsher; +Cc: netdev
In-Reply-To: <1333068960.2622.72.camel@jtkirshe-mobl>
On 03/29/2012 05:56 PM, Jeff Kirsher wrote:
> On Thu, 2012-03-29 at 15:47 -0700, greearb@candelatech.com wrote:
>>
>> From: Ben Greear<greearb@candelatech.com>
>>
>> This allows the NIC to receive errored frames (bad FCS, etc)
>> and pass them up the stack. This can be useful when using
>> sniffers.
>>
>> Signed-off-by: Ben Greear<greearb@candelatech.com>
>> ---
>> :100644 100644 a680ee6... ab2f748...
>> M drivers/net/ethernet/intel/e1000/e1000_main.c
>> drivers/net/ethernet/intel/e1000/e1000_main.c | 22
>> ++++++++++++++++++++--
>> 1 files changed, 20 insertions(+), 2 deletions(-)
>
> FYI- I was just about to push this upstream :) Thanks Ben!
>
> This is the same patch Aaron has tested in-house.
Sounds good.
From what I recall, igb is missing rx-fcs (and it may not be possible to
support the feature..chipset seems to act weird), but I think that takes care
of the rest of the 10/100/1000 Intel NICs.
I'll see if I can add some support for ixgbe when I get a chance. That would
take care of all the NICs I normally use I think...
Thanks,
Ben
--
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc http://www.candelatech.com
^ permalink raw reply
* [PATCH] net: sh_eth: fix endian check for architecture independent
From: Shimoda, Yoshihiro @ 2012-03-30 5:32 UTC (permalink / raw)
To: netdev; +Cc: SH-Linux
SuperH has the "CONFIG_CPU_LITTLE_ENDIAN" and the "__LITTLE_ENDIAN__".
But, other architecture doesn't have them. So, this patch fixes it.
Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
---
drivers/net/ethernet/renesas/sh_eth.c | 2 +-
drivers/net/ethernet/renesas/sh_eth.h | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c
index 8bdf070..d63e09b 100644
--- a/drivers/net/ethernet/renesas/sh_eth.c
+++ b/drivers/net/ethernet/renesas/sh_eth.c
@@ -804,7 +804,7 @@ static int sh_eth_dev_init(struct net_device *ndev)
/* all sh_eth int mask */
sh_eth_write(ndev, 0, EESIPR);
-#if defined(__LITTLE_ENDIAN__)
+#if defined(__LITTLE_ENDIAN)
if (mdp->cd->hw_swap)
sh_eth_write(ndev, EDMR_EL, EDMR);
else
diff --git a/drivers/net/ethernet/renesas/sh_eth.h b/drivers/net/ethernet/renesas/sh_eth.h
index e66de18..0fa14af 100644
--- a/drivers/net/ethernet/renesas/sh_eth.h
+++ b/drivers/net/ethernet/renesas/sh_eth.h
@@ -693,7 +693,7 @@ enum TSU_FWSLC_BIT {
*/
struct sh_eth_txdesc {
u32 status; /* TD0 */
-#if defined(CONFIG_CPU_LITTLE_ENDIAN)
+#if defined(__LITTLE_ENDIAN)
u16 pad0; /* TD1 */
u16 buffer_length; /* TD1 */
#else
@@ -710,7 +710,7 @@ struct sh_eth_txdesc {
*/
struct sh_eth_rxdesc {
u32 status; /* RD0 */
-#if defined(CONFIG_CPU_LITTLE_ENDIAN)
+#if defined(__LITTLE_ENDIAN)
u16 frame_length; /* RD1 */
u16 buffer_length; /* RD1 */
#else
--
1.7.1
^ permalink raw reply related
* Re: [BUGFIX][PATCH 2/3] memcg/tcp: remove static_branch_slow_dec() at changing limit
From: Glauber Costa @ 2012-03-30 6:18 UTC (permalink / raw)
To: KAMEZAWA Hiroyuki; +Cc: netdev, David Miller, Andrew Morton
In-Reply-To: <4F74F57C.4030001@jp.fujitsu.com>
On 03/30/2012 01:51 AM, KAMEZAWA Hiroyuki wrote:
> (2012/03/29 19:58), Glauber Costa wrote:
>
>> On 03/29/2012 09:07 AM, KAMEZAWA Hiroyuki wrote:
>>> tcp memcontrol uses static_branch to optimize limit=RESOURCE_MAX case.
>>> If all cgroup's limit=RESOUCE_MAX, resource usage is not accounted.
>>> But it's buggy now.
>>>
>>> For example, do following
>>> # while sleep 1;do
>>> echo 9223372036854775807> /cgroup/memory/A/memory.kmem.tcp.limit_in_bytes;
>>> echo 300M> /cgroup/memory/A/memory.kmem.tcp.limit_in_bytes;
>>> done
>>>
>>> and run network application under A. tcp's usage is sometimes accounted
>>> and sometimes not accounted because of frequent changes of static_branch.
>>> Then, finally, you can see broken tcp.usage_in_bytes.
>>> WARN_ON() is printed because res_counter->usage goes below 0.
>>> ==
>>> kernel: ------------[ cut here ]----------
>>> kernel: WARNING: at kernel/res_counter.c:96 res_counter_uncharge_locked+0x37/0x40()
>>> <snip>
>>> kernel: Pid: 17753, comm: bash Tainted: G W 3.3.0+ #99
>>> kernel: Call Trace:
>>> kernel:<IRQ> [<ffffffff8104cc9f>] warn_slowpath_common+0x7f/0xc0
>>> kernel: [<ffffffff810d7e88>] ? rb_reserve__next_event+0x68/0x470
>>> kernel: [<ffffffff8104ccfa>] warn_slowpath_null+0x1a/0x20
>>> kernel: [<ffffffff810b4e37>] res_counter_uncharge_locked+0x37/0x40
>>> ...
>>> ==
>>>
>>> This patch removes static_branch_slow_dec() at changing res_counter's
>>> limit to RESOUCE_MAX. By this, once accounting started, the accountting
>>> will continue until the tcp cgroup is destroyed.
>>>
>>> I think this will not be problem in real use.
>>>
>>
>> So...
>>
>> Are the warnings still there if you have your other patch in this series?
>
>
> I wrote patch 3/3 after 2/3 because I found all case cannot be fixed by this.
>
> So, comparing patch 3/3 this fixes is leaking.
> Considering following sequence
>
> enable accounting
> tcp allocate buffer
> disable accounting
> tcp free buffer
>
> The accounted usage nerver disappear. This is the probelem which cannot be
> covered by patch 3/3. Maybe it's better to change order of patches 3/3 -> 2/3
> and describe this explicitly.
>
>> Maybe what we should do is, flush the resource counters so they go back
>> to 0 besides decrementing the static branch. This way we get a more
>> consistent behavior.
>>
>
> set all memcg's usage to be 0 at enable/disable accounting ?
> But, there is a problem which static_branch() update is slow. So,
> IIUC, we can't catch all cases because of races.
>
>
>> Another thing to keep in mind, is that the static branch will only be
>> inactive if we turn off *all* controllers. You see this happening
>> because you are only testing with one.
>
> yes. So, the behavior change by this patch will not affect usual cases.
>
>> So even if we go to the route you're proposing, we could probably try
>> doing something on the
>> global level, instead of a per-memcg boolean flat.
>
> In global level, static_key's counter handles it.
>
I gave it a bit more thought through the night... and I guess your
solution is okay.
^ permalink raw reply
* [PATCH net-next v3 1/5] r8169: modify pll power function
From: Hayes Wang @ 2012-03-30 6:33 UTC (permalink / raw)
To: romieu; +Cc: netdev, linux-kernel, Hayes Wang
Adjust r810x_pll_power_down, r810x_pll_power_up, and r8168_pll_power_up.
Always power up device during rtl_open. For r810x, turn off more power
when the WOL is disabled.
Signed-off-by: Hayes Wang <hayeswang@realtek.com>
---
drivers/net/ethernet/realtek/r8169.c | 37 +++++++++++++++++++++++++++------
1 files changed, 30 insertions(+), 7 deletions(-)
diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c
index 27c358c..3edb996 100644
--- a/drivers/net/ethernet/realtek/r8169.c
+++ b/drivers/net/ethernet/realtek/r8169.c
@@ -3508,15 +3508,45 @@ static void r810x_phy_power_up(struct rtl8169_private *tp)
static void r810x_pll_power_down(struct rtl8169_private *tp)
{
+ void __iomem *ioaddr = tp->mmio_addr;
+
if (rtl_wol_pll_power_down(tp))
return;
r810x_phy_power_down(tp);
+
+ switch (tp->mac_version) {
+ case RTL_GIGA_MAC_VER_07:
+ case RTL_GIGA_MAC_VER_08:
+ case RTL_GIGA_MAC_VER_09:
+ case RTL_GIGA_MAC_VER_10:
+ case RTL_GIGA_MAC_VER_13:
+ case RTL_GIGA_MAC_VER_16:
+ break;
+ default:
+ RTL_W8(PMCH, RTL_R8(PMCH) & ~0x80);
+ break;
+ }
}
static void r810x_pll_power_up(struct rtl8169_private *tp)
{
+ void __iomem *ioaddr = tp->mmio_addr;
+
r810x_phy_power_up(tp);
+
+ switch (tp->mac_version) {
+ case RTL_GIGA_MAC_VER_07:
+ case RTL_GIGA_MAC_VER_08:
+ case RTL_GIGA_MAC_VER_09:
+ case RTL_GIGA_MAC_VER_10:
+ case RTL_GIGA_MAC_VER_13:
+ case RTL_GIGA_MAC_VER_16:
+ break;
+ default:
+ RTL_W8(PMCH, RTL_R8(PMCH) | 0x80);
+ break;
+ }
}
static void r8168_phy_power_up(struct rtl8169_private *tp)
@@ -3620,13 +3650,6 @@ static void r8168_pll_power_up(struct rtl8169_private *tp)
{
void __iomem *ioaddr = tp->mmio_addr;
- if ((tp->mac_version == RTL_GIGA_MAC_VER_27 ||
- tp->mac_version == RTL_GIGA_MAC_VER_28 ||
- tp->mac_version == RTL_GIGA_MAC_VER_31) &&
- r8168dp_check_dash(tp)) {
- return;
- }
-
switch (tp->mac_version) {
case RTL_GIGA_MAC_VER_25:
case RTL_GIGA_MAC_VER_26:
--
1.7.7.6
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox