Merge git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next

Alexei Starovoitov says:

====================
pull-request: bpf-next 2020-05-01 (v2)

The following pull-request contains BPF updates for your *net-next* tree.

We've added 61 non-merge commits during the last 6 day(s) which contain
a total of 153 files changed, 6739 insertions(+), 3367 deletions(-).

The main changes are:

1) pulled work.sysctl from vfs tree with sysctl bpf changes.

2) bpf_link observability, from Andrii.

3) BTF-defined map in map, from Andrii.

4) asan fixes for selftests, from Andrii.

5) Allow bpf_map_lookup_elem for SOCKMAP and SOCKHASH, from Jakub.

6) production cloudflare classifier as a selftes, from Lorenz.

7) bpf_ktime_get_*_ns() helper improvements, from Maciej.

8) unprivileged bpftool feature probe, from Quentin.

9) BPF_ENABLE_STATS command, from Song.

10) enable bpf_[gs]etsockopt() helpers for sock_ops progs, from Stanislav.

11) enable a bunch of common helpers for cg-device, sysctl, sockopt progs,
 from Stanislav.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
David S. Miller 2020-05-01 17:02:27 -07:00
commit 115506fea4
153 changed files with 6401 additions and 3029 deletions

View File

@ -203,7 +203,7 @@ static void __init register_insn_emulation(struct insn_emulation_ops *ops)
} }
static int emulation_proc_handler(struct ctl_table *table, int write, static int emulation_proc_handler(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, void *buffer, size_t *lenp,
loff_t *ppos) loff_t *ppos)
{ {
int ret = 0; int ret = 0;

View File

@ -341,8 +341,7 @@ static unsigned int find_supported_vector_length(unsigned int vl)
#ifdef CONFIG_SYSCTL #ifdef CONFIG_SYSCTL
static int sve_proc_do_default_vl(struct ctl_table *table, int write, static int sve_proc_do_default_vl(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, void *buffer, size_t *lenp, loff_t *ppos)
loff_t *ppos)
{ {
int ret; int ret;
int vl = sve_default_vl; int vl = sve_default_vl;

View File

@ -95,16 +95,15 @@ int proc_lasat_ip(struct ctl_table *table, int write,
len = 0; len = 0;
p = buffer; p = buffer;
while (len < *lenp) { while (len < *lenp) {
if (get_user(c, p++)) c = *p;
return -EFAULT; p++;
if (c == 0 || c == '\n') if (c == 0 || c == '\n')
break; break;
len++; len++;
} }
if (len >= sizeof(ipbuf)-1) if (len >= sizeof(ipbuf)-1)
len = sizeof(ipbuf) - 1; len = sizeof(ipbuf) - 1;
if (copy_from_user(ipbuf, buffer, len)) memcpy(ipbuf, buffer, len);
return -EFAULT;
ipbuf[len] = 0; ipbuf[len] = 0;
*ppos += *lenp; *ppos += *lenp;
/* Now see if we can convert it to a valid IP */ /* Now see if we can convert it to a valid IP */
@ -122,11 +121,9 @@ int proc_lasat_ip(struct ctl_table *table, int write,
if (len > *lenp) if (len > *lenp)
len = *lenp; len = *lenp;
if (len) if (len)
if (copy_to_user(buffer, ipbuf, len)) memcpy(buffer, ipbuf, len);
return -EFAULT;
if (len < *lenp) { if (len < *lenp) {
if (put_user('\n', ((char *) buffer) + len)) *((char *)buffer + len) = '\n';
return -EFAULT;
len++; len++;
} }
*lenp = len; *lenp = len;

View File

@ -13,8 +13,35 @@
#include <linux/filter.h> #include <linux/filter.h>
#include "bpf_jit.h" #include "bpf_jit.h"
/*
* Stack layout during BPF program execution:
*
* high
* RV32 fp => +----------+
* | saved ra |
* | saved fp | RV32 callee-saved registers
* | ... |
* +----------+ <= (fp - 4 * NR_SAVED_REGISTERS)
* | hi(R6) |
* | lo(R6) |
* | hi(R7) | JIT scratch space for BPF registers
* | lo(R7) |
* | ... |
* BPF_REG_FP => +----------+ <= (fp - 4 * NR_SAVED_REGISTERS
* | | - 4 * BPF_JIT_SCRATCH_REGS)
* | |
* | ... | BPF program stack
* | |
* RV32 sp => +----------+
* | |
* | ... | Function call stack
* | |
* +----------+
* low
*/
enum { enum {
/* Stack layout - these are offsets from (top of stack - 4). */ /* Stack layout - these are offsets from top of JIT scratch space. */
BPF_R6_HI, BPF_R6_HI,
BPF_R6_LO, BPF_R6_LO,
BPF_R7_HI, BPF_R7_HI,
@ -29,7 +56,11 @@ enum {
BPF_JIT_SCRATCH_REGS, BPF_JIT_SCRATCH_REGS,
}; };
#define STACK_OFFSET(k) (-4 - ((k) * 4)) /* Number of callee-saved registers stored to stack: ra, fp, s1--s7. */
#define NR_SAVED_REGISTERS 9
/* Offset from fp for BPF registers stored on stack. */
#define STACK_OFFSET(k) (-4 - (4 * NR_SAVED_REGISTERS) - (4 * (k)))
#define TMP_REG_1 (MAX_BPF_JIT_REG + 0) #define TMP_REG_1 (MAX_BPF_JIT_REG + 0)
#define TMP_REG_2 (MAX_BPF_JIT_REG + 1) #define TMP_REG_2 (MAX_BPF_JIT_REG + 1)
@ -111,11 +142,9 @@ static void emit_imm64(const s8 *rd, s32 imm_hi, s32 imm_lo,
static void __build_epilogue(bool is_tail_call, struct rv_jit_context *ctx) static void __build_epilogue(bool is_tail_call, struct rv_jit_context *ctx)
{ {
int stack_adjust = ctx->stack_size, store_offset = stack_adjust - 4; int stack_adjust = ctx->stack_size;
const s8 *r0 = bpf2rv32[BPF_REG_0]; const s8 *r0 = bpf2rv32[BPF_REG_0];
store_offset -= 4 * BPF_JIT_SCRATCH_REGS;
/* Set return value if not tail call. */ /* Set return value if not tail call. */
if (!is_tail_call) { if (!is_tail_call) {
emit(rv_addi(RV_REG_A0, lo(r0), 0), ctx); emit(rv_addi(RV_REG_A0, lo(r0), 0), ctx);
@ -123,15 +152,15 @@ static void __build_epilogue(bool is_tail_call, struct rv_jit_context *ctx)
} }
/* Restore callee-saved registers. */ /* Restore callee-saved registers. */
emit(rv_lw(RV_REG_RA, store_offset - 0, RV_REG_SP), ctx); emit(rv_lw(RV_REG_RA, stack_adjust - 4, RV_REG_SP), ctx);
emit(rv_lw(RV_REG_FP, store_offset - 4, RV_REG_SP), ctx); emit(rv_lw(RV_REG_FP, stack_adjust - 8, RV_REG_SP), ctx);
emit(rv_lw(RV_REG_S1, store_offset - 8, RV_REG_SP), ctx); emit(rv_lw(RV_REG_S1, stack_adjust - 12, RV_REG_SP), ctx);
emit(rv_lw(RV_REG_S2, store_offset - 12, RV_REG_SP), ctx); emit(rv_lw(RV_REG_S2, stack_adjust - 16, RV_REG_SP), ctx);
emit(rv_lw(RV_REG_S3, store_offset - 16, RV_REG_SP), ctx); emit(rv_lw(RV_REG_S3, stack_adjust - 20, RV_REG_SP), ctx);
emit(rv_lw(RV_REG_S4, store_offset - 20, RV_REG_SP), ctx); emit(rv_lw(RV_REG_S4, stack_adjust - 24, RV_REG_SP), ctx);
emit(rv_lw(RV_REG_S5, store_offset - 24, RV_REG_SP), ctx); emit(rv_lw(RV_REG_S5, stack_adjust - 28, RV_REG_SP), ctx);
emit(rv_lw(RV_REG_S6, store_offset - 28, RV_REG_SP), ctx); emit(rv_lw(RV_REG_S6, stack_adjust - 32, RV_REG_SP), ctx);
emit(rv_lw(RV_REG_S7, store_offset - 32, RV_REG_SP), ctx); emit(rv_lw(RV_REG_S7, stack_adjust - 36, RV_REG_SP), ctx);
emit(rv_addi(RV_REG_SP, RV_REG_SP, stack_adjust), ctx); emit(rv_addi(RV_REG_SP, RV_REG_SP, stack_adjust), ctx);
@ -770,12 +799,13 @@ static int emit_bpf_tail_call(int insn, struct rv_jit_context *ctx)
emit_bcc(BPF_JGE, lo(idx_reg), RV_REG_T1, off, ctx); emit_bcc(BPF_JGE, lo(idx_reg), RV_REG_T1, off, ctx);
/* /*
* if ((temp_tcc = tcc - 1) < 0) * temp_tcc = tcc - 1;
* if (tcc < 0)
* goto out; * goto out;
*/ */
emit(rv_addi(RV_REG_T1, RV_REG_TCC, -1), ctx); emit(rv_addi(RV_REG_T1, RV_REG_TCC, -1), ctx);
off = (tc_ninsn - (ctx->ninsns - start_insn)) << 2; off = (tc_ninsn - (ctx->ninsns - start_insn)) << 2;
emit_bcc(BPF_JSLT, RV_REG_T1, RV_REG_ZERO, off, ctx); emit_bcc(BPF_JSLT, RV_REG_TCC, RV_REG_ZERO, off, ctx);
/* /*
* prog = array->ptrs[index]; * prog = array->ptrs[index];
@ -1259,17 +1289,20 @@ notsupported:
void bpf_jit_build_prologue(struct rv_jit_context *ctx) void bpf_jit_build_prologue(struct rv_jit_context *ctx)
{ {
/* Make space to save 9 registers: ra, fp, s1--s7. */
int stack_adjust = 9 * sizeof(u32), store_offset, bpf_stack_adjust;
const s8 *fp = bpf2rv32[BPF_REG_FP]; const s8 *fp = bpf2rv32[BPF_REG_FP];
const s8 *r1 = bpf2rv32[BPF_REG_1]; const s8 *r1 = bpf2rv32[BPF_REG_1];
int stack_adjust = 0;
int bpf_stack_adjust =
round_up(ctx->prog->aux->stack_depth, STACK_ALIGN);
bpf_stack_adjust = round_up(ctx->prog->aux->stack_depth, 16); /* Make space for callee-saved registers. */
stack_adjust += NR_SAVED_REGISTERS * sizeof(u32);
/* Make space for BPF registers on stack. */
stack_adjust += BPF_JIT_SCRATCH_REGS * sizeof(u32);
/* Make space for BPF stack. */
stack_adjust += bpf_stack_adjust; stack_adjust += bpf_stack_adjust;
/* Round up for stack alignment. */
store_offset = stack_adjust - 4; stack_adjust = round_up(stack_adjust, STACK_ALIGN);
stack_adjust += 4 * BPF_JIT_SCRATCH_REGS;
/* /*
* The first instruction sets the tail-call-counter (TCC) register. * The first instruction sets the tail-call-counter (TCC) register.
@ -1280,24 +1313,24 @@ void bpf_jit_build_prologue(struct rv_jit_context *ctx)
emit(rv_addi(RV_REG_SP, RV_REG_SP, -stack_adjust), ctx); emit(rv_addi(RV_REG_SP, RV_REG_SP, -stack_adjust), ctx);
/* Save callee-save registers. */ /* Save callee-save registers. */
emit(rv_sw(RV_REG_SP, store_offset - 0, RV_REG_RA), ctx); emit(rv_sw(RV_REG_SP, stack_adjust - 4, RV_REG_RA), ctx);
emit(rv_sw(RV_REG_SP, store_offset - 4, RV_REG_FP), ctx); emit(rv_sw(RV_REG_SP, stack_adjust - 8, RV_REG_FP), ctx);
emit(rv_sw(RV_REG_SP, store_offset - 8, RV_REG_S1), ctx); emit(rv_sw(RV_REG_SP, stack_adjust - 12, RV_REG_S1), ctx);
emit(rv_sw(RV_REG_SP, store_offset - 12, RV_REG_S2), ctx); emit(rv_sw(RV_REG_SP, stack_adjust - 16, RV_REG_S2), ctx);
emit(rv_sw(RV_REG_SP, store_offset - 16, RV_REG_S3), ctx); emit(rv_sw(RV_REG_SP, stack_adjust - 20, RV_REG_S3), ctx);
emit(rv_sw(RV_REG_SP, store_offset - 20, RV_REG_S4), ctx); emit(rv_sw(RV_REG_SP, stack_adjust - 24, RV_REG_S4), ctx);
emit(rv_sw(RV_REG_SP, store_offset - 24, RV_REG_S5), ctx); emit(rv_sw(RV_REG_SP, stack_adjust - 28, RV_REG_S5), ctx);
emit(rv_sw(RV_REG_SP, store_offset - 28, RV_REG_S6), ctx); emit(rv_sw(RV_REG_SP, stack_adjust - 32, RV_REG_S6), ctx);
emit(rv_sw(RV_REG_SP, store_offset - 32, RV_REG_S7), ctx); emit(rv_sw(RV_REG_SP, stack_adjust - 36, RV_REG_S7), ctx);
/* Set fp: used as the base address for stacked BPF registers. */ /* Set fp: used as the base address for stacked BPF registers. */
emit(rv_addi(RV_REG_FP, RV_REG_SP, stack_adjust), ctx); emit(rv_addi(RV_REG_FP, RV_REG_SP, stack_adjust), ctx);
/* Set up BPF stack pointer. */ /* Set up BPF frame pointer. */
emit(rv_addi(lo(fp), RV_REG_SP, bpf_stack_adjust), ctx); emit(rv_addi(lo(fp), RV_REG_SP, bpf_stack_adjust), ctx);
emit(rv_addi(hi(fp), RV_REG_ZERO, 0), ctx); emit(rv_addi(hi(fp), RV_REG_ZERO, 0), ctx);
/* Set up context pointer. */ /* Set up BPF context pointer. */
emit(rv_addi(lo(r1), RV_REG_A0, 0), ctx); emit(rv_addi(lo(r1), RV_REG_A0, 0), ctx);
emit(rv_addi(hi(r1), RV_REG_ZERO, 0), ctx); emit(rv_addi(hi(r1), RV_REG_ZERO, 0), ctx);

View File

@ -51,10 +51,9 @@ static struct platform_device *appldata_pdev;
*/ */
static const char appldata_proc_name[APPLDATA_PROC_NAME_LENGTH] = "appldata"; static const char appldata_proc_name[APPLDATA_PROC_NAME_LENGTH] = "appldata";
static int appldata_timer_handler(struct ctl_table *ctl, int write, static int appldata_timer_handler(struct ctl_table *ctl, int write,
void __user *buffer, size_t *lenp, loff_t *ppos); void *buffer, size_t *lenp, loff_t *ppos);
static int appldata_interval_handler(struct ctl_table *ctl, int write, static int appldata_interval_handler(struct ctl_table *ctl, int write,
void __user *buffer, void *buffer, size_t *lenp, loff_t *ppos);
size_t *lenp, loff_t *ppos);
static struct ctl_table_header *appldata_sysctl_header; static struct ctl_table_header *appldata_sysctl_header;
static struct ctl_table appldata_table[] = { static struct ctl_table appldata_table[] = {
@ -217,7 +216,7 @@ static void __appldata_vtimer_setup(int cmd)
*/ */
static int static int
appldata_timer_handler(struct ctl_table *ctl, int write, appldata_timer_handler(struct ctl_table *ctl, int write,
void __user *buffer, size_t *lenp, loff_t *ppos) void *buffer, size_t *lenp, loff_t *ppos)
{ {
int timer_active = appldata_timer_active; int timer_active = appldata_timer_active;
int rc; int rc;
@ -250,7 +249,7 @@ appldata_timer_handler(struct ctl_table *ctl, int write,
*/ */
static int static int
appldata_interval_handler(struct ctl_table *ctl, int write, appldata_interval_handler(struct ctl_table *ctl, int write,
void __user *buffer, size_t *lenp, loff_t *ppos) void *buffer, size_t *lenp, loff_t *ppos)
{ {
int interval = appldata_interval; int interval = appldata_interval;
int rc; int rc;
@ -280,7 +279,7 @@ appldata_interval_handler(struct ctl_table *ctl, int write,
*/ */
static int static int
appldata_generic_handler(struct ctl_table *ctl, int write, appldata_generic_handler(struct ctl_table *ctl, int write,
void __user *buffer, size_t *lenp, loff_t *ppos) void *buffer, size_t *lenp, loff_t *ppos)
{ {
struct appldata_ops *ops = NULL, *tmp_ops; struct appldata_ops *ops = NULL, *tmp_ops;
struct list_head *lh; struct list_head *lh;

View File

@ -867,7 +867,7 @@ static int debug_active = 1;
* if debug_active is already off * if debug_active is already off
*/ */
static int s390dbf_procactive(struct ctl_table *table, int write, static int s390dbf_procactive(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos) void *buffer, size_t *lenp, loff_t *ppos)
{ {
if (!write || debug_stoppable || !debug_active) if (!write || debug_stoppable || !debug_active)
return proc_dointvec(table, write, buffer, lenp, ppos); return proc_dointvec(table, write, buffer, lenp, ppos);

View File

@ -594,7 +594,7 @@ static int __init topology_setup(char *str)
early_param("topology", topology_setup); early_param("topology", topology_setup);
static int topology_ctl_handler(struct ctl_table *ctl, int write, static int topology_ctl_handler(struct ctl_table *ctl, int write,
void __user *buffer, size_t *lenp, loff_t *ppos) void *buffer, size_t *lenp, loff_t *ppos)
{ {
int enabled = topology_is_enabled(); int enabled = topology_is_enabled();
int new_mode; int new_mode;

View File

@ -245,7 +245,7 @@ static int cmm_skip_blanks(char *cp, char **endp)
} }
static int cmm_pages_handler(struct ctl_table *ctl, int write, static int cmm_pages_handler(struct ctl_table *ctl, int write,
void __user *buffer, size_t *lenp, loff_t *ppos) void *buffer, size_t *lenp, loff_t *ppos)
{ {
long nr = cmm_get_pages(); long nr = cmm_get_pages();
struct ctl_table ctl_entry = { struct ctl_table ctl_entry = {
@ -264,7 +264,7 @@ static int cmm_pages_handler(struct ctl_table *ctl, int write,
} }
static int cmm_timed_pages_handler(struct ctl_table *ctl, int write, static int cmm_timed_pages_handler(struct ctl_table *ctl, int write,
void __user *buffer, size_t *lenp, void *buffer, size_t *lenp,
loff_t *ppos) loff_t *ppos)
{ {
long nr = cmm_get_timed_pages(); long nr = cmm_get_timed_pages();
@ -284,7 +284,7 @@ static int cmm_timed_pages_handler(struct ctl_table *ctl, int write,
} }
static int cmm_timeout_handler(struct ctl_table *ctl, int write, static int cmm_timeout_handler(struct ctl_table *ctl, int write,
void __user *buffer, size_t *lenp, loff_t *ppos) void *buffer, size_t *lenp, loff_t *ppos)
{ {
char buf[64], *p; char buf[64], *p;
long nr, seconds; long nr, seconds;
@ -297,8 +297,7 @@ static int cmm_timeout_handler(struct ctl_table *ctl, int write,
if (write) { if (write) {
len = min(*lenp, sizeof(buf)); len = min(*lenp, sizeof(buf));
if (copy_from_user(buf, buffer, len)) memcpy(buf, buffer, len);
return -EFAULT;
buf[len - 1] = '\0'; buf[len - 1] = '\0';
cmm_skip_blanks(buf, &p); cmm_skip_blanks(buf, &p);
nr = simple_strtoul(p, &p, 0); nr = simple_strtoul(p, &p, 0);
@ -311,8 +310,7 @@ static int cmm_timeout_handler(struct ctl_table *ctl, int write,
cmm_timeout_pages, cmm_timeout_seconds); cmm_timeout_pages, cmm_timeout_seconds);
if (len > *lenp) if (len > *lenp)
len = *lenp; len = *lenp;
if (copy_to_user(buffer, buf, len)) memcpy(buffer, buf, len);
return -EFAULT;
*lenp = len; *lenp = len;
*ppos += len; *ppos += len;
} }

View File

@ -39,8 +39,7 @@ static bool __read_mostly sched_itmt_capable;
unsigned int __read_mostly sysctl_sched_itmt_enabled; unsigned int __read_mostly sysctl_sched_itmt_enabled;
static int sched_itmt_update_handler(struct ctl_table *table, int write, static int sched_itmt_update_handler(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, void *buffer, size_t *lenp, loff_t *ppos)
loff_t *ppos)
{ {
unsigned int old_sysctl; unsigned int old_sysctl;
int ret; int ret;

View File

@ -3631,7 +3631,7 @@ static void cdrom_update_settings(void)
} }
static int cdrom_sysctl_handler(struct ctl_table *ctl, int write, static int cdrom_sysctl_handler(struct ctl_table *ctl, int write,
void __user *buffer, size_t *lenp, loff_t *ppos) void *buffer, size_t *lenp, loff_t *ppos)
{ {
int ret; int ret;

View File

@ -2057,7 +2057,7 @@ static char sysctl_bootid[16];
* sysctl system call, as 16 bytes of binary data. * sysctl system call, as 16 bytes of binary data.
*/ */
static int proc_do_uuid(struct ctl_table *table, int write, static int proc_do_uuid(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos) void *buffer, size_t *lenp, loff_t *ppos)
{ {
struct ctl_table fake_table; struct ctl_table fake_table;
unsigned char buf[64], tmp_uuid[16], *uuid; unsigned char buf[64], tmp_uuid[16], *uuid;

View File

@ -183,8 +183,7 @@ static void mac_hid_stop_emulation(void)
} }
static int mac_hid_toggle_emumouse(struct ctl_table *table, int write, static int mac_hid_toggle_emumouse(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, void *buffer, size_t *lenp, loff_t *ppos)
loff_t *ppos)
{ {
int *valp = table->data; int *valp = table->data;
int old_val = *valp; int old_val = *valp;

View File

@ -103,6 +103,8 @@ lirc_mode2_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
return &bpf_map_peek_elem_proto; return &bpf_map_peek_elem_proto;
case BPF_FUNC_ktime_get_ns: case BPF_FUNC_ktime_get_ns:
return &bpf_ktime_get_ns_proto; return &bpf_ktime_get_ns_proto;
case BPF_FUNC_ktime_get_boot_ns:
return &bpf_ktime_get_boot_ns_proto;
case BPF_FUNC_tail_call: case BPF_FUNC_tail_call:
return &bpf_tail_call_proto; return &bpf_tail_call_proto;
case BPF_FUNC_get_prandom_u32: case BPF_FUNC_get_prandom_u32:

View File

@ -34,7 +34,7 @@
#define PARPORT_MAX_SPINTIME_VALUE 1000 #define PARPORT_MAX_SPINTIME_VALUE 1000
static int do_active_device(struct ctl_table *table, int write, static int do_active_device(struct ctl_table *table, int write,
void __user *result, size_t *lenp, loff_t *ppos) void *result, size_t *lenp, loff_t *ppos)
{ {
struct parport *port = (struct parport *)table->extra1; struct parport *port = (struct parport *)table->extra1;
char buffer[256]; char buffer[256];
@ -65,13 +65,13 @@ static int do_active_device(struct ctl_table *table, int write,
*lenp = len; *lenp = len;
*ppos += len; *ppos += len;
memcpy(result, buffer, len);
return copy_to_user(result, buffer, len) ? -EFAULT : 0; return 0;
} }
#ifdef CONFIG_PARPORT_1284 #ifdef CONFIG_PARPORT_1284
static int do_autoprobe(struct ctl_table *table, int write, static int do_autoprobe(struct ctl_table *table, int write,
void __user *result, size_t *lenp, loff_t *ppos) void *result, size_t *lenp, loff_t *ppos)
{ {
struct parport_device_info *info = table->extra2; struct parport_device_info *info = table->extra2;
const char *str; const char *str;
@ -108,13 +108,13 @@ static int do_autoprobe(struct ctl_table *table, int write,
*ppos += len; *ppos += len;
return copy_to_user (result, buffer, len) ? -EFAULT : 0; memcpy(result, buffer, len);
return 0;
} }
#endif /* IEEE1284.3 support. */ #endif /* IEEE1284.3 support. */
static int do_hardware_base_addr(struct ctl_table *table, int write, static int do_hardware_base_addr(struct ctl_table *table, int write,
void __user *result, void *result, size_t *lenp, loff_t *ppos)
size_t *lenp, loff_t *ppos)
{ {
struct parport *port = (struct parport *)table->extra1; struct parport *port = (struct parport *)table->extra1;
char buffer[20]; char buffer[20];
@ -136,13 +136,12 @@ static int do_hardware_base_addr(struct ctl_table *table, int write,
*lenp = len; *lenp = len;
*ppos += len; *ppos += len;
memcpy(result, buffer, len);
return copy_to_user(result, buffer, len) ? -EFAULT : 0; return 0;
} }
static int do_hardware_irq(struct ctl_table *table, int write, static int do_hardware_irq(struct ctl_table *table, int write,
void __user *result, void *result, size_t *lenp, loff_t *ppos)
size_t *lenp, loff_t *ppos)
{ {
struct parport *port = (struct parport *)table->extra1; struct parport *port = (struct parport *)table->extra1;
char buffer[20]; char buffer[20];
@ -164,13 +163,12 @@ static int do_hardware_irq(struct ctl_table *table, int write,
*lenp = len; *lenp = len;
*ppos += len; *ppos += len;
memcpy(result, buffer, len);
return copy_to_user(result, buffer, len) ? -EFAULT : 0; return 0;
} }
static int do_hardware_dma(struct ctl_table *table, int write, static int do_hardware_dma(struct ctl_table *table, int write,
void __user *result, void *result, size_t *lenp, loff_t *ppos)
size_t *lenp, loff_t *ppos)
{ {
struct parport *port = (struct parport *)table->extra1; struct parport *port = (struct parport *)table->extra1;
char buffer[20]; char buffer[20];
@ -192,13 +190,12 @@ static int do_hardware_dma(struct ctl_table *table, int write,
*lenp = len; *lenp = len;
*ppos += len; *ppos += len;
memcpy(result, buffer, len);
return copy_to_user(result, buffer, len) ? -EFAULT : 0; return 0;
} }
static int do_hardware_modes(struct ctl_table *table, int write, static int do_hardware_modes(struct ctl_table *table, int write,
void __user *result, void *result, size_t *lenp, loff_t *ppos)
size_t *lenp, loff_t *ppos)
{ {
struct parport *port = (struct parport *)table->extra1; struct parport *port = (struct parport *)table->extra1;
char buffer[40]; char buffer[40];
@ -231,8 +228,8 @@ static int do_hardware_modes(struct ctl_table *table, int write,
*lenp = len; *lenp = len;
*ppos += len; *ppos += len;
memcpy(result, buffer, len);
return copy_to_user(result, buffer, len) ? -EFAULT : 0; return 0;
} }
#define PARPORT_PORT_DIR(CHILD) { .procname = NULL, .mode = 0555, .child = CHILD } #define PARPORT_PORT_DIR(CHILD) { .procname = NULL, .mode = 0555, .child = CHILD }

View File

@ -165,7 +165,7 @@ static long get_nr_dentry_negative(void)
return sum < 0 ? 0 : sum; return sum < 0 ? 0 : sum;
} }
int proc_nr_dentry(struct ctl_table *table, int write, void __user *buffer, int proc_nr_dentry(struct ctl_table *table, int write, void *buffer,
size_t *lenp, loff_t *ppos) size_t *lenp, loff_t *ppos)
{ {
dentry_stat.nr_dentry = get_nr_dentry(); dentry_stat.nr_dentry = get_nr_dentry();

View File

@ -47,7 +47,7 @@ static void drop_pagecache_sb(struct super_block *sb, void *unused)
} }
int drop_caches_sysctl_handler(struct ctl_table *table, int write, int drop_caches_sysctl_handler(struct ctl_table *table, int write,
void __user *buffer, size_t *length, loff_t *ppos) void *buffer, size_t *length, loff_t *ppos)
{ {
int ret; int ret;

View File

@ -80,14 +80,14 @@ EXPORT_SYMBOL_GPL(get_max_files);
*/ */
#if defined(CONFIG_SYSCTL) && defined(CONFIG_PROC_FS) #if defined(CONFIG_SYSCTL) && defined(CONFIG_PROC_FS)
int proc_nr_files(struct ctl_table *table, int write, int proc_nr_files(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos) void *buffer, size_t *lenp, loff_t *ppos)
{ {
files_stat.nr_files = get_nr_files(); files_stat.nr_files = get_nr_files();
return proc_doulongvec_minmax(table, write, buffer, lenp, ppos); return proc_doulongvec_minmax(table, write, buffer, lenp, ppos);
} }
#else #else
int proc_nr_files(struct ctl_table *table, int write, int proc_nr_files(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos) void *buffer, size_t *lenp, loff_t *ppos)
{ {
return -ENOSYS; return -ENOSYS;
} }

View File

@ -51,8 +51,7 @@ static unsigned fscache_op_max_active = 2;
static struct ctl_table_header *fscache_sysctl_header; static struct ctl_table_header *fscache_sysctl_header;
static int fscache_max_active_sysctl(struct ctl_table *table, int write, static int fscache_max_active_sysctl(struct ctl_table *table, int write,
void __user *buffer, void *buffer, size_t *lenp, loff_t *ppos)
size_t *lenp, loff_t *ppos)
{ {
struct workqueue_struct **wqp = table->extra1; struct workqueue_struct **wqp = table->extra1;
unsigned int *datap = table->data; unsigned int *datap = table->data;

View File

@ -108,7 +108,7 @@ long get_nr_dirty_inodes(void)
*/ */
#ifdef CONFIG_SYSCTL #ifdef CONFIG_SYSCTL
int proc_nr_inodes(struct ctl_table *table, int write, int proc_nr_inodes(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos) void *buffer, size_t *lenp, loff_t *ppos)
{ {
inodes_stat.nr_inodes = get_nr_inodes(); inodes_stat.nr_inodes = get_nr_inodes();
inodes_stat.nr_unused = get_nr_inodes_unused(); inodes_stat.nr_unused = get_nr_inodes_unused();

View File

@ -539,13 +539,13 @@ out:
return err; return err;
} }
static ssize_t proc_sys_call_handler(struct file *filp, void __user *buf, static ssize_t proc_sys_call_handler(struct file *filp, void __user *ubuf,
size_t count, loff_t *ppos, int write) size_t count, loff_t *ppos, int write)
{ {
struct inode *inode = file_inode(filp); struct inode *inode = file_inode(filp);
struct ctl_table_header *head = grab_header(inode); struct ctl_table_header *head = grab_header(inode);
struct ctl_table *table = PROC_I(inode)->sysctl_entry; struct ctl_table *table = PROC_I(inode)->sysctl_entry;
void *new_buf = NULL; void *kbuf;
ssize_t error; ssize_t error;
if (IS_ERR(head)) if (IS_ERR(head))
@ -564,27 +564,38 @@ static ssize_t proc_sys_call_handler(struct file *filp, void __user *buf,
if (!table->proc_handler) if (!table->proc_handler)
goto out; goto out;
error = BPF_CGROUP_RUN_PROG_SYSCTL(head, table, write, buf, &count, if (write) {
ppos, &new_buf); kbuf = memdup_user_nul(ubuf, count);
if (error) if (IS_ERR(kbuf)) {
goto out; error = PTR_ERR(kbuf);
goto out;
/* careful: calling conventions are nasty here */ }
if (new_buf) {
mm_segment_t old_fs;
old_fs = get_fs();
set_fs(KERNEL_DS);
error = table->proc_handler(table, write, (void __user *)new_buf,
&count, ppos);
set_fs(old_fs);
kfree(new_buf);
} else { } else {
error = table->proc_handler(table, write, buf, &count, ppos); error = -ENOMEM;
kbuf = kzalloc(count, GFP_KERNEL);
if (!kbuf)
goto out;
} }
if (!error) error = BPF_CGROUP_RUN_PROG_SYSCTL(head, table, write, &kbuf, &count,
error = count; ppos);
if (error)
goto out_free_buf;
/* careful: calling conventions are nasty here */
error = table->proc_handler(table, write, kbuf, &count, ppos);
if (error)
goto out_free_buf;
if (!write) {
error = -EFAULT;
if (copy_to_user(ubuf, kbuf, count))
goto out_free_buf;
}
error = count;
out_free_buf:
kfree(kbuf);
out: out:
sysctl_head_finish(head); sysctl_head_finish(head);

View File

@ -2841,7 +2841,7 @@ const struct quotactl_ops dquot_quotactl_sysfile_ops = {
EXPORT_SYMBOL(dquot_quotactl_sysfile_ops); EXPORT_SYMBOL(dquot_quotactl_sysfile_ops);
static int do_proc_dqstats(struct ctl_table *table, int write, static int do_proc_dqstats(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos) void *buffer, size_t *lenp, loff_t *ppos)
{ {
unsigned int type = (unsigned long *)table->data - dqstats.stat; unsigned int type = (unsigned long *)table->data - dqstats.stat;
s64 value = percpu_counter_sum(&dqstats.counter[type]); s64 value = percpu_counter_sum(&dqstats.counter[type]);

View File

@ -13,7 +13,7 @@ STATIC int
xfs_stats_clear_proc_handler( xfs_stats_clear_proc_handler(
struct ctl_table *ctl, struct ctl_table *ctl,
int write, int write,
void __user *buffer, void *buffer,
size_t *lenp, size_t *lenp,
loff_t *ppos) loff_t *ppos)
{ {
@ -33,7 +33,7 @@ STATIC int
xfs_panic_mask_proc_handler( xfs_panic_mask_proc_handler(
struct ctl_table *ctl, struct ctl_table *ctl,
int write, int write,
void __user *buffer, void *buffer,
size_t *lenp, size_t *lenp,
loff_t *ppos) loff_t *ppos)
{ {

View File

@ -57,8 +57,6 @@ struct bpf_cgroup_link {
enum bpf_attach_type type; enum bpf_attach_type type;
}; };
extern const struct bpf_link_ops bpf_cgroup_link_lops;
struct bpf_prog_list { struct bpf_prog_list {
struct list_head node; struct list_head node;
struct bpf_prog *prog; struct bpf_prog *prog;
@ -100,8 +98,6 @@ int __cgroup_bpf_attach(struct cgroup *cgrp,
int __cgroup_bpf_detach(struct cgroup *cgrp, struct bpf_prog *prog, int __cgroup_bpf_detach(struct cgroup *cgrp, struct bpf_prog *prog,
struct bpf_cgroup_link *link, struct bpf_cgroup_link *link,
enum bpf_attach_type type); enum bpf_attach_type type);
int __cgroup_bpf_replace(struct cgroup *cgrp, struct bpf_cgroup_link *link,
struct bpf_prog *new_prog);
int __cgroup_bpf_query(struct cgroup *cgrp, const union bpf_attr *attr, int __cgroup_bpf_query(struct cgroup *cgrp, const union bpf_attr *attr,
union bpf_attr __user *uattr); union bpf_attr __user *uattr);
@ -112,8 +108,6 @@ int cgroup_bpf_attach(struct cgroup *cgrp,
u32 flags); u32 flags);
int cgroup_bpf_detach(struct cgroup *cgrp, struct bpf_prog *prog, int cgroup_bpf_detach(struct cgroup *cgrp, struct bpf_prog *prog,
enum bpf_attach_type type); enum bpf_attach_type type);
int cgroup_bpf_replace(struct bpf_link *link, struct bpf_prog *old_prog,
struct bpf_prog *new_prog);
int cgroup_bpf_query(struct cgroup *cgrp, const union bpf_attr *attr, int cgroup_bpf_query(struct cgroup *cgrp, const union bpf_attr *attr,
union bpf_attr __user *uattr); union bpf_attr __user *uattr);
@ -138,8 +132,7 @@ int __cgroup_bpf_check_dev_permission(short dev_type, u32 major, u32 minor,
int __cgroup_bpf_run_filter_sysctl(struct ctl_table_header *head, int __cgroup_bpf_run_filter_sysctl(struct ctl_table_header *head,
struct ctl_table *table, int write, struct ctl_table *table, int write,
void __user *buf, size_t *pcount, void **buf, size_t *pcount, loff_t *ppos,
loff_t *ppos, void **new_buf,
enum bpf_attach_type type); enum bpf_attach_type type);
int __cgroup_bpf_run_filter_setsockopt(struct sock *sock, int *level, int __cgroup_bpf_run_filter_setsockopt(struct sock *sock, int *level,
@ -302,12 +295,12 @@ int bpf_percpu_cgroup_storage_update(struct bpf_map *map, void *key,
}) })
#define BPF_CGROUP_RUN_PROG_SYSCTL(head, table, write, buf, count, pos, nbuf) \ #define BPF_CGROUP_RUN_PROG_SYSCTL(head, table, write, buf, count, pos) \
({ \ ({ \
int __ret = 0; \ int __ret = 0; \
if (cgroup_bpf_enabled) \ if (cgroup_bpf_enabled) \
__ret = __cgroup_bpf_run_filter_sysctl(head, table, write, \ __ret = __cgroup_bpf_run_filter_sysctl(head, table, write, \
buf, count, pos, nbuf, \ buf, count, pos, \
BPF_CGROUP_SYSCTL); \ BPF_CGROUP_SYSCTL); \
__ret; \ __ret; \
}) })
@ -354,7 +347,6 @@ int cgroup_bpf_prog_query(const union bpf_attr *attr,
#else #else
struct bpf_prog; struct bpf_prog;
struct bpf_link;
struct cgroup_bpf {}; struct cgroup_bpf {};
static inline int cgroup_bpf_inherit(struct cgroup *cgrp) { return 0; } static inline int cgroup_bpf_inherit(struct cgroup *cgrp) { return 0; }
static inline void cgroup_bpf_offline(struct cgroup *cgrp) {} static inline void cgroup_bpf_offline(struct cgroup *cgrp) {}
@ -378,13 +370,6 @@ static inline int cgroup_bpf_link_attach(const union bpf_attr *attr,
return -EINVAL; return -EINVAL;
} }
static inline int cgroup_bpf_replace(struct bpf_link *link,
struct bpf_prog *old_prog,
struct bpf_prog *new_prog)
{
return -EINVAL;
}
static inline int cgroup_bpf_prog_query(const union bpf_attr *attr, static inline int cgroup_bpf_prog_query(const union bpf_attr *attr,
union bpf_attr __user *uattr) union bpf_attr __user *uattr)
{ {
@ -429,7 +414,7 @@ static inline int bpf_percpu_cgroup_storage_update(struct bpf_map *map,
#define BPF_CGROUP_RUN_PROG_UDP6_RECVMSG_LOCK(sk, uaddr) ({ 0; }) #define BPF_CGROUP_RUN_PROG_UDP6_RECVMSG_LOCK(sk, uaddr) ({ 0; })
#define BPF_CGROUP_RUN_PROG_SOCK_OPS(sock_ops) ({ 0; }) #define BPF_CGROUP_RUN_PROG_SOCK_OPS(sock_ops) ({ 0; })
#define BPF_CGROUP_RUN_PROG_DEVICE_CGROUP(type,major,minor,access) ({ 0; }) #define BPF_CGROUP_RUN_PROG_DEVICE_CGROUP(type,major,minor,access) ({ 0; })
#define BPF_CGROUP_RUN_PROG_SYSCTL(head,table,write,buf,count,pos,nbuf) ({ 0; }) #define BPF_CGROUP_RUN_PROG_SYSCTL(head,table,write,buf,count,pos) ({ 0; })
#define BPF_CGROUP_GETSOCKOPT_MAX_OPTLEN(optlen) ({ 0; }) #define BPF_CGROUP_GETSOCKOPT_MAX_OPTLEN(optlen) ({ 0; })
#define BPF_CGROUP_RUN_PROG_GETSOCKOPT(sock, level, optname, optval, \ #define BPF_CGROUP_RUN_PROG_GETSOCKOPT(sock, level, optname, optval, \
optlen, max_optlen, retval) ({ retval; }) optlen, max_optlen, retval) ({ retval; })

View File

@ -987,6 +987,7 @@ _out: \
#ifdef CONFIG_BPF_SYSCALL #ifdef CONFIG_BPF_SYSCALL
DECLARE_PER_CPU(int, bpf_prog_active); DECLARE_PER_CPU(int, bpf_prog_active);
extern struct mutex bpf_stats_enabled_mutex;
/* /*
* Block execution of BPF programs attached to instrumentation (perf, * Block execution of BPF programs attached to instrumentation (perf,
@ -1026,9 +1027,11 @@ extern const struct file_operations bpf_prog_fops;
extern const struct bpf_verifier_ops _name ## _verifier_ops; extern const struct bpf_verifier_ops _name ## _verifier_ops;
#define BPF_MAP_TYPE(_id, _ops) \ #define BPF_MAP_TYPE(_id, _ops) \
extern const struct bpf_map_ops _ops; extern const struct bpf_map_ops _ops;
#define BPF_LINK_TYPE(_id, _name)
#include <linux/bpf_types.h> #include <linux/bpf_types.h>
#undef BPF_PROG_TYPE #undef BPF_PROG_TYPE
#undef BPF_MAP_TYPE #undef BPF_MAP_TYPE
#undef BPF_LINK_TYPE
extern const struct bpf_prog_ops bpf_offload_prog_ops; extern const struct bpf_prog_ops bpf_offload_prog_ops;
extern const struct bpf_verifier_ops tc_cls_act_analyzer_ops; extern const struct bpf_verifier_ops tc_cls_act_analyzer_ops;
@ -1085,21 +1088,35 @@ int bpf_prog_new_fd(struct bpf_prog *prog);
struct bpf_link { struct bpf_link {
atomic64_t refcnt; atomic64_t refcnt;
u32 id;
enum bpf_link_type type;
const struct bpf_link_ops *ops; const struct bpf_link_ops *ops;
struct bpf_prog *prog; struct bpf_prog *prog;
struct work_struct work; struct work_struct work;
}; };
struct bpf_link_primer {
struct bpf_link *link;
struct file *file;
int fd;
u32 id;
};
struct bpf_link_ops { struct bpf_link_ops {
void (*release)(struct bpf_link *link); void (*release)(struct bpf_link *link);
void (*dealloc)(struct bpf_link *link); void (*dealloc)(struct bpf_link *link);
int (*update_prog)(struct bpf_link *link, struct bpf_prog *new_prog,
struct bpf_prog *old_prog);
void (*show_fdinfo)(const struct bpf_link *link, struct seq_file *seq);
int (*fill_link_info)(const struct bpf_link *link,
struct bpf_link_info *info);
}; };
void bpf_link_init(struct bpf_link *link, const struct bpf_link_ops *ops, void bpf_link_init(struct bpf_link *link, enum bpf_link_type type,
struct bpf_prog *prog); const struct bpf_link_ops *ops, struct bpf_prog *prog);
void bpf_link_cleanup(struct bpf_link *link, struct file *link_file, int bpf_link_prime(struct bpf_link *link, struct bpf_link_primer *primer);
int link_fd); int bpf_link_settle(struct bpf_link_primer *primer);
void bpf_link_cleanup(struct bpf_link_primer *primer);
void bpf_link_inc(struct bpf_link *link); void bpf_link_inc(struct bpf_link *link);
void bpf_link_put(struct bpf_link *link); void bpf_link_put(struct bpf_link *link);
int bpf_link_new_fd(struct bpf_link *link); int bpf_link_new_fd(struct bpf_link *link);
@ -1215,6 +1232,7 @@ int btf_check_type_match(struct bpf_verifier_env *env, struct bpf_prog *prog,
struct bpf_prog *bpf_prog_by_id(u32 id); struct bpf_prog *bpf_prog_by_id(u32 id);
const struct bpf_func_proto *bpf_base_func_proto(enum bpf_func_id func_id);
#else /* !CONFIG_BPF_SYSCALL */ #else /* !CONFIG_BPF_SYSCALL */
static inline struct bpf_prog *bpf_prog_get(u32 ufd) static inline struct bpf_prog *bpf_prog_get(u32 ufd)
{ {
@ -1365,6 +1383,12 @@ static inline struct bpf_prog *bpf_prog_by_id(u32 id)
{ {
return ERR_PTR(-ENOTSUPP); return ERR_PTR(-ENOTSUPP);
} }
static inline const struct bpf_func_proto *
bpf_base_func_proto(enum bpf_func_id func_id)
{
return NULL;
}
#endif /* CONFIG_BPF_SYSCALL */ #endif /* CONFIG_BPF_SYSCALL */
static inline struct bpf_prog *bpf_prog_get_type(u32 ufd, static inline struct bpf_prog *bpf_prog_get_type(u32 ufd,
@ -1502,6 +1526,7 @@ extern const struct bpf_func_proto bpf_get_smp_processor_id_proto;
extern const struct bpf_func_proto bpf_get_numa_node_id_proto; extern const struct bpf_func_proto bpf_get_numa_node_id_proto;
extern const struct bpf_func_proto bpf_tail_call_proto; extern const struct bpf_func_proto bpf_tail_call_proto;
extern const struct bpf_func_proto bpf_ktime_get_ns_proto; extern const struct bpf_func_proto bpf_ktime_get_ns_proto;
extern const struct bpf_func_proto bpf_ktime_get_boot_ns_proto;
extern const struct bpf_func_proto bpf_get_current_pid_tgid_proto; extern const struct bpf_func_proto bpf_get_current_pid_tgid_proto;
extern const struct bpf_func_proto bpf_get_current_uid_gid_proto; extern const struct bpf_func_proto bpf_get_current_uid_gid_proto;
extern const struct bpf_func_proto bpf_get_current_comm_proto; extern const struct bpf_func_proto bpf_get_current_comm_proto;
@ -1523,6 +1548,7 @@ extern const struct bpf_func_proto bpf_strtoul_proto;
extern const struct bpf_func_proto bpf_tcp_sock_proto; extern const struct bpf_func_proto bpf_tcp_sock_proto;
extern const struct bpf_func_proto bpf_jiffies64_proto; extern const struct bpf_func_proto bpf_jiffies64_proto;
extern const struct bpf_func_proto bpf_get_ns_current_pid_tgid_proto; extern const struct bpf_func_proto bpf_get_ns_current_pid_tgid_proto;
extern const struct bpf_func_proto bpf_event_output_data_proto;
const struct bpf_func_proto *bpf_tracing_func_proto( const struct bpf_func_proto *bpf_tracing_func_proto(
enum bpf_func_id func_id, const struct bpf_prog *prog); enum bpf_func_id func_id, const struct bpf_prog *prog);
@ -1530,6 +1556,7 @@ const struct bpf_func_proto *bpf_tracing_func_proto(
/* Shared helpers among cBPF and eBPF. */ /* Shared helpers among cBPF and eBPF. */
void bpf_user_rnd_init_once(void); void bpf_user_rnd_init_once(void);
u64 bpf_user_rnd_u32(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5); u64 bpf_user_rnd_u32(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5);
u64 bpf_get_raw_cpu_id(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5);
#if defined(CONFIG_NET) #if defined(CONFIG_NET)
bool bpf_sock_common_is_valid_access(int off, int size, bool bpf_sock_common_is_valid_access(int off, int size,

View File

@ -118,3 +118,9 @@ BPF_MAP_TYPE(BPF_MAP_TYPE_STACK, stack_map_ops)
#if defined(CONFIG_BPF_JIT) #if defined(CONFIG_BPF_JIT)
BPF_MAP_TYPE(BPF_MAP_TYPE_STRUCT_OPS, bpf_struct_ops_map_ops) BPF_MAP_TYPE(BPF_MAP_TYPE_STRUCT_OPS, bpf_struct_ops_map_ops)
#endif #endif
BPF_LINK_TYPE(BPF_LINK_TYPE_RAW_TRACEPOINT, raw_tracepoint)
BPF_LINK_TYPE(BPF_LINK_TYPE_TRACING, tracing)
#ifdef CONFIG_CGROUP_BPF
BPF_LINK_TYPE(BPF_LINK_TYPE_CGROUP, cgroup)
#endif

View File

@ -86,7 +86,7 @@ static inline unsigned long compact_gap(unsigned int order)
#ifdef CONFIG_COMPACTION #ifdef CONFIG_COMPACTION
extern int sysctl_compact_memory; extern int sysctl_compact_memory;
extern int sysctl_compaction_handler(struct ctl_table *table, int write, extern int sysctl_compaction_handler(struct ctl_table *table, int write,
void __user *buffer, size_t *length, loff_t *ppos); void *buffer, size_t *length, loff_t *ppos);
extern int sysctl_extfrag_threshold; extern int sysctl_extfrag_threshold;
extern int sysctl_compact_unevictable_allowed; extern int sysctl_compact_unevictable_allowed;

View File

@ -22,4 +22,8 @@ extern void do_coredump(const kernel_siginfo_t *siginfo);
static inline void do_coredump(const kernel_siginfo_t *siginfo) {} static inline void do_coredump(const kernel_siginfo_t *siginfo) {}
#endif #endif
extern int core_uses_pid;
extern char core_pattern[];
extern unsigned int core_pipe_limit;
#endif /* _LINUX_COREDUMP_H */ #endif /* _LINUX_COREDUMP_H */

View File

@ -94,4 +94,6 @@ extern void fd_install(unsigned int fd, struct file *file);
extern void flush_delayed_fput(void); extern void flush_delayed_fput(void);
extern void __fput_sync(struct file *); extern void __fput_sync(struct file *);
extern unsigned int sysctl_nr_open_min, sysctl_nr_open_max;
#endif /* __LINUX_FILE_H */ #endif /* __LINUX_FILE_H */

View File

@ -863,8 +863,6 @@ int bpf_prog_create(struct bpf_prog **pfp, struct sock_fprog_kern *fprog);
int bpf_prog_create_from_user(struct bpf_prog **pfp, struct sock_fprog *fprog, int bpf_prog_create_from_user(struct bpf_prog **pfp, struct sock_fprog *fprog,
bpf_aux_classic_check_t trans, bool save_orig); bpf_aux_classic_check_t trans, bool save_orig);
void bpf_prog_destroy(struct bpf_prog *fp); void bpf_prog_destroy(struct bpf_prog *fp);
const struct bpf_func_proto *
bpf_base_func_proto(enum bpf_func_id func_id);
int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk); int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk);
int sk_attach_bpf(u32 ufd, struct sock *sk); int sk_attach_bpf(u32 ufd, struct sock *sk);

View File

@ -3536,11 +3536,11 @@ ssize_t simple_attr_write(struct file *file, const char __user *buf,
struct ctl_table; struct ctl_table;
int proc_nr_files(struct ctl_table *table, int write, int proc_nr_files(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos); void *buffer, size_t *lenp, loff_t *ppos);
int proc_nr_dentry(struct ctl_table *table, int write, int proc_nr_dentry(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos); void *buffer, size_t *lenp, loff_t *ppos);
int proc_nr_inodes(struct ctl_table *table, int write, int proc_nr_inodes(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos); void *buffer, size_t *lenp, loff_t *ppos);
int __init get_filesystem_list(char *buf); int __init get_filesystem_list(char *buf);
#define __FMODE_EXEC ((__force int) FMODE_EXEC) #define __FMODE_EXEC ((__force int) FMODE_EXEC)

View File

@ -1005,8 +1005,7 @@ extern void disable_trace_on_warning(void);
extern int __disable_trace_on_warning; extern int __disable_trace_on_warning;
int tracepoint_printk_sysctl(struct ctl_table *table, int write, int tracepoint_printk_sysctl(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, void *buffer, size_t *lenp, loff_t *ppos);
loff_t *ppos);
#else /* CONFIG_TRACING */ #else /* CONFIG_TRACING */
static inline void disable_trace_on_warning(void) { } static inline void disable_trace_on_warning(void) { }

View File

@ -105,14 +105,13 @@ struct hugepage_subpool *hugepage_new_subpool(struct hstate *h, long max_hpages,
void hugepage_put_subpool(struct hugepage_subpool *spool); void hugepage_put_subpool(struct hugepage_subpool *spool);
void reset_vma_resv_huge_pages(struct vm_area_struct *vma); void reset_vma_resv_huge_pages(struct vm_area_struct *vma);
int hugetlb_sysctl_handler(struct ctl_table *, int, void __user *, size_t *, loff_t *); int hugetlb_sysctl_handler(struct ctl_table *, int, void *, size_t *, loff_t *);
int hugetlb_overcommit_handler(struct ctl_table *, int, void __user *, size_t *, loff_t *); int hugetlb_overcommit_handler(struct ctl_table *, int, void *, size_t *,
int hugetlb_treat_movable_handler(struct ctl_table *, int, void __user *, size_t *, loff_t *); loff_t *);
int hugetlb_treat_movable_handler(struct ctl_table *, int, void *, size_t *,
#ifdef CONFIG_NUMA loff_t *);
int hugetlb_mempolicy_sysctl_handler(struct ctl_table *, int, int hugetlb_mempolicy_sysctl_handler(struct ctl_table *, int, void *, size_t *,
void __user *, size_t *, loff_t *); loff_t *);
#endif
int copy_hugetlb_page_range(struct mm_struct *, struct mm_struct *, struct vm_area_struct *); int copy_hugetlb_page_range(struct mm_struct *, struct mm_struct *, struct vm_area_struct *);
long follow_hugetlb_page(struct mm_struct *, struct vm_area_struct *, long follow_hugetlb_page(struct mm_struct *, struct vm_area_struct *,

View File

@ -312,7 +312,7 @@ DEFINE_INSN_CACHE_OPS(optinsn);
#ifdef CONFIG_SYSCTL #ifdef CONFIG_SYSCTL
extern int sysctl_kprobes_optimization; extern int sysctl_kprobes_optimization;
extern int proc_kprobes_optimization_handler(struct ctl_table *table, extern int proc_kprobes_optimization_handler(struct ctl_table *table,
int write, void __user *buffer, int write, void *buffer,
size_t *length, loff_t *ppos); size_t *length, loff_t *ppos);
#endif #endif
extern void wait_for_kprobe_optimizer(void); extern void wait_for_kprobe_optimizer(void);

View File

@ -38,8 +38,8 @@ account_scheduler_latency(struct task_struct *task, int usecs, int inter)
void clear_tsk_latency_tracing(struct task_struct *p); void clear_tsk_latency_tracing(struct task_struct *p);
extern int sysctl_latencytop(struct ctl_table *table, int write, int sysctl_latencytop(struct ctl_table *table, int write, void *buffer,
void __user *buffer, size_t *lenp, loff_t *ppos); size_t *lenp, loff_t *ppos);
#else #else

View File

@ -201,10 +201,10 @@ extern int sysctl_overcommit_memory;
extern int sysctl_overcommit_ratio; extern int sysctl_overcommit_ratio;
extern unsigned long sysctl_overcommit_kbytes; extern unsigned long sysctl_overcommit_kbytes;
extern int overcommit_ratio_handler(struct ctl_table *, int, void __user *, int overcommit_ratio_handler(struct ctl_table *, int, void *, size_t *,
size_t *, loff_t *); loff_t *);
extern int overcommit_kbytes_handler(struct ctl_table *, int, void __user *, int overcommit_kbytes_handler(struct ctl_table *, int, void *, size_t *,
size_t *, loff_t *); loff_t *);
#define nth_page(page,n) pfn_to_page(page_to_pfn((page)) + (n)) #define nth_page(page,n) pfn_to_page(page_to_pfn((page)) + (n))
@ -2957,8 +2957,8 @@ extern bool process_shares_mm(struct task_struct *p, struct mm_struct *mm);
#ifdef CONFIG_SYSCTL #ifdef CONFIG_SYSCTL
extern int sysctl_drop_caches; extern int sysctl_drop_caches;
int drop_caches_sysctl_handler(struct ctl_table *, int, int drop_caches_sysctl_handler(struct ctl_table *, int, void *, size_t *,
void __user *, size_t *, loff_t *); loff_t *);
#endif #endif
void drop_slab(void); void drop_slab(void);
@ -3140,5 +3140,7 @@ unsigned long wp_shared_mapping_range(struct address_space *mapping,
pgoff_t first_index, pgoff_t nr); pgoff_t first_index, pgoff_t nr);
#endif #endif
extern int sysctl_nr_trim_pages;
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */
#endif /* _LINUX_MM_H */ #endif /* _LINUX_MM_H */

View File

@ -909,24 +909,23 @@ static inline int is_highmem(struct zone *zone)
/* These two functions are used to setup the per zone pages min values */ /* These two functions are used to setup the per zone pages min values */
struct ctl_table; struct ctl_table;
int min_free_kbytes_sysctl_handler(struct ctl_table *, int,
void __user *, size_t *, loff_t *);
int watermark_boost_factor_sysctl_handler(struct ctl_table *, int,
void __user *, size_t *, loff_t *);
int watermark_scale_factor_sysctl_handler(struct ctl_table *, int,
void __user *, size_t *, loff_t *);
extern int sysctl_lowmem_reserve_ratio[MAX_NR_ZONES];
int lowmem_reserve_ratio_sysctl_handler(struct ctl_table *, int,
void __user *, size_t *, loff_t *);
int percpu_pagelist_fraction_sysctl_handler(struct ctl_table *, int,
void __user *, size_t *, loff_t *);
int sysctl_min_unmapped_ratio_sysctl_handler(struct ctl_table *, int,
void __user *, size_t *, loff_t *);
int sysctl_min_slab_ratio_sysctl_handler(struct ctl_table *, int,
void __user *, size_t *, loff_t *);
extern int numa_zonelist_order_handler(struct ctl_table *, int, int min_free_kbytes_sysctl_handler(struct ctl_table *, int, void *, size_t *,
void __user *, size_t *, loff_t *); loff_t *);
int watermark_scale_factor_sysctl_handler(struct ctl_table *, int, void *,
size_t *, loff_t *);
extern int sysctl_lowmem_reserve_ratio[MAX_NR_ZONES];
int lowmem_reserve_ratio_sysctl_handler(struct ctl_table *, int, void *,
size_t *, loff_t *);
int percpu_pagelist_fraction_sysctl_handler(struct ctl_table *, int,
void *, size_t *, loff_t *);
int sysctl_min_unmapped_ratio_sysctl_handler(struct ctl_table *, int,
void *, size_t *, loff_t *);
int sysctl_min_slab_ratio_sysctl_handler(struct ctl_table *, int,
void *, size_t *, loff_t *);
int numa_zonelist_order_handler(struct ctl_table *, int,
void *, size_t *, loff_t *);
extern int percpu_pagelist_fraction;
extern char numa_zonelist_order[]; extern char numa_zonelist_order[];
#define NUMA_ZONELIST_ORDER_LEN 16 #define NUMA_ZONELIST_ORDER_LEN 16

View File

@ -202,16 +202,11 @@ static inline void watchdog_update_hrtimer_threshold(u64 period) { }
#endif #endif
struct ctl_table; struct ctl_table;
extern int proc_watchdog(struct ctl_table *, int , int proc_watchdog(struct ctl_table *, int, void *, size_t *, loff_t *);
void __user *, size_t *, loff_t *); int proc_nmi_watchdog(struct ctl_table *, int , void *, size_t *, loff_t *);
extern int proc_nmi_watchdog(struct ctl_table *, int , int proc_soft_watchdog(struct ctl_table *, int , void *, size_t *, loff_t *);
void __user *, size_t *, loff_t *); int proc_watchdog_thresh(struct ctl_table *, int , void *, size_t *, loff_t *);
extern int proc_soft_watchdog(struct ctl_table *, int , int proc_watchdog_cpumask(struct ctl_table *, int, void *, size_t *, loff_t *);
void __user *, size_t *, loff_t *);
extern int proc_watchdog_thresh(struct ctl_table *, int ,
void __user *, size_t *, loff_t *);
extern int proc_watchdog_cpumask(struct ctl_table *, int,
void __user *, size_t *, loff_t *);
#ifdef CONFIG_HAVE_ACPI_APEI_NMI #ifdef CONFIG_HAVE_ACPI_APEI_NMI
#include <asm/nmi.h> #include <asm/nmi.h>

View File

@ -1280,15 +1280,12 @@ extern int sysctl_perf_cpu_time_max_percent;
extern void perf_sample_event_took(u64 sample_len_ns); extern void perf_sample_event_took(u64 sample_len_ns);
extern int perf_proc_update_handler(struct ctl_table *table, int write, int perf_proc_update_handler(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, void *buffer, size_t *lenp, loff_t *ppos);
loff_t *ppos); int perf_cpu_time_max_percent_handler(struct ctl_table *table, int write,
extern int perf_cpu_time_max_percent_handler(struct ctl_table *table, int write, void *buffer, size_t *lenp, loff_t *ppos);
void __user *buffer, size_t *lenp,
loff_t *ppos);
int perf_event_max_stack_handler(struct ctl_table *table, int write, int perf_event_max_stack_handler(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos); void *buffer, size_t *lenp, loff_t *ppos);
/* Access to perf_event_open(2) syscall. */ /* Access to perf_event_open(2) syscall. */
#define PERF_SECURITY_OPEN 0 #define PERF_SECURITY_OPEN 0

View File

@ -108,6 +108,9 @@ extern void transfer_pid(struct task_struct *old, struct task_struct *new,
struct pid_namespace; struct pid_namespace;
extern struct pid_namespace init_pid_ns; extern struct pid_namespace init_pid_ns;
extern int pid_max;
extern int pid_max_min, pid_max_max;
/* /*
* look up a PID in the hash table. Must be called with the tasklist_lock * look up a PID in the hash table. Must be called with the tasklist_lock
* or rcu_read_lock() held. * or rcu_read_lock() held.

View File

@ -189,7 +189,7 @@ extern int printk_delay_msec;
extern int dmesg_restrict; extern int dmesg_restrict;
extern int extern int
devkmsg_sysctl_set_loglvl(struct ctl_table *table, int write, void __user *buf, devkmsg_sysctl_set_loglvl(struct ctl_table *table, int write, void *buf,
size_t *lenp, loff_t *ppos); size_t *lenp, loff_t *ppos);
extern void wake_up_klogd(void); extern void wake_up_klogd(void);

View File

@ -12,9 +12,8 @@ extern unsigned int sysctl_hung_task_panic;
extern unsigned long sysctl_hung_task_timeout_secs; extern unsigned long sysctl_hung_task_timeout_secs;
extern unsigned long sysctl_hung_task_check_interval_secs; extern unsigned long sysctl_hung_task_check_interval_secs;
extern int sysctl_hung_task_warnings; extern int sysctl_hung_task_warnings;
extern int proc_dohung_task_timeout_secs(struct ctl_table *table, int write, int proc_dohung_task_timeout_secs(struct ctl_table *table, int write,
void __user *buffer, void *buffer, size_t *lenp, loff_t *ppos);
size_t *lenp, loff_t *ppos);
#else #else
/* Avoid need for ifdefs elsewhere in the code */ /* Avoid need for ifdefs elsewhere in the code */
enum { sysctl_hung_task_timeout_secs = 0 }; enum { sysctl_hung_task_timeout_secs = 0 };
@ -43,8 +42,7 @@ extern __read_mostly unsigned int sysctl_sched_migration_cost;
extern __read_mostly unsigned int sysctl_sched_nr_migrate; extern __read_mostly unsigned int sysctl_sched_nr_migrate;
int sched_proc_update_handler(struct ctl_table *table, int write, int sched_proc_update_handler(struct ctl_table *table, int write,
void __user *buffer, size_t *length, void *buffer, size_t *length, loff_t *ppos);
loff_t *ppos);
#endif #endif
/* /*
@ -72,33 +70,21 @@ extern unsigned int sysctl_sched_autogroup_enabled;
extern int sysctl_sched_rr_timeslice; extern int sysctl_sched_rr_timeslice;
extern int sched_rr_timeslice; extern int sched_rr_timeslice;
extern int sched_rr_handler(struct ctl_table *table, int write, int sched_rr_handler(struct ctl_table *table, int write, void *buffer,
void __user *buffer, size_t *lenp, size_t *lenp, loff_t *ppos);
loff_t *ppos); int sched_rt_handler(struct ctl_table *table, int write, void *buffer,
size_t *lenp, loff_t *ppos);
extern int sched_rt_handler(struct ctl_table *table, int write, int sysctl_sched_uclamp_handler(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, void *buffer, size_t *lenp, loff_t *ppos);
loff_t *ppos); int sysctl_numa_balancing(struct ctl_table *table, int write, void *buffer,
size_t *lenp, loff_t *ppos);
#ifdef CONFIG_UCLAMP_TASK int sysctl_schedstats(struct ctl_table *table, int write, void *buffer,
extern int sysctl_sched_uclamp_handler(struct ctl_table *table, int write, size_t *lenp, loff_t *ppos);
void __user *buffer, size_t *lenp,
loff_t *ppos);
#endif
extern int sysctl_numa_balancing(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp,
loff_t *ppos);
extern int sysctl_schedstats(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp,
loff_t *ppos);
#if defined(CONFIG_ENERGY_MODEL) && defined(CONFIG_CPU_FREQ_GOV_SCHEDUTIL) #if defined(CONFIG_ENERGY_MODEL) && defined(CONFIG_CPU_FREQ_GOV_SCHEDUTIL)
extern unsigned int sysctl_sched_energy_aware; extern unsigned int sysctl_sched_energy_aware;
extern int sched_energy_aware_handler(struct ctl_table *table, int write, int sched_energy_aware_handler(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, void *buffer, size_t *lenp, loff_t *ppos);
loff_t *ppos);
#endif #endif
#endif /* _LINUX_SCHED_SYSCTL_H */ #endif /* _LINUX_SCHED_SYSCTL_H */

View File

@ -211,7 +211,7 @@ struct request_sock;
#ifdef CONFIG_MMU #ifdef CONFIG_MMU
extern int mmap_min_addr_handler(struct ctl_table *table, int write, extern int mmap_min_addr_handler(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos); void *buffer, size_t *lenp, loff_t *ppos);
#endif #endif
/* security_inode_init_security callback function to write xattrs */ /* security_inode_init_security callback function to write xattrs */

View File

@ -44,35 +44,26 @@ struct ctl_dir;
extern const int sysctl_vals[]; extern const int sysctl_vals[];
typedef int proc_handler (struct ctl_table *ctl, int write, typedef int proc_handler(struct ctl_table *ctl, int write, void *buffer,
void __user *buffer, size_t *lenp, loff_t *ppos); size_t *lenp, loff_t *ppos);
extern int proc_dostring(struct ctl_table *, int, int proc_dostring(struct ctl_table *, int, void *, size_t *, loff_t *);
void __user *, size_t *, loff_t *); int proc_dointvec(struct ctl_table *, int, void *, size_t *, loff_t *);
extern int proc_dointvec(struct ctl_table *, int, int proc_douintvec(struct ctl_table *, int, void *, size_t *, loff_t *);
void __user *, size_t *, loff_t *); int proc_dointvec_minmax(struct ctl_table *, int, void *, size_t *, loff_t *);
extern int proc_douintvec(struct ctl_table *, int, int proc_douintvec_minmax(struct ctl_table *table, int write, void *buffer,
void __user *, size_t *, loff_t *); size_t *lenp, loff_t *ppos);
extern int proc_dointvec_minmax(struct ctl_table *, int, int proc_dointvec_jiffies(struct ctl_table *, int, void *, size_t *, loff_t *);
void __user *, size_t *, loff_t *); int proc_dointvec_userhz_jiffies(struct ctl_table *, int, void *, size_t *,
extern int proc_douintvec_minmax(struct ctl_table *table, int write, loff_t *);
void __user *buffer, size_t *lenp, int proc_dointvec_ms_jiffies(struct ctl_table *, int, void *, size_t *,
loff_t *ppos); loff_t *);
extern int proc_dointvec_jiffies(struct ctl_table *, int, int proc_doulongvec_minmax(struct ctl_table *, int, void *, size_t *, loff_t *);
void __user *, size_t *, loff_t *); int proc_doulongvec_ms_jiffies_minmax(struct ctl_table *table, int, void *,
extern int proc_dointvec_userhz_jiffies(struct ctl_table *, int, size_t *, loff_t *);
void __user *, size_t *, loff_t *); int proc_do_large_bitmap(struct ctl_table *, int, void *, size_t *, loff_t *);
extern int proc_dointvec_ms_jiffies(struct ctl_table *, int, int proc_do_static_key(struct ctl_table *table, int write, void *buffer,
void __user *, size_t *, loff_t *); size_t *lenp, loff_t *ppos);
extern int proc_doulongvec_minmax(struct ctl_table *, int,
void __user *, size_t *, loff_t *);
extern int proc_doulongvec_ms_jiffies_minmax(struct ctl_table *table, int,
void __user *, size_t *, loff_t *);
extern int proc_do_large_bitmap(struct ctl_table *, int,
void __user *, size_t *, loff_t *);
extern int proc_do_static_key(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp,
loff_t *ppos);
/* /*
* Register a set of sysctl names by calling register_sysctl_table * Register a set of sysctl names by calling register_sysctl_table
@ -207,7 +198,15 @@ void unregister_sysctl_table(struct ctl_table_header * table);
extern int sysctl_init(void); extern int sysctl_init(void);
extern int pwrsw_enabled;
extern int unaligned_enabled;
extern int unaligned_dump_stack;
extern int no_unaligned_warning;
extern struct ctl_table sysctl_mount_point[]; extern struct ctl_table sysctl_mount_point[];
extern struct ctl_table random_table[];
extern struct ctl_table firmware_config_table[];
extern struct ctl_table epoll_table[];
#else /* CONFIG_SYSCTL */ #else /* CONFIG_SYSCTL */
static inline struct ctl_table_header *register_sysctl_table(struct ctl_table * table) static inline struct ctl_table_header *register_sysctl_table(struct ctl_table * table)
@ -238,7 +237,7 @@ static inline void setup_sysctl_set(struct ctl_table_set *p,
#endif /* CONFIG_SYSCTL */ #endif /* CONFIG_SYSCTL */
int sysctl_max_threads(struct ctl_table *table, int write, int sysctl_max_threads(struct ctl_table *table, int write, void *buffer,
void __user *buffer, size_t *lenp, loff_t *ppos); size_t *lenp, loff_t *ppos);
#endif /* _LINUX_SYSCTL_H */ #endif /* _LINUX_SYSCTL_H */

View File

@ -201,8 +201,7 @@ struct ctl_table;
extern unsigned int sysctl_timer_migration; extern unsigned int sysctl_timer_migration;
int timer_migration_handler(struct ctl_table *table, int write, int timer_migration_handler(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, void *buffer, size_t *lenp, loff_t *ppos);
loff_t *ppos);
#endif #endif
unsigned long __round_jiffies(unsigned long j, int cpu); unsigned long __round_jiffies(unsigned long j, int cpu);

View File

@ -16,8 +16,8 @@ extern int sysctl_stat_interval;
#define DISABLE_NUMA_STAT 0 #define DISABLE_NUMA_STAT 0
extern int sysctl_vm_numa_stat; extern int sysctl_vm_numa_stat;
DECLARE_STATIC_KEY_TRUE(vm_numa_stat_key); DECLARE_STATIC_KEY_TRUE(vm_numa_stat_key);
extern int sysctl_vm_numa_stat_handler(struct ctl_table *table, int sysctl_vm_numa_stat_handler(struct ctl_table *table, int write,
int write, void __user *buffer, size_t *length, loff_t *ppos); void *buffer, size_t *length, loff_t *ppos);
#endif #endif
struct reclaim_stat { struct reclaim_stat {
@ -274,8 +274,8 @@ void cpu_vm_stats_fold(int cpu);
void refresh_zone_stat_thresholds(void); void refresh_zone_stat_thresholds(void);
struct ctl_table; struct ctl_table;
int vmstat_refresh(struct ctl_table *, int write, int vmstat_refresh(struct ctl_table *, int write, void *buffer, size_t *lenp,
void __user *buffer, size_t *lenp, loff_t *ppos); loff_t *ppos);
void drain_zonestat(struct zone *zone, struct per_cpu_pageset *); void drain_zonestat(struct zone *zone, struct per_cpu_pageset *);

View File

@ -362,24 +362,18 @@ extern int vm_highmem_is_dirtyable;
extern int block_dump; extern int block_dump;
extern int laptop_mode; extern int laptop_mode;
extern int dirty_background_ratio_handler(struct ctl_table *table, int write, int dirty_background_ratio_handler(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, void *buffer, size_t *lenp, loff_t *ppos);
loff_t *ppos); int dirty_background_bytes_handler(struct ctl_table *table, int write,
extern int dirty_background_bytes_handler(struct ctl_table *table, int write, void *buffer, size_t *lenp, loff_t *ppos);
void __user *buffer, size_t *lenp, int dirty_ratio_handler(struct ctl_table *table, int write,
loff_t *ppos); void *buffer, size_t *lenp, loff_t *ppos);
extern int dirty_ratio_handler(struct ctl_table *table, int write, int dirty_bytes_handler(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, void *buffer, size_t *lenp, loff_t *ppos);
loff_t *ppos);
extern int dirty_bytes_handler(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp,
loff_t *ppos);
int dirtytime_interval_handler(struct ctl_table *table, int write, int dirtytime_interval_handler(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos); void *buffer, size_t *lenp, loff_t *ppos);
int dirty_writeback_centisecs_handler(struct ctl_table *table, int write,
struct ctl_table; void *buffer, size_t *lenp, loff_t *ppos);
int dirty_writeback_centisecs_handler(struct ctl_table *, int,
void __user *, size_t *, loff_t *);
void global_dirty_limits(unsigned long *pbackground, unsigned long *pdirty); void global_dirty_limits(unsigned long *pbackground, unsigned long *pdirty);
unsigned long wb_calc_thresh(struct bdi_writeback *wb, unsigned long thresh); unsigned long wb_calc_thresh(struct bdi_writeback *wb, unsigned long thresh);

View File

@ -113,6 +113,9 @@ enum bpf_cmd {
BPF_MAP_DELETE_BATCH, BPF_MAP_DELETE_BATCH,
BPF_LINK_CREATE, BPF_LINK_CREATE,
BPF_LINK_UPDATE, BPF_LINK_UPDATE,
BPF_LINK_GET_FD_BY_ID,
BPF_LINK_GET_NEXT_ID,
BPF_ENABLE_STATS,
}; };
enum bpf_map_type { enum bpf_map_type {
@ -220,6 +223,15 @@ enum bpf_attach_type {
#define MAX_BPF_ATTACH_TYPE __MAX_BPF_ATTACH_TYPE #define MAX_BPF_ATTACH_TYPE __MAX_BPF_ATTACH_TYPE
enum bpf_link_type {
BPF_LINK_TYPE_UNSPEC = 0,
BPF_LINK_TYPE_RAW_TRACEPOINT = 1,
BPF_LINK_TYPE_TRACING = 2,
BPF_LINK_TYPE_CGROUP = 3,
MAX_BPF_LINK_TYPE,
};
/* cgroup-bpf attach flags used in BPF_PROG_ATTACH command /* cgroup-bpf attach flags used in BPF_PROG_ATTACH command
* *
* NONE(default): No further bpf programs allowed in the subtree. * NONE(default): No further bpf programs allowed in the subtree.
@ -379,6 +391,12 @@ enum {
*/ */
#define BPF_F_QUERY_EFFECTIVE (1U << 0) #define BPF_F_QUERY_EFFECTIVE (1U << 0)
/* type for BPF_ENABLE_STATS */
enum bpf_stats_type {
/* enabled run_time_ns and run_cnt */
BPF_STATS_RUN_TIME = 0,
};
enum bpf_stack_build_id_status { enum bpf_stack_build_id_status {
/* user space need an empty entry to identify end of a trace */ /* user space need an empty entry to identify end of a trace */
BPF_STACK_BUILD_ID_EMPTY = 0, BPF_STACK_BUILD_ID_EMPTY = 0,
@ -523,6 +541,7 @@ union bpf_attr {
__u32 prog_id; __u32 prog_id;
__u32 map_id; __u32 map_id;
__u32 btf_id; __u32 btf_id;
__u32 link_id;
}; };
__u32 next_id; __u32 next_id;
__u32 open_flags; __u32 open_flags;
@ -589,6 +608,10 @@ union bpf_attr {
__u32 old_prog_fd; __u32 old_prog_fd;
} link_update; } link_update;
struct { /* struct used by BPF_ENABLE_STATS command */
__u32 type;
} enable_stats;
} __attribute__((aligned(8))); } __attribute__((aligned(8)));
/* The description below is an attempt at providing documentation to eBPF /* The description below is an attempt at providing documentation to eBPF
@ -652,6 +675,8 @@ union bpf_attr {
* u64 bpf_ktime_get_ns(void) * u64 bpf_ktime_get_ns(void)
* Description * Description
* Return the time elapsed since system boot, in nanoseconds. * Return the time elapsed since system boot, in nanoseconds.
* Does not include time the system was suspended.
* See: clock_gettime(CLOCK_MONOTONIC)
* Return * Return
* Current *ktime*. * Current *ktime*.
* *
@ -1562,7 +1587,7 @@ union bpf_attr {
* Return * Return
* 0 * 0
* *
* int bpf_setsockopt(struct bpf_sock_ops *bpf_socket, int level, int optname, void *optval, int optlen) * int bpf_setsockopt(void *bpf_socket, int level, int optname, void *optval, int optlen)
* Description * Description
* Emulate a call to **setsockopt()** on the socket associated to * Emulate a call to **setsockopt()** on the socket associated to
* *bpf_socket*, which must be a full socket. The *level* at * *bpf_socket*, which must be a full socket. The *level* at
@ -1570,6 +1595,11 @@ union bpf_attr {
* must be specified, see **setsockopt(2)** for more information. * must be specified, see **setsockopt(2)** for more information.
* The option value of length *optlen* is pointed by *optval*. * The option value of length *optlen* is pointed by *optval*.
* *
* *bpf_socket* should be one of the following:
* * **struct bpf_sock_ops** for **BPF_PROG_TYPE_SOCK_OPS**.
* * **struct bpf_sock_addr** for **BPF_CGROUP_INET4_CONNECT**
* and **BPF_CGROUP_INET6_CONNECT**.
*
* This helper actually implements a subset of **setsockopt()**. * This helper actually implements a subset of **setsockopt()**.
* It supports the following *level*\ s: * It supports the following *level*\ s:
* *
@ -1764,7 +1794,7 @@ union bpf_attr {
* Return * Return
* 0 on success, or a negative error in case of failure. * 0 on success, or a negative error in case of failure.
* *
* int bpf_getsockopt(struct bpf_sock_ops *bpf_socket, int level, int optname, void *optval, int optlen) * int bpf_getsockopt(void *bpf_socket, int level, int optname, void *optval, int optlen)
* Description * Description
* Emulate a call to **getsockopt()** on the socket associated to * Emulate a call to **getsockopt()** on the socket associated to
* *bpf_socket*, which must be a full socket. The *level* at * *bpf_socket*, which must be a full socket. The *level* at
@ -1773,6 +1803,11 @@ union bpf_attr {
* The retrieved value is stored in the structure pointed by * The retrieved value is stored in the structure pointed by
* *opval* and of length *optlen*. * *opval* and of length *optlen*.
* *
* *bpf_socket* should be one of the following:
* * **struct bpf_sock_ops** for **BPF_PROG_TYPE_SOCK_OPS**.
* * **struct bpf_sock_addr** for **BPF_CGROUP_INET4_CONNECT**
* and **BPF_CGROUP_INET6_CONNECT**.
*
* This helper actually implements a subset of **getsockopt()**. * This helper actually implements a subset of **getsockopt()**.
* It supports the following *level*\ s: * It supports the following *level*\ s:
* *
@ -3025,6 +3060,14 @@ union bpf_attr {
* * **-EOPNOTSUPP** Unsupported operation, for example a * * **-EOPNOTSUPP** Unsupported operation, for example a
* call from outside of TC ingress. * call from outside of TC ingress.
* * **-ESOCKTNOSUPPORT** Socket type not supported (reuseport). * * **-ESOCKTNOSUPPORT** Socket type not supported (reuseport).
*
* u64 bpf_ktime_get_boot_ns(void)
* Description
* Return the time elapsed since system boot, in nanoseconds.
* Does include the time the system was suspended.
* See: clock_gettime(CLOCK_BOOTTIME)
* Return
* Current *ktime*.
*/ */
#define __BPF_FUNC_MAPPER(FN) \ #define __BPF_FUNC_MAPPER(FN) \
FN(unspec), \ FN(unspec), \
@ -3151,7 +3194,8 @@ union bpf_attr {
FN(xdp_output), \ FN(xdp_output), \
FN(get_netns_cookie), \ FN(get_netns_cookie), \
FN(get_current_ancestor_cgroup_id), \ FN(get_current_ancestor_cgroup_id), \
FN(sk_assign), FN(sk_assign), \
FN(ktime_get_boot_ns),
/* integer value in 'imm' field of BPF_CALL instruction selects which helper /* integer value in 'imm' field of BPF_CALL instruction selects which helper
* function eBPF program intends to call * function eBPF program intends to call
@ -3598,6 +3642,25 @@ struct bpf_btf_info {
__u32 id; __u32 id;
} __attribute__((aligned(8))); } __attribute__((aligned(8)));
struct bpf_link_info {
__u32 type;
__u32 id;
__u32 prog_id;
union {
struct {
__aligned_u64 tp_name; /* in/out: tp_name buffer ptr */
__u32 tp_name_len; /* in/out: tp_name buffer len */
} raw_tracepoint;
struct {
__u32 attach_type;
} tracing;
struct {
__u64 cgroup_id;
__u32 attach_type;
} cgroup;
};
} __attribute__((aligned(8)));
/* User bpf_sock_addr struct to access socket fields and sockaddr struct passed /* User bpf_sock_addr struct to access socket fields and sockaddr struct passed
* by user and intended to be used by socket (e.g. to bind to, depends on * by user and intended to be used by socket (e.g. to bind to, depends on
* attach attach type). * attach attach type).

View File

@ -24,7 +24,7 @@ static void *get_ipc(struct ctl_table *table)
#ifdef CONFIG_PROC_SYSCTL #ifdef CONFIG_PROC_SYSCTL
static int proc_ipc_dointvec(struct ctl_table *table, int write, static int proc_ipc_dointvec(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos) void *buffer, size_t *lenp, loff_t *ppos)
{ {
struct ctl_table ipc_table; struct ctl_table ipc_table;
@ -35,7 +35,7 @@ static int proc_ipc_dointvec(struct ctl_table *table, int write,
} }
static int proc_ipc_dointvec_minmax(struct ctl_table *table, int write, static int proc_ipc_dointvec_minmax(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos) void *buffer, size_t *lenp, loff_t *ppos)
{ {
struct ctl_table ipc_table; struct ctl_table ipc_table;
@ -46,7 +46,7 @@ static int proc_ipc_dointvec_minmax(struct ctl_table *table, int write,
} }
static int proc_ipc_dointvec_minmax_orphans(struct ctl_table *table, int write, static int proc_ipc_dointvec_minmax_orphans(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos) void *buffer, size_t *lenp, loff_t *ppos)
{ {
struct ipc_namespace *ns = current->nsproxy->ipc_ns; struct ipc_namespace *ns = current->nsproxy->ipc_ns;
int err = proc_ipc_dointvec_minmax(table, write, buffer, lenp, ppos); int err = proc_ipc_dointvec_minmax(table, write, buffer, lenp, ppos);
@ -59,7 +59,7 @@ static int proc_ipc_dointvec_minmax_orphans(struct ctl_table *table, int write,
} }
static int proc_ipc_doulongvec_minmax(struct ctl_table *table, int write, static int proc_ipc_doulongvec_minmax(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos) void *buffer, size_t *lenp, loff_t *ppos)
{ {
struct ctl_table ipc_table; struct ctl_table ipc_table;
memcpy(&ipc_table, table, sizeof(ipc_table)); memcpy(&ipc_table, table, sizeof(ipc_table));
@ -70,7 +70,7 @@ static int proc_ipc_doulongvec_minmax(struct ctl_table *table, int write,
} }
static int proc_ipc_auto_msgmni(struct ctl_table *table, int write, static int proc_ipc_auto_msgmni(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos) void *buffer, size_t *lenp, loff_t *ppos)
{ {
struct ctl_table ipc_table; struct ctl_table ipc_table;
int dummy = 0; int dummy = 0;

View File

@ -19,7 +19,7 @@ static void *get_mq(struct ctl_table *table)
} }
static int proc_mq_dointvec(struct ctl_table *table, int write, static int proc_mq_dointvec(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos) void *buffer, size_t *lenp, loff_t *ppos)
{ {
struct ctl_table mq_table; struct ctl_table mq_table;
memcpy(&mq_table, table, sizeof(mq_table)); memcpy(&mq_table, table, sizeof(mq_table));
@ -29,7 +29,7 @@ static int proc_mq_dointvec(struct ctl_table *table, int write,
} }
static int proc_mq_dointvec_minmax(struct ctl_table *table, int write, static int proc_mq_dointvec_minmax(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos) void *buffer, size_t *lenp, loff_t *ppos)
{ {
struct ctl_table mq_table; struct ctl_table mq_table;
memcpy(&mq_table, table, sizeof(mq_table)); memcpy(&mq_table, table, sizeof(mq_table));

View File

@ -3482,6 +3482,7 @@ extern char __weak __stop_BTF[];
extern struct btf *btf_vmlinux; extern struct btf *btf_vmlinux;
#define BPF_MAP_TYPE(_id, _ops) #define BPF_MAP_TYPE(_id, _ops)
#define BPF_LINK_TYPE(_id, _name)
static union { static union {
struct bpf_ctx_convert { struct bpf_ctx_convert {
#define BPF_PROG_TYPE(_id, _name, prog_ctx_type, kern_ctx_type) \ #define BPF_PROG_TYPE(_id, _name, prog_ctx_type, kern_ctx_type) \
@ -3508,6 +3509,7 @@ static u8 bpf_ctx_convert_map[] = {
0, /* avoid empty array */ 0, /* avoid empty array */
}; };
#undef BPF_MAP_TYPE #undef BPF_MAP_TYPE
#undef BPF_LINK_TYPE
static const struct btf_member * static const struct btf_member *
btf_get_prog_ctx_type(struct bpf_verifier_log *log, struct btf *btf, btf_get_prog_ctx_type(struct bpf_verifier_log *log, struct btf *btf,

View File

@ -557,8 +557,9 @@ found:
* *
* Must be called with cgroup_mutex held. * Must be called with cgroup_mutex held.
*/ */
int __cgroup_bpf_replace(struct cgroup *cgrp, struct bpf_cgroup_link *link, static int __cgroup_bpf_replace(struct cgroup *cgrp,
struct bpf_prog *new_prog) struct bpf_cgroup_link *link,
struct bpf_prog *new_prog)
{ {
struct list_head *progs = &cgrp->bpf.progs[link->type]; struct list_head *progs = &cgrp->bpf.progs[link->type];
struct bpf_prog *old_prog; struct bpf_prog *old_prog;
@ -583,6 +584,30 @@ int __cgroup_bpf_replace(struct cgroup *cgrp, struct bpf_cgroup_link *link,
return 0; return 0;
} }
static int cgroup_bpf_replace(struct bpf_link *link, struct bpf_prog *new_prog,
struct bpf_prog *old_prog)
{
struct bpf_cgroup_link *cg_link;
int ret;
cg_link = container_of(link, struct bpf_cgroup_link, link);
mutex_lock(&cgroup_mutex);
/* link might have been auto-released by dying cgroup, so fail */
if (!cg_link->cgroup) {
ret = -EINVAL;
goto out_unlock;
}
if (old_prog && link->prog != old_prog) {
ret = -EPERM;
goto out_unlock;
}
ret = __cgroup_bpf_replace(cg_link->cgroup, cg_link, new_prog);
out_unlock:
mutex_unlock(&cgroup_mutex);
return ret;
}
static struct bpf_prog_list *find_detach_entry(struct list_head *progs, static struct bpf_prog_list *find_detach_entry(struct list_head *progs,
struct bpf_prog *prog, struct bpf_prog *prog,
struct bpf_cgroup_link *link, struct bpf_cgroup_link *link,
@ -808,17 +833,56 @@ static void bpf_cgroup_link_dealloc(struct bpf_link *link)
kfree(cg_link); kfree(cg_link);
} }
const struct bpf_link_ops bpf_cgroup_link_lops = { static void bpf_cgroup_link_show_fdinfo(const struct bpf_link *link,
struct seq_file *seq)
{
struct bpf_cgroup_link *cg_link =
container_of(link, struct bpf_cgroup_link, link);
u64 cg_id = 0;
mutex_lock(&cgroup_mutex);
if (cg_link->cgroup)
cg_id = cgroup_id(cg_link->cgroup);
mutex_unlock(&cgroup_mutex);
seq_printf(seq,
"cgroup_id:\t%llu\n"
"attach_type:\t%d\n",
cg_id,
cg_link->type);
}
static int bpf_cgroup_link_fill_link_info(const struct bpf_link *link,
struct bpf_link_info *info)
{
struct bpf_cgroup_link *cg_link =
container_of(link, struct bpf_cgroup_link, link);
u64 cg_id = 0;
mutex_lock(&cgroup_mutex);
if (cg_link->cgroup)
cg_id = cgroup_id(cg_link->cgroup);
mutex_unlock(&cgroup_mutex);
info->cgroup.cgroup_id = cg_id;
info->cgroup.attach_type = cg_link->type;
return 0;
}
static const struct bpf_link_ops bpf_cgroup_link_lops = {
.release = bpf_cgroup_link_release, .release = bpf_cgroup_link_release,
.dealloc = bpf_cgroup_link_dealloc, .dealloc = bpf_cgroup_link_dealloc,
.update_prog = cgroup_bpf_replace,
.show_fdinfo = bpf_cgroup_link_show_fdinfo,
.fill_link_info = bpf_cgroup_link_fill_link_info,
}; };
int cgroup_bpf_link_attach(const union bpf_attr *attr, struct bpf_prog *prog) int cgroup_bpf_link_attach(const union bpf_attr *attr, struct bpf_prog *prog)
{ {
struct bpf_link_primer link_primer;
struct bpf_cgroup_link *link; struct bpf_cgroup_link *link;
struct file *link_file;
struct cgroup *cgrp; struct cgroup *cgrp;
int err, link_fd; int err;
if (attr->link_create.flags) if (attr->link_create.flags)
return -EINVAL; return -EINVAL;
@ -832,26 +896,25 @@ int cgroup_bpf_link_attach(const union bpf_attr *attr, struct bpf_prog *prog)
err = -ENOMEM; err = -ENOMEM;
goto out_put_cgroup; goto out_put_cgroup;
} }
bpf_link_init(&link->link, &bpf_cgroup_link_lops, prog); bpf_link_init(&link->link, BPF_LINK_TYPE_CGROUP, &bpf_cgroup_link_lops,
prog);
link->cgroup = cgrp; link->cgroup = cgrp;
link->type = attr->link_create.attach_type; link->type = attr->link_create.attach_type;
link_file = bpf_link_new_file(&link->link, &link_fd); err = bpf_link_prime(&link->link, &link_primer);
if (IS_ERR(link_file)) { if (err) {
kfree(link); kfree(link);
err = PTR_ERR(link_file);
goto out_put_cgroup; goto out_put_cgroup;
} }
err = cgroup_bpf_attach(cgrp, NULL, NULL, link, link->type, err = cgroup_bpf_attach(cgrp, NULL, NULL, link, link->type,
BPF_F_ALLOW_MULTI); BPF_F_ALLOW_MULTI);
if (err) { if (err) {
bpf_link_cleanup(&link->link, link_file, link_fd); bpf_link_cleanup(&link_primer);
goto out_put_cgroup; goto out_put_cgroup;
} }
fd_install(link_fd, link_file); return bpf_link_settle(&link_primer);
return link_fd;
out_put_cgroup: out_put_cgroup:
cgroup_put(cgrp); cgroup_put(cgrp);
@ -1054,36 +1117,21 @@ int __cgroup_bpf_check_dev_permission(short dev_type, u32 major, u32 minor,
return !allow; return !allow;
} }
EXPORT_SYMBOL(__cgroup_bpf_check_dev_permission);
static const struct bpf_func_proto * static const struct bpf_func_proto *
cgroup_base_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog) cgroup_base_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
{ {
switch (func_id) { switch (func_id) {
case BPF_FUNC_map_lookup_elem:
return &bpf_map_lookup_elem_proto;
case BPF_FUNC_map_update_elem:
return &bpf_map_update_elem_proto;
case BPF_FUNC_map_delete_elem:
return &bpf_map_delete_elem_proto;
case BPF_FUNC_map_push_elem:
return &bpf_map_push_elem_proto;
case BPF_FUNC_map_pop_elem:
return &bpf_map_pop_elem_proto;
case BPF_FUNC_map_peek_elem:
return &bpf_map_peek_elem_proto;
case BPF_FUNC_get_current_uid_gid: case BPF_FUNC_get_current_uid_gid:
return &bpf_get_current_uid_gid_proto; return &bpf_get_current_uid_gid_proto;
case BPF_FUNC_get_local_storage: case BPF_FUNC_get_local_storage:
return &bpf_get_local_storage_proto; return &bpf_get_local_storage_proto;
case BPF_FUNC_get_current_cgroup_id: case BPF_FUNC_get_current_cgroup_id:
return &bpf_get_current_cgroup_id_proto; return &bpf_get_current_cgroup_id_proto;
case BPF_FUNC_trace_printk: case BPF_FUNC_perf_event_output:
if (capable(CAP_SYS_ADMIN)) return &bpf_event_output_data_proto;
return bpf_get_trace_printk_proto();
/* fall through */
default: default:
return NULL; return bpf_base_func_proto(func_id);
} }
} }
@ -1137,16 +1185,13 @@ const struct bpf_verifier_ops cg_dev_verifier_ops = {
* @head: sysctl table header * @head: sysctl table header
* @table: sysctl table * @table: sysctl table
* @write: sysctl is being read (= 0) or written (= 1) * @write: sysctl is being read (= 0) or written (= 1)
* @buf: pointer to buffer passed by user space * @buf: pointer to buffer (in and out)
* @pcount: value-result argument: value is size of buffer pointed to by @buf, * @pcount: value-result argument: value is size of buffer pointed to by @buf,
* result is size of @new_buf if program set new value, initial value * result is size of @new_buf if program set new value, initial value
* otherwise * otherwise
* @ppos: value-result argument: value is position at which read from or write * @ppos: value-result argument: value is position at which read from or write
* to sysctl is happening, result is new position if program overrode it, * to sysctl is happening, result is new position if program overrode it,
* initial value otherwise * initial value otherwise
* @new_buf: pointer to pointer to new buffer that will be allocated if program
* overrides new value provided by user space on sysctl write
* NOTE: it's caller responsibility to free *new_buf if it was set
* @type: type of program to be executed * @type: type of program to be executed
* *
* Program is run when sysctl is being accessed, either read or written, and * Program is run when sysctl is being accessed, either read or written, and
@ -1157,8 +1202,7 @@ const struct bpf_verifier_ops cg_dev_verifier_ops = {
*/ */
int __cgroup_bpf_run_filter_sysctl(struct ctl_table_header *head, int __cgroup_bpf_run_filter_sysctl(struct ctl_table_header *head,
struct ctl_table *table, int write, struct ctl_table *table, int write,
void __user *buf, size_t *pcount, void **buf, size_t *pcount, loff_t *ppos,
loff_t *ppos, void **new_buf,
enum bpf_attach_type type) enum bpf_attach_type type)
{ {
struct bpf_sysctl_kern ctx = { struct bpf_sysctl_kern ctx = {
@ -1173,36 +1217,28 @@ int __cgroup_bpf_run_filter_sysctl(struct ctl_table_header *head,
.new_updated = 0, .new_updated = 0,
}; };
struct cgroup *cgrp; struct cgroup *cgrp;
loff_t pos = 0;
int ret; int ret;
ctx.cur_val = kmalloc_track_caller(ctx.cur_len, GFP_KERNEL); ctx.cur_val = kmalloc_track_caller(ctx.cur_len, GFP_KERNEL);
if (ctx.cur_val) { if (!ctx.cur_val ||
mm_segment_t old_fs; table->proc_handler(table, 0, ctx.cur_val, &ctx.cur_len, &pos)) {
loff_t pos = 0;
old_fs = get_fs();
set_fs(KERNEL_DS);
if (table->proc_handler(table, 0, (void __user *)ctx.cur_val,
&ctx.cur_len, &pos)) {
/* Let BPF program decide how to proceed. */
ctx.cur_len = 0;
}
set_fs(old_fs);
} else {
/* Let BPF program decide how to proceed. */ /* Let BPF program decide how to proceed. */
ctx.cur_len = 0; ctx.cur_len = 0;
} }
if (write && buf && *pcount) { if (write && *buf && *pcount) {
/* BPF program should be able to override new value with a /* BPF program should be able to override new value with a
* buffer bigger than provided by user. * buffer bigger than provided by user.
*/ */
ctx.new_val = kmalloc_track_caller(PAGE_SIZE, GFP_KERNEL); ctx.new_val = kmalloc_track_caller(PAGE_SIZE, GFP_KERNEL);
ctx.new_len = min_t(size_t, PAGE_SIZE, *pcount); ctx.new_len = min_t(size_t, PAGE_SIZE, *pcount);
if (!ctx.new_val || if (ctx.new_val) {
copy_from_user(ctx.new_val, buf, ctx.new_len)) memcpy(ctx.new_val, *buf, ctx.new_len);
} else {
/* Let BPF program decide how to proceed. */ /* Let BPF program decide how to proceed. */
ctx.new_len = 0; ctx.new_len = 0;
}
} }
rcu_read_lock(); rcu_read_lock();
@ -1213,7 +1249,8 @@ int __cgroup_bpf_run_filter_sysctl(struct ctl_table_header *head,
kfree(ctx.cur_val); kfree(ctx.cur_val);
if (ret == 1 && ctx.new_updated) { if (ret == 1 && ctx.new_updated) {
*new_buf = ctx.new_val; kfree(*buf);
*buf = ctx.new_val;
*pcount = ctx.new_len; *pcount = ctx.new_len;
} else { } else {
kfree(ctx.new_val); kfree(ctx.new_val);
@ -1221,7 +1258,6 @@ int __cgroup_bpf_run_filter_sysctl(struct ctl_table_header *head,
return ret == 1 ? 0 : -EPERM; return ret == 1 ? 0 : -EPERM;
} }
EXPORT_SYMBOL(__cgroup_bpf_run_filter_sysctl);
#ifdef CONFIG_NET #ifdef CONFIG_NET
static bool __cgroup_bpf_prog_array_is_empty(struct cgroup *cgrp, static bool __cgroup_bpf_prog_array_is_empty(struct cgroup *cgrp,
@ -1326,7 +1362,6 @@ out:
sockopt_free_buf(&ctx); sockopt_free_buf(&ctx);
return ret; return ret;
} }
EXPORT_SYMBOL(__cgroup_bpf_run_filter_setsockopt);
int __cgroup_bpf_run_filter_getsockopt(struct sock *sk, int level, int __cgroup_bpf_run_filter_getsockopt(struct sock *sk, int level,
int optname, char __user *optval, int optname, char __user *optval,
@ -1413,7 +1448,6 @@ out:
sockopt_free_buf(&ctx); sockopt_free_buf(&ctx);
return ret; return ret;
} }
EXPORT_SYMBOL(__cgroup_bpf_run_filter_getsockopt);
#endif #endif
static ssize_t sysctl_cpy_dir(const struct ctl_dir *dir, char **bufp, static ssize_t sysctl_cpy_dir(const struct ctl_dir *dir, char **bufp,

View File

@ -2136,6 +2136,11 @@ BPF_CALL_0(bpf_user_rnd_u32)
return res; return res;
} }
BPF_CALL_0(bpf_get_raw_cpu_id)
{
return raw_smp_processor_id();
}
/* Weak definitions of helper functions in case we don't have bpf syscall. */ /* Weak definitions of helper functions in case we don't have bpf syscall. */
const struct bpf_func_proto bpf_map_lookup_elem_proto __weak; const struct bpf_func_proto bpf_map_lookup_elem_proto __weak;
const struct bpf_func_proto bpf_map_update_elem_proto __weak; const struct bpf_func_proto bpf_map_update_elem_proto __weak;
@ -2151,6 +2156,7 @@ const struct bpf_func_proto bpf_get_prandom_u32_proto __weak;
const struct bpf_func_proto bpf_get_smp_processor_id_proto __weak; const struct bpf_func_proto bpf_get_smp_processor_id_proto __weak;
const struct bpf_func_proto bpf_get_numa_node_id_proto __weak; const struct bpf_func_proto bpf_get_numa_node_id_proto __weak;
const struct bpf_func_proto bpf_ktime_get_ns_proto __weak; const struct bpf_func_proto bpf_ktime_get_ns_proto __weak;
const struct bpf_func_proto bpf_ktime_get_boot_ns_proto __weak;
const struct bpf_func_proto bpf_get_current_pid_tgid_proto __weak; const struct bpf_func_proto bpf_get_current_pid_tgid_proto __weak;
const struct bpf_func_proto bpf_get_current_uid_gid_proto __weak; const struct bpf_func_proto bpf_get_current_uid_gid_proto __weak;

View File

@ -151,7 +151,19 @@ BPF_CALL_0(bpf_ktime_get_ns)
const struct bpf_func_proto bpf_ktime_get_ns_proto = { const struct bpf_func_proto bpf_ktime_get_ns_proto = {
.func = bpf_ktime_get_ns, .func = bpf_ktime_get_ns,
.gpl_only = true, .gpl_only = false,
.ret_type = RET_INTEGER,
};
BPF_CALL_0(bpf_ktime_get_boot_ns)
{
/* NMI safe access to clock boottime */
return ktime_get_boot_fast_ns();
}
const struct bpf_func_proto bpf_ktime_get_boot_ns_proto = {
.func = bpf_ktime_get_boot_ns,
.gpl_only = false,
.ret_type = RET_INTEGER, .ret_type = RET_INTEGER,
}; };
@ -562,3 +574,78 @@ const struct bpf_func_proto bpf_get_ns_current_pid_tgid_proto = {
.arg3_type = ARG_PTR_TO_UNINIT_MEM, .arg3_type = ARG_PTR_TO_UNINIT_MEM,
.arg4_type = ARG_CONST_SIZE, .arg4_type = ARG_CONST_SIZE,
}; };
static const struct bpf_func_proto bpf_get_raw_smp_processor_id_proto = {
.func = bpf_get_raw_cpu_id,
.gpl_only = false,
.ret_type = RET_INTEGER,
};
BPF_CALL_5(bpf_event_output_data, void *, ctx, struct bpf_map *, map,
u64, flags, void *, data, u64, size)
{
if (unlikely(flags & ~(BPF_F_INDEX_MASK)))
return -EINVAL;
return bpf_event_output(map, flags, data, size, NULL, 0, NULL);
}
const struct bpf_func_proto bpf_event_output_data_proto = {
.func = bpf_event_output_data,
.gpl_only = true,
.ret_type = RET_INTEGER,
.arg1_type = ARG_PTR_TO_CTX,
.arg2_type = ARG_CONST_MAP_PTR,
.arg3_type = ARG_ANYTHING,
.arg4_type = ARG_PTR_TO_MEM,
.arg5_type = ARG_CONST_SIZE_OR_ZERO,
};
const struct bpf_func_proto *
bpf_base_func_proto(enum bpf_func_id func_id)
{
switch (func_id) {
case BPF_FUNC_map_lookup_elem:
return &bpf_map_lookup_elem_proto;
case BPF_FUNC_map_update_elem:
return &bpf_map_update_elem_proto;
case BPF_FUNC_map_delete_elem:
return &bpf_map_delete_elem_proto;
case BPF_FUNC_map_push_elem:
return &bpf_map_push_elem_proto;
case BPF_FUNC_map_pop_elem:
return &bpf_map_pop_elem_proto;
case BPF_FUNC_map_peek_elem:
return &bpf_map_peek_elem_proto;
case BPF_FUNC_get_prandom_u32:
return &bpf_get_prandom_u32_proto;
case BPF_FUNC_get_smp_processor_id:
return &bpf_get_raw_smp_processor_id_proto;
case BPF_FUNC_get_numa_node_id:
return &bpf_get_numa_node_id_proto;
case BPF_FUNC_tail_call:
return &bpf_tail_call_proto;
case BPF_FUNC_ktime_get_ns:
return &bpf_ktime_get_ns_proto;
case BPF_FUNC_ktime_get_boot_ns:
return &bpf_ktime_get_boot_ns_proto;
default:
break;
}
if (!capable(CAP_SYS_ADMIN))
return NULL;
switch (func_id) {
case BPF_FUNC_spin_lock:
return &bpf_spin_lock_proto;
case BPF_FUNC_spin_unlock:
return &bpf_spin_unlock_proto;
case BPF_FUNC_trace_printk:
return bpf_get_trace_printk_proto();
case BPF_FUNC_jiffies64:
return &bpf_jiffies64_proto;
default:
return NULL;
}
}

View File

@ -42,6 +42,8 @@ static DEFINE_IDR(prog_idr);
static DEFINE_SPINLOCK(prog_idr_lock); static DEFINE_SPINLOCK(prog_idr_lock);
static DEFINE_IDR(map_idr); static DEFINE_IDR(map_idr);
static DEFINE_SPINLOCK(map_idr_lock); static DEFINE_SPINLOCK(map_idr_lock);
static DEFINE_IDR(link_idr);
static DEFINE_SPINLOCK(link_idr_lock);
int sysctl_unprivileged_bpf_disabled __read_mostly; int sysctl_unprivileged_bpf_disabled __read_mostly;
@ -49,9 +51,11 @@ static const struct bpf_map_ops * const bpf_map_types[] = {
#define BPF_PROG_TYPE(_id, _name, prog_ctx_type, kern_ctx_type) #define BPF_PROG_TYPE(_id, _name, prog_ctx_type, kern_ctx_type)
#define BPF_MAP_TYPE(_id, _ops) \ #define BPF_MAP_TYPE(_id, _ops) \
[_id] = &_ops, [_id] = &_ops,
#define BPF_LINK_TYPE(_id, _name)
#include <linux/bpf_types.h> #include <linux/bpf_types.h>
#undef BPF_PROG_TYPE #undef BPF_PROG_TYPE
#undef BPF_MAP_TYPE #undef BPF_MAP_TYPE
#undef BPF_LINK_TYPE
}; };
/* /*
@ -1546,9 +1550,11 @@ static const struct bpf_prog_ops * const bpf_prog_types[] = {
#define BPF_PROG_TYPE(_id, _name, prog_ctx_type, kern_ctx_type) \ #define BPF_PROG_TYPE(_id, _name, prog_ctx_type, kern_ctx_type) \
[_id] = & _name ## _prog_ops, [_id] = & _name ## _prog_ops,
#define BPF_MAP_TYPE(_id, _ops) #define BPF_MAP_TYPE(_id, _ops)
#define BPF_LINK_TYPE(_id, _name)
#include <linux/bpf_types.h> #include <linux/bpf_types.h>
#undef BPF_PROG_TYPE #undef BPF_PROG_TYPE
#undef BPF_MAP_TYPE #undef BPF_MAP_TYPE
#undef BPF_LINK_TYPE
}; };
static int find_prog_type(enum bpf_prog_type type, struct bpf_prog *prog) static int find_prog_type(enum bpf_prog_type type, struct bpf_prog *prog)
@ -2181,25 +2187,39 @@ static int bpf_obj_get(const union bpf_attr *attr)
attr->file_flags); attr->file_flags);
} }
void bpf_link_init(struct bpf_link *link, const struct bpf_link_ops *ops, void bpf_link_init(struct bpf_link *link, enum bpf_link_type type,
struct bpf_prog *prog) const struct bpf_link_ops *ops, struct bpf_prog *prog)
{ {
atomic64_set(&link->refcnt, 1); atomic64_set(&link->refcnt, 1);
link->type = type;
link->id = 0;
link->ops = ops; link->ops = ops;
link->prog = prog; link->prog = prog;
} }
static void bpf_link_free_id(int id)
{
if (!id)
return;
spin_lock_bh(&link_idr_lock);
idr_remove(&link_idr, id);
spin_unlock_bh(&link_idr_lock);
}
/* Clean up bpf_link and corresponding anon_inode file and FD. After /* Clean up bpf_link and corresponding anon_inode file and FD. After
* anon_inode is created, bpf_link can't be just kfree()'d due to deferred * anon_inode is created, bpf_link can't be just kfree()'d due to deferred
* anon_inode's release() call. This helper manages marking bpf_link as * anon_inode's release() call. This helper marksbpf_link as
* defunct, releases anon_inode file and puts reserved FD. * defunct, releases anon_inode file and puts reserved FD. bpf_prog's refcnt
* is not decremented, it's the responsibility of a calling code that failed
* to complete bpf_link initialization.
*/ */
void bpf_link_cleanup(struct bpf_link *link, struct file *link_file, void bpf_link_cleanup(struct bpf_link_primer *primer)
int link_fd)
{ {
link->prog = NULL; primer->link->prog = NULL;
fput(link_file); bpf_link_free_id(primer->id);
put_unused_fd(link_fd); fput(primer->file);
put_unused_fd(primer->fd);
} }
void bpf_link_inc(struct bpf_link *link) void bpf_link_inc(struct bpf_link *link)
@ -2210,6 +2230,7 @@ void bpf_link_inc(struct bpf_link *link)
/* bpf_link_free is guaranteed to be called from process context */ /* bpf_link_free is guaranteed to be called from process context */
static void bpf_link_free(struct bpf_link *link) static void bpf_link_free(struct bpf_link *link)
{ {
bpf_link_free_id(link->id);
if (link->prog) { if (link->prog) {
/* detach BPF program, clean up used resources */ /* detach BPF program, clean up used resources */
link->ops->release(link); link->ops->release(link);
@ -2251,35 +2272,35 @@ static int bpf_link_release(struct inode *inode, struct file *filp)
} }
#ifdef CONFIG_PROC_FS #ifdef CONFIG_PROC_FS
static const struct bpf_link_ops bpf_raw_tp_lops; #define BPF_PROG_TYPE(_id, _name, prog_ctx_type, kern_ctx_type)
static const struct bpf_link_ops bpf_tracing_link_lops; #define BPF_MAP_TYPE(_id, _ops)
#define BPF_LINK_TYPE(_id, _name) [_id] = #_name,
static const char *bpf_link_type_strs[] = {
[BPF_LINK_TYPE_UNSPEC] = "<invalid>",
#include <linux/bpf_types.h>
};
#undef BPF_PROG_TYPE
#undef BPF_MAP_TYPE
#undef BPF_LINK_TYPE
static void bpf_link_show_fdinfo(struct seq_file *m, struct file *filp) static void bpf_link_show_fdinfo(struct seq_file *m, struct file *filp)
{ {
const struct bpf_link *link = filp->private_data; const struct bpf_link *link = filp->private_data;
const struct bpf_prog *prog = link->prog; const struct bpf_prog *prog = link->prog;
char prog_tag[sizeof(prog->tag) * 2 + 1] = { }; char prog_tag[sizeof(prog->tag) * 2 + 1] = { };
const char *link_type;
if (link->ops == &bpf_raw_tp_lops)
link_type = "raw_tracepoint";
else if (link->ops == &bpf_tracing_link_lops)
link_type = "tracing";
#ifdef CONFIG_CGROUP_BPF
else if (link->ops == &bpf_cgroup_link_lops)
link_type = "cgroup";
#endif
else
link_type = "unknown";
bin2hex(prog_tag, prog->tag, sizeof(prog->tag)); bin2hex(prog_tag, prog->tag, sizeof(prog->tag));
seq_printf(m, seq_printf(m,
"link_type:\t%s\n" "link_type:\t%s\n"
"link_id:\t%u\n"
"prog_tag:\t%s\n" "prog_tag:\t%s\n"
"prog_id:\t%u\n", "prog_id:\t%u\n",
link_type, bpf_link_type_strs[link->type],
link->id,
prog_tag, prog_tag,
prog->aux->id); prog->aux->id);
if (link->ops->show_fdinfo)
link->ops->show_fdinfo(link, m);
} }
#endif #endif
@ -2292,36 +2313,77 @@ static const struct file_operations bpf_link_fops = {
.write = bpf_dummy_write, .write = bpf_dummy_write,
}; };
int bpf_link_new_fd(struct bpf_link *link) static int bpf_link_alloc_id(struct bpf_link *link)
{ {
return anon_inode_getfd("bpf-link", &bpf_link_fops, link, O_CLOEXEC); int id;
idr_preload(GFP_KERNEL);
spin_lock_bh(&link_idr_lock);
id = idr_alloc_cyclic(&link_idr, link, 1, INT_MAX, GFP_ATOMIC);
spin_unlock_bh(&link_idr_lock);
idr_preload_end();
return id;
} }
/* Similar to bpf_link_new_fd, create anon_inode for given bpf_link, but /* Prepare bpf_link to be exposed to user-space by allocating anon_inode file,
* instead of immediately installing fd in fdtable, just reserve it and * reserving unused FD and allocating ID from link_idr. This is to be paired
* return. Caller then need to either install it with fd_install(fd, file) or * with bpf_link_settle() to install FD and ID and expose bpf_link to
* release with put_unused_fd(fd). * user-space, if bpf_link is successfully attached. If not, bpf_link and
* This is useful for cases when bpf_link attachment/detachment are * pre-allocated resources are to be freed with bpf_cleanup() call. All the
* complicated and expensive operations and should be delayed until all the fd * transient state is passed around in struct bpf_link_primer.
* reservation and anon_inode creation succeeds. * This is preferred way to create and initialize bpf_link, especially when
* there are complicated and expensive operations inbetween creating bpf_link
* itself and attaching it to BPF hook. By using bpf_link_prime() and
* bpf_link_settle() kernel code using bpf_link doesn't have to perform
* expensive (and potentially failing) roll back operations in a rare case
* that file, FD, or ID can't be allocated.
*/ */
struct file *bpf_link_new_file(struct bpf_link *link, int *reserved_fd) int bpf_link_prime(struct bpf_link *link, struct bpf_link_primer *primer)
{ {
struct file *file; struct file *file;
int fd; int fd, id;
fd = get_unused_fd_flags(O_CLOEXEC); fd = get_unused_fd_flags(O_CLOEXEC);
if (fd < 0) if (fd < 0)
return ERR_PTR(fd); return fd;
id = bpf_link_alloc_id(link);
if (id < 0) {
put_unused_fd(fd);
return id;
}
file = anon_inode_getfile("bpf_link", &bpf_link_fops, link, O_CLOEXEC); file = anon_inode_getfile("bpf_link", &bpf_link_fops, link, O_CLOEXEC);
if (IS_ERR(file)) { if (IS_ERR(file)) {
bpf_link_free_id(id);
put_unused_fd(fd); put_unused_fd(fd);
return file; return PTR_ERR(file);
} }
*reserved_fd = fd; primer->link = link;
return file; primer->file = file;
primer->fd = fd;
primer->id = id;
return 0;
}
int bpf_link_settle(struct bpf_link_primer *primer)
{
/* make bpf_link fetchable by ID */
spin_lock_bh(&link_idr_lock);
primer->link->id = primer->id;
spin_unlock_bh(&link_idr_lock);
/* make bpf_link fetchable by FD */
fd_install(primer->fd, primer->file);
/* pass through installed FD */
return primer->fd;
}
int bpf_link_new_fd(struct bpf_link *link)
{
return anon_inode_getfd("bpf-link", &bpf_link_fops, link, O_CLOEXEC);
} }
struct bpf_link *bpf_link_get_from_fd(u32 ufd) struct bpf_link *bpf_link_get_from_fd(u32 ufd)
@ -2345,6 +2407,7 @@ struct bpf_link *bpf_link_get_from_fd(u32 ufd)
struct bpf_tracing_link { struct bpf_tracing_link {
struct bpf_link link; struct bpf_link link;
enum bpf_attach_type attach_type;
}; };
static void bpf_tracing_link_release(struct bpf_link *link) static void bpf_tracing_link_release(struct bpf_link *link)
@ -2360,16 +2423,40 @@ static void bpf_tracing_link_dealloc(struct bpf_link *link)
kfree(tr_link); kfree(tr_link);
} }
static void bpf_tracing_link_show_fdinfo(const struct bpf_link *link,
struct seq_file *seq)
{
struct bpf_tracing_link *tr_link =
container_of(link, struct bpf_tracing_link, link);
seq_printf(seq,
"attach_type:\t%d\n",
tr_link->attach_type);
}
static int bpf_tracing_link_fill_link_info(const struct bpf_link *link,
struct bpf_link_info *info)
{
struct bpf_tracing_link *tr_link =
container_of(link, struct bpf_tracing_link, link);
info->tracing.attach_type = tr_link->attach_type;
return 0;
}
static const struct bpf_link_ops bpf_tracing_link_lops = { static const struct bpf_link_ops bpf_tracing_link_lops = {
.release = bpf_tracing_link_release, .release = bpf_tracing_link_release,
.dealloc = bpf_tracing_link_dealloc, .dealloc = bpf_tracing_link_dealloc,
.show_fdinfo = bpf_tracing_link_show_fdinfo,
.fill_link_info = bpf_tracing_link_fill_link_info,
}; };
static int bpf_tracing_prog_attach(struct bpf_prog *prog) static int bpf_tracing_prog_attach(struct bpf_prog *prog)
{ {
struct bpf_link_primer link_primer;
struct bpf_tracing_link *link; struct bpf_tracing_link *link;
struct file *link_file; int err;
int link_fd, err;
switch (prog->type) { switch (prog->type) {
case BPF_PROG_TYPE_TRACING: case BPF_PROG_TYPE_TRACING:
@ -2402,24 +2489,23 @@ static int bpf_tracing_prog_attach(struct bpf_prog *prog)
err = -ENOMEM; err = -ENOMEM;
goto out_put_prog; goto out_put_prog;
} }
bpf_link_init(&link->link, &bpf_tracing_link_lops, prog); bpf_link_init(&link->link, BPF_LINK_TYPE_TRACING,
&bpf_tracing_link_lops, prog);
link->attach_type = prog->expected_attach_type;
link_file = bpf_link_new_file(&link->link, &link_fd); err = bpf_link_prime(&link->link, &link_primer);
if (IS_ERR(link_file)) { if (err) {
kfree(link); kfree(link);
err = PTR_ERR(link_file);
goto out_put_prog; goto out_put_prog;
} }
err = bpf_trampoline_link_prog(prog); err = bpf_trampoline_link_prog(prog);
if (err) { if (err) {
bpf_link_cleanup(&link->link, link_file, link_fd); bpf_link_cleanup(&link_primer);
goto out_put_prog; goto out_put_prog;
} }
fd_install(link_fd, link_file); return bpf_link_settle(&link_primer);
return link_fd;
out_put_prog: out_put_prog:
bpf_prog_put(prog); bpf_prog_put(prog);
return err; return err;
@ -2447,22 +2533,69 @@ static void bpf_raw_tp_link_dealloc(struct bpf_link *link)
kfree(raw_tp); kfree(raw_tp);
} }
static const struct bpf_link_ops bpf_raw_tp_lops = { static void bpf_raw_tp_link_show_fdinfo(const struct bpf_link *link,
struct seq_file *seq)
{
struct bpf_raw_tp_link *raw_tp_link =
container_of(link, struct bpf_raw_tp_link, link);
seq_printf(seq,
"tp_name:\t%s\n",
raw_tp_link->btp->tp->name);
}
static int bpf_raw_tp_link_fill_link_info(const struct bpf_link *link,
struct bpf_link_info *info)
{
struct bpf_raw_tp_link *raw_tp_link =
container_of(link, struct bpf_raw_tp_link, link);
char __user *ubuf = u64_to_user_ptr(info->raw_tracepoint.tp_name);
const char *tp_name = raw_tp_link->btp->tp->name;
u32 ulen = info->raw_tracepoint.tp_name_len;
size_t tp_len = strlen(tp_name);
if (ulen && !ubuf)
return -EINVAL;
info->raw_tracepoint.tp_name_len = tp_len + 1;
if (!ubuf)
return 0;
if (ulen >= tp_len + 1) {
if (copy_to_user(ubuf, tp_name, tp_len + 1))
return -EFAULT;
} else {
char zero = '\0';
if (copy_to_user(ubuf, tp_name, ulen - 1))
return -EFAULT;
if (put_user(zero, ubuf + ulen - 1))
return -EFAULT;
return -ENOSPC;
}
return 0;
}
static const struct bpf_link_ops bpf_raw_tp_link_lops = {
.release = bpf_raw_tp_link_release, .release = bpf_raw_tp_link_release,
.dealloc = bpf_raw_tp_link_dealloc, .dealloc = bpf_raw_tp_link_dealloc,
.show_fdinfo = bpf_raw_tp_link_show_fdinfo,
.fill_link_info = bpf_raw_tp_link_fill_link_info,
}; };
#define BPF_RAW_TRACEPOINT_OPEN_LAST_FIELD raw_tracepoint.prog_fd #define BPF_RAW_TRACEPOINT_OPEN_LAST_FIELD raw_tracepoint.prog_fd
static int bpf_raw_tracepoint_open(const union bpf_attr *attr) static int bpf_raw_tracepoint_open(const union bpf_attr *attr)
{ {
struct bpf_link_primer link_primer;
struct bpf_raw_tp_link *link; struct bpf_raw_tp_link *link;
struct bpf_raw_event_map *btp; struct bpf_raw_event_map *btp;
struct file *link_file;
struct bpf_prog *prog; struct bpf_prog *prog;
const char *tp_name; const char *tp_name;
char buf[128]; char buf[128];
int link_fd, err; int err;
if (CHECK_ATTR(BPF_RAW_TRACEPOINT_OPEN)) if (CHECK_ATTR(BPF_RAW_TRACEPOINT_OPEN))
return -EINVAL; return -EINVAL;
@ -2515,24 +2648,23 @@ static int bpf_raw_tracepoint_open(const union bpf_attr *attr)
err = -ENOMEM; err = -ENOMEM;
goto out_put_btp; goto out_put_btp;
} }
bpf_link_init(&link->link, &bpf_raw_tp_lops, prog); bpf_link_init(&link->link, BPF_LINK_TYPE_RAW_TRACEPOINT,
&bpf_raw_tp_link_lops, prog);
link->btp = btp; link->btp = btp;
link_file = bpf_link_new_file(&link->link, &link_fd); err = bpf_link_prime(&link->link, &link_primer);
if (IS_ERR(link_file)) { if (err) {
kfree(link); kfree(link);
err = PTR_ERR(link_file);
goto out_put_btp; goto out_put_btp;
} }
err = bpf_probe_register(link->btp, prog); err = bpf_probe_register(link->btp, prog);
if (err) { if (err) {
bpf_link_cleanup(&link->link, link_file, link_fd); bpf_link_cleanup(&link_primer);
goto out_put_btp; goto out_put_btp;
} }
fd_install(link_fd, link_file); return bpf_link_settle(&link_primer);
return link_fd;
out_put_btp: out_put_btp:
bpf_put_raw_tracepoint(btp); bpf_put_raw_tracepoint(btp);
@ -3313,6 +3445,42 @@ static int bpf_btf_get_info_by_fd(struct btf *btf,
return btf_get_info_by_fd(btf, attr, uattr); return btf_get_info_by_fd(btf, attr, uattr);
} }
static int bpf_link_get_info_by_fd(struct bpf_link *link,
const union bpf_attr *attr,
union bpf_attr __user *uattr)
{
struct bpf_link_info __user *uinfo = u64_to_user_ptr(attr->info.info);
struct bpf_link_info info;
u32 info_len = attr->info.info_len;
int err;
err = bpf_check_uarg_tail_zero(uinfo, sizeof(info), info_len);
if (err)
return err;
info_len = min_t(u32, sizeof(info), info_len);
memset(&info, 0, sizeof(info));
if (copy_from_user(&info, uinfo, info_len))
return -EFAULT;
info.type = link->type;
info.id = link->id;
info.prog_id = link->prog->aux->id;
if (link->ops->fill_link_info) {
err = link->ops->fill_link_info(link, &info);
if (err)
return err;
}
if (copy_to_user(uinfo, &info, info_len) ||
put_user(info_len, &uattr->info.info_len))
return -EFAULT;
return 0;
}
#define BPF_OBJ_GET_INFO_BY_FD_LAST_FIELD info.info #define BPF_OBJ_GET_INFO_BY_FD_LAST_FIELD info.info
static int bpf_obj_get_info_by_fd(const union bpf_attr *attr, static int bpf_obj_get_info_by_fd(const union bpf_attr *attr,
@ -3337,6 +3505,9 @@ static int bpf_obj_get_info_by_fd(const union bpf_attr *attr,
uattr); uattr);
else if (f.file->f_op == &btf_fops) else if (f.file->f_op == &btf_fops)
err = bpf_btf_get_info_by_fd(f.file->private_data, attr, uattr); err = bpf_btf_get_info_by_fd(f.file->private_data, attr, uattr);
else if (f.file->f_op == &bpf_link_fops)
err = bpf_link_get_info_by_fd(f.file->private_data,
attr, uattr);
else else
err = -EINVAL; err = -EINVAL;
@ -3464,7 +3635,7 @@ static int bpf_task_fd_query(const union bpf_attr *attr,
if (file->f_op == &bpf_link_fops) { if (file->f_op == &bpf_link_fops) {
struct bpf_link *link = file->private_data; struct bpf_link *link = file->private_data;
if (link->ops == &bpf_raw_tp_lops) { if (link->ops == &bpf_raw_tp_link_lops) {
struct bpf_raw_tp_link *raw_tp = struct bpf_raw_tp_link *raw_tp =
container_of(link, struct bpf_raw_tp_link, link); container_of(link, struct bpf_raw_tp_link, link);
struct bpf_raw_event_map *btp = raw_tp->btp; struct bpf_raw_event_map *btp = raw_tp->btp;
@ -3645,13 +3816,10 @@ static int link_update(union bpf_attr *attr)
goto out_put_progs; goto out_put_progs;
} }
#ifdef CONFIG_CGROUP_BPF if (link->ops->update_prog)
if (link->ops == &bpf_cgroup_link_lops) { ret = link->ops->update_prog(link, new_prog, old_prog);
ret = cgroup_bpf_replace(link, old_prog, new_prog); else
goto out_put_progs; ret = EINVAL;
}
#endif
ret = -EINVAL;
out_put_progs: out_put_progs:
if (old_prog) if (old_prog)
@ -3663,6 +3831,102 @@ out_put_link:
return ret; return ret;
} }
static int bpf_link_inc_not_zero(struct bpf_link *link)
{
return atomic64_fetch_add_unless(&link->refcnt, 1, 0) ? 0 : -ENOENT;
}
#define BPF_LINK_GET_FD_BY_ID_LAST_FIELD link_id
static int bpf_link_get_fd_by_id(const union bpf_attr *attr)
{
struct bpf_link *link;
u32 id = attr->link_id;
int fd, err;
if (CHECK_ATTR(BPF_LINK_GET_FD_BY_ID))
return -EINVAL;
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
spin_lock_bh(&link_idr_lock);
link = idr_find(&link_idr, id);
/* before link is "settled", ID is 0, pretend it doesn't exist yet */
if (link) {
if (link->id)
err = bpf_link_inc_not_zero(link);
else
err = -EAGAIN;
} else {
err = -ENOENT;
}
spin_unlock_bh(&link_idr_lock);
if (err)
return err;
fd = bpf_link_new_fd(link);
if (fd < 0)
bpf_link_put(link);
return fd;
}
DEFINE_MUTEX(bpf_stats_enabled_mutex);
static int bpf_stats_release(struct inode *inode, struct file *file)
{
mutex_lock(&bpf_stats_enabled_mutex);
static_key_slow_dec(&bpf_stats_enabled_key.key);
mutex_unlock(&bpf_stats_enabled_mutex);
return 0;
}
static const struct file_operations bpf_stats_fops = {
.release = bpf_stats_release,
};
static int bpf_enable_runtime_stats(void)
{
int fd;
mutex_lock(&bpf_stats_enabled_mutex);
/* Set a very high limit to avoid overflow */
if (static_key_count(&bpf_stats_enabled_key.key) > INT_MAX / 2) {
mutex_unlock(&bpf_stats_enabled_mutex);
return -EBUSY;
}
fd = anon_inode_getfd("bpf-stats", &bpf_stats_fops, NULL, O_CLOEXEC);
if (fd >= 0)
static_key_slow_inc(&bpf_stats_enabled_key.key);
mutex_unlock(&bpf_stats_enabled_mutex);
return fd;
}
#define BPF_ENABLE_STATS_LAST_FIELD enable_stats.type
static int bpf_enable_stats(union bpf_attr *attr)
{
if (CHECK_ATTR(BPF_ENABLE_STATS))
return -EINVAL;
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
switch (attr->enable_stats.type) {
case BPF_STATS_RUN_TIME:
return bpf_enable_runtime_stats();
default:
break;
}
return -EINVAL;
}
SYSCALL_DEFINE3(bpf, int, cmd, union bpf_attr __user *, uattr, unsigned int, size) SYSCALL_DEFINE3(bpf, int, cmd, union bpf_attr __user *, uattr, unsigned int, size)
{ {
union bpf_attr attr; union bpf_attr attr;
@ -3780,6 +4044,16 @@ SYSCALL_DEFINE3(bpf, int, cmd, union bpf_attr __user *, uattr, unsigned int, siz
case BPF_LINK_UPDATE: case BPF_LINK_UPDATE:
err = link_update(&attr); err = link_update(&attr);
break; break;
case BPF_LINK_GET_FD_BY_ID:
err = bpf_link_get_fd_by_id(&attr);
break;
case BPF_LINK_GET_NEXT_ID:
err = bpf_obj_get_next_id(&attr, uattr,
&link_idr, &link_idr_lock);
break;
case BPF_ENABLE_STATS:
err = bpf_enable_stats(&attr);
break;
default: default:
err = -EINVAL; err = -EINVAL;
break; break;

View File

@ -28,9 +28,11 @@ static const struct bpf_verifier_ops * const bpf_verifier_ops[] = {
#define BPF_PROG_TYPE(_id, _name, prog_ctx_type, kern_ctx_type) \ #define BPF_PROG_TYPE(_id, _name, prog_ctx_type, kern_ctx_type) \
[_id] = & _name ## _verifier_ops, [_id] = & _name ## _verifier_ops,
#define BPF_MAP_TYPE(_id, _ops) #define BPF_MAP_TYPE(_id, _ops)
#define BPF_LINK_TYPE(_id, _name)
#include <linux/bpf_types.h> #include <linux/bpf_types.h>
#undef BPF_PROG_TYPE #undef BPF_PROG_TYPE
#undef BPF_MAP_TYPE #undef BPF_MAP_TYPE
#undef BPF_LINK_TYPE
}; };
/* bpf_check() is a static code analyzer that walks eBPF program /* bpf_check() is a static code analyzer that walks eBPF program
@ -168,6 +170,8 @@ struct bpf_verifier_stack_elem {
int insn_idx; int insn_idx;
int prev_insn_idx; int prev_insn_idx;
struct bpf_verifier_stack_elem *next; struct bpf_verifier_stack_elem *next;
/* length of verifier log at the time this state was pushed on stack */
u32 log_pos;
}; };
#define BPF_COMPLEXITY_LIMIT_JMP_SEQ 8192 #define BPF_COMPLEXITY_LIMIT_JMP_SEQ 8192
@ -283,6 +287,18 @@ void bpf_verifier_vlog(struct bpf_verifier_log *log, const char *fmt,
log->ubuf = NULL; log->ubuf = NULL;
} }
static void bpf_vlog_reset(struct bpf_verifier_log *log, u32 new_pos)
{
char zero = 0;
if (!bpf_verifier_log_needed(log))
return;
log->len_used = new_pos;
if (put_user(zero, log->ubuf + new_pos))
log->ubuf = NULL;
}
/* log_level controls verbosity level of eBPF verifier. /* log_level controls verbosity level of eBPF verifier.
* bpf_verifier_log_write() is used to dump the verification trace to the log, * bpf_verifier_log_write() is used to dump the verification trace to the log,
* so the user can figure out what's wrong with the program * so the user can figure out what's wrong with the program
@ -413,11 +429,30 @@ static bool is_release_function(enum bpf_func_id func_id)
return func_id == BPF_FUNC_sk_release; return func_id == BPF_FUNC_sk_release;
} }
static bool is_acquire_function(enum bpf_func_id func_id) static bool may_be_acquire_function(enum bpf_func_id func_id)
{ {
return func_id == BPF_FUNC_sk_lookup_tcp || return func_id == BPF_FUNC_sk_lookup_tcp ||
func_id == BPF_FUNC_sk_lookup_udp || func_id == BPF_FUNC_sk_lookup_udp ||
func_id == BPF_FUNC_skc_lookup_tcp; func_id == BPF_FUNC_skc_lookup_tcp ||
func_id == BPF_FUNC_map_lookup_elem;
}
static bool is_acquire_function(enum bpf_func_id func_id,
const struct bpf_map *map)
{
enum bpf_map_type map_type = map ? map->map_type : BPF_MAP_TYPE_UNSPEC;
if (func_id == BPF_FUNC_sk_lookup_tcp ||
func_id == BPF_FUNC_sk_lookup_udp ||
func_id == BPF_FUNC_skc_lookup_tcp)
return true;
if (func_id == BPF_FUNC_map_lookup_elem &&
(map_type == BPF_MAP_TYPE_SOCKMAP ||
map_type == BPF_MAP_TYPE_SOCKHASH))
return true;
return false;
} }
static bool is_ptr_cast_function(enum bpf_func_id func_id) static bool is_ptr_cast_function(enum bpf_func_id func_id)
@ -846,7 +881,7 @@ static void update_branch_counts(struct bpf_verifier_env *env, struct bpf_verifi
} }
static int pop_stack(struct bpf_verifier_env *env, int *prev_insn_idx, static int pop_stack(struct bpf_verifier_env *env, int *prev_insn_idx,
int *insn_idx) int *insn_idx, bool pop_log)
{ {
struct bpf_verifier_state *cur = env->cur_state; struct bpf_verifier_state *cur = env->cur_state;
struct bpf_verifier_stack_elem *elem, *head = env->head; struct bpf_verifier_stack_elem *elem, *head = env->head;
@ -860,6 +895,8 @@ static int pop_stack(struct bpf_verifier_env *env, int *prev_insn_idx,
if (err) if (err)
return err; return err;
} }
if (pop_log)
bpf_vlog_reset(&env->log, head->log_pos);
if (insn_idx) if (insn_idx)
*insn_idx = head->insn_idx; *insn_idx = head->insn_idx;
if (prev_insn_idx) if (prev_insn_idx)
@ -887,6 +924,7 @@ static struct bpf_verifier_state *push_stack(struct bpf_verifier_env *env,
elem->insn_idx = insn_idx; elem->insn_idx = insn_idx;
elem->prev_insn_idx = prev_insn_idx; elem->prev_insn_idx = prev_insn_idx;
elem->next = env->head; elem->next = env->head;
elem->log_pos = env->log.len_used;
env->head = elem; env->head = elem;
env->stack_size++; env->stack_size++;
err = copy_verifier_state(&elem->st, cur); err = copy_verifier_state(&elem->st, cur);
@ -915,7 +953,7 @@ err:
free_verifier_state(env->cur_state, true); free_verifier_state(env->cur_state, true);
env->cur_state = NULL; env->cur_state = NULL;
/* pop all elements and return */ /* pop all elements and return */
while (!pop_stack(env, NULL, NULL)); while (!pop_stack(env, NULL, NULL, false));
return NULL; return NULL;
} }
@ -3915,7 +3953,8 @@ static int check_map_func_compatibility(struct bpf_verifier_env *env,
func_id != BPF_FUNC_sock_map_update && func_id != BPF_FUNC_sock_map_update &&
func_id != BPF_FUNC_map_delete_elem && func_id != BPF_FUNC_map_delete_elem &&
func_id != BPF_FUNC_msg_redirect_map && func_id != BPF_FUNC_msg_redirect_map &&
func_id != BPF_FUNC_sk_select_reuseport) func_id != BPF_FUNC_sk_select_reuseport &&
func_id != BPF_FUNC_map_lookup_elem)
goto error; goto error;
break; break;
case BPF_MAP_TYPE_SOCKHASH: case BPF_MAP_TYPE_SOCKHASH:
@ -3923,7 +3962,8 @@ static int check_map_func_compatibility(struct bpf_verifier_env *env,
func_id != BPF_FUNC_sock_hash_update && func_id != BPF_FUNC_sock_hash_update &&
func_id != BPF_FUNC_map_delete_elem && func_id != BPF_FUNC_map_delete_elem &&
func_id != BPF_FUNC_msg_redirect_hash && func_id != BPF_FUNC_msg_redirect_hash &&
func_id != BPF_FUNC_sk_select_reuseport) func_id != BPF_FUNC_sk_select_reuseport &&
func_id != BPF_FUNC_map_lookup_elem)
goto error; goto error;
break; break;
case BPF_MAP_TYPE_REUSEPORT_SOCKARRAY: case BPF_MAP_TYPE_REUSEPORT_SOCKARRAY:
@ -4093,7 +4133,7 @@ static bool check_refcount_ok(const struct bpf_func_proto *fn, int func_id)
/* A reference acquiring function cannot acquire /* A reference acquiring function cannot acquire
* another refcounted ptr. * another refcounted ptr.
*/ */
if (is_acquire_function(func_id) && count) if (may_be_acquire_function(func_id) && count)
return false; return false;
/* We only support one arg being unreferenced at the moment, /* We only support one arg being unreferenced at the moment,
@ -4604,7 +4644,7 @@ static int check_helper_call(struct bpf_verifier_env *env, int func_id, int insn
if (is_ptr_cast_function(func_id)) { if (is_ptr_cast_function(func_id)) {
/* For release_reference() */ /* For release_reference() */
regs[BPF_REG_0].ref_obj_id = meta.ref_obj_id; regs[BPF_REG_0].ref_obj_id = meta.ref_obj_id;
} else if (is_acquire_function(func_id)) { } else if (is_acquire_function(func_id, meta.map_ptr)) {
int id = acquire_reference_state(env, insn_idx); int id = acquire_reference_state(env, insn_idx);
if (id < 0) if (id < 0)
@ -5609,7 +5649,7 @@ static int adjust_scalar_min_max_vals(struct bpf_verifier_env *env,
{ {
struct bpf_reg_state *regs = cur_regs(env); struct bpf_reg_state *regs = cur_regs(env);
u8 opcode = BPF_OP(insn->code); u8 opcode = BPF_OP(insn->code);
bool src_known, dst_known; bool src_known;
s64 smin_val, smax_val; s64 smin_val, smax_val;
u64 umin_val, umax_val; u64 umin_val, umax_val;
s32 s32_min_val, s32_max_val; s32 s32_min_val, s32_max_val;
@ -5631,7 +5671,6 @@ static int adjust_scalar_min_max_vals(struct bpf_verifier_env *env,
if (alu32) { if (alu32) {
src_known = tnum_subreg_is_const(src_reg.var_off); src_known = tnum_subreg_is_const(src_reg.var_off);
dst_known = tnum_subreg_is_const(dst_reg->var_off);
if ((src_known && if ((src_known &&
(s32_min_val != s32_max_val || u32_min_val != u32_max_val)) || (s32_min_val != s32_max_val || u32_min_val != u32_max_val)) ||
s32_min_val > s32_max_val || u32_min_val > u32_max_val) { s32_min_val > s32_max_val || u32_min_val > u32_max_val) {
@ -5643,7 +5682,6 @@ static int adjust_scalar_min_max_vals(struct bpf_verifier_env *env,
} }
} else { } else {
src_known = tnum_is_const(src_reg.var_off); src_known = tnum_is_const(src_reg.var_off);
dst_known = tnum_is_const(dst_reg->var_off);
if ((src_known && if ((src_known &&
(smin_val != smax_val || umin_val != umax_val)) || (smin_val != smax_val || umin_val != umax_val)) ||
smin_val > smax_val || umin_val > umax_val) { smin_val > smax_val || umin_val > umax_val) {
@ -6515,12 +6553,16 @@ static void mark_ptr_or_null_reg(struct bpf_func_state *state,
if (is_null) { if (is_null) {
reg->type = SCALAR_VALUE; reg->type = SCALAR_VALUE;
} else if (reg->type == PTR_TO_MAP_VALUE_OR_NULL) { } else if (reg->type == PTR_TO_MAP_VALUE_OR_NULL) {
if (reg->map_ptr->inner_map_meta) { const struct bpf_map *map = reg->map_ptr;
if (map->inner_map_meta) {
reg->type = CONST_PTR_TO_MAP; reg->type = CONST_PTR_TO_MAP;
reg->map_ptr = reg->map_ptr->inner_map_meta; reg->map_ptr = map->inner_map_meta;
} else if (reg->map_ptr->map_type == } else if (map->map_type == BPF_MAP_TYPE_XSKMAP) {
BPF_MAP_TYPE_XSKMAP) {
reg->type = PTR_TO_XDP_SOCK; reg->type = PTR_TO_XDP_SOCK;
} else if (map->map_type == BPF_MAP_TYPE_SOCKMAP ||
map->map_type == BPF_MAP_TYPE_SOCKHASH) {
reg->type = PTR_TO_SOCKET;
} else { } else {
reg->type = PTR_TO_MAP_VALUE; reg->type = PTR_TO_MAP_VALUE;
} }
@ -8409,6 +8451,7 @@ static bool reg_type_mismatch(enum bpf_reg_type src, enum bpf_reg_type prev)
static int do_check(struct bpf_verifier_env *env) static int do_check(struct bpf_verifier_env *env)
{ {
bool pop_log = !(env->log.level & BPF_LOG_LEVEL2);
struct bpf_verifier_state *state = env->cur_state; struct bpf_verifier_state *state = env->cur_state;
struct bpf_insn *insns = env->prog->insnsi; struct bpf_insn *insns = env->prog->insnsi;
struct bpf_reg_state *regs; struct bpf_reg_state *regs;
@ -8685,7 +8728,7 @@ static int do_check(struct bpf_verifier_env *env)
process_bpf_exit: process_bpf_exit:
update_branch_counts(env, env->cur_state); update_branch_counts(env, env->cur_state);
err = pop_stack(env, &prev_insn_idx, err = pop_stack(env, &prev_insn_idx,
&env->insn_idx); &env->insn_idx, pop_log);
if (err < 0) { if (err < 0) {
if (err != -ENOENT) if (err != -ENOENT)
return err; return err;
@ -10208,6 +10251,7 @@ static void sanitize_insn_aux_data(struct bpf_verifier_env *env)
static int do_check_common(struct bpf_verifier_env *env, int subprog) static int do_check_common(struct bpf_verifier_env *env, int subprog)
{ {
bool pop_log = !(env->log.level & BPF_LOG_LEVEL2);
struct bpf_verifier_state *state; struct bpf_verifier_state *state;
struct bpf_reg_state *regs; struct bpf_reg_state *regs;
int ret, i; int ret, i;
@ -10270,7 +10314,9 @@ out:
free_verifier_state(env->cur_state, true); free_verifier_state(env->cur_state, true);
env->cur_state = NULL; env->cur_state = NULL;
} }
while (!pop_stack(env, NULL, NULL)); while (!pop_stack(env, NULL, NULL, false));
if (!ret && pop_log)
bpf_vlog_reset(&env->log, 0);
free_states(env); free_states(env);
if (ret) if (ret)
/* clean aux data in case subprog was rejected */ /* clean aux data in case subprog was rejected */

View File

@ -6508,33 +6508,6 @@ int cgroup_bpf_attach(struct cgroup *cgrp,
return ret; return ret;
} }
int cgroup_bpf_replace(struct bpf_link *link, struct bpf_prog *old_prog,
struct bpf_prog *new_prog)
{
struct bpf_cgroup_link *cg_link;
int ret;
if (link->ops != &bpf_cgroup_link_lops)
return -EINVAL;
cg_link = container_of(link, struct bpf_cgroup_link, link);
mutex_lock(&cgroup_mutex);
/* link might have been auto-released by dying cgroup, so fail */
if (!cg_link->cgroup) {
ret = -EINVAL;
goto out_unlock;
}
if (old_prog && link->prog != old_prog) {
ret = -EPERM;
goto out_unlock;
}
ret = __cgroup_bpf_replace(cg_link->cgroup, cg_link, new_prog);
out_unlock:
mutex_unlock(&cgroup_mutex);
return ret;
}
int cgroup_bpf_detach(struct cgroup *cgrp, struct bpf_prog *prog, int cgroup_bpf_detach(struct cgroup *cgrp, struct bpf_prog *prog,
enum bpf_attach_type type) enum bpf_attach_type type)
{ {

View File

@ -236,7 +236,7 @@ exit_put:
* sysctl_perf_event_max_contexts_per_stack. * sysctl_perf_event_max_contexts_per_stack.
*/ */
int perf_event_max_stack_handler(struct ctl_table *table, int write, int perf_event_max_stack_handler(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos) void *buffer, size_t *lenp, loff_t *ppos)
{ {
int *value = table->data; int *value = table->data;
int new_value = *value, ret; int new_value = *value, ret;

View File

@ -437,8 +437,7 @@ static void update_perf_cpu_limits(void)
static bool perf_rotate_context(struct perf_cpu_context *cpuctx); static bool perf_rotate_context(struct perf_cpu_context *cpuctx);
int perf_proc_update_handler(struct ctl_table *table, int write, int perf_proc_update_handler(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, void *buffer, size_t *lenp, loff_t *ppos)
loff_t *ppos)
{ {
int ret; int ret;
int perf_cpu = sysctl_perf_cpu_time_max_percent; int perf_cpu = sysctl_perf_cpu_time_max_percent;
@ -462,8 +461,7 @@ int perf_proc_update_handler(struct ctl_table *table, int write,
int sysctl_perf_cpu_time_max_percent __read_mostly = DEFAULT_CPU_TIME_MAX_PERCENT; int sysctl_perf_cpu_time_max_percent __read_mostly = DEFAULT_CPU_TIME_MAX_PERCENT;
int perf_cpu_time_max_percent_handler(struct ctl_table *table, int write, int perf_cpu_time_max_percent_handler(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, void *buffer, size_t *lenp, loff_t *ppos)
loff_t *ppos)
{ {
int ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos); int ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos);

View File

@ -892,7 +892,7 @@ static void unoptimize_all_kprobes(void)
static DEFINE_MUTEX(kprobe_sysctl_mutex); static DEFINE_MUTEX(kprobe_sysctl_mutex);
int sysctl_kprobes_optimization; int sysctl_kprobes_optimization;
int proc_kprobes_optimization_handler(struct ctl_table *table, int write, int proc_kprobes_optimization_handler(struct ctl_table *table, int write,
void __user *buffer, size_t *length, void *buffer, size_t *length,
loff_t *ppos) loff_t *ppos)
{ {
int ret; int ret;

View File

@ -269,8 +269,8 @@ static int __init init_lstats_procfs(void)
return 0; return 0;
} }
int sysctl_latencytop(struct ctl_table *table, int write, int sysctl_latencytop(struct ctl_table *table, int write, void *buffer,
void __user *buffer, size_t *lenp, loff_t *ppos) size_t *lenp, loff_t *ppos)
{ {
int err; int err;

View File

@ -263,7 +263,7 @@ void zap_pid_ns_processes(struct pid_namespace *pid_ns)
#ifdef CONFIG_CHECKPOINT_RESTORE #ifdef CONFIG_CHECKPOINT_RESTORE
static int pid_ns_ctl_handler(struct ctl_table *table, int write, static int pid_ns_ctl_handler(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos) void *buffer, size_t *lenp, loff_t *ppos)
{ {
struct pid_namespace *pid_ns = task_active_pid_ns(current); struct pid_namespace *pid_ns = task_active_pid_ns(current);
struct ctl_table tmp = *table; struct ctl_table tmp = *table;

View File

@ -173,7 +173,7 @@ __setup("printk.devkmsg=", control_devkmsg);
char devkmsg_log_str[DEVKMSG_STR_MAX_SIZE] = "ratelimit"; char devkmsg_log_str[DEVKMSG_STR_MAX_SIZE] = "ratelimit";
int devkmsg_sysctl_set_loglvl(struct ctl_table *table, int write, int devkmsg_sysctl_set_loglvl(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos) void *buffer, size_t *lenp, loff_t *ppos)
{ {
char old_str[DEVKMSG_STR_MAX_SIZE]; char old_str[DEVKMSG_STR_MAX_SIZE];
unsigned int old; unsigned int old;

View File

@ -1110,8 +1110,7 @@ static void uclamp_update_root_tg(void) { }
#endif #endif
int sysctl_sched_uclamp_handler(struct ctl_table *table, int write, int sysctl_sched_uclamp_handler(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, void *buffer, size_t *lenp, loff_t *ppos)
loff_t *ppos)
{ {
bool update_root_tg = false; bool update_root_tg = false;
int old_min, old_max; int old_min, old_max;
@ -2718,7 +2717,7 @@ void set_numabalancing_state(bool enabled)
#ifdef CONFIG_PROC_SYSCTL #ifdef CONFIG_PROC_SYSCTL
int sysctl_numa_balancing(struct ctl_table *table, int write, int sysctl_numa_balancing(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos) void *buffer, size_t *lenp, loff_t *ppos)
{ {
struct ctl_table t; struct ctl_table t;
int err; int err;
@ -2792,8 +2791,8 @@ static void __init init_schedstats(void)
} }
#ifdef CONFIG_PROC_SYSCTL #ifdef CONFIG_PROC_SYSCTL
int sysctl_schedstats(struct ctl_table *table, int write, int sysctl_schedstats(struct ctl_table *table, int write, void *buffer,
void __user *buffer, size_t *lenp, loff_t *ppos) size_t *lenp, loff_t *ppos)
{ {
struct ctl_table t; struct ctl_table t;
int err; int err;

View File

@ -645,8 +645,7 @@ struct sched_entity *__pick_last_entity(struct cfs_rq *cfs_rq)
*/ */
int sched_proc_update_handler(struct ctl_table *table, int write, int sched_proc_update_handler(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, void *buffer, size_t *lenp, loff_t *ppos)
loff_t *ppos)
{ {
int ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos); int ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos);
unsigned int factor = get_update_sysctl_factor(); unsigned int factor = get_update_sysctl_factor();

View File

@ -2714,9 +2714,8 @@ static void sched_rt_do_global(void)
def_rt_bandwidth.rt_period = ns_to_ktime(global_rt_period()); def_rt_bandwidth.rt_period = ns_to_ktime(global_rt_period());
} }
int sched_rt_handler(struct ctl_table *table, int write, int sched_rt_handler(struct ctl_table *table, int write, void *buffer,
void __user *buffer, size_t *lenp, size_t *lenp, loff_t *ppos)
loff_t *ppos)
{ {
int old_period, old_runtime; int old_period, old_runtime;
static DEFINE_MUTEX(mutex); static DEFINE_MUTEX(mutex);
@ -2754,9 +2753,8 @@ undo:
return ret; return ret;
} }
int sched_rr_handler(struct ctl_table *table, int write, int sched_rr_handler(struct ctl_table *table, int write, void *buffer,
void __user *buffer, size_t *lenp, size_t *lenp, loff_t *ppos)
loff_t *ppos)
{ {
int ret; int ret;
static DEFINE_MUTEX(mutex); static DEFINE_MUTEX(mutex);

View File

@ -209,7 +209,7 @@ bool sched_energy_update;
#ifdef CONFIG_PROC_SYSCTL #ifdef CONFIG_PROC_SYSCTL
int sched_energy_aware_handler(struct ctl_table *table, int write, int sched_energy_aware_handler(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos) void *buffer, size_t *lenp, loff_t *ppos)
{ {
int ret, state; int ret, state;

View File

@ -1776,7 +1776,7 @@ static void audit_actions_logged(u32 actions_logged, u32 old_actions_logged,
} }
static int seccomp_actions_logged_handler(struct ctl_table *ro_table, int write, static int seccomp_actions_logged_handler(struct ctl_table *ro_table, int write,
void __user *buffer, size_t *lenp, void *buffer, size_t *lenp,
loff_t *ppos) loff_t *ppos)
{ {
int ret; int ret;

File diff suppressed because it is too large Load Diff

View File

@ -249,8 +249,7 @@ void timers_update_nohz(void)
} }
int timer_migration_handler(struct ctl_table *table, int write, int timer_migration_handler(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, void *buffer, size_t *lenp, loff_t *ppos)
loff_t *ppos)
{ {
int ret; int ret;

View File

@ -797,6 +797,8 @@ bpf_tracing_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
return &bpf_map_peek_elem_proto; return &bpf_map_peek_elem_proto;
case BPF_FUNC_ktime_get_ns: case BPF_FUNC_ktime_get_ns:
return &bpf_ktime_get_ns_proto; return &bpf_ktime_get_ns_proto;
case BPF_FUNC_ktime_get_boot_ns:
return &bpf_ktime_get_boot_ns_proto;
case BPF_FUNC_tail_call: case BPF_FUNC_tail_call:
return &bpf_tail_call_proto; return &bpf_tail_call_proto;
case BPF_FUNC_get_current_pid_tgid: case BPF_FUNC_get_current_pid_tgid:

View File

@ -2661,7 +2661,7 @@ static void output_printk(struct trace_event_buffer *fbuffer)
} }
int tracepoint_printk_sysctl(struct ctl_table *table, int write, int tracepoint_printk_sysctl(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, void *buffer, size_t *lenp,
loff_t *ppos) loff_t *ppos)
{ {
int save_tracepoint_printk; int save_tracepoint_printk;

View File

@ -630,7 +630,7 @@ int call_usermodehelper(const char *path, char **argv, char **envp, int wait)
EXPORT_SYMBOL(call_usermodehelper); EXPORT_SYMBOL(call_usermodehelper);
static int proc_cap_handler(struct ctl_table *table, int write, static int proc_cap_handler(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos) void *buffer, size_t *lenp, loff_t *ppos)
{ {
struct ctl_table t; struct ctl_table t;
unsigned long cap_array[_KERNEL_CAPABILITY_U32S]; unsigned long cap_array[_KERNEL_CAPABILITY_U32S];

View File

@ -30,7 +30,7 @@ static void *get_uts(struct ctl_table *table)
* to observe. Should this be in kernel/sys.c ???? * to observe. Should this be in kernel/sys.c ????
*/ */
static int proc_do_uts_string(struct ctl_table *table, int write, static int proc_do_uts_string(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos) void *buffer, size_t *lenp, loff_t *ppos)
{ {
struct ctl_table uts_table; struct ctl_table uts_table;
int r; int r;

View File

@ -661,7 +661,7 @@ static void proc_watchdog_update(void)
* proc_soft_watchdog | soft_watchdog_user_enabled | SOFT_WATCHDOG_ENABLED * proc_soft_watchdog | soft_watchdog_user_enabled | SOFT_WATCHDOG_ENABLED
*/ */
static int proc_watchdog_common(int which, struct ctl_table *table, int write, static int proc_watchdog_common(int which, struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos) void *buffer, size_t *lenp, loff_t *ppos)
{ {
int err, old, *param = table->data; int err, old, *param = table->data;
@ -688,7 +688,7 @@ static int proc_watchdog_common(int which, struct ctl_table *table, int write,
* /proc/sys/kernel/watchdog * /proc/sys/kernel/watchdog
*/ */
int proc_watchdog(struct ctl_table *table, int write, int proc_watchdog(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos) void *buffer, size_t *lenp, loff_t *ppos)
{ {
return proc_watchdog_common(NMI_WATCHDOG_ENABLED|SOFT_WATCHDOG_ENABLED, return proc_watchdog_common(NMI_WATCHDOG_ENABLED|SOFT_WATCHDOG_ENABLED,
table, write, buffer, lenp, ppos); table, write, buffer, lenp, ppos);
@ -698,7 +698,7 @@ int proc_watchdog(struct ctl_table *table, int write,
* /proc/sys/kernel/nmi_watchdog * /proc/sys/kernel/nmi_watchdog
*/ */
int proc_nmi_watchdog(struct ctl_table *table, int write, int proc_nmi_watchdog(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos) void *buffer, size_t *lenp, loff_t *ppos)
{ {
if (!nmi_watchdog_available && write) if (!nmi_watchdog_available && write)
return -ENOTSUPP; return -ENOTSUPP;
@ -710,7 +710,7 @@ int proc_nmi_watchdog(struct ctl_table *table, int write,
* /proc/sys/kernel/soft_watchdog * /proc/sys/kernel/soft_watchdog
*/ */
int proc_soft_watchdog(struct ctl_table *table, int write, int proc_soft_watchdog(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos) void *buffer, size_t *lenp, loff_t *ppos)
{ {
return proc_watchdog_common(SOFT_WATCHDOG_ENABLED, return proc_watchdog_common(SOFT_WATCHDOG_ENABLED,
table, write, buffer, lenp, ppos); table, write, buffer, lenp, ppos);
@ -720,7 +720,7 @@ int proc_soft_watchdog(struct ctl_table *table, int write,
* /proc/sys/kernel/watchdog_thresh * /proc/sys/kernel/watchdog_thresh
*/ */
int proc_watchdog_thresh(struct ctl_table *table, int write, int proc_watchdog_thresh(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos) void *buffer, size_t *lenp, loff_t *ppos)
{ {
int err, old; int err, old;
@ -743,7 +743,7 @@ int proc_watchdog_thresh(struct ctl_table *table, int write,
* been brought online, if desired. * been brought online, if desired.
*/ */
int proc_watchdog_cpumask(struct ctl_table *table, int write, int proc_watchdog_cpumask(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos) void *buffer, size_t *lenp, loff_t *ppos)
{ {
int err; int err;

View File

@ -2463,7 +2463,7 @@ int sysctl_compact_memory;
* /proc/sys/vm/compact_memory * /proc/sys/vm/compact_memory
*/ */
int sysctl_compaction_handler(struct ctl_table *table, int write, int sysctl_compaction_handler(struct ctl_table *table, int write,
void __user *buffer, size_t *length, loff_t *ppos) void *buffer, size_t *length, loff_t *ppos)
{ {
if (write) if (write)
compact_nodes(); compact_nodes();

View File

@ -3352,7 +3352,7 @@ static unsigned int cpuset_mems_nr(unsigned int *array)
#ifdef CONFIG_SYSCTL #ifdef CONFIG_SYSCTL
static int hugetlb_sysctl_handler_common(bool obey_mempolicy, static int hugetlb_sysctl_handler_common(bool obey_mempolicy,
struct ctl_table *table, int write, struct ctl_table *table, int write,
void __user *buffer, size_t *length, loff_t *ppos) void *buffer, size_t *length, loff_t *ppos)
{ {
struct hstate *h = &default_hstate; struct hstate *h = &default_hstate;
unsigned long tmp = h->max_huge_pages; unsigned long tmp = h->max_huge_pages;
@ -3375,7 +3375,7 @@ out:
} }
int hugetlb_sysctl_handler(struct ctl_table *table, int write, int hugetlb_sysctl_handler(struct ctl_table *table, int write,
void __user *buffer, size_t *length, loff_t *ppos) void *buffer, size_t *length, loff_t *ppos)
{ {
return hugetlb_sysctl_handler_common(false, table, write, return hugetlb_sysctl_handler_common(false, table, write,
@ -3384,7 +3384,7 @@ int hugetlb_sysctl_handler(struct ctl_table *table, int write,
#ifdef CONFIG_NUMA #ifdef CONFIG_NUMA
int hugetlb_mempolicy_sysctl_handler(struct ctl_table *table, int write, int hugetlb_mempolicy_sysctl_handler(struct ctl_table *table, int write,
void __user *buffer, size_t *length, loff_t *ppos) void *buffer, size_t *length, loff_t *ppos)
{ {
return hugetlb_sysctl_handler_common(true, table, write, return hugetlb_sysctl_handler_common(true, table, write,
buffer, length, ppos); buffer, length, ppos);
@ -3392,8 +3392,7 @@ int hugetlb_mempolicy_sysctl_handler(struct ctl_table *table, int write,
#endif /* CONFIG_NUMA */ #endif /* CONFIG_NUMA */
int hugetlb_overcommit_handler(struct ctl_table *table, int write, int hugetlb_overcommit_handler(struct ctl_table *table, int write,
void __user *buffer, void *buffer, size_t *length, loff_t *ppos)
size_t *length, loff_t *ppos)
{ {
struct hstate *h = &default_hstate; struct hstate *h = &default_hstate;
unsigned long tmp; unsigned long tmp;

View File

@ -512,8 +512,7 @@ bool node_dirty_ok(struct pglist_data *pgdat)
} }
int dirty_background_ratio_handler(struct ctl_table *table, int write, int dirty_background_ratio_handler(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, void *buffer, size_t *lenp, loff_t *ppos)
loff_t *ppos)
{ {
int ret; int ret;
@ -524,8 +523,7 @@ int dirty_background_ratio_handler(struct ctl_table *table, int write,
} }
int dirty_background_bytes_handler(struct ctl_table *table, int write, int dirty_background_bytes_handler(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, void *buffer, size_t *lenp, loff_t *ppos)
loff_t *ppos)
{ {
int ret; int ret;
@ -535,9 +533,8 @@ int dirty_background_bytes_handler(struct ctl_table *table, int write,
return ret; return ret;
} }
int dirty_ratio_handler(struct ctl_table *table, int write, int dirty_ratio_handler(struct ctl_table *table, int write, void *buffer,
void __user *buffer, size_t *lenp, size_t *lenp, loff_t *ppos)
loff_t *ppos)
{ {
int old_ratio = vm_dirty_ratio; int old_ratio = vm_dirty_ratio;
int ret; int ret;
@ -551,8 +548,7 @@ int dirty_ratio_handler(struct ctl_table *table, int write,
} }
int dirty_bytes_handler(struct ctl_table *table, int write, int dirty_bytes_handler(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, void *buffer, size_t *lenp, loff_t *ppos)
loff_t *ppos)
{ {
unsigned long old_bytes = vm_dirty_bytes; unsigned long old_bytes = vm_dirty_bytes;
int ret; int ret;
@ -1972,7 +1968,7 @@ bool wb_over_bg_thresh(struct bdi_writeback *wb)
* sysctl handler for /proc/sys/vm/dirty_writeback_centisecs * sysctl handler for /proc/sys/vm/dirty_writeback_centisecs
*/ */
int dirty_writeback_centisecs_handler(struct ctl_table *table, int write, int dirty_writeback_centisecs_handler(struct ctl_table *table, int write,
void __user *buffer, size_t *length, loff_t *ppos) void *buffer, size_t *length, loff_t *ppos)
{ {
unsigned int old_interval = dirty_writeback_interval; unsigned int old_interval = dirty_writeback_interval;
int ret; int ret;

View File

@ -5546,21 +5546,11 @@ char numa_zonelist_order[] = "Node";
* sysctl handler for numa_zonelist_order * sysctl handler for numa_zonelist_order
*/ */
int numa_zonelist_order_handler(struct ctl_table *table, int write, int numa_zonelist_order_handler(struct ctl_table *table, int write,
void __user *buffer, size_t *length, void *buffer, size_t *length, loff_t *ppos)
loff_t *ppos)
{ {
char *str; if (write)
int ret; return __parse_numa_zonelist_order(buffer);
return proc_dostring(table, write, buffer, length, ppos);
if (!write)
return proc_dostring(table, write, buffer, length, ppos);
str = memdup_user_nul(buffer, 16);
if (IS_ERR(str))
return PTR_ERR(str);
ret = __parse_numa_zonelist_order(str);
kfree(str);
return ret;
} }
@ -7963,7 +7953,7 @@ core_initcall(init_per_zone_wmark_min)
* changes. * changes.
*/ */
int min_free_kbytes_sysctl_handler(struct ctl_table *table, int write, int min_free_kbytes_sysctl_handler(struct ctl_table *table, int write,
void __user *buffer, size_t *length, loff_t *ppos) void *buffer, size_t *length, loff_t *ppos)
{ {
int rc; int rc;
@ -7978,20 +7968,8 @@ int min_free_kbytes_sysctl_handler(struct ctl_table *table, int write,
return 0; return 0;
} }
int watermark_boost_factor_sysctl_handler(struct ctl_table *table, int write,
void __user *buffer, size_t *length, loff_t *ppos)
{
int rc;
rc = proc_dointvec_minmax(table, write, buffer, length, ppos);
if (rc)
return rc;
return 0;
}
int watermark_scale_factor_sysctl_handler(struct ctl_table *table, int write, int watermark_scale_factor_sysctl_handler(struct ctl_table *table, int write,
void __user *buffer, size_t *length, loff_t *ppos) void *buffer, size_t *length, loff_t *ppos)
{ {
int rc; int rc;
@ -8021,7 +7999,7 @@ static void setup_min_unmapped_ratio(void)
int sysctl_min_unmapped_ratio_sysctl_handler(struct ctl_table *table, int write, int sysctl_min_unmapped_ratio_sysctl_handler(struct ctl_table *table, int write,
void __user *buffer, size_t *length, loff_t *ppos) void *buffer, size_t *length, loff_t *ppos)
{ {
int rc; int rc;
@ -8048,7 +8026,7 @@ static void setup_min_slab_ratio(void)
} }
int sysctl_min_slab_ratio_sysctl_handler(struct ctl_table *table, int write, int sysctl_min_slab_ratio_sysctl_handler(struct ctl_table *table, int write,
void __user *buffer, size_t *length, loff_t *ppos) void *buffer, size_t *length, loff_t *ppos)
{ {
int rc; int rc;
@ -8072,7 +8050,7 @@ int sysctl_min_slab_ratio_sysctl_handler(struct ctl_table *table, int write,
* if in function of the boot time zone sizes. * if in function of the boot time zone sizes.
*/ */
int lowmem_reserve_ratio_sysctl_handler(struct ctl_table *table, int write, int lowmem_reserve_ratio_sysctl_handler(struct ctl_table *table, int write,
void __user *buffer, size_t *length, loff_t *ppos) void *buffer, size_t *length, loff_t *ppos)
{ {
proc_dointvec_minmax(table, write, buffer, length, ppos); proc_dointvec_minmax(table, write, buffer, length, ppos);
setup_per_zone_lowmem_reserve(); setup_per_zone_lowmem_reserve();
@ -8094,7 +8072,7 @@ static void __zone_pcp_update(struct zone *zone)
* pagelist can have before it gets flushed back to buddy allocator. * pagelist can have before it gets flushed back to buddy allocator.
*/ */
int percpu_pagelist_fraction_sysctl_handler(struct ctl_table *table, int write, int percpu_pagelist_fraction_sysctl_handler(struct ctl_table *table, int write,
void __user *buffer, size_t *length, loff_t *ppos) void *buffer, size_t *length, loff_t *ppos)
{ {
struct zone *zone; struct zone *zone;
int old_percpu_pagelist_fraction; int old_percpu_pagelist_fraction;

View File

@ -717,9 +717,8 @@ int sysctl_max_map_count __read_mostly = DEFAULT_MAX_MAP_COUNT;
unsigned long sysctl_user_reserve_kbytes __read_mostly = 1UL << 17; /* 128MB */ unsigned long sysctl_user_reserve_kbytes __read_mostly = 1UL << 17; /* 128MB */
unsigned long sysctl_admin_reserve_kbytes __read_mostly = 1UL << 13; /* 8MB */ unsigned long sysctl_admin_reserve_kbytes __read_mostly = 1UL << 13; /* 8MB */
int overcommit_ratio_handler(struct ctl_table *table, int write, int overcommit_ratio_handler(struct ctl_table *table, int write, void *buffer,
void __user *buffer, size_t *lenp, size_t *lenp, loff_t *ppos)
loff_t *ppos)
{ {
int ret; int ret;
@ -729,9 +728,8 @@ int overcommit_ratio_handler(struct ctl_table *table, int write,
return ret; return ret;
} }
int overcommit_kbytes_handler(struct ctl_table *table, int write, int overcommit_kbytes_handler(struct ctl_table *table, int write, void *buffer,
void __user *buffer, size_t *lenp, size_t *lenp, loff_t *ppos)
loff_t *ppos)
{ {
int ret; int ret;

View File

@ -76,7 +76,7 @@ static void invalid_numa_statistics(void)
static DEFINE_MUTEX(vm_numa_stat_lock); static DEFINE_MUTEX(vm_numa_stat_lock);
int sysctl_vm_numa_stat_handler(struct ctl_table *table, int write, int sysctl_vm_numa_stat_handler(struct ctl_table *table, int write,
void __user *buffer, size_t *length, loff_t *ppos) void *buffer, size_t *length, loff_t *ppos)
{ {
int ret, oldval; int ret, oldval;
@ -1751,7 +1751,7 @@ static void refresh_vm_stats(struct work_struct *work)
} }
int vmstat_refresh(struct ctl_table *table, int write, int vmstat_refresh(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos) void *buffer, size_t *lenp, loff_t *ppos)
{ {
long val; long val;
int err; int err;

View File

@ -1027,7 +1027,7 @@ int br_nf_hook_thresh(unsigned int hook, struct net *net,
#ifdef CONFIG_SYSCTL #ifdef CONFIG_SYSCTL
static static
int brnf_sysctl_call_tables(struct ctl_table *ctl, int write, int brnf_sysctl_call_tables(struct ctl_table *ctl, int write,
void __user *buffer, size_t *lenp, loff_t *ppos) void *buffer, size_t *lenp, loff_t *ppos)
{ {
int ret; int ret;

View File

@ -256,17 +256,6 @@ BPF_CALL_2(bpf_skb_load_helper_32_no_cache, const struct sk_buff *, skb,
offset); offset);
} }
BPF_CALL_0(bpf_get_raw_cpu_id)
{
return raw_smp_processor_id();
}
static const struct bpf_func_proto bpf_get_raw_smp_processor_id_proto = {
.func = bpf_get_raw_cpu_id,
.gpl_only = false,
.ret_type = RET_INTEGER,
};
static u32 convert_skb_access(int skb_field, int dst_reg, int src_reg, static u32 convert_skb_access(int skb_field, int dst_reg, int src_reg,
struct bpf_insn *insn_buf) struct bpf_insn *insn_buf)
{ {
@ -4205,36 +4194,19 @@ static const struct bpf_func_proto bpf_get_socket_uid_proto = {
.arg1_type = ARG_PTR_TO_CTX, .arg1_type = ARG_PTR_TO_CTX,
}; };
BPF_CALL_5(bpf_event_output_data, void *, ctx, struct bpf_map *, map, u64, flags, #define SOCKOPT_CC_REINIT (1 << 0)
void *, data, u64, size)
static int _bpf_setsockopt(struct sock *sk, int level, int optname,
char *optval, int optlen, u32 flags)
{ {
if (unlikely(flags & ~(BPF_F_INDEX_MASK)))
return -EINVAL;
return bpf_event_output(map, flags, data, size, NULL, 0, NULL);
}
static const struct bpf_func_proto bpf_event_output_data_proto = {
.func = bpf_event_output_data,
.gpl_only = true,
.ret_type = RET_INTEGER,
.arg1_type = ARG_PTR_TO_CTX,
.arg2_type = ARG_CONST_MAP_PTR,
.arg3_type = ARG_ANYTHING,
.arg4_type = ARG_PTR_TO_MEM,
.arg5_type = ARG_CONST_SIZE_OR_ZERO,
};
BPF_CALL_5(bpf_setsockopt, struct bpf_sock_ops_kern *, bpf_sock,
int, level, int, optname, char *, optval, int, optlen)
{
struct sock *sk = bpf_sock->sk;
int ret = 0; int ret = 0;
int val; int val;
if (!sk_fullsock(sk)) if (!sk_fullsock(sk))
return -EINVAL; return -EINVAL;
sock_owned_by_me(sk);
if (level == SOL_SOCKET) { if (level == SOL_SOCKET) {
if (optlen != sizeof(int)) if (optlen != sizeof(int))
return -EINVAL; return -EINVAL;
@ -4329,7 +4301,7 @@ BPF_CALL_5(bpf_setsockopt, struct bpf_sock_ops_kern *, bpf_sock,
sk->sk_prot->setsockopt == tcp_setsockopt) { sk->sk_prot->setsockopt == tcp_setsockopt) {
if (optname == TCP_CONGESTION) { if (optname == TCP_CONGESTION) {
char name[TCP_CA_NAME_MAX]; char name[TCP_CA_NAME_MAX];
bool reinit = bpf_sock->op > BPF_SOCK_OPS_NEEDS_ECN; bool reinit = flags & SOCKOPT_CC_REINIT;
strncpy(name, optval, min_t(long, optlen, strncpy(name, optval, min_t(long, optlen,
TCP_CA_NAME_MAX-1)); TCP_CA_NAME_MAX-1));
@ -4376,24 +4348,14 @@ BPF_CALL_5(bpf_setsockopt, struct bpf_sock_ops_kern *, bpf_sock,
return ret; return ret;
} }
static const struct bpf_func_proto bpf_setsockopt_proto = { static int _bpf_getsockopt(struct sock *sk, int level, int optname,
.func = bpf_setsockopt, char *optval, int optlen)
.gpl_only = false,
.ret_type = RET_INTEGER,
.arg1_type = ARG_PTR_TO_CTX,
.arg2_type = ARG_ANYTHING,
.arg3_type = ARG_ANYTHING,
.arg4_type = ARG_PTR_TO_MEM,
.arg5_type = ARG_CONST_SIZE,
};
BPF_CALL_5(bpf_getsockopt, struct bpf_sock_ops_kern *, bpf_sock,
int, level, int, optname, char *, optval, int, optlen)
{ {
struct sock *sk = bpf_sock->sk;
if (!sk_fullsock(sk)) if (!sk_fullsock(sk))
goto err_clear; goto err_clear;
sock_owned_by_me(sk);
#ifdef CONFIG_INET #ifdef CONFIG_INET
if (level == SOL_TCP && sk->sk_prot->getsockopt == tcp_getsockopt) { if (level == SOL_TCP && sk->sk_prot->getsockopt == tcp_getsockopt) {
struct inet_connection_sock *icsk; struct inet_connection_sock *icsk;
@ -4459,8 +4421,71 @@ err_clear:
return -EINVAL; return -EINVAL;
} }
static const struct bpf_func_proto bpf_getsockopt_proto = { BPF_CALL_5(bpf_sock_addr_setsockopt, struct bpf_sock_addr_kern *, ctx,
.func = bpf_getsockopt, int, level, int, optname, char *, optval, int, optlen)
{
u32 flags = 0;
return _bpf_setsockopt(ctx->sk, level, optname, optval, optlen,
flags);
}
static const struct bpf_func_proto bpf_sock_addr_setsockopt_proto = {
.func = bpf_sock_addr_setsockopt,
.gpl_only = false,
.ret_type = RET_INTEGER,
.arg1_type = ARG_PTR_TO_CTX,
.arg2_type = ARG_ANYTHING,
.arg3_type = ARG_ANYTHING,
.arg4_type = ARG_PTR_TO_MEM,
.arg5_type = ARG_CONST_SIZE,
};
BPF_CALL_5(bpf_sock_addr_getsockopt, struct bpf_sock_addr_kern *, ctx,
int, level, int, optname, char *, optval, int, optlen)
{
return _bpf_getsockopt(ctx->sk, level, optname, optval, optlen);
}
static const struct bpf_func_proto bpf_sock_addr_getsockopt_proto = {
.func = bpf_sock_addr_getsockopt,
.gpl_only = false,
.ret_type = RET_INTEGER,
.arg1_type = ARG_PTR_TO_CTX,
.arg2_type = ARG_ANYTHING,
.arg3_type = ARG_ANYTHING,
.arg4_type = ARG_PTR_TO_UNINIT_MEM,
.arg5_type = ARG_CONST_SIZE,
};
BPF_CALL_5(bpf_sock_ops_setsockopt, struct bpf_sock_ops_kern *, bpf_sock,
int, level, int, optname, char *, optval, int, optlen)
{
u32 flags = 0;
if (bpf_sock->op > BPF_SOCK_OPS_NEEDS_ECN)
flags |= SOCKOPT_CC_REINIT;
return _bpf_setsockopt(bpf_sock->sk, level, optname, optval, optlen,
flags);
}
static const struct bpf_func_proto bpf_sock_ops_setsockopt_proto = {
.func = bpf_sock_ops_setsockopt,
.gpl_only = false,
.ret_type = RET_INTEGER,
.arg1_type = ARG_PTR_TO_CTX,
.arg2_type = ARG_ANYTHING,
.arg3_type = ARG_ANYTHING,
.arg4_type = ARG_PTR_TO_MEM,
.arg5_type = ARG_CONST_SIZE,
};
BPF_CALL_5(bpf_sock_ops_getsockopt, struct bpf_sock_ops_kern *, bpf_sock,
int, level, int, optname, char *, optval, int, optlen)
{
return _bpf_getsockopt(bpf_sock->sk, level, optname, optval, optlen);
}
static const struct bpf_func_proto bpf_sock_ops_getsockopt_proto = {
.func = bpf_sock_ops_getsockopt,
.gpl_only = false, .gpl_only = false,
.ret_type = RET_INTEGER, .ret_type = RET_INTEGER,
.arg1_type = ARG_PTR_TO_CTX, .arg1_type = ARG_PTR_TO_CTX,
@ -5983,52 +6008,7 @@ bool bpf_helper_changes_pkt_data(void *func)
return false; return false;
} }
const struct bpf_func_proto * const struct bpf_func_proto bpf_event_output_data_proto __weak;
bpf_base_func_proto(enum bpf_func_id func_id)
{
switch (func_id) {
case BPF_FUNC_map_lookup_elem:
return &bpf_map_lookup_elem_proto;
case BPF_FUNC_map_update_elem:
return &bpf_map_update_elem_proto;
case BPF_FUNC_map_delete_elem:
return &bpf_map_delete_elem_proto;
case BPF_FUNC_map_push_elem:
return &bpf_map_push_elem_proto;
case BPF_FUNC_map_pop_elem:
return &bpf_map_pop_elem_proto;
case BPF_FUNC_map_peek_elem:
return &bpf_map_peek_elem_proto;
case BPF_FUNC_get_prandom_u32:
return &bpf_get_prandom_u32_proto;
case BPF_FUNC_get_smp_processor_id:
return &bpf_get_raw_smp_processor_id_proto;
case BPF_FUNC_get_numa_node_id:
return &bpf_get_numa_node_id_proto;
case BPF_FUNC_tail_call:
return &bpf_tail_call_proto;
case BPF_FUNC_ktime_get_ns:
return &bpf_ktime_get_ns_proto;
default:
break;
}
if (!capable(CAP_SYS_ADMIN))
return NULL;
switch (func_id) {
case BPF_FUNC_spin_lock:
return &bpf_spin_lock_proto;
case BPF_FUNC_spin_unlock:
return &bpf_spin_unlock_proto;
case BPF_FUNC_trace_printk:
return bpf_get_trace_printk_proto();
case BPF_FUNC_jiffies64:
return &bpf_jiffies64_proto;
default:
return NULL;
}
}
static const struct bpf_func_proto * static const struct bpf_func_proto *
sock_filter_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog) sock_filter_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
@ -6119,6 +6099,22 @@ sock_addr_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
return &bpf_sk_storage_get_proto; return &bpf_sk_storage_get_proto;
case BPF_FUNC_sk_storage_delete: case BPF_FUNC_sk_storage_delete:
return &bpf_sk_storage_delete_proto; return &bpf_sk_storage_delete_proto;
case BPF_FUNC_setsockopt:
switch (prog->expected_attach_type) {
case BPF_CGROUP_INET4_CONNECT:
case BPF_CGROUP_INET6_CONNECT:
return &bpf_sock_addr_setsockopt_proto;
default:
return NULL;
}
case BPF_FUNC_getsockopt:
switch (prog->expected_attach_type) {
case BPF_CGROUP_INET4_CONNECT:
case BPF_CGROUP_INET6_CONNECT:
return &bpf_sock_addr_getsockopt_proto;
default:
return NULL;
}
default: default:
return bpf_base_func_proto(func_id); return bpf_base_func_proto(func_id);
} }
@ -6213,6 +6209,8 @@ tc_cls_act_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
return &bpf_skb_adjust_room_proto; return &bpf_skb_adjust_room_proto;
case BPF_FUNC_skb_change_tail: case BPF_FUNC_skb_change_tail:
return &bpf_skb_change_tail_proto; return &bpf_skb_change_tail_proto;
case BPF_FUNC_skb_change_head:
return &bpf_skb_change_head_proto;
case BPF_FUNC_skb_get_tunnel_key: case BPF_FUNC_skb_get_tunnel_key:
return &bpf_skb_get_tunnel_key_proto; return &bpf_skb_get_tunnel_key_proto;
case BPF_FUNC_skb_set_tunnel_key: case BPF_FUNC_skb_set_tunnel_key:
@ -6335,9 +6333,9 @@ sock_ops_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
{ {
switch (func_id) { switch (func_id) {
case BPF_FUNC_setsockopt: case BPF_FUNC_setsockopt:
return &bpf_setsockopt_proto; return &bpf_sock_ops_setsockopt_proto;
case BPF_FUNC_getsockopt: case BPF_FUNC_getsockopt:
return &bpf_getsockopt_proto; return &bpf_sock_ops_getsockopt_proto;
case BPF_FUNC_sock_ops_cb_flags_set: case BPF_FUNC_sock_ops_cb_flags_set:
return &bpf_sock_ops_cb_flags_set_proto; return &bpf_sock_ops_cb_flags_set_proto;
case BPF_FUNC_sock_map_update: case BPF_FUNC_sock_map_update:
@ -8786,6 +8784,10 @@ BPF_CALL_4(sk_select_reuseport, struct sk_reuseport_kern *, reuse_kern,
reuse = rcu_dereference(selected_sk->sk_reuseport_cb); reuse = rcu_dereference(selected_sk->sk_reuseport_cb);
if (!reuse) { if (!reuse) {
/* Lookup in sock_map can return TCP ESTABLISHED sockets. */
if (sk_is_refcounted(selected_sk))
sock_put(selected_sk);
/* reuseport_array has only sk with non NULL sk_reuseport_cb. /* reuseport_array has only sk with non NULL sk_reuseport_cb.
* The only (!reuse) case here is - the sk has already been * The only (!reuse) case here is - the sk has already been
* unhashed (e.g. by close()), so treat it as -ENOENT. * unhashed (e.g. by close()), so treat it as -ENOENT.

View File

@ -3379,7 +3379,7 @@ EXPORT_SYMBOL(neigh_app_ns);
static int unres_qlen_max = INT_MAX / SKB_TRUESIZE(ETH_FRAME_LEN); static int unres_qlen_max = INT_MAX / SKB_TRUESIZE(ETH_FRAME_LEN);
static int proc_unres_qlen(struct ctl_table *ctl, int write, static int proc_unres_qlen(struct ctl_table *ctl, int write,
void __user *buffer, size_t *lenp, loff_t *ppos) void *buffer, size_t *lenp, loff_t *ppos)
{ {
int size, ret; int size, ret;
struct ctl_table tmp = *ctl; struct ctl_table tmp = *ctl;
@ -3443,8 +3443,8 @@ static void neigh_proc_update(struct ctl_table *ctl, int write)
} }
static int neigh_proc_dointvec_zero_intmax(struct ctl_table *ctl, int write, static int neigh_proc_dointvec_zero_intmax(struct ctl_table *ctl, int write,
void __user *buffer, void *buffer, size_t *lenp,
size_t *lenp, loff_t *ppos) loff_t *ppos)
{ {
struct ctl_table tmp = *ctl; struct ctl_table tmp = *ctl;
int ret; int ret;
@ -3457,8 +3457,8 @@ static int neigh_proc_dointvec_zero_intmax(struct ctl_table *ctl, int write,
return ret; return ret;
} }
int neigh_proc_dointvec(struct ctl_table *ctl, int write, int neigh_proc_dointvec(struct ctl_table *ctl, int write, void *buffer,
void __user *buffer, size_t *lenp, loff_t *ppos) size_t *lenp, loff_t *ppos)
{ {
int ret = proc_dointvec(ctl, write, buffer, lenp, ppos); int ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
@ -3467,8 +3467,7 @@ int neigh_proc_dointvec(struct ctl_table *ctl, int write,
} }
EXPORT_SYMBOL(neigh_proc_dointvec); EXPORT_SYMBOL(neigh_proc_dointvec);
int neigh_proc_dointvec_jiffies(struct ctl_table *ctl, int write, int neigh_proc_dointvec_jiffies(struct ctl_table *ctl, int write, void *buffer,
void __user *buffer,
size_t *lenp, loff_t *ppos) size_t *lenp, loff_t *ppos)
{ {
int ret = proc_dointvec_jiffies(ctl, write, buffer, lenp, ppos); int ret = proc_dointvec_jiffies(ctl, write, buffer, lenp, ppos);
@ -3479,8 +3478,8 @@ int neigh_proc_dointvec_jiffies(struct ctl_table *ctl, int write,
EXPORT_SYMBOL(neigh_proc_dointvec_jiffies); EXPORT_SYMBOL(neigh_proc_dointvec_jiffies);
static int neigh_proc_dointvec_userhz_jiffies(struct ctl_table *ctl, int write, static int neigh_proc_dointvec_userhz_jiffies(struct ctl_table *ctl, int write,
void __user *buffer, void *buffer, size_t *lenp,
size_t *lenp, loff_t *ppos) loff_t *ppos)
{ {
int ret = proc_dointvec_userhz_jiffies(ctl, write, buffer, lenp, ppos); int ret = proc_dointvec_userhz_jiffies(ctl, write, buffer, lenp, ppos);
@ -3489,8 +3488,7 @@ static int neigh_proc_dointvec_userhz_jiffies(struct ctl_table *ctl, int write,
} }
int neigh_proc_dointvec_ms_jiffies(struct ctl_table *ctl, int write, int neigh_proc_dointvec_ms_jiffies(struct ctl_table *ctl, int write,
void __user *buffer, void *buffer, size_t *lenp, loff_t *ppos)
size_t *lenp, loff_t *ppos)
{ {
int ret = proc_dointvec_ms_jiffies(ctl, write, buffer, lenp, ppos); int ret = proc_dointvec_ms_jiffies(ctl, write, buffer, lenp, ppos);
@ -3500,8 +3498,8 @@ int neigh_proc_dointvec_ms_jiffies(struct ctl_table *ctl, int write,
EXPORT_SYMBOL(neigh_proc_dointvec_ms_jiffies); EXPORT_SYMBOL(neigh_proc_dointvec_ms_jiffies);
static int neigh_proc_dointvec_unres_qlen(struct ctl_table *ctl, int write, static int neigh_proc_dointvec_unres_qlen(struct ctl_table *ctl, int write,
void __user *buffer, void *buffer, size_t *lenp,
size_t *lenp, loff_t *ppos) loff_t *ppos)
{ {
int ret = proc_unres_qlen(ctl, write, buffer, lenp, ppos); int ret = proc_unres_qlen(ctl, write, buffer, lenp, ppos);
@ -3510,8 +3508,8 @@ static int neigh_proc_dointvec_unres_qlen(struct ctl_table *ctl, int write,
} }
static int neigh_proc_base_reachable_time(struct ctl_table *ctl, int write, static int neigh_proc_base_reachable_time(struct ctl_table *ctl, int write,
void __user *buffer, void *buffer, size_t *lenp,
size_t *lenp, loff_t *ppos) loff_t *ppos)
{ {
struct neigh_parms *p = ctl->extra2; struct neigh_parms *p = ctl->extra2;
int ret; int ret;

View File

@ -343,7 +343,14 @@ static struct sock *__sock_map_lookup_elem(struct bpf_map *map, u32 key)
static void *sock_map_lookup(struct bpf_map *map, void *key) static void *sock_map_lookup(struct bpf_map *map, void *key)
{ {
return __sock_map_lookup_elem(map, *(u32 *)key); struct sock *sk;
sk = __sock_map_lookup_elem(map, *(u32 *)key);
if (!sk || !sk_fullsock(sk))
return NULL;
if (sk_is_refcounted(sk) && !refcount_inc_not_zero(&sk->sk_refcnt))
return NULL;
return sk;
} }
static void *sock_map_lookup_sys(struct bpf_map *map, void *key) static void *sock_map_lookup_sys(struct bpf_map *map, void *key)
@ -1051,7 +1058,14 @@ static void *sock_hash_lookup_sys(struct bpf_map *map, void *key)
static void *sock_hash_lookup(struct bpf_map *map, void *key) static void *sock_hash_lookup(struct bpf_map *map, void *key)
{ {
return __sock_hash_lookup_elem(map, key); struct sock *sk;
sk = __sock_hash_lookup_elem(map, key);
if (!sk || !sk_fullsock(sk))
return NULL;
if (sk_is_refcounted(sk) && !refcount_inc_not_zero(&sk->sk_refcnt))
return NULL;
return sk;
} }
static void sock_hash_release_progs(struct bpf_map *map) static void sock_hash_release_progs(struct bpf_map *map)

View File

@ -45,7 +45,7 @@ EXPORT_SYMBOL(sysctl_devconf_inherit_init_net);
#ifdef CONFIG_RPS #ifdef CONFIG_RPS
static int rps_sock_flow_sysctl(struct ctl_table *table, int write, static int rps_sock_flow_sysctl(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos) void *buffer, size_t *lenp, loff_t *ppos)
{ {
unsigned int orig_size, size; unsigned int orig_size, size;
int ret, i; int ret, i;
@ -115,8 +115,7 @@ static int rps_sock_flow_sysctl(struct ctl_table *table, int write,
static DEFINE_MUTEX(flow_limit_update_mutex); static DEFINE_MUTEX(flow_limit_update_mutex);
static int flow_limit_cpu_sysctl(struct ctl_table *table, int write, static int flow_limit_cpu_sysctl(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, void *buffer, size_t *lenp, loff_t *ppos)
loff_t *ppos)
{ {
struct sd_flow_limit *cur; struct sd_flow_limit *cur;
struct softnet_data *sd; struct softnet_data *sd;
@ -180,10 +179,7 @@ write_unlock:
} }
if (len < *lenp) if (len < *lenp)
kbuf[len++] = '\n'; kbuf[len++] = '\n';
if (copy_to_user(buffer, kbuf, len)) { memcpy(buffer, kbuf, len);
ret = -EFAULT;
goto done;
}
*lenp = len; *lenp = len;
*ppos += len; *ppos += len;
} }
@ -194,8 +190,7 @@ done:
} }
static int flow_limit_table_len_sysctl(struct ctl_table *table, int write, static int flow_limit_table_len_sysctl(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, void *buffer, size_t *lenp, loff_t *ppos)
loff_t *ppos)
{ {
unsigned int old, *ptr; unsigned int old, *ptr;
int ret; int ret;
@ -217,7 +212,7 @@ static int flow_limit_table_len_sysctl(struct ctl_table *table, int write,
#ifdef CONFIG_NET_SCHED #ifdef CONFIG_NET_SCHED
static int set_default_qdisc(struct ctl_table *table, int write, static int set_default_qdisc(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos) void *buffer, size_t *lenp, loff_t *ppos)
{ {
char id[IFNAMSIZ]; char id[IFNAMSIZ];
struct ctl_table tbl = { struct ctl_table tbl = {
@ -236,7 +231,7 @@ static int set_default_qdisc(struct ctl_table *table, int write,
#endif #endif
static int proc_do_dev_weight(struct ctl_table *table, int write, static int proc_do_dev_weight(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos) void *buffer, size_t *lenp, loff_t *ppos)
{ {
int ret; int ret;
@ -251,7 +246,7 @@ static int proc_do_dev_weight(struct ctl_table *table, int write,
} }
static int proc_do_rss_key(struct ctl_table *table, int write, static int proc_do_rss_key(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos) void *buffer, size_t *lenp, loff_t *ppos)
{ {
struct ctl_table fake_table; struct ctl_table fake_table;
char buf[NETDEV_RSS_KEY_LEN * 3]; char buf[NETDEV_RSS_KEY_LEN * 3];
@ -264,7 +259,7 @@ static int proc_do_rss_key(struct ctl_table *table, int write,
#ifdef CONFIG_BPF_JIT #ifdef CONFIG_BPF_JIT
static int proc_dointvec_minmax_bpf_enable(struct ctl_table *table, int write, static int proc_dointvec_minmax_bpf_enable(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, void *buffer, size_t *lenp,
loff_t *ppos) loff_t *ppos)
{ {
int ret, jit_enable = *(int *)table->data; int ret, jit_enable = *(int *)table->data;
@ -291,8 +286,7 @@ static int proc_dointvec_minmax_bpf_enable(struct ctl_table *table, int write,
# ifdef CONFIG_HAVE_EBPF_JIT # ifdef CONFIG_HAVE_EBPF_JIT
static int static int
proc_dointvec_minmax_bpf_restricted(struct ctl_table *table, int write, proc_dointvec_minmax_bpf_restricted(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, void *buffer, size_t *lenp, loff_t *ppos)
loff_t *ppos)
{ {
if (!capable(CAP_SYS_ADMIN)) if (!capable(CAP_SYS_ADMIN))
return -EPERM; return -EPERM;
@ -303,8 +297,7 @@ proc_dointvec_minmax_bpf_restricted(struct ctl_table *table, int write,
static int static int
proc_dolongvec_minmax_bpf_restricted(struct ctl_table *table, int write, proc_dolongvec_minmax_bpf_restricted(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, void *buffer, size_t *lenp, loff_t *ppos)
loff_t *ppos)
{ {
if (!capable(CAP_SYS_ADMIN)) if (!capable(CAP_SYS_ADMIN))
return -EPERM; return -EPERM;

View File

@ -160,8 +160,8 @@ static int max_t3[] = { 8191 }; /* Must fit in 16 bits when multiplied by BCT3MU
static int min_priority[1]; static int min_priority[1];
static int max_priority[] = { 127 }; /* From DECnet spec */ static int max_priority[] = { 127 }; /* From DECnet spec */
static int dn_forwarding_proc(struct ctl_table *, int, static int dn_forwarding_proc(struct ctl_table *, int, void *, size_t *,
void __user *, size_t *, loff_t *); loff_t *);
static struct dn_dev_sysctl_table { static struct dn_dev_sysctl_table {
struct ctl_table_header *sysctl_header; struct ctl_table_header *sysctl_header;
struct ctl_table dn_dev_vars[5]; struct ctl_table dn_dev_vars[5];
@ -245,8 +245,7 @@ static void dn_dev_sysctl_unregister(struct dn_dev_parms *parms)
} }
static int dn_forwarding_proc(struct ctl_table *table, int write, static int dn_forwarding_proc(struct ctl_table *table, int write,
void __user *buffer, void *buffer, size_t *lenp, loff_t *ppos)
size_t *lenp, loff_t *ppos)
{ {
#ifdef CONFIG_DECNET_ROUTER #ifdef CONFIG_DECNET_ROUTER
struct net_device *dev = table->extra1; struct net_device *dev = table->extra1;

View File

@ -134,8 +134,7 @@ static int parse_addr(__le16 *addr, char *str)
} }
static int dn_node_address_handler(struct ctl_table *table, int write, static int dn_node_address_handler(struct ctl_table *table, int write,
void __user *buffer, void *buffer, size_t *lenp, loff_t *ppos)
size_t *lenp, loff_t *ppos)
{ {
char addr[DN_ASCBUF_LEN]; char addr[DN_ASCBUF_LEN];
size_t len; size_t len;
@ -148,10 +147,7 @@ static int dn_node_address_handler(struct ctl_table *table, int write,
if (write) { if (write) {
len = (*lenp < DN_ASCBUF_LEN) ? *lenp : (DN_ASCBUF_LEN-1); len = (*lenp < DN_ASCBUF_LEN) ? *lenp : (DN_ASCBUF_LEN-1);
memcpy(addr, buffer, len);
if (copy_from_user(addr, buffer, len))
return -EFAULT;
addr[len] = 0; addr[len] = 0;
strip_it(addr); strip_it(addr);
@ -173,11 +169,9 @@ static int dn_node_address_handler(struct ctl_table *table, int write,
len = strlen(addr); len = strlen(addr);
addr[len++] = '\n'; addr[len++] = '\n';
if (len > *lenp) len = *lenp; if (len > *lenp)
len = *lenp;
if (copy_to_user(buffer, addr, len)) memcpy(buffer, addr, len);
return -EFAULT;
*lenp = len; *lenp = len;
*ppos += len; *ppos += len;
@ -185,8 +179,7 @@ static int dn_node_address_handler(struct ctl_table *table, int write,
} }
static int dn_def_dev_handler(struct ctl_table *table, int write, static int dn_def_dev_handler(struct ctl_table *table, int write,
void __user *buffer, void *buffer, size_t *lenp, loff_t *ppos)
size_t *lenp, loff_t *ppos)
{ {
size_t len; size_t len;
struct net_device *dev; struct net_device *dev;
@ -201,9 +194,7 @@ static int dn_def_dev_handler(struct ctl_table *table, int write,
if (*lenp > 16) if (*lenp > 16)
return -E2BIG; return -E2BIG;
if (copy_from_user(devname, buffer, *lenp)) memcpy(devname, buffer, *lenp);
return -EFAULT;
devname[*lenp] = 0; devname[*lenp] = 0;
strip_it(devname); strip_it(devname);
@ -238,9 +229,7 @@ static int dn_def_dev_handler(struct ctl_table *table, int write,
if (len > *lenp) len = *lenp; if (len > *lenp) len = *lenp;
if (copy_to_user(buffer, devname, len)) memcpy(buffer, devname, len);
return -EFAULT;
*lenp = len; *lenp = len;
*ppos += len; *ppos += len;

View File

@ -2366,8 +2366,7 @@ static int devinet_conf_ifindex(struct net *net, struct ipv4_devconf *cnf)
} }
static int devinet_conf_proc(struct ctl_table *ctl, int write, static int devinet_conf_proc(struct ctl_table *ctl, int write,
void __user *buffer, void *buffer, size_t *lenp, loff_t *ppos)
size_t *lenp, loff_t *ppos)
{ {
int old_value = *(int *)ctl->data; int old_value = *(int *)ctl->data;
int ret = proc_dointvec(ctl, write, buffer, lenp, ppos); int ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
@ -2419,8 +2418,7 @@ static int devinet_conf_proc(struct ctl_table *ctl, int write,
} }
static int devinet_sysctl_forward(struct ctl_table *ctl, int write, static int devinet_sysctl_forward(struct ctl_table *ctl, int write,
void __user *buffer, void *buffer, size_t *lenp, loff_t *ppos)
size_t *lenp, loff_t *ppos)
{ {
int *valp = ctl->data; int *valp = ctl->data;
int val = *valp; int val = *valp;
@ -2463,8 +2461,7 @@ static int devinet_sysctl_forward(struct ctl_table *ctl, int write,
} }
static int ipv4_doint_and_flush(struct ctl_table *ctl, int write, static int ipv4_doint_and_flush(struct ctl_table *ctl, int write,
void __user *buffer, void *buffer, size_t *lenp, loff_t *ppos)
size_t *lenp, loff_t *ppos)
{ {
int *valp = ctl->data; int *valp = ctl->data;
int val = *valp; int val = *valp;

View File

@ -3336,8 +3336,7 @@ static int ip_rt_gc_elasticity __read_mostly = 8;
static int ip_min_valid_pmtu __read_mostly = IPV4_MIN_MTU; static int ip_min_valid_pmtu __read_mostly = IPV4_MIN_MTU;
static int ipv4_sysctl_rtcache_flush(struct ctl_table *__ctl, int write, static int ipv4_sysctl_rtcache_flush(struct ctl_table *__ctl, int write,
void __user *buffer, void *buffer, size_t *lenp, loff_t *ppos)
size_t *lenp, loff_t *ppos)
{ {
struct net *net = (struct net *)__ctl->extra1; struct net *net = (struct net *)__ctl->extra1;

View File

@ -71,8 +71,7 @@ static void set_local_port_range(struct net *net, int range[2])
/* Validate changes from /proc interface. */ /* Validate changes from /proc interface. */
static int ipv4_local_port_range(struct ctl_table *table, int write, static int ipv4_local_port_range(struct ctl_table *table, int write,
void __user *buffer, void *buffer, size_t *lenp, loff_t *ppos)
size_t *lenp, loff_t *ppos)
{ {
struct net *net = struct net *net =
container_of(table->data, struct net, ipv4.ip_local_ports.range); container_of(table->data, struct net, ipv4.ip_local_ports.range);
@ -107,7 +106,7 @@ static int ipv4_local_port_range(struct ctl_table *table, int write,
/* Validate changes from /proc interface. */ /* Validate changes from /proc interface. */
static int ipv4_privileged_ports(struct ctl_table *table, int write, static int ipv4_privileged_ports(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos) void *buffer, size_t *lenp, loff_t *ppos)
{ {
struct net *net = container_of(table->data, struct net, struct net *net = container_of(table->data, struct net,
ipv4.sysctl_ip_prot_sock); ipv4.sysctl_ip_prot_sock);
@ -168,8 +167,7 @@ static void set_ping_group_range(struct ctl_table *table, kgid_t low, kgid_t hig
/* Validate changes from /proc interface. */ /* Validate changes from /proc interface. */
static int ipv4_ping_group_range(struct ctl_table *table, int write, static int ipv4_ping_group_range(struct ctl_table *table, int write,
void __user *buffer, void *buffer, size_t *lenp, loff_t *ppos)
size_t *lenp, loff_t *ppos)
{ {
struct user_namespace *user_ns = current_user_ns(); struct user_namespace *user_ns = current_user_ns();
int ret; int ret;
@ -204,8 +202,7 @@ static int ipv4_ping_group_range(struct ctl_table *table, int write,
} }
static int ipv4_fwd_update_priority(struct ctl_table *table, int write, static int ipv4_fwd_update_priority(struct ctl_table *table, int write,
void __user *buffer, void *buffer, size_t *lenp, loff_t *ppos)
size_t *lenp, loff_t *ppos)
{ {
struct net *net; struct net *net;
int ret; int ret;
@ -221,7 +218,7 @@ static int ipv4_fwd_update_priority(struct ctl_table *table, int write,
} }
static int proc_tcp_congestion_control(struct ctl_table *ctl, int write, static int proc_tcp_congestion_control(struct ctl_table *ctl, int write,
void __user *buffer, size_t *lenp, loff_t *ppos) void *buffer, size_t *lenp, loff_t *ppos)
{ {
struct net *net = container_of(ctl->data, struct net, struct net *net = container_of(ctl->data, struct net,
ipv4.tcp_congestion_control); ipv4.tcp_congestion_control);
@ -241,9 +238,8 @@ static int proc_tcp_congestion_control(struct ctl_table *ctl, int write,
} }
static int proc_tcp_available_congestion_control(struct ctl_table *ctl, static int proc_tcp_available_congestion_control(struct ctl_table *ctl,
int write, int write, void *buffer,
void __user *buffer, size_t *lenp, size_t *lenp, loff_t *ppos)
loff_t *ppos)
{ {
struct ctl_table tbl = { .maxlen = TCP_CA_BUF_MAX, }; struct ctl_table tbl = { .maxlen = TCP_CA_BUF_MAX, };
int ret; int ret;
@ -258,9 +254,8 @@ static int proc_tcp_available_congestion_control(struct ctl_table *ctl,
} }
static int proc_allowed_congestion_control(struct ctl_table *ctl, static int proc_allowed_congestion_control(struct ctl_table *ctl,
int write, int write, void *buffer,
void __user *buffer, size_t *lenp, size_t *lenp, loff_t *ppos)
loff_t *ppos)
{ {
struct ctl_table tbl = { .maxlen = TCP_CA_BUF_MAX }; struct ctl_table tbl = { .maxlen = TCP_CA_BUF_MAX };
int ret; int ret;
@ -296,8 +291,7 @@ static int sscanf_key(char *buf, __le32 *key)
} }
static int proc_tcp_fastopen_key(struct ctl_table *table, int write, static int proc_tcp_fastopen_key(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, void *buffer, size_t *lenp, loff_t *ppos)
loff_t *ppos)
{ {
struct net *net = container_of(table->data, struct net, struct net *net = container_of(table->data, struct net,
ipv4.sysctl_tcp_fastopen); ipv4.sysctl_tcp_fastopen);
@ -399,7 +393,7 @@ static void proc_configure_early_demux(int enabled, int protocol)
} }
static int proc_tcp_early_demux(struct ctl_table *table, int write, static int proc_tcp_early_demux(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos) void *buffer, size_t *lenp, loff_t *ppos)
{ {
int ret = 0; int ret = 0;
@ -415,7 +409,7 @@ static int proc_tcp_early_demux(struct ctl_table *table, int write,
} }
static int proc_udp_early_demux(struct ctl_table *table, int write, static int proc_udp_early_demux(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos) void *buffer, size_t *lenp, loff_t *ppos)
{ {
int ret = 0; int ret = 0;
@ -431,8 +425,7 @@ static int proc_udp_early_demux(struct ctl_table *table, int write,
} }
static int proc_tfo_blackhole_detect_timeout(struct ctl_table *table, static int proc_tfo_blackhole_detect_timeout(struct ctl_table *table,
int write, int write, void *buffer,
void __user *buffer,
size_t *lenp, loff_t *ppos) size_t *lenp, loff_t *ppos)
{ {
struct net *net = container_of(table->data, struct net, struct net *net = container_of(table->data, struct net,
@ -447,8 +440,7 @@ static int proc_tfo_blackhole_detect_timeout(struct ctl_table *table,
} }
static int proc_tcp_available_ulp(struct ctl_table *ctl, static int proc_tcp_available_ulp(struct ctl_table *ctl,
int write, int write, void *buffer, size_t *lenp,
void __user *buffer, size_t *lenp,
loff_t *ppos) loff_t *ppos)
{ {
struct ctl_table tbl = { .maxlen = TCP_ULP_BUF_MAX, }; struct ctl_table tbl = { .maxlen = TCP_ULP_BUF_MAX, };
@ -466,7 +458,7 @@ static int proc_tcp_available_ulp(struct ctl_table *ctl,
#ifdef CONFIG_IP_ROUTE_MULTIPATH #ifdef CONFIG_IP_ROUTE_MULTIPATH
static int proc_fib_multipath_hash_policy(struct ctl_table *table, int write, static int proc_fib_multipath_hash_policy(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, void *buffer, size_t *lenp,
loff_t *ppos) loff_t *ppos)
{ {
struct net *net = container_of(table->data, struct net, struct net *net = container_of(table->data, struct net,

View File

@ -6095,9 +6095,8 @@ static void ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp)
#ifdef CONFIG_SYSCTL #ifdef CONFIG_SYSCTL
static static int addrconf_sysctl_forward(struct ctl_table *ctl, int write,
int addrconf_sysctl_forward(struct ctl_table *ctl, int write, void *buffer, size_t *lenp, loff_t *ppos)
void __user *buffer, size_t *lenp, loff_t *ppos)
{ {
int *valp = ctl->data; int *valp = ctl->data;
int val = *valp; int val = *valp;
@ -6121,9 +6120,8 @@ int addrconf_sysctl_forward(struct ctl_table *ctl, int write,
return ret; return ret;
} }
static static int addrconf_sysctl_mtu(struct ctl_table *ctl, int write,
int addrconf_sysctl_mtu(struct ctl_table *ctl, int write, void *buffer, size_t *lenp, loff_t *ppos)
void __user *buffer, size_t *lenp, loff_t *ppos)
{ {
struct inet6_dev *idev = ctl->extra1; struct inet6_dev *idev = ctl->extra1;
int min_mtu = IPV6_MIN_MTU; int min_mtu = IPV6_MIN_MTU;
@ -6193,9 +6191,8 @@ static int addrconf_disable_ipv6(struct ctl_table *table, int *p, int newf)
return 0; return 0;
} }
static static int addrconf_sysctl_disable(struct ctl_table *ctl, int write,
int addrconf_sysctl_disable(struct ctl_table *ctl, int write, void *buffer, size_t *lenp, loff_t *ppos)
void __user *buffer, size_t *lenp, loff_t *ppos)
{ {
int *valp = ctl->data; int *valp = ctl->data;
int val = *valp; int val = *valp;
@ -6219,9 +6216,8 @@ int addrconf_sysctl_disable(struct ctl_table *ctl, int write,
return ret; return ret;
} }
static static int addrconf_sysctl_proxy_ndp(struct ctl_table *ctl, int write,
int addrconf_sysctl_proxy_ndp(struct ctl_table *ctl, int write, void *buffer, size_t *lenp, loff_t *ppos)
void __user *buffer, size_t *lenp, loff_t *ppos)
{ {
int *valp = ctl->data; int *valp = ctl->data;
int ret; int ret;
@ -6262,7 +6258,7 @@ int addrconf_sysctl_proxy_ndp(struct ctl_table *ctl, int write,
} }
static int addrconf_sysctl_addr_gen_mode(struct ctl_table *ctl, int write, static int addrconf_sysctl_addr_gen_mode(struct ctl_table *ctl, int write,
void __user *buffer, size_t *lenp, void *buffer, size_t *lenp,
loff_t *ppos) loff_t *ppos)
{ {
int ret = 0; int ret = 0;
@ -6324,7 +6320,7 @@ out:
} }
static int addrconf_sysctl_stable_secret(struct ctl_table *ctl, int write, static int addrconf_sysctl_stable_secret(struct ctl_table *ctl, int write,
void __user *buffer, size_t *lenp, void *buffer, size_t *lenp,
loff_t *ppos) loff_t *ppos)
{ {
int err; int err;
@ -6391,8 +6387,7 @@ out:
static static
int addrconf_sysctl_ignore_routes_with_linkdown(struct ctl_table *ctl, int addrconf_sysctl_ignore_routes_with_linkdown(struct ctl_table *ctl,
int write, int write, void *buffer,
void __user *buffer,
size_t *lenp, size_t *lenp,
loff_t *ppos) loff_t *ppos)
{ {
@ -6492,10 +6487,8 @@ int addrconf_disable_policy(struct ctl_table *ctl, int *valp, int val)
return 0; return 0;
} }
static static int addrconf_sysctl_disable_policy(struct ctl_table *ctl, int write,
int addrconf_sysctl_disable_policy(struct ctl_table *ctl, int write, void *buffer, size_t *lenp, loff_t *ppos)
void __user *buffer, size_t *lenp,
loff_t *ppos)
{ {
int *valp = ctl->data; int *valp = ctl->data;
int val = *valp; int val = *valp;

View File

@ -1835,7 +1835,8 @@ static void ndisc_warn_deprecated_sysctl(struct ctl_table *ctl,
} }
} }
int ndisc_ifinfo_sysctl_change(struct ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos) int ndisc_ifinfo_sysctl_change(struct ctl_table *ctl, int write, void *buffer,
size_t *lenp, loff_t *ppos)
{ {
struct net_device *dev = ctl->extra1; struct net_device *dev = ctl->extra1;
struct inet6_dev *idev; struct inet6_dev *idev;

View File

@ -6092,9 +6092,8 @@ static int rt6_stats_seq_show(struct seq_file *seq, void *v)
#ifdef CONFIG_SYSCTL #ifdef CONFIG_SYSCTL
static static int ipv6_sysctl_rtcache_flush(struct ctl_table *ctl, int write,
int ipv6_sysctl_rtcache_flush(struct ctl_table *ctl, int write, void *buffer, size_t *lenp, loff_t *ppos)
void __user *buffer, size_t *lenp, loff_t *ppos)
{ {
struct net *net; struct net *net;
int delay; int delay;

View File

@ -26,8 +26,7 @@ static int auto_flowlabels_min;
static int auto_flowlabels_max = IP6_AUTO_FLOW_LABEL_MAX; static int auto_flowlabels_max = IP6_AUTO_FLOW_LABEL_MAX;
static int proc_rt6_multipath_hash_policy(struct ctl_table *table, int write, static int proc_rt6_multipath_hash_policy(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, void *buffer, size_t *lenp, loff_t *ppos)
loff_t *ppos)
{ {
struct net *net; struct net *net;
int ret; int ret;

View File

@ -1362,8 +1362,7 @@ done:
(&((struct mpls_dev *)0)->field) (&((struct mpls_dev *)0)->field)
static int mpls_conf_proc(struct ctl_table *ctl, int write, static int mpls_conf_proc(struct ctl_table *ctl, int write,
void __user *buffer, void *buffer, size_t *lenp, loff_t *ppos)
size_t *lenp, loff_t *ppos)
{ {
int oval = *(int *)ctl->data; int oval = *(int *)ctl->data;
int ret = proc_dointvec(ctl, write, buffer, lenp, ppos); int ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
@ -2594,7 +2593,7 @@ nolabels:
} }
static int mpls_platform_labels(struct ctl_table *table, int write, static int mpls_platform_labels(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos) void *buffer, size_t *lenp, loff_t *ppos)
{ {
struct net *net = table->data; struct net *net = table->data;
int platform_labels = net->mpls.platform_labels; int platform_labels = net->mpls.platform_labels;

View File

@ -1736,7 +1736,7 @@ static int three = 3;
static int static int
proc_do_defense_mode(struct ctl_table *table, int write, proc_do_defense_mode(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos) void *buffer, size_t *lenp, loff_t *ppos)
{ {
struct netns_ipvs *ipvs = table->extra2; struct netns_ipvs *ipvs = table->extra2;
int *valp = table->data; int *valp = table->data;
@ -1763,7 +1763,7 @@ proc_do_defense_mode(struct ctl_table *table, int write,
static int static int
proc_do_sync_threshold(struct ctl_table *table, int write, proc_do_sync_threshold(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos) void *buffer, size_t *lenp, loff_t *ppos)
{ {
int *valp = table->data; int *valp = table->data;
int val[2]; int val[2];
@ -1788,7 +1788,7 @@ proc_do_sync_threshold(struct ctl_table *table, int write,
static int static int
proc_do_sync_ports(struct ctl_table *table, int write, proc_do_sync_ports(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos) void *buffer, size_t *lenp, loff_t *ppos)
{ {
int *valp = table->data; int *valp = table->data;
int val = *valp; int val = *valp;

View File

@ -519,7 +519,7 @@ static unsigned int nf_conntrack_htable_size_user __read_mostly;
static int static int
nf_conntrack_hash_sysctl(struct ctl_table *table, int write, nf_conntrack_hash_sysctl(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos) void *buffer, size_t *lenp, loff_t *ppos)
{ {
int ret; int ret;

View File

@ -414,7 +414,7 @@ static struct ctl_table nf_log_sysctl_ftable[] = {
}; };
static int nf_log_proc_dostring(struct ctl_table *table, int write, static int nf_log_proc_dostring(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos) void *buffer, size_t *lenp, loff_t *ppos)
{ {
const struct nf_logger *logger; const struct nf_logger *logger;
char buf[NFLOGGER_NAME_LEN]; char buf[NFLOGGER_NAME_LEN];

View File

@ -49,8 +49,7 @@ void phonet_get_local_port_range(int *min, int *max)
} }
static int proc_local_port_range(struct ctl_table *table, int write, static int proc_local_port_range(struct ctl_table *table, int write,
void __user *buffer, void *buffer, size_t *lenp, loff_t *ppos)
size_t *lenp, loff_t *ppos)
{ {
int ret; int ret;
int range[2] = {local_port_range[0], local_port_range[1]}; int range[2] = {local_port_range[0], local_port_range[1]};

View File

@ -62,8 +62,7 @@ static atomic_t rds_tcp_unloading = ATOMIC_INIT(0);
static struct kmem_cache *rds_tcp_conn_slab; static struct kmem_cache *rds_tcp_conn_slab;
static int rds_tcp_skbuf_handler(struct ctl_table *ctl, int write, static int rds_tcp_skbuf_handler(struct ctl_table *ctl, int write,
void __user *buffer, size_t *lenp, void *buffer, size_t *lenp, loff_t *fpos);
loff_t *fpos);
static int rds_tcp_min_sndbuf = SOCK_MIN_SNDBUF; static int rds_tcp_min_sndbuf = SOCK_MIN_SNDBUF;
static int rds_tcp_min_rcvbuf = SOCK_MIN_RCVBUF; static int rds_tcp_min_rcvbuf = SOCK_MIN_RCVBUF;
@ -676,8 +675,7 @@ static void rds_tcp_sysctl_reset(struct net *net)
} }
static int rds_tcp_skbuf_handler(struct ctl_table *ctl, int write, static int rds_tcp_skbuf_handler(struct ctl_table *ctl, int write,
void __user *buffer, size_t *lenp, void *buffer, size_t *lenp, loff_t *fpos)
loff_t *fpos)
{ {
struct net *net = current->nsproxy->net_ns; struct net *net = current->nsproxy->net_ns;
int err; int err;

Some files were not shown because too many files have changed in this diff Show More