Merge 5.10.136 into android12-5.10-lts

Changes in 5.10.136
	x86/speculation: Make all RETbleed mitigations 64-bit only
	ath9k_htc: fix NULL pointer dereference at ath9k_htc_rxep()
	ath9k_htc: fix NULL pointer dereference at ath9k_htc_tx_get_packet()
	selftests/bpf: Extend verifier and bpf_sock tests for dst_port loads
	selftests/bpf: Check dst_port only on the client socket
	tun: avoid double free in tun_free_netdev
	ACPI: video: Force backlight native for some TongFang devices
	ACPI: video: Shortening quirk list by identifying Clevo by board_name only
	ACPI: APEI: Better fix to avoid spamming the console with old error logs
	crypto: arm64/poly1305 - fix a read out-of-bound
	tools/kvm_stat: fix display of error when multiple processes are found
	selftests: KVM: Handle compiler optimizations in ucall
	Bluetooth: hci_bcm: Add BCM4349B1 variant
	Bluetooth: hci_bcm: Add DT compatible for CYW55572
	Bluetooth: btusb: Add support of IMC Networks PID 0x3568
	Bluetooth: btusb: Add Realtek RTL8852C support ID 0x04CA:0x4007
	Bluetooth: btusb: Add Realtek RTL8852C support ID 0x04C5:0x1675
	Bluetooth: btusb: Add Realtek RTL8852C support ID 0x0CB8:0xC558
	Bluetooth: btusb: Add Realtek RTL8852C support ID 0x13D3:0x3587
	Bluetooth: btusb: Add Realtek RTL8852C support ID 0x13D3:0x3586
	macintosh/adb: fix oob read in do_adb_query() function
	x86/speculation: Add RSB VM Exit protections
	x86/speculation: Add LFENCE to RSB fill sequence
	Linux 5.10.136

Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
Change-Id: If3acb748677e784475236f80fbab77933c566c26
This commit is contained in:
Greg Kroah-Hartman
2022-08-11 15:56:44 +02:00
28 changed files with 455 additions and 154 deletions

View File

@@ -422,6 +422,14 @@ The possible values in this file are:
'RSB filling' Protection of RSB on context switch enabled 'RSB filling' Protection of RSB on context switch enabled
============= =========================================== ============= ===========================================
- EIBRS Post-barrier Return Stack Buffer (PBRSB) protection status:
=========================== =======================================================
'PBRSB-eIBRS: SW sequence' CPU is affected and protection of RSB on VMEXIT enabled
'PBRSB-eIBRS: Vulnerable' CPU is vulnerable
'PBRSB-eIBRS: Not affected' CPU is not affected by PBRSB
=========================== =======================================================
Full mitigation might require a microcode update from the CPU Full mitigation might require a microcode update from the CPU
vendor. When the necessary microcode is not available, the kernel will vendor. When the necessary microcode is not available, the kernel will
report vulnerability. report vulnerability.

View File

@@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0 # SPDX-License-Identifier: GPL-2.0
VERSION = 5 VERSION = 5
PATCHLEVEL = 10 PATCHLEVEL = 10
SUBLEVEL = 135 SUBLEVEL = 136
EXTRAVERSION = EXTRAVERSION =
NAME = Dare mighty things NAME = Dare mighty things

View File

@@ -52,7 +52,7 @@ static void neon_poly1305_blocks(struct poly1305_desc_ctx *dctx, const u8 *src,
{ {
if (unlikely(!dctx->sset)) { if (unlikely(!dctx->sset)) {
if (!dctx->rset) { if (!dctx->rset) {
poly1305_init_arch(dctx, src); poly1305_init_arm64(&dctx->h, src);
src += POLY1305_BLOCK_SIZE; src += POLY1305_BLOCK_SIZE;
len -= POLY1305_BLOCK_SIZE; len -= POLY1305_BLOCK_SIZE;
dctx->rset = 1; dctx->rset = 1;

View File

@@ -2454,7 +2454,7 @@ config RETPOLINE
config RETHUNK config RETHUNK
bool "Enable return-thunks" bool "Enable return-thunks"
depends on RETPOLINE && CC_HAS_RETURN_THUNK depends on RETPOLINE && CC_HAS_RETURN_THUNK
default y default y if X86_64
help help
Compile the kernel with the return-thunks compiler option to guard Compile the kernel with the return-thunks compiler option to guard
against kernel-to-user data leaks by avoiding return speculation. against kernel-to-user data leaks by avoiding return speculation.
@@ -2463,21 +2463,21 @@ config RETHUNK
config CPU_UNRET_ENTRY config CPU_UNRET_ENTRY
bool "Enable UNRET on kernel entry" bool "Enable UNRET on kernel entry"
depends on CPU_SUP_AMD && RETHUNK depends on CPU_SUP_AMD && RETHUNK && X86_64
default y default y
help help
Compile the kernel with support for the retbleed=unret mitigation. Compile the kernel with support for the retbleed=unret mitigation.
config CPU_IBPB_ENTRY config CPU_IBPB_ENTRY
bool "Enable IBPB on kernel entry" bool "Enable IBPB on kernel entry"
depends on CPU_SUP_AMD depends on CPU_SUP_AMD && X86_64
default y default y
help help
Compile the kernel with support for the retbleed=ibpb mitigation. Compile the kernel with support for the retbleed=ibpb mitigation.
config CPU_IBRS_ENTRY config CPU_IBRS_ENTRY
bool "Enable IBRS on kernel entry" bool "Enable IBRS on kernel entry"
depends on CPU_SUP_INTEL depends on CPU_SUP_INTEL && X86_64
default y default y
help help
Compile the kernel with support for the spectre_v2=ibrs mitigation. Compile the kernel with support for the spectre_v2=ibrs mitigation.

View File

@@ -299,6 +299,7 @@
#define X86_FEATURE_RETHUNK (11*32+14) /* "" Use REturn THUNK */ #define X86_FEATURE_RETHUNK (11*32+14) /* "" Use REturn THUNK */
#define X86_FEATURE_UNRET (11*32+15) /* "" AMD BTB untrain return */ #define X86_FEATURE_UNRET (11*32+15) /* "" AMD BTB untrain return */
#define X86_FEATURE_USE_IBPB_FW (11*32+16) /* "" Use IBPB during runtime firmware calls */ #define X86_FEATURE_USE_IBPB_FW (11*32+16) /* "" Use IBPB during runtime firmware calls */
#define X86_FEATURE_RSB_VMEXIT_LITE (11*32+17) /* "" Fill RSB on VM exit when EIBRS is enabled */
/* Intel-defined CPU features, CPUID level 0x00000007:1 (EAX), word 12 */ /* Intel-defined CPU features, CPUID level 0x00000007:1 (EAX), word 12 */
#define X86_FEATURE_AVX512_BF16 (12*32+ 5) /* AVX512 BFLOAT16 instructions */ #define X86_FEATURE_AVX512_BF16 (12*32+ 5) /* AVX512 BFLOAT16 instructions */
@@ -429,5 +430,6 @@
#define X86_BUG_SRBDS X86_BUG(24) /* CPU may leak RNG bits if not mitigated */ #define X86_BUG_SRBDS X86_BUG(24) /* CPU may leak RNG bits if not mitigated */
#define X86_BUG_MMIO_STALE_DATA X86_BUG(25) /* CPU is affected by Processor MMIO Stale Data vulnerabilities */ #define X86_BUG_MMIO_STALE_DATA X86_BUG(25) /* CPU is affected by Processor MMIO Stale Data vulnerabilities */
#define X86_BUG_RETBLEED X86_BUG(26) /* CPU is affected by RETBleed */ #define X86_BUG_RETBLEED X86_BUG(26) /* CPU is affected by RETBleed */
#define X86_BUG_EIBRS_PBRSB X86_BUG(27) /* EIBRS is vulnerable to Post Barrier RSB Predictions */
#endif /* _ASM_X86_CPUFEATURES_H */ #endif /* _ASM_X86_CPUFEATURES_H */

View File

@@ -148,6 +148,10 @@
* are restricted to targets in * are restricted to targets in
* kernel. * kernel.
*/ */
#define ARCH_CAP_PBRSB_NO BIT(24) /*
* Not susceptible to Post-Barrier
* Return Stack Buffer Predictions.
*/
#define MSR_IA32_FLUSH_CMD 0x0000010b #define MSR_IA32_FLUSH_CMD 0x0000010b
#define L1D_FLUSH BIT(0) /* #define L1D_FLUSH BIT(0) /*

View File

@@ -60,7 +60,9 @@
774: \ 774: \
add $(BITS_PER_LONG/8) * 2, sp; \ add $(BITS_PER_LONG/8) * 2, sp; \
dec reg; \ dec reg; \
jnz 771b; jnz 771b; \
/* barrier for jnz misprediction */ \
lfence;
#ifdef __ASSEMBLY__ #ifdef __ASSEMBLY__
@@ -118,13 +120,28 @@
#endif #endif
.endm .endm
.macro ISSUE_UNBALANCED_RET_GUARD
ANNOTATE_INTRA_FUNCTION_CALL
call .Lunbalanced_ret_guard_\@
int3
.Lunbalanced_ret_guard_\@:
add $(BITS_PER_LONG/8), %_ASM_SP
lfence
.endm
/* /*
* A simpler FILL_RETURN_BUFFER macro. Don't make people use the CPP * A simpler FILL_RETURN_BUFFER macro. Don't make people use the CPP
* monstrosity above, manually. * monstrosity above, manually.
*/ */
.macro FILL_RETURN_BUFFER reg:req nr:req ftr:req .macro FILL_RETURN_BUFFER reg:req nr:req ftr:req ftr2
.ifb \ftr2
ALTERNATIVE "jmp .Lskip_rsb_\@", "", \ftr ALTERNATIVE "jmp .Lskip_rsb_\@", "", \ftr
.else
ALTERNATIVE_2 "jmp .Lskip_rsb_\@", "", \ftr, "jmp .Lunbalanced_\@", \ftr2
.endif
__FILL_RETURN_BUFFER(\reg,\nr,%_ASM_SP) __FILL_RETURN_BUFFER(\reg,\nr,%_ASM_SP)
.Lunbalanced_\@:
ISSUE_UNBALANCED_RET_GUARD
.Lskip_rsb_\@: .Lskip_rsb_\@:
.endm .endm

View File

@@ -1291,6 +1291,53 @@ static void __init spec_ctrl_disable_kernel_rrsba(void)
} }
} }
static void __init spectre_v2_determine_rsb_fill_type_at_vmexit(enum spectre_v2_mitigation mode)
{
/*
* Similar to context switches, there are two types of RSB attacks
* after VM exit:
*
* 1) RSB underflow
*
* 2) Poisoned RSB entry
*
* When retpoline is enabled, both are mitigated by filling/clearing
* the RSB.
*
* When IBRS is enabled, while #1 would be mitigated by the IBRS branch
* prediction isolation protections, RSB still needs to be cleared
* because of #2. Note that SMEP provides no protection here, unlike
* user-space-poisoned RSB entries.
*
* eIBRS should protect against RSB poisoning, but if the EIBRS_PBRSB
* bug is present then a LITE version of RSB protection is required,
* just a single call needs to retire before a RET is executed.
*/
switch (mode) {
case SPECTRE_V2_NONE:
return;
case SPECTRE_V2_EIBRS_LFENCE:
case SPECTRE_V2_EIBRS:
if (boot_cpu_has_bug(X86_BUG_EIBRS_PBRSB)) {
setup_force_cpu_cap(X86_FEATURE_RSB_VMEXIT_LITE);
pr_info("Spectre v2 / PBRSB-eIBRS: Retire a single CALL on VMEXIT\n");
}
return;
case SPECTRE_V2_EIBRS_RETPOLINE:
case SPECTRE_V2_RETPOLINE:
case SPECTRE_V2_LFENCE:
case SPECTRE_V2_IBRS:
setup_force_cpu_cap(X86_FEATURE_RSB_VMEXIT);
pr_info("Spectre v2 / SpectreRSB : Filling RSB on VMEXIT\n");
return;
}
pr_warn_once("Unknown Spectre v2 mode, disabling RSB mitigation at VM exit");
dump_stack();
}
static void __init spectre_v2_select_mitigation(void) static void __init spectre_v2_select_mitigation(void)
{ {
enum spectre_v2_mitigation_cmd cmd = spectre_v2_parse_cmdline(); enum spectre_v2_mitigation_cmd cmd = spectre_v2_parse_cmdline();
@@ -1441,28 +1488,7 @@ static void __init spectre_v2_select_mitigation(void)
setup_force_cpu_cap(X86_FEATURE_RSB_CTXSW); setup_force_cpu_cap(X86_FEATURE_RSB_CTXSW);
pr_info("Spectre v2 / SpectreRSB mitigation: Filling RSB on context switch\n"); pr_info("Spectre v2 / SpectreRSB mitigation: Filling RSB on context switch\n");
/* spectre_v2_determine_rsb_fill_type_at_vmexit(mode);
* Similar to context switches, there are two types of RSB attacks
* after vmexit:
*
* 1) RSB underflow
*
* 2) Poisoned RSB entry
*
* When retpoline is enabled, both are mitigated by filling/clearing
* the RSB.
*
* When IBRS is enabled, while #1 would be mitigated by the IBRS branch
* prediction isolation protections, RSB still needs to be cleared
* because of #2. Note that SMEP provides no protection here, unlike
* user-space-poisoned RSB entries.
*
* eIBRS, on the other hand, has RSB-poisoning protections, so it
* doesn't need RSB clearing after vmexit.
*/
if (boot_cpu_has(X86_FEATURE_RETPOLINE) ||
boot_cpu_has(X86_FEATURE_KERNEL_IBRS))
setup_force_cpu_cap(X86_FEATURE_RSB_VMEXIT);
/* /*
* Retpoline protects the kernel, but doesn't protect firmware. IBRS * Retpoline protects the kernel, but doesn't protect firmware. IBRS
@@ -2215,6 +2241,19 @@ static char *ibpb_state(void)
return ""; return "";
} }
static char *pbrsb_eibrs_state(void)
{
if (boot_cpu_has_bug(X86_BUG_EIBRS_PBRSB)) {
if (boot_cpu_has(X86_FEATURE_RSB_VMEXIT_LITE) ||
boot_cpu_has(X86_FEATURE_RSB_VMEXIT))
return ", PBRSB-eIBRS: SW sequence";
else
return ", PBRSB-eIBRS: Vulnerable";
} else {
return ", PBRSB-eIBRS: Not affected";
}
}
static ssize_t spectre_v2_show_state(char *buf) static ssize_t spectre_v2_show_state(char *buf)
{ {
if (spectre_v2_enabled == SPECTRE_V2_LFENCE) if (spectre_v2_enabled == SPECTRE_V2_LFENCE)
@@ -2227,12 +2266,13 @@ static ssize_t spectre_v2_show_state(char *buf)
spectre_v2_enabled == SPECTRE_V2_EIBRS_LFENCE) spectre_v2_enabled == SPECTRE_V2_EIBRS_LFENCE)
return sprintf(buf, "Vulnerable: eIBRS+LFENCE with unprivileged eBPF and SMT\n"); return sprintf(buf, "Vulnerable: eIBRS+LFENCE with unprivileged eBPF and SMT\n");
return sprintf(buf, "%s%s%s%s%s%s\n", return sprintf(buf, "%s%s%s%s%s%s%s\n",
spectre_v2_strings[spectre_v2_enabled], spectre_v2_strings[spectre_v2_enabled],
ibpb_state(), ibpb_state(),
boot_cpu_has(X86_FEATURE_USE_IBRS_FW) ? ", IBRS_FW" : "", boot_cpu_has(X86_FEATURE_USE_IBRS_FW) ? ", IBRS_FW" : "",
stibp_state(), stibp_state(),
boot_cpu_has(X86_FEATURE_RSB_CTXSW) ? ", RSB filling" : "", boot_cpu_has(X86_FEATURE_RSB_CTXSW) ? ", RSB filling" : "",
pbrsb_eibrs_state(),
spectre_v2_module_string()); spectre_v2_module_string());
} }

View File

@@ -1024,6 +1024,7 @@ static void identify_cpu_without_cpuid(struct cpuinfo_x86 *c)
#define NO_SWAPGS BIT(6) #define NO_SWAPGS BIT(6)
#define NO_ITLB_MULTIHIT BIT(7) #define NO_ITLB_MULTIHIT BIT(7)
#define NO_SPECTRE_V2 BIT(8) #define NO_SPECTRE_V2 BIT(8)
#define NO_EIBRS_PBRSB BIT(9)
#define VULNWL(vendor, family, model, whitelist) \ #define VULNWL(vendor, family, model, whitelist) \
X86_MATCH_VENDOR_FAM_MODEL(vendor, family, model, whitelist) X86_MATCH_VENDOR_FAM_MODEL(vendor, family, model, whitelist)
@@ -1064,7 +1065,7 @@ static const __initconst struct x86_cpu_id cpu_vuln_whitelist[] = {
VULNWL_INTEL(ATOM_GOLDMONT, NO_MDS | NO_L1TF | NO_SWAPGS | NO_ITLB_MULTIHIT), VULNWL_INTEL(ATOM_GOLDMONT, NO_MDS | NO_L1TF | NO_SWAPGS | NO_ITLB_MULTIHIT),
VULNWL_INTEL(ATOM_GOLDMONT_D, NO_MDS | NO_L1TF | NO_SWAPGS | NO_ITLB_MULTIHIT), VULNWL_INTEL(ATOM_GOLDMONT_D, NO_MDS | NO_L1TF | NO_SWAPGS | NO_ITLB_MULTIHIT),
VULNWL_INTEL(ATOM_GOLDMONT_PLUS, NO_MDS | NO_L1TF | NO_SWAPGS | NO_ITLB_MULTIHIT), VULNWL_INTEL(ATOM_GOLDMONT_PLUS, NO_MDS | NO_L1TF | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_EIBRS_PBRSB),
/* /*
* Technically, swapgs isn't serializing on AMD (despite it previously * Technically, swapgs isn't serializing on AMD (despite it previously
@@ -1074,7 +1075,9 @@ static const __initconst struct x86_cpu_id cpu_vuln_whitelist[] = {
* good enough for our purposes. * good enough for our purposes.
*/ */
VULNWL_INTEL(ATOM_TREMONT_D, NO_ITLB_MULTIHIT), VULNWL_INTEL(ATOM_TREMONT, NO_EIBRS_PBRSB),
VULNWL_INTEL(ATOM_TREMONT_L, NO_EIBRS_PBRSB),
VULNWL_INTEL(ATOM_TREMONT_D, NO_ITLB_MULTIHIT | NO_EIBRS_PBRSB),
/* AMD Family 0xf - 0x12 */ /* AMD Family 0xf - 0x12 */
VULNWL_AMD(0x0f, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT), VULNWL_AMD(0x0f, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT),
@@ -1252,6 +1255,11 @@ static void __init cpu_set_bug_bits(struct cpuinfo_x86 *c)
setup_force_cpu_bug(X86_BUG_RETBLEED); setup_force_cpu_bug(X86_BUG_RETBLEED);
} }
if (cpu_has(c, X86_FEATURE_IBRS_ENHANCED) &&
!cpu_matches(cpu_vuln_whitelist, NO_EIBRS_PBRSB) &&
!(ia32_cap & ARCH_CAP_PBRSB_NO))
setup_force_cpu_bug(X86_BUG_EIBRS_PBRSB);
if (cpu_matches(cpu_vuln_whitelist, NO_MELTDOWN)) if (cpu_matches(cpu_vuln_whitelist, NO_MELTDOWN))
return; return;

View File

@@ -197,11 +197,13 @@ SYM_INNER_LABEL(vmx_vmexit, SYM_L_GLOBAL)
* entries and (in some cases) RSB underflow. * entries and (in some cases) RSB underflow.
* *
* eIBRS has its own protection against poisoned RSB, so it doesn't * eIBRS has its own protection against poisoned RSB, so it doesn't
* need the RSB filling sequence. But it does need to be enabled * need the RSB filling sequence. But it does need to be enabled, and a
* before the first unbalanced RET. * single call to retire, before the first unbalanced RET.
*/ */
FILL_RETURN_BUFFER %_ASM_CX, RSB_CLEAR_LOOPS, X86_FEATURE_RSB_VMEXIT FILL_RETURN_BUFFER %_ASM_CX, RSB_CLEAR_LOOPS, X86_FEATURE_RSB_VMEXIT,\
X86_FEATURE_RSB_VMEXIT_LITE
pop %_ASM_ARG2 /* @flags */ pop %_ASM_ARG2 /* @flags */
pop %_ASM_ARG1 /* @vmx */ pop %_ASM_ARG1 /* @vmx */

View File

@@ -29,16 +29,26 @@
#undef pr_fmt #undef pr_fmt
#define pr_fmt(fmt) "BERT: " fmt #define pr_fmt(fmt) "BERT: " fmt
#define ACPI_BERT_PRINT_MAX_RECORDS 5
#define ACPI_BERT_PRINT_MAX_LEN 1024 #define ACPI_BERT_PRINT_MAX_LEN 1024
static int bert_disable; static int bert_disable;
/*
* Print "all" the error records in the BERT table, but avoid huge spam to
* the console if the BIOS included oversize records, or too many records.
* Skipping some records here does not lose anything because the full
* data is available to user tools in:
* /sys/firmware/acpi/tables/data/BERT
*/
static void __init bert_print_all(struct acpi_bert_region *region, static void __init bert_print_all(struct acpi_bert_region *region,
unsigned int region_len) unsigned int region_len)
{ {
struct acpi_hest_generic_status *estatus = struct acpi_hest_generic_status *estatus =
(struct acpi_hest_generic_status *)region; (struct acpi_hest_generic_status *)region;
int remain = region_len; int remain = region_len;
int printed = 0, skipped = 0;
u32 estatus_len; u32 estatus_len;
while (remain >= sizeof(struct acpi_bert_region)) { while (remain >= sizeof(struct acpi_bert_region)) {
@@ -46,24 +56,26 @@ static void __init bert_print_all(struct acpi_bert_region *region,
if (remain < estatus_len) { if (remain < estatus_len) {
pr_err(FW_BUG "Truncated status block (length: %u).\n", pr_err(FW_BUG "Truncated status block (length: %u).\n",
estatus_len); estatus_len);
return; break;
} }
/* No more error records. */ /* No more error records. */
if (!estatus->block_status) if (!estatus->block_status)
return; break;
if (cper_estatus_check(estatus)) { if (cper_estatus_check(estatus)) {
pr_err(FW_BUG "Invalid error record.\n"); pr_err(FW_BUG "Invalid error record.\n");
return; break;
} }
if (estatus_len < ACPI_BERT_PRINT_MAX_LEN &&
printed < ACPI_BERT_PRINT_MAX_RECORDS) {
pr_info_once("Error records from previous boot:\n"); pr_info_once("Error records from previous boot:\n");
if (region_len < ACPI_BERT_PRINT_MAX_LEN)
cper_estatus_print(KERN_INFO HW_ERR, estatus); cper_estatus_print(KERN_INFO HW_ERR, estatus);
else printed++;
pr_info_once("Max print length exceeded, table data is available at:\n" } else {
"/sys/firmware/acpi/tables/data/BERT"); skipped++;
}
/* /*
* Because the boot error source is "one-time polled" type, * Because the boot error source is "one-time polled" type,
@@ -75,6 +87,9 @@ static void __init bert_print_all(struct acpi_bert_region *region,
estatus = (void *)estatus + estatus_len; estatus = (void *)estatus + estatus_len;
remain -= estatus_len; remain -= estatus_len;
} }
if (skipped)
pr_info(HW_ERR "Skipped %d error records\n", skipped);
} }
static int __init setup_bert_disable(char *str) static int __init setup_bert_disable(char *str)

View File

@@ -424,23 +424,6 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
.callback = video_detect_force_native, .callback = video_detect_force_native,
.ident = "Clevo NL5xRU", .ident = "Clevo NL5xRU",
.matches = { .matches = {
DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
DMI_MATCH(DMI_BOARD_NAME, "NL5xRU"),
},
},
{
.callback = video_detect_force_native,
.ident = "Clevo NL5xRU",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "SchenkerTechnologiesGmbH"),
DMI_MATCH(DMI_BOARD_NAME, "NL5xRU"),
},
},
{
.callback = video_detect_force_native,
.ident = "Clevo NL5xRU",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Notebook"),
DMI_MATCH(DMI_BOARD_NAME, "NL5xRU"), DMI_MATCH(DMI_BOARD_NAME, "NL5xRU"),
}, },
}, },
@@ -463,28 +446,60 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
{ {
.callback = video_detect_force_native, .callback = video_detect_force_native,
.ident = "Clevo NL5xNU", .ident = "Clevo NL5xNU",
.matches = {
DMI_MATCH(DMI_BOARD_NAME, "NL5xNU"),
},
},
/*
* The TongFang PF5PU1G, PF4NU1F, PF5NU1G, and PF5LUXG/TUXEDO BA15 Gen10,
* Pulse 14/15 Gen1, and Pulse 15 Gen2 have the same problem as the Clevo
* NL5xRU and NL5xNU/TUXEDO Aura 15 Gen1 and Gen2. See the description
* above.
*/
{
.callback = video_detect_force_native,
.ident = "TongFang PF5PU1G",
.matches = {
DMI_MATCH(DMI_BOARD_NAME, "PF5PU1G"),
},
},
{
.callback = video_detect_force_native,
.ident = "TongFang PF4NU1F",
.matches = {
DMI_MATCH(DMI_BOARD_NAME, "PF4NU1F"),
},
},
{
.callback = video_detect_force_native,
.ident = "TongFang PF4NU1F",
.matches = { .matches = {
DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
DMI_MATCH(DMI_BOARD_NAME, "NL5xNU"), DMI_MATCH(DMI_BOARD_NAME, "PULSE1401"),
}, },
}, },
{ {
.callback = video_detect_force_native, .callback = video_detect_force_native,
.ident = "Clevo NL5xNU", .ident = "TongFang PF5NU1G",
.matches = { .matches = {
DMI_MATCH(DMI_SYS_VENDOR, "SchenkerTechnologiesGmbH"), DMI_MATCH(DMI_BOARD_NAME, "PF5NU1G"),
DMI_MATCH(DMI_BOARD_NAME, "NL5xNU"),
}, },
}, },
{ {
.callback = video_detect_force_native, .callback = video_detect_force_native,
.ident = "Clevo NL5xNU", .ident = "TongFang PF5NU1G",
.matches = { .matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Notebook"), DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
DMI_MATCH(DMI_BOARD_NAME, "NL5xNU"), DMI_MATCH(DMI_BOARD_NAME, "PULSE1501"),
},
},
{
.callback = video_detect_force_native,
.ident = "TongFang PF5LUXG",
.matches = {
DMI_MATCH(DMI_BOARD_NAME, "PF5LUXG"),
}, },
}, },
/* /*
* Desktops which falsely report a backlight and which our heuristics * Desktops which falsely report a backlight and which our heuristics
* for this do not catch. * for this do not catch.

View File

@@ -401,6 +401,8 @@ static const struct bcm_subver_table bcm_uart_subver_table[] = {
{ 0x6606, "BCM4345C5" }, /* 003.006.006 */ { 0x6606, "BCM4345C5" }, /* 003.006.006 */
{ 0x230f, "BCM4356A2" }, /* 001.003.015 */ { 0x230f, "BCM4356A2" }, /* 001.003.015 */
{ 0x220e, "BCM20702A1" }, /* 001.002.014 */ { 0x220e, "BCM20702A1" }, /* 001.002.014 */
{ 0x420d, "BCM4349B1" }, /* 002.002.013 */
{ 0x420e, "BCM4349B1" }, /* 002.002.014 */
{ 0x4217, "BCM4329B1" }, /* 002.002.023 */ { 0x4217, "BCM4329B1" }, /* 002.002.023 */
{ 0x6106, "BCM4359C0" }, /* 003.001.006 */ { 0x6106, "BCM4359C0" }, /* 003.001.006 */
{ 0x4106, "BCM4335A0" }, /* 002.001.006 */ { 0x4106, "BCM4335A0" }, /* 002.001.006 */

View File

@@ -399,6 +399,18 @@ static const struct usb_device_id blacklist_table[] = {
{ USB_DEVICE(0x0bda, 0xc822), .driver_info = BTUSB_REALTEK | { USB_DEVICE(0x0bda, 0xc822), .driver_info = BTUSB_REALTEK |
BTUSB_WIDEBAND_SPEECH }, BTUSB_WIDEBAND_SPEECH },
/* Realtek 8852CE Bluetooth devices */
{ USB_DEVICE(0x04ca, 0x4007), .driver_info = BTUSB_REALTEK |
BTUSB_WIDEBAND_SPEECH },
{ USB_DEVICE(0x04c5, 0x1675), .driver_info = BTUSB_REALTEK |
BTUSB_WIDEBAND_SPEECH },
{ USB_DEVICE(0x0cb8, 0xc558), .driver_info = BTUSB_REALTEK |
BTUSB_WIDEBAND_SPEECH },
{ USB_DEVICE(0x13d3, 0x3587), .driver_info = BTUSB_REALTEK |
BTUSB_WIDEBAND_SPEECH },
{ USB_DEVICE(0x13d3, 0x3586), .driver_info = BTUSB_REALTEK |
BTUSB_WIDEBAND_SPEECH },
/* Realtek Bluetooth devices */ /* Realtek Bluetooth devices */
{ USB_VENDOR_AND_INTERFACE_INFO(0x0bda, 0xe0, 0x01, 0x01), { USB_VENDOR_AND_INTERFACE_INFO(0x0bda, 0xe0, 0x01, 0x01),
.driver_info = BTUSB_REALTEK }, .driver_info = BTUSB_REALTEK },
@@ -416,6 +428,9 @@ static const struct usb_device_id blacklist_table[] = {
{ USB_DEVICE(0x0489, 0xe0d9), .driver_info = BTUSB_MEDIATEK | { USB_DEVICE(0x0489, 0xe0d9), .driver_info = BTUSB_MEDIATEK |
BTUSB_WIDEBAND_SPEECH | BTUSB_WIDEBAND_SPEECH |
BTUSB_VALID_LE_STATES }, BTUSB_VALID_LE_STATES },
{ USB_DEVICE(0x13d3, 0x3568), .driver_info = BTUSB_MEDIATEK |
BTUSB_WIDEBAND_SPEECH |
BTUSB_VALID_LE_STATES },
/* Additional Realtek 8723AE Bluetooth devices */ /* Additional Realtek 8723AE Bluetooth devices */
{ USB_DEVICE(0x0930, 0x021d), .driver_info = BTUSB_REALTEK }, { USB_DEVICE(0x0930, 0x021d), .driver_info = BTUSB_REALTEK },

View File

@@ -1490,8 +1490,10 @@ static const struct of_device_id bcm_bluetooth_of_match[] = {
{ .compatible = "brcm,bcm4345c5" }, { .compatible = "brcm,bcm4345c5" },
{ .compatible = "brcm,bcm4330-bt" }, { .compatible = "brcm,bcm4330-bt" },
{ .compatible = "brcm,bcm43438-bt", .data = &bcm43438_device_data }, { .compatible = "brcm,bcm43438-bt", .data = &bcm43438_device_data },
{ .compatible = "brcm,bcm4349-bt", .data = &bcm43438_device_data },
{ .compatible = "brcm,bcm43540-bt", .data = &bcm4354_device_data }, { .compatible = "brcm,bcm43540-bt", .data = &bcm4354_device_data },
{ .compatible = "brcm,bcm4335a0" }, { .compatible = "brcm,bcm4335a0" },
{ .compatible = "infineon,cyw55572-bt" },
{ }, { },
}; };
MODULE_DEVICE_TABLE(of, bcm_bluetooth_of_match); MODULE_DEVICE_TABLE(of, bcm_bluetooth_of_match);

View File

@@ -647,7 +647,7 @@ do_adb_query(struct adb_request *req)
switch(req->data[1]) { switch(req->data[1]) {
case ADB_QUERY_GETDEVINFO: case ADB_QUERY_GETDEVINFO:
if (req->nbytes < 3) if (req->nbytes < 3 || req->data[2] >= 16)
break; break;
mutex_lock(&adb_handler_mutex); mutex_lock(&adb_handler_mutex);
req->reply[0] = adb_handler[req->data[2]].original_address; req->reply[0] = adb_handler[req->data[2]].original_address;

View File

@@ -220,6 +220,9 @@ struct tun_struct {
struct tun_prog __rcu *steering_prog; struct tun_prog __rcu *steering_prog;
struct tun_prog __rcu *filter_prog; struct tun_prog __rcu *filter_prog;
struct ethtool_link_ksettings link_ksettings; struct ethtool_link_ksettings link_ksettings;
/* init args */
struct file *file;
struct ifreq *ifr;
}; };
struct veth { struct veth {
@@ -227,6 +230,9 @@ struct veth {
__be16 h_vlan_TCI; __be16 h_vlan_TCI;
}; };
static void tun_flow_init(struct tun_struct *tun);
static void tun_flow_uninit(struct tun_struct *tun);
static int tun_napi_receive(struct napi_struct *napi, int budget) static int tun_napi_receive(struct napi_struct *napi, int budget)
{ {
struct tun_file *tfile = container_of(napi, struct tun_file, napi); struct tun_file *tfile = container_of(napi, struct tun_file, napi);
@@ -975,6 +981,49 @@ static int check_filter(struct tap_filter *filter, const struct sk_buff *skb)
static const struct ethtool_ops tun_ethtool_ops; static const struct ethtool_ops tun_ethtool_ops;
static int tun_net_init(struct net_device *dev)
{
struct tun_struct *tun = netdev_priv(dev);
struct ifreq *ifr = tun->ifr;
int err;
tun->pcpu_stats = netdev_alloc_pcpu_stats(struct tun_pcpu_stats);
if (!tun->pcpu_stats)
return -ENOMEM;
spin_lock_init(&tun->lock);
err = security_tun_dev_alloc_security(&tun->security);
if (err < 0) {
free_percpu(tun->pcpu_stats);
return err;
}
tun_flow_init(tun);
dev->hw_features = NETIF_F_SG | NETIF_F_FRAGLIST |
TUN_USER_FEATURES | NETIF_F_HW_VLAN_CTAG_TX |
NETIF_F_HW_VLAN_STAG_TX;
dev->features = dev->hw_features | NETIF_F_LLTX;
dev->vlan_features = dev->features &
~(NETIF_F_HW_VLAN_CTAG_TX |
NETIF_F_HW_VLAN_STAG_TX);
tun->flags = (tun->flags & ~TUN_FEATURES) |
(ifr->ifr_flags & TUN_FEATURES);
INIT_LIST_HEAD(&tun->disabled);
err = tun_attach(tun, tun->file, false, ifr->ifr_flags & IFF_NAPI,
ifr->ifr_flags & IFF_NAPI_FRAGS, false);
if (err < 0) {
tun_flow_uninit(tun);
security_tun_dev_free_security(tun->security);
free_percpu(tun->pcpu_stats);
return err;
}
return 0;
}
/* Net device detach from fd. */ /* Net device detach from fd. */
static void tun_net_uninit(struct net_device *dev) static void tun_net_uninit(struct net_device *dev)
{ {
@@ -1216,6 +1265,7 @@ static int tun_net_change_carrier(struct net_device *dev, bool new_carrier)
} }
static const struct net_device_ops tun_netdev_ops = { static const struct net_device_ops tun_netdev_ops = {
.ndo_init = tun_net_init,
.ndo_uninit = tun_net_uninit, .ndo_uninit = tun_net_uninit,
.ndo_open = tun_net_open, .ndo_open = tun_net_open,
.ndo_stop = tun_net_close, .ndo_stop = tun_net_close,
@@ -1296,6 +1346,7 @@ static int tun_xdp_tx(struct net_device *dev, struct xdp_buff *xdp)
} }
static const struct net_device_ops tap_netdev_ops = { static const struct net_device_ops tap_netdev_ops = {
.ndo_init = tun_net_init,
.ndo_uninit = tun_net_uninit, .ndo_uninit = tun_net_uninit,
.ndo_open = tun_net_open, .ndo_open = tun_net_open,
.ndo_stop = tun_net_close, .ndo_stop = tun_net_close,
@@ -1336,7 +1387,7 @@ static void tun_flow_uninit(struct tun_struct *tun)
#define MAX_MTU 65535 #define MAX_MTU 65535
/* Initialize net device. */ /* Initialize net device. */
static void tun_net_init(struct net_device *dev) static void tun_net_initialize(struct net_device *dev)
{ {
struct tun_struct *tun = netdev_priv(dev); struct tun_struct *tun = netdev_priv(dev);
@@ -2268,10 +2319,6 @@ static void tun_free_netdev(struct net_device *dev)
BUG_ON(!(list_empty(&tun->disabled))); BUG_ON(!(list_empty(&tun->disabled)));
free_percpu(tun->pcpu_stats); free_percpu(tun->pcpu_stats);
/* We clear pcpu_stats so that tun_set_iff() can tell if
* tun_free_netdev() has been called from register_netdevice().
*/
tun->pcpu_stats = NULL;
tun_flow_uninit(tun); tun_flow_uninit(tun);
security_tun_dev_free_security(tun->security); security_tun_dev_free_security(tun->security);
@@ -2784,41 +2831,16 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
tun->rx_batched = 0; tun->rx_batched = 0;
RCU_INIT_POINTER(tun->steering_prog, NULL); RCU_INIT_POINTER(tun->steering_prog, NULL);
tun->pcpu_stats = netdev_alloc_pcpu_stats(struct tun_pcpu_stats); tun->ifr = ifr;
if (!tun->pcpu_stats) { tun->file = file;
err = -ENOMEM;
goto err_free_dev;
}
spin_lock_init(&tun->lock); tun_net_initialize(dev);
err = security_tun_dev_alloc_security(&tun->security);
if (err < 0)
goto err_free_stat;
tun_net_init(dev);
tun_flow_init(tun);
dev->hw_features = NETIF_F_SG | NETIF_F_FRAGLIST |
TUN_USER_FEATURES | NETIF_F_HW_VLAN_CTAG_TX |
NETIF_F_HW_VLAN_STAG_TX;
dev->features = dev->hw_features | NETIF_F_LLTX;
dev->vlan_features = dev->features &
~(NETIF_F_HW_VLAN_CTAG_TX |
NETIF_F_HW_VLAN_STAG_TX);
tun->flags = (tun->flags & ~TUN_FEATURES) |
(ifr->ifr_flags & TUN_FEATURES);
INIT_LIST_HEAD(&tun->disabled);
err = tun_attach(tun, file, false, ifr->ifr_flags & IFF_NAPI,
ifr->ifr_flags & IFF_NAPI_FRAGS, false);
if (err < 0)
goto err_free_flow;
err = register_netdevice(tun->dev); err = register_netdevice(tun->dev);
if (err < 0) if (err < 0) {
goto err_detach; free_netdev(dev);
return err;
}
/* free_netdev() won't check refcnt, to aovid race /* free_netdev() won't check refcnt, to aovid race
* with dev_put() we need publish tun after registration. * with dev_put() we need publish tun after registration.
*/ */
@@ -2835,24 +2857,6 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
strcpy(ifr->ifr_name, tun->dev->name); strcpy(ifr->ifr_name, tun->dev->name);
return 0; return 0;
err_detach:
tun_detach_all(dev);
/* We are here because register_netdevice() has failed.
* If register_netdevice() already called tun_free_netdev()
* while dealing with the error, tun->pcpu_stats has been cleared.
*/
if (!tun->pcpu_stats)
goto err_free_dev;
err_free_flow:
tun_flow_uninit(tun);
security_tun_dev_free_security(tun->security);
err_free_stat:
free_percpu(tun->pcpu_stats);
err_free_dev:
free_netdev(dev);
return err;
} }
static void tun_get_iff(struct tun_struct *tun, struct ifreq *ifr) static void tun_get_iff(struct tun_struct *tun, struct ifreq *ifr)

View File

@@ -281,6 +281,7 @@ struct ath9k_htc_rxbuf {
struct ath9k_htc_rx { struct ath9k_htc_rx {
struct list_head rxbuf; struct list_head rxbuf;
spinlock_t rxbuflock; spinlock_t rxbuflock;
bool initialized;
}; };
#define ATH9K_HTC_TX_CLEANUP_INTERVAL 50 /* ms */ #define ATH9K_HTC_TX_CLEANUP_INTERVAL 50 /* ms */
@@ -305,6 +306,7 @@ struct ath9k_htc_tx {
DECLARE_BITMAP(tx_slot, MAX_TX_BUF_NUM); DECLARE_BITMAP(tx_slot, MAX_TX_BUF_NUM);
struct timer_list cleanup_timer; struct timer_list cleanup_timer;
spinlock_t tx_lock; spinlock_t tx_lock;
bool initialized;
}; };
struct ath9k_htc_tx_ctl { struct ath9k_htc_tx_ctl {

View File

@@ -808,6 +808,11 @@ int ath9k_tx_init(struct ath9k_htc_priv *priv)
skb_queue_head_init(&priv->tx.data_vi_queue); skb_queue_head_init(&priv->tx.data_vi_queue);
skb_queue_head_init(&priv->tx.data_vo_queue); skb_queue_head_init(&priv->tx.data_vo_queue);
skb_queue_head_init(&priv->tx.tx_failed); skb_queue_head_init(&priv->tx.tx_failed);
/* Allow ath9k_wmi_event_tasklet(WMI_TXSTATUS_EVENTID) to operate. */
smp_wmb();
priv->tx.initialized = true;
return 0; return 0;
} }
@@ -1133,6 +1138,10 @@ void ath9k_htc_rxep(void *drv_priv, struct sk_buff *skb,
struct ath9k_htc_rxbuf *rxbuf = NULL, *tmp_buf = NULL; struct ath9k_htc_rxbuf *rxbuf = NULL, *tmp_buf = NULL;
unsigned long flags; unsigned long flags;
/* Check if ath9k_rx_init() completed. */
if (!data_race(priv->rx.initialized))
goto err;
spin_lock_irqsave(&priv->rx.rxbuflock, flags); spin_lock_irqsave(&priv->rx.rxbuflock, flags);
list_for_each_entry(tmp_buf, &priv->rx.rxbuf, list) { list_for_each_entry(tmp_buf, &priv->rx.rxbuf, list) {
if (!tmp_buf->in_process) { if (!tmp_buf->in_process) {
@@ -1188,6 +1197,10 @@ int ath9k_rx_init(struct ath9k_htc_priv *priv)
list_add_tail(&rxbuf->list, &priv->rx.rxbuf); list_add_tail(&rxbuf->list, &priv->rx.rxbuf);
} }
/* Allow ath9k_htc_rxep() to operate. */
smp_wmb();
priv->rx.initialized = true;
return 0; return 0;
err: err:

View File

@@ -169,6 +169,10 @@ void ath9k_wmi_event_tasklet(struct tasklet_struct *t)
&wmi->drv_priv->fatal_work); &wmi->drv_priv->fatal_work);
break; break;
case WMI_TXSTATUS_EVENTID: case WMI_TXSTATUS_EVENTID:
/* Check if ath9k_tx_init() completed. */
if (!data_race(priv->tx.initialized))
break;
spin_lock_bh(&priv->tx.tx_lock); spin_lock_bh(&priv->tx.tx_lock);
if (priv->tx.flags & ATH9K_HTC_OP_TX_DRAIN) { if (priv->tx.flags & ATH9K_HTC_OP_TX_DRAIN) {
spin_unlock_bh(&priv->tx.tx_lock); spin_unlock_bh(&priv->tx.tx_lock);

View File

@@ -296,6 +296,7 @@
#define X86_FEATURE_RETPOLINE_LFENCE (11*32+13) /* "" Use LFENCE for Spectre variant 2 */ #define X86_FEATURE_RETPOLINE_LFENCE (11*32+13) /* "" Use LFENCE for Spectre variant 2 */
#define X86_FEATURE_RETHUNK (11*32+14) /* "" Use REturn THUNK */ #define X86_FEATURE_RETHUNK (11*32+14) /* "" Use REturn THUNK */
#define X86_FEATURE_UNRET (11*32+15) /* "" AMD BTB untrain return */ #define X86_FEATURE_UNRET (11*32+15) /* "" AMD BTB untrain return */
#define X86_FEATURE_RSB_VMEXIT_LITE (11*32+17) /* "" Fill RSB on VM-Exit when EIBRS is enabled */
/* Intel-defined CPU features, CPUID level 0x00000007:1 (EAX), word 12 */ /* Intel-defined CPU features, CPUID level 0x00000007:1 (EAX), word 12 */
#define X86_FEATURE_AVX512_BF16 (12*32+ 5) /* AVX512 BFLOAT16 instructions */ #define X86_FEATURE_AVX512_BF16 (12*32+ 5) /* AVX512 BFLOAT16 instructions */

View File

@@ -148,6 +148,10 @@
* are restricted to targets in * are restricted to targets in
* kernel. * kernel.
*/ */
#define ARCH_CAP_PBRSB_NO BIT(24) /*
* Not susceptible to Post-Barrier
* Return Stack Buffer Predictions.
*/
#define MSR_IA32_FLUSH_CMD 0x0000010b #define MSR_IA32_FLUSH_CMD 0x0000010b
#define L1D_FLUSH BIT(0) /* #define L1D_FLUSH BIT(0) /*

View File

@@ -4180,7 +4180,8 @@ struct bpf_sock {
__u32 src_ip4; __u32 src_ip4;
__u32 src_ip6[4]; __u32 src_ip6[4];
__u32 src_port; /* host byte order */ __u32 src_port; /* host byte order */
__u32 dst_port; /* network byte order */ __be16 dst_port; /* network byte order */
__u16 :16; /* zero padding */
__u32 dst_ip4; __u32 dst_ip4;
__u32 dst_ip6[4]; __u32 dst_ip6[4];
__u32 state; __u32 state;

View File

@@ -1646,7 +1646,8 @@ Press any other key to refresh statistics immediately.
.format(values)) .format(values))
if len(pids) > 1: if len(pids) > 1:
sys.exit('Error: Multiple processes found (pids: {}). Use "-p"' sys.exit('Error: Multiple processes found (pids: {}). Use "-p"'
' to specify the desired pid'.format(" ".join(pids))) ' to specify the desired pid'
.format(" ".join(map(str, pids))))
namespace.pid = pids[0] namespace.pid = pids[0]
argparser = argparse.ArgumentParser(description=description_text, argparser = argparse.ArgumentParser(description=description_text,

View File

@@ -1,9 +1,11 @@
// SPDX-License-Identifier: GPL-2.0 // SPDX-License-Identifier: GPL-2.0
/* Copyright (c) 2019 Facebook */ /* Copyright (c) 2019 Facebook */
#define _GNU_SOURCE
#include <netinet/in.h> #include <netinet/in.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <unistd.h> #include <unistd.h>
#include <sched.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
@@ -21,6 +23,7 @@
enum bpf_linum_array_idx { enum bpf_linum_array_idx {
EGRESS_LINUM_IDX, EGRESS_LINUM_IDX,
INGRESS_LINUM_IDX, INGRESS_LINUM_IDX,
READ_SK_DST_PORT_LINUM_IDX,
__NR_BPF_LINUM_ARRAY_IDX, __NR_BPF_LINUM_ARRAY_IDX,
}; };
@@ -43,8 +46,16 @@ static __u64 child_cg_id;
static int linum_map_fd; static int linum_map_fd;
static __u32 duration; static __u32 duration;
static __u32 egress_linum_idx = EGRESS_LINUM_IDX; static bool create_netns(void)
static __u32 ingress_linum_idx = INGRESS_LINUM_IDX; {
if (!ASSERT_OK(unshare(CLONE_NEWNET), "create netns"))
return false;
if (!ASSERT_OK(system("ip link set dev lo up"), "bring up lo"))
return false;
return true;
}
static void print_sk(const struct bpf_sock *sk, const char *prefix) static void print_sk(const struct bpf_sock *sk, const char *prefix)
{ {
@@ -92,19 +103,24 @@ static void check_result(void)
{ {
struct bpf_tcp_sock srv_tp, cli_tp, listen_tp; struct bpf_tcp_sock srv_tp, cli_tp, listen_tp;
struct bpf_sock srv_sk, cli_sk, listen_sk; struct bpf_sock srv_sk, cli_sk, listen_sk;
__u32 ingress_linum, egress_linum; __u32 idx, ingress_linum, egress_linum, linum;
int err; int err;
err = bpf_map_lookup_elem(linum_map_fd, &egress_linum_idx, idx = EGRESS_LINUM_IDX;
&egress_linum); err = bpf_map_lookup_elem(linum_map_fd, &idx, &egress_linum);
CHECK(err == -1, "bpf_map_lookup_elem(linum_map_fd)", CHECK(err == -1, "bpf_map_lookup_elem(linum_map_fd)",
"err:%d errno:%d\n", err, errno); "err:%d errno:%d\n", err, errno);
err = bpf_map_lookup_elem(linum_map_fd, &ingress_linum_idx, idx = INGRESS_LINUM_IDX;
&ingress_linum); err = bpf_map_lookup_elem(linum_map_fd, &idx, &ingress_linum);
CHECK(err == -1, "bpf_map_lookup_elem(linum_map_fd)", CHECK(err == -1, "bpf_map_lookup_elem(linum_map_fd)",
"err:%d errno:%d\n", err, errno); "err:%d errno:%d\n", err, errno);
idx = READ_SK_DST_PORT_LINUM_IDX;
err = bpf_map_lookup_elem(linum_map_fd, &idx, &linum);
ASSERT_OK(err, "bpf_map_lookup_elem(linum_map_fd, READ_SK_DST_PORT_IDX)");
ASSERT_EQ(linum, 0, "failure in read_sk_dst_port on line");
memcpy(&srv_sk, &skel->bss->srv_sk, sizeof(srv_sk)); memcpy(&srv_sk, &skel->bss->srv_sk, sizeof(srv_sk));
memcpy(&srv_tp, &skel->bss->srv_tp, sizeof(srv_tp)); memcpy(&srv_tp, &skel->bss->srv_tp, sizeof(srv_tp));
memcpy(&cli_sk, &skel->bss->cli_sk, sizeof(cli_sk)); memcpy(&cli_sk, &skel->bss->cli_sk, sizeof(cli_sk));
@@ -263,7 +279,7 @@ static void test(void)
char buf[DATA_LEN]; char buf[DATA_LEN];
/* Prepare listen_fd */ /* Prepare listen_fd */
listen_fd = start_server(AF_INET6, SOCK_STREAM, "::1", 0, 0); listen_fd = start_server(AF_INET6, SOCK_STREAM, "::1", 0xcafe, 0);
/* start_server() has logged the error details */ /* start_server() has logged the error details */
if (CHECK_FAIL(listen_fd == -1)) if (CHECK_FAIL(listen_fd == -1))
goto done; goto done;
@@ -331,8 +347,12 @@ done:
void test_sock_fields(void) void test_sock_fields(void)
{ {
struct bpf_link *egress_link = NULL, *ingress_link = NULL;
int parent_cg_fd = -1, child_cg_fd = -1; int parent_cg_fd = -1, child_cg_fd = -1;
struct bpf_link *link;
/* Use a dedicated netns to have a fixed listen port */
if (!create_netns())
return;
/* Create a cgroup, get fd, and join it */ /* Create a cgroup, get fd, and join it */
parent_cg_fd = test__join_cgroup(PARENT_CGROUP); parent_cg_fd = test__join_cgroup(PARENT_CGROUP);
@@ -353,17 +373,20 @@ void test_sock_fields(void)
if (CHECK(!skel, "test_sock_fields__open_and_load", "failed\n")) if (CHECK(!skel, "test_sock_fields__open_and_load", "failed\n"))
goto done; goto done;
egress_link = bpf_program__attach_cgroup(skel->progs.egress_read_sock_fields, link = bpf_program__attach_cgroup(skel->progs.egress_read_sock_fields, child_cg_fd);
child_cg_fd); if (!ASSERT_OK_PTR(link, "attach_cgroup(egress_read_sock_fields)"))
if (CHECK(IS_ERR(egress_link), "attach_cgroup(egress)", "err:%ld\n",
PTR_ERR(egress_link)))
goto done; goto done;
skel->links.egress_read_sock_fields = link;
ingress_link = bpf_program__attach_cgroup(skel->progs.ingress_read_sock_fields, link = bpf_program__attach_cgroup(skel->progs.ingress_read_sock_fields, child_cg_fd);
child_cg_fd); if (!ASSERT_OK_PTR(link, "attach_cgroup(ingress_read_sock_fields)"))
if (CHECK(IS_ERR(ingress_link), "attach_cgroup(ingress)", "err:%ld\n",
PTR_ERR(ingress_link)))
goto done; goto done;
skel->links.ingress_read_sock_fields = link;
link = bpf_program__attach_cgroup(skel->progs.read_sk_dst_port, child_cg_fd);
if (!ASSERT_OK_PTR(link, "attach_cgroup(read_sk_dst_port"))
goto done;
skel->links.read_sk_dst_port = link;
linum_map_fd = bpf_map__fd(skel->maps.linum_map); linum_map_fd = bpf_map__fd(skel->maps.linum_map);
sk_pkt_out_cnt_fd = bpf_map__fd(skel->maps.sk_pkt_out_cnt); sk_pkt_out_cnt_fd = bpf_map__fd(skel->maps.sk_pkt_out_cnt);
@@ -372,8 +395,7 @@ void test_sock_fields(void)
test(); test();
done: done:
bpf_link__destroy(egress_link); test_sock_fields__detach(skel);
bpf_link__destroy(ingress_link);
test_sock_fields__destroy(skel); test_sock_fields__destroy(skel);
if (child_cg_fd != -1) if (child_cg_fd != -1)
close(child_cg_fd); close(child_cg_fd);

View File

@@ -12,6 +12,7 @@
enum bpf_linum_array_idx { enum bpf_linum_array_idx {
EGRESS_LINUM_IDX, EGRESS_LINUM_IDX,
INGRESS_LINUM_IDX, INGRESS_LINUM_IDX,
READ_SK_DST_PORT_LINUM_IDX,
__NR_BPF_LINUM_ARRAY_IDX, __NR_BPF_LINUM_ARRAY_IDX,
}; };
@@ -250,4 +251,48 @@ int ingress_read_sock_fields(struct __sk_buff *skb)
return CG_OK; return CG_OK;
} }
static __noinline bool sk_dst_port__load_word(struct bpf_sock *sk)
{
__u32 *word = (__u32 *)&sk->dst_port;
return word[0] == bpf_htonl(0xcafe0000);
}
static __noinline bool sk_dst_port__load_half(struct bpf_sock *sk)
{
__u16 *half = (__u16 *)&sk->dst_port;
return half[0] == bpf_htons(0xcafe);
}
static __noinline bool sk_dst_port__load_byte(struct bpf_sock *sk)
{
__u8 *byte = (__u8 *)&sk->dst_port;
return byte[0] == 0xca && byte[1] == 0xfe;
}
SEC("cgroup_skb/egress")
int read_sk_dst_port(struct __sk_buff *skb)
{
__u32 linum, linum_idx;
struct bpf_sock *sk;
linum_idx = READ_SK_DST_PORT_LINUM_IDX;
sk = skb->sk;
if (!sk)
RET_LOG();
/* Ignore everything but the SYN from the client socket */
if (sk->state != BPF_TCP_SYN_SENT)
return CG_OK;
if (!sk_dst_port__load_word(sk))
RET_LOG();
if (!sk_dst_port__load_half(sk))
RET_LOG();
if (!sk_dst_port__load_byte(sk))
RET_LOG();
return CG_OK;
}
char _license[] SEC("license") = "GPL"; char _license[] SEC("license") = "GPL";

View File

@@ -121,7 +121,25 @@
.result = ACCEPT, .result = ACCEPT,
}, },
{ {
"sk_fullsock(skb->sk): sk->dst_port [narrow load]", "sk_fullsock(skb->sk): sk->dst_port [word load] (backward compatibility)",
.insns = {
BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_1, offsetof(struct __sk_buff, sk)),
BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 2),
BPF_MOV64_IMM(BPF_REG_0, 0),
BPF_EXIT_INSN(),
BPF_EMIT_CALL(BPF_FUNC_sk_fullsock),
BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
BPF_MOV64_IMM(BPF_REG_0, 0),
BPF_EXIT_INSN(),
BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0, offsetof(struct bpf_sock, dst_port)),
BPF_MOV64_IMM(BPF_REG_0, 0),
BPF_EXIT_INSN(),
},
.prog_type = BPF_PROG_TYPE_CGROUP_SKB,
.result = ACCEPT,
},
{
"sk_fullsock(skb->sk): sk->dst_port [half load]",
.insns = { .insns = {
BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_1, offsetof(struct __sk_buff, sk)), BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_1, offsetof(struct __sk_buff, sk)),
BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 2), BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 2),
@@ -139,7 +157,7 @@
.result = ACCEPT, .result = ACCEPT,
}, },
{ {
"sk_fullsock(skb->sk): sk->dst_port [load 2nd byte]", "sk_fullsock(skb->sk): sk->dst_port [half load] (invalid)",
.insns = { .insns = {
BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_1, offsetof(struct __sk_buff, sk)), BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_1, offsetof(struct __sk_buff, sk)),
BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 2), BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 2),
@@ -149,7 +167,64 @@
BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2), BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
BPF_MOV64_IMM(BPF_REG_0, 0), BPF_MOV64_IMM(BPF_REG_0, 0),
BPF_EXIT_INSN(), BPF_EXIT_INSN(),
BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, offsetof(struct bpf_sock, dst_port) + 1), BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_0, offsetof(struct bpf_sock, dst_port) + 2),
BPF_MOV64_IMM(BPF_REG_0, 0),
BPF_EXIT_INSN(),
},
.prog_type = BPF_PROG_TYPE_CGROUP_SKB,
.result = REJECT,
.errstr = "invalid sock access",
},
{
"sk_fullsock(skb->sk): sk->dst_port [byte load]",
.insns = {
BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_1, offsetof(struct __sk_buff, sk)),
BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 2),
BPF_MOV64_IMM(BPF_REG_0, 0),
BPF_EXIT_INSN(),
BPF_EMIT_CALL(BPF_FUNC_sk_fullsock),
BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
BPF_MOV64_IMM(BPF_REG_0, 0),
BPF_EXIT_INSN(),
BPF_LDX_MEM(BPF_B, BPF_REG_2, BPF_REG_0, offsetof(struct bpf_sock, dst_port)),
BPF_LDX_MEM(BPF_B, BPF_REG_2, BPF_REG_0, offsetof(struct bpf_sock, dst_port) + 1),
BPF_MOV64_IMM(BPF_REG_0, 0),
BPF_EXIT_INSN(),
},
.prog_type = BPF_PROG_TYPE_CGROUP_SKB,
.result = ACCEPT,
},
{
"sk_fullsock(skb->sk): sk->dst_port [byte load] (invalid)",
.insns = {
BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_1, offsetof(struct __sk_buff, sk)),
BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 2),
BPF_MOV64_IMM(BPF_REG_0, 0),
BPF_EXIT_INSN(),
BPF_EMIT_CALL(BPF_FUNC_sk_fullsock),
BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
BPF_MOV64_IMM(BPF_REG_0, 0),
BPF_EXIT_INSN(),
BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, offsetof(struct bpf_sock, dst_port) + 2),
BPF_MOV64_IMM(BPF_REG_0, 0),
BPF_EXIT_INSN(),
},
.prog_type = BPF_PROG_TYPE_CGROUP_SKB,
.result = REJECT,
.errstr = "invalid sock access",
},
{
"sk_fullsock(skb->sk): past sk->dst_port [half load] (invalid)",
.insns = {
BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_1, offsetof(struct __sk_buff, sk)),
BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 2),
BPF_MOV64_IMM(BPF_REG_0, 0),
BPF_EXIT_INSN(),
BPF_EMIT_CALL(BPF_FUNC_sk_fullsock),
BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
BPF_MOV64_IMM(BPF_REG_0, 0),
BPF_EXIT_INSN(),
BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_0, offsetofend(struct bpf_sock, dst_port)),
BPF_MOV64_IMM(BPF_REG_0, 0), BPF_MOV64_IMM(BPF_REG_0, 0),
BPF_EXIT_INSN(), BPF_EXIT_INSN(),
}, },

View File

@@ -73,20 +73,19 @@ void ucall_uninit(struct kvm_vm *vm)
void ucall(uint64_t cmd, int nargs, ...) void ucall(uint64_t cmd, int nargs, ...)
{ {
struct ucall uc = { struct ucall uc = {};
.cmd = cmd,
};
va_list va; va_list va;
int i; int i;
WRITE_ONCE(uc.cmd, cmd);
nargs = nargs <= UCALL_MAX_ARGS ? nargs : UCALL_MAX_ARGS; nargs = nargs <= UCALL_MAX_ARGS ? nargs : UCALL_MAX_ARGS;
va_start(va, nargs); va_start(va, nargs);
for (i = 0; i < nargs; ++i) for (i = 0; i < nargs; ++i)
uc.args[i] = va_arg(va, uint64_t); WRITE_ONCE(uc.args[i], va_arg(va, uint64_t));
va_end(va); va_end(va);
*ucall_exit_mmio_addr = (vm_vaddr_t)&uc; WRITE_ONCE(*ucall_exit_mmio_addr, (vm_vaddr_t)&uc);
} }
uint64_t get_ucall(struct kvm_vm *vm, uint32_t vcpu_id, struct ucall *uc) uint64_t get_ucall(struct kvm_vm *vm, uint32_t vcpu_id, struct ucall *uc)