Merge Official Source
Signed-off-by: Tianling Shen <cnsztl@immortalwrt.org>
This commit is contained in:
commit
bb56c18f7c
@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
DEP_FINDPARAMS := -x "*/.svn*" -x ".*" -x "*:*" -x "*\!*" -x "* *" -x "*\\\#*" -x "*/.*_check" -x "*/.*.swp" -x "*/.pkgdir*"
|
DEP_FINDPARAMS := -x "*/.svn*" -x ".*" -x "*:*" -x "*\!*" -x "* *" -x "*\\\#*" -x "*/.*_check" -x "*/.*.swp" -x "*/.pkgdir*"
|
||||||
|
|
||||||
find_md5=find $(wildcard $(1)) -type f $(patsubst -x,-and -not -path,$(DEP_FINDPARAMS) $(2)) -printf "%p%T@\n" | sort | mkhash md5
|
find_md5=find $(wildcard $(1)) -type f $(patsubst -x,-and -not -path,$(DEP_FINDPARAMS) $(2)) -printf "%p%T@\n" | sort | $(MKHASH) md5
|
||||||
|
|
||||||
define rdep
|
define rdep
|
||||||
.PRECIOUS: $(2)
|
.PRECIOUS: $(2)
|
||||||
|
@ -74,7 +74,7 @@ else
|
|||||||
check_warn = $(if $(filter-out undefined,$(origin F_$(1))),$(filter ,$(shell $(call F_$(1),$(2),$(3),$(4)) >&2)),$(check_warn_nofix))
|
check_warn = $(if $(filter-out undefined,$(origin F_$(1))),$(filter ,$(shell $(call F_$(1),$(2),$(3),$(4)) >&2)),$(check_warn_nofix))
|
||||||
endif
|
endif
|
||||||
|
|
||||||
gen_sha256sum = $(shell mkhash sha256 $(DL_DIR)/$(1))
|
gen_sha256sum = $(shell $(MKHASH) sha256 $(DL_DIR)/$(1))
|
||||||
|
|
||||||
ifdef FIXUP
|
ifdef FIXUP
|
||||||
F_hash_deprecated = $(SCRIPT_DIR)/fixup-makefile.pl $(CURDIR)/Makefile fix-hash $(3) $(call gen_sha256sum,$(1)) $(2)
|
F_hash_deprecated = $(SCRIPT_DIR)/fixup-makefile.pl $(CURDIR)/Makefile fix-hash $(3) $(call gen_sha256sum,$(1)) $(2)
|
||||||
|
@ -198,7 +198,7 @@ define Build/elx-header
|
|||||||
dd bs=20 count=1 conv=sync; \
|
dd bs=20 count=1 conv=sync; \
|
||||||
echo -ne "$$(printf '%08x' $$(stat -c%s $@) | fold -s2 | xargs -I {} echo \\x{} | tr -d '\n')" | \
|
echo -ne "$$(printf '%08x' $$(stat -c%s $@) | fold -s2 | xargs -I {} echo \\x{} | tr -d '\n')" | \
|
||||||
dd bs=8 count=1 conv=sync; \
|
dd bs=8 count=1 conv=sync; \
|
||||||
echo -ne "$$($(STAGING_DIR_HOST)/bin/mkhash md5 $@ | fold -s2 | xargs -I {} echo \\x{} | tr -d '\n')" | \
|
echo -ne "$$($(MKHASH) md5 $@ | fold -s2 | xargs -I {} echo \\x{} | tr -d '\n')" | \
|
||||||
dd bs=58 count=1 conv=sync; \
|
dd bs=58 count=1 conv=sync; \
|
||||||
) > $(KDIR)/tmp/$(DEVICE_NAME).header
|
) > $(KDIR)/tmp/$(DEVICE_NAME).header
|
||||||
$(call Build/xor-image,-p $(xor_pattern) -x)
|
$(call Build/xor-image,-p $(xor_pattern) -x)
|
||||||
@ -272,8 +272,11 @@ define Build/jffs2
|
|||||||
endef
|
endef
|
||||||
|
|
||||||
define Build/kernel2minor
|
define Build/kernel2minor
|
||||||
kernel2minor -k $@ -r $@.new $(1)
|
$(eval temp_file := $(shell mktemp))
|
||||||
mv $@.new $@
|
cp $@ $(temp_file)
|
||||||
|
kernel2minor -k $(temp_file) -r $(temp_file).new $(1)
|
||||||
|
mv $(temp_file).new $@
|
||||||
|
rm -f $(temp_file)
|
||||||
endef
|
endef
|
||||||
|
|
||||||
define Build/kernel-bin
|
define Build/kernel-bin
|
||||||
|
@ -26,7 +26,7 @@ param_get_default = $(firstword $(call param_get,$(1),$(2)) $(3))
|
|||||||
param_mangle = $(subst $(space),_,$(strip $(1)))
|
param_mangle = $(subst $(space),_,$(strip $(1)))
|
||||||
param_unmangle = $(subst _,$(space),$(1))
|
param_unmangle = $(subst _,$(space),$(1))
|
||||||
|
|
||||||
mkfs_packages_id = $(shell echo $(sort $(1)) | mkhash md5 | cut -b1-8)
|
mkfs_packages_id = $(shell echo $(sort $(1)) | $(MKHASH) md5 | cut -b1-8)
|
||||||
mkfs_target_dir = $(if $(call param_get,pkg,$(1)),$(KDIR)/target-dir-$(call param_get,pkg,$(1)),$(TARGET_DIR))
|
mkfs_target_dir = $(if $(call param_get,pkg,$(1)),$(KDIR)/target-dir-$(call param_get,pkg,$(1)),$(TARGET_DIR))
|
||||||
|
|
||||||
KDIR=$(KERNEL_BUILD_DIR)
|
KDIR=$(KERNEL_BUILD_DIR)
|
||||||
@ -40,8 +40,8 @@ IMG_PREFIX_VERCODE:=$(if $(CONFIG_VERSION_CODE_FILENAMES),$(call sanitize,$(VERS
|
|||||||
IMG_PREFIX:=$(VERSION_DIST_SANITIZED)-$(IMG_PREFIX_VERNUM)$(IMG_PREFIX_VERCODE)$(IMG_PREFIX_EXTRA)$(BOARD)$(if $(SUBTARGET),-$(SUBTARGET))
|
IMG_PREFIX:=$(VERSION_DIST_SANITIZED)-$(IMG_PREFIX_VERNUM)$(IMG_PREFIX_VERCODE)$(IMG_PREFIX_EXTRA)$(BOARD)$(if $(SUBTARGET),-$(SUBTARGET))
|
||||||
IMG_ROOTFS:=$(IMG_PREFIX)-rootfs
|
IMG_ROOTFS:=$(IMG_PREFIX)-rootfs
|
||||||
IMG_COMBINED:=$(IMG_PREFIX)-combined
|
IMG_COMBINED:=$(IMG_PREFIX)-combined
|
||||||
IMG_PART_SIGNATURE:=$(shell echo $(SOURCE_DATE_EPOCH)$(LINUX_VERMAGIC) | mkhash md5 | cut -b1-8)
|
IMG_PART_SIGNATURE:=$(shell echo $(SOURCE_DATE_EPOCH)$(LINUX_VERMAGIC) | $(MKHASH) md5 | cut -b1-8)
|
||||||
IMG_PART_DISKGUID:=$(shell echo $(SOURCE_DATE_EPOCH)$(LINUX_VERMAGIC) | mkhash md5 | sed -E 's/(.{8})(.{4})(.{4})(.{4})(.{10})../\1-\2-\3-\4-\500/')
|
IMG_PART_DISKGUID:=$(shell echo $(SOURCE_DATE_EPOCH)$(LINUX_VERMAGIC) | $(MKHASH) md5 | sed -E 's/(.{8})(.{4})(.{4})(.{4})(.{10})../\1-\2-\3-\4-\500/')
|
||||||
|
|
||||||
MKFS_DEVTABLE_OPT := -D $(INCLUDE_DIR)/device_table.txt
|
MKFS_DEVTABLE_OPT := -D $(INCLUDE_DIR)/device_table.txt
|
||||||
|
|
||||||
|
@ -116,7 +116,7 @@ define Kernel/Configure/Default
|
|||||||
cp $(LINUX_DIR)/.config.set $(LINUX_DIR)/.config.prev; \
|
cp $(LINUX_DIR)/.config.set $(LINUX_DIR)/.config.prev; \
|
||||||
}
|
}
|
||||||
$(_SINGLE) [ -d $(LINUX_DIR)/user_headers ] || $(KERNEL_MAKE) INSTALL_HDR_PATH=$(LINUX_DIR)/user_headers headers_install
|
$(_SINGLE) [ -d $(LINUX_DIR)/user_headers ] || $(KERNEL_MAKE) INSTALL_HDR_PATH=$(LINUX_DIR)/user_headers headers_install
|
||||||
grep '=[ym]' $(LINUX_DIR)/.config.set | LC_ALL=C sort | mkhash md5 > $(LINUX_DIR)/.vermagic
|
grep '=[ym]' $(LINUX_DIR)/.config.set | LC_ALL=C sort | $(MKHASH) md5 > $(LINUX_DIR)/.vermagic
|
||||||
endef
|
endef
|
||||||
|
|
||||||
define Kernel/Configure/Initramfs
|
define Kernel/Configure/Initramfs
|
||||||
@ -186,5 +186,3 @@ define Kernel/Clean/Default
|
|||||||
rm -f $(LINUX_KERNEL)
|
rm -f $(LINUX_KERNEL)
|
||||||
$(_SINGLE)$(MAKE) -C $(KERNEL_BUILD_DIR)/linux-$(LINUX_VERSION) clean
|
$(_SINGLE)$(MAKE) -C $(KERNEL_BUILD_DIR)/linux-$(LINUX_VERSION) clean
|
||||||
endef
|
endef
|
||||||
|
|
||||||
|
|
||||||
|
@ -221,7 +221,7 @@ $(_endef)
|
|||||||
ifneq ($$(CONFIG_IPK_FILES_CHECKSUMS),)
|
ifneq ($$(CONFIG_IPK_FILES_CHECKSUMS),)
|
||||||
(cd $$(IDIR_$(1)); \
|
(cd $$(IDIR_$(1)); \
|
||||||
( \
|
( \
|
||||||
find . -type f \! -path ./CONTROL/\* -exec mkhash sha256 -n \{\} \; 2> /dev/null | \
|
find . -type f \! -path ./CONTROL/\* -exec $(MKHASH) sha256 -n \{\} \; 2> /dev/null | \
|
||||||
sed 's|\([[:blank:]]\)\./| \1/|' > $$(IDIR_$(1))/CONTROL/files-sha256sum \
|
sed 's|\([[:blank:]]\)\./| \1/|' > $$(IDIR_$(1))/CONTROL/files-sha256sum \
|
||||||
) || true \
|
) || true \
|
||||||
)
|
)
|
||||||
|
@ -159,7 +159,7 @@ define Quilt/Template
|
|||||||
false; \
|
false; \
|
||||||
}
|
}
|
||||||
@[ -n "$$$$(ls $(1)/patches/series)" -o \
|
@[ -n "$$$$(ls $(1)/patches/series)" -o \
|
||||||
"$$$$(cat $(1)/patches/series | mkhash md5)" = "$$(sort $(1)/patches/series | mkhash md5)" ] || { \
|
"$$$$(cat $(1)/patches/series | $(MKHASH) md5)" = "$$(sort $(1)/patches/series | $(MKHASH) md5)" ] || { \
|
||||||
echo "The patches are not sorted in the right order. Please fix."; \
|
echo "The patches are not sorted in the right order. Please fix."; \
|
||||||
false; \
|
false; \
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
include $(TOPDIR)/include/verbose.mk
|
include $(TOPDIR)/include/verbose.mk
|
||||||
|
include $(TOPDIR)/rules.mk
|
||||||
TMP_DIR:=$(TOPDIR)/tmp
|
TMP_DIR:=$(TOPDIR)/tmp
|
||||||
|
|
||||||
all: $(TMP_DIR)/.$(SCAN_TARGET)
|
all: $(TMP_DIR)/.$(SCAN_TARGET)
|
||||||
@ -100,7 +101,7 @@ $(TMP_DIR)/info/.files-$(SCAN_TARGET).mk: $(FILELIST)
|
|||||||
$(TARGET_STAMP)::
|
$(TARGET_STAMP)::
|
||||||
+( \
|
+( \
|
||||||
$(NO_TRACE_MAKE) $(FILELIST); \
|
$(NO_TRACE_MAKE) $(FILELIST); \
|
||||||
MD5SUM=$$(cat $(FILELIST) $(OVERRIDELIST) | mkhash md5 | awk '{print $$1}'); \
|
MD5SUM=$$(cat $(FILELIST) $(OVERRIDELIST) | $(MKHASH) md5 | awk '{print $$1}'); \
|
||||||
[ -f "$@.$$MD5SUM" ] || { \
|
[ -f "$@.$$MD5SUM" ] || { \
|
||||||
rm -f $@.*; \
|
rm -f $@.*; \
|
||||||
touch $@.$$MD5SUM; \
|
touch $@.$$MD5SUM; \
|
||||||
|
@ -66,8 +66,10 @@ $(curdir)/install: $(TMP_DIR)/.build $(curdir)/merge $(if $(CONFIG_TARGET_PER_DE
|
|||||||
- find $(STAGING_DIR_ROOT) -type d | $(XARGS) chmod 0755
|
- find $(STAGING_DIR_ROOT) -type d | $(XARGS) chmod 0755
|
||||||
rm -rf $(TARGET_DIR) $(TARGET_DIR_ORIG)
|
rm -rf $(TARGET_DIR) $(TARGET_DIR_ORIG)
|
||||||
mkdir -p $(TARGET_DIR)/tmp
|
mkdir -p $(TARGET_DIR)/tmp
|
||||||
$(call opkg,$(TARGET_DIR)) install \
|
$(file >$(TMP_DIR)/opkg_install_list,\
|
||||||
$(call opkg_package_files,$(foreach pkg,$(shell cat $(PACKAGE_INSTALL_FILES) 2>/dev/null),$(pkg)$(call GetABISuffix,$(pkg))))
|
$(call opkg_package_files,\
|
||||||
|
$(foreach pkg,$(shell cat $(PACKAGE_INSTALL_FILES) 2>/dev/null),$(pkg)$(call GetABISuffix,$(pkg)))))
|
||||||
|
$(call opkg,$(TARGET_DIR)) install $$(cat $(TMP_DIR)/opkg_install_list)
|
||||||
@for file in $(PACKAGE_INSTALL_FILES); do \
|
@for file in $(PACKAGE_INSTALL_FILES); do \
|
||||||
[ -s $$file.flags ] || continue; \
|
[ -s $$file.flags ] || continue; \
|
||||||
for flag in `cat $$file.flags`; do \
|
for flag in `cat $$file.flags`; do \
|
||||||
|
@ -30,7 +30,7 @@ PKG_CONFIG_DEPENDS += \
|
|||||||
include $(INCLUDE_DIR)/package.mk
|
include $(INCLUDE_DIR)/package.mk
|
||||||
|
|
||||||
ifneq ($(DUMP),1)
|
ifneq ($(DUMP),1)
|
||||||
STAMP_CONFIGURED:=$(strip $(STAMP_CONFIGURED))_$(shell echo $(CONFIG_TARGET_INIT_PATH) | mkhash md5)
|
STAMP_CONFIGURED:=$(strip $(STAMP_CONFIGURED))_$(shell echo $(CONFIG_TARGET_INIT_PATH) | $(MKHASH) md5)
|
||||||
TARGET:=-$(BOARD)
|
TARGET:=-$(BOARD)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ service() {
|
|||||||
printf "%-30s\t%10s\t%10s\n" "$F" \
|
printf "%-30s\t%10s\t%10s\n" "$F" \
|
||||||
$( $($F enabled) && echo "enabled" || echo "disabled" ) \
|
$( $($F enabled) && echo "enabled" || echo "disabled" ) \
|
||||||
$( [ "$(ubus call service list "{ 'verbose': true, 'name': '$(basename $F)' }" \
|
$( [ "$(ubus call service list "{ 'verbose': true, 'name': '$(basename $F)' }" \
|
||||||
| jsonfilter -q -e "@.$(basename $F).instances[*].running" | uniq)" = "true" ] \
|
| jsonfilter -q -e "@['$(basename $F)'].instances[*].running" | uniq)" = "true" ] \
|
||||||
&& echo "running" || echo "stopped" )
|
&& echo "running" || echo "stopped" )
|
||||||
done;
|
done;
|
||||||
return 1
|
return 1
|
||||||
|
@ -24,7 +24,7 @@ export SHELL:=/bin/sh
|
|||||||
include $(INCLUDE_DIR)/package.mk
|
include $(INCLUDE_DIR)/package.mk
|
||||||
|
|
||||||
ifeq ($(DUMP),)
|
ifeq ($(DUMP),)
|
||||||
STAMP_BUILT:=$(STAMP_BUILT)_$(shell $(SCRIPT_DIR)/kconfig.pl $(LINUX_DIR)/.config | mkhash md5)
|
STAMP_BUILT:=$(STAMP_BUILT)_$(shell $(SCRIPT_DIR)/kconfig.pl $(LINUX_DIR)/.config | $(MKHASH) md5)
|
||||||
-include $(LINUX_DIR)/.config
|
-include $(LINUX_DIR)/.config
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
@ -145,3 +145,17 @@ define KernelPackage/leds-pwm/description
|
|||||||
endef
|
endef
|
||||||
|
|
||||||
$(eval $(call KernelPackage,leds-pwm))
|
$(eval $(call KernelPackage,leds-pwm))
|
||||||
|
|
||||||
|
define KernelPackage/leds-uleds
|
||||||
|
SUBMENU:=$(LEDS_MENU)
|
||||||
|
TITLE:=Userspace LEDs
|
||||||
|
KCONFIG:=CONFIG_LEDS_USER
|
||||||
|
FILES:=$(LINUX_DIR)/drivers/leds/uleds.ko
|
||||||
|
AUTOLOAD:=$(call AutoLoad,60,leds-uleds,1)
|
||||||
|
endef
|
||||||
|
|
||||||
|
define KernelPackage/leds-uleds/description
|
||||||
|
This option enables support for userspace LEDs.
|
||||||
|
endef
|
||||||
|
|
||||||
|
$(eval $(call KernelPackage,leds-uleds))
|
||||||
|
@ -37,7 +37,7 @@
|
|||||||
void ath10k_thermal_event_temperature(struct ath10k *ar, int temperature);
|
void ath10k_thermal_event_temperature(struct ath10k *ar, int temperature);
|
||||||
--- a/local-symbols
|
--- a/local-symbols
|
||||||
+++ b/local-symbols
|
+++ b/local-symbols
|
||||||
@@ -142,6 +142,7 @@ ATH10K_SNOC=
|
@@ -143,6 +143,7 @@ ATH10K_SNOC=
|
||||||
ATH10K_DEBUG=
|
ATH10K_DEBUG=
|
||||||
ATH10K_DEBUGFS=
|
ATH10K_DEBUGFS=
|
||||||
ATH10K_SPECTRAL=
|
ATH10K_SPECTRAL=
|
||||||
|
@ -0,0 +1,180 @@
|
|||||||
|
From: Wen Gong <wgong@codeaurora.org>
|
||||||
|
Date: Tue, 11 May 2021 20:02:52 +0200
|
||||||
|
Subject: [PATCH] ath10k: add CCMP PN replay protection for fragmented
|
||||||
|
frames for PCIe
|
||||||
|
|
||||||
|
PN replay check for not fragmented frames is finished in the firmware,
|
||||||
|
but this was not done for fragmented frames when ath10k is used with
|
||||||
|
QCA6174/QCA6377 PCIe. mac80211 has the function
|
||||||
|
ieee80211_rx_h_defragment() for PN replay check for fragmented frames,
|
||||||
|
but this does not get checked with QCA6174 due to the
|
||||||
|
ieee80211_has_protected() condition not matching the cleared Protected
|
||||||
|
bit case.
|
||||||
|
|
||||||
|
Validate the PN of received fragmented frames within ath10k when CCMP is
|
||||||
|
used and drop the fragment if the PN is not correct (incremented by
|
||||||
|
exactly one from the previous fragment). This applies only for
|
||||||
|
QCA6174/QCA6377 PCIe.
|
||||||
|
|
||||||
|
Tested-on: QCA6174 hw3.2 PCI WLAN.RM.4.4.1-00110-QCARMSWP-1
|
||||||
|
|
||||||
|
Cc: stable@vger.kernel.org
|
||||||
|
Signed-off-by: Wen Gong <wgong@codeaurora.org>
|
||||||
|
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
|
||||||
|
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||||
|
---
|
||||||
|
|
||||||
|
--- a/drivers/net/wireless/ath/ath10k/htt.h
|
||||||
|
+++ b/drivers/net/wireless/ath/ath10k/htt.h
|
||||||
|
@@ -846,6 +846,7 @@ enum htt_security_types {
|
||||||
|
|
||||||
|
#define ATH10K_HTT_TXRX_PEER_SECURITY_MAX 2
|
||||||
|
#define ATH10K_TXRX_NUM_EXT_TIDS 19
|
||||||
|
+#define ATH10K_TXRX_NON_QOS_TID 16
|
||||||
|
|
||||||
|
enum htt_security_flags {
|
||||||
|
#define HTT_SECURITY_TYPE_MASK 0x7F
|
||||||
|
--- a/drivers/net/wireless/ath/ath10k/htt_rx.c
|
||||||
|
+++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
|
||||||
|
@@ -1746,16 +1746,87 @@ static void ath10k_htt_rx_h_csum_offload
|
||||||
|
msdu->ip_summed = ath10k_htt_rx_get_csum_state(msdu);
|
||||||
|
}
|
||||||
|
|
||||||
|
+static u64 ath10k_htt_rx_h_get_pn(struct ath10k *ar, struct sk_buff *skb,
|
||||||
|
+ u16 offset,
|
||||||
|
+ enum htt_rx_mpdu_encrypt_type enctype)
|
||||||
|
+{
|
||||||
|
+ struct ieee80211_hdr *hdr;
|
||||||
|
+ u64 pn = 0;
|
||||||
|
+ u8 *ehdr;
|
||||||
|
+
|
||||||
|
+ hdr = (struct ieee80211_hdr *)(skb->data + offset);
|
||||||
|
+ ehdr = skb->data + offset + ieee80211_hdrlen(hdr->frame_control);
|
||||||
|
+
|
||||||
|
+ if (enctype == HTT_RX_MPDU_ENCRYPT_AES_CCM_WPA2) {
|
||||||
|
+ pn = ehdr[0];
|
||||||
|
+ pn |= (u64)ehdr[1] << 8;
|
||||||
|
+ pn |= (u64)ehdr[4] << 16;
|
||||||
|
+ pn |= (u64)ehdr[5] << 24;
|
||||||
|
+ pn |= (u64)ehdr[6] << 32;
|
||||||
|
+ pn |= (u64)ehdr[7] << 40;
|
||||||
|
+ }
|
||||||
|
+ return pn;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static bool ath10k_htt_rx_h_frag_pn_check(struct ath10k *ar,
|
||||||
|
+ struct sk_buff *skb,
|
||||||
|
+ u16 peer_id,
|
||||||
|
+ u16 offset,
|
||||||
|
+ enum htt_rx_mpdu_encrypt_type enctype)
|
||||||
|
+{
|
||||||
|
+ struct ath10k_peer *peer;
|
||||||
|
+ union htt_rx_pn_t *last_pn, new_pn = {0};
|
||||||
|
+ struct ieee80211_hdr *hdr;
|
||||||
|
+ bool more_frags;
|
||||||
|
+ u8 tid, frag_number;
|
||||||
|
+ u32 seq;
|
||||||
|
+
|
||||||
|
+ peer = ath10k_peer_find_by_id(ar, peer_id);
|
||||||
|
+ if (!peer) {
|
||||||
|
+ ath10k_dbg(ar, ATH10K_DBG_HTT, "invalid peer for frag pn check\n");
|
||||||
|
+ return false;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ hdr = (struct ieee80211_hdr *)(skb->data + offset);
|
||||||
|
+ if (ieee80211_is_data_qos(hdr->frame_control))
|
||||||
|
+ tid = ieee80211_get_tid(hdr);
|
||||||
|
+ else
|
||||||
|
+ tid = ATH10K_TXRX_NON_QOS_TID;
|
||||||
|
+
|
||||||
|
+ last_pn = &peer->frag_tids_last_pn[tid];
|
||||||
|
+ new_pn.pn48 = ath10k_htt_rx_h_get_pn(ar, skb, offset, enctype);
|
||||||
|
+ more_frags = ieee80211_has_morefrags(hdr->frame_control);
|
||||||
|
+ frag_number = le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG;
|
||||||
|
+ seq = (__le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4;
|
||||||
|
+
|
||||||
|
+ if (frag_number == 0) {
|
||||||
|
+ last_pn->pn48 = new_pn.pn48;
|
||||||
|
+ peer->frag_tids_seq[tid] = seq;
|
||||||
|
+ } else {
|
||||||
|
+ if (seq != peer->frag_tids_seq[tid])
|
||||||
|
+ return false;
|
||||||
|
+
|
||||||
|
+ if (new_pn.pn48 != last_pn->pn48 + 1)
|
||||||
|
+ return false;
|
||||||
|
+
|
||||||
|
+ last_pn->pn48 = new_pn.pn48;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return true;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static void ath10k_htt_rx_h_mpdu(struct ath10k *ar,
|
||||||
|
struct sk_buff_head *amsdu,
|
||||||
|
struct ieee80211_rx_status *status,
|
||||||
|
bool fill_crypt_header,
|
||||||
|
u8 *rx_hdr,
|
||||||
|
- enum ath10k_pkt_rx_err *err)
|
||||||
|
+ enum ath10k_pkt_rx_err *err,
|
||||||
|
+ u16 peer_id,
|
||||||
|
+ bool frag)
|
||||||
|
{
|
||||||
|
struct sk_buff *first;
|
||||||
|
struct sk_buff *last;
|
||||||
|
- struct sk_buff *msdu;
|
||||||
|
+ struct sk_buff *msdu, *temp;
|
||||||
|
struct htt_rx_desc *rxd;
|
||||||
|
struct ieee80211_hdr *hdr;
|
||||||
|
enum htt_rx_mpdu_encrypt_type enctype;
|
||||||
|
@@ -1768,6 +1839,7 @@ static void ath10k_htt_rx_h_mpdu(struct
|
||||||
|
bool is_decrypted;
|
||||||
|
bool is_mgmt;
|
||||||
|
u32 attention;
|
||||||
|
+ bool frag_pn_check = true;
|
||||||
|
|
||||||
|
if (skb_queue_empty(amsdu))
|
||||||
|
return;
|
||||||
|
@@ -1866,6 +1938,24 @@ static void ath10k_htt_rx_h_mpdu(struct
|
||||||
|
}
|
||||||
|
|
||||||
|
skb_queue_walk(amsdu, msdu) {
|
||||||
|
+ if (frag && !fill_crypt_header && is_decrypted &&
|
||||||
|
+ enctype == HTT_RX_MPDU_ENCRYPT_AES_CCM_WPA2)
|
||||||
|
+ frag_pn_check = ath10k_htt_rx_h_frag_pn_check(ar,
|
||||||
|
+ msdu,
|
||||||
|
+ peer_id,
|
||||||
|
+ 0,
|
||||||
|
+ enctype);
|
||||||
|
+
|
||||||
|
+ if (!frag_pn_check) {
|
||||||
|
+ /* Discard the fragment with invalid PN */
|
||||||
|
+ temp = msdu->prev;
|
||||||
|
+ __skb_unlink(msdu, amsdu);
|
||||||
|
+ dev_kfree_skb_any(msdu);
|
||||||
|
+ msdu = temp;
|
||||||
|
+ frag_pn_check = true;
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
ath10k_htt_rx_h_csum_offload(msdu);
|
||||||
|
ath10k_htt_rx_h_undecap(ar, msdu, status, first_hdr, enctype,
|
||||||
|
is_decrypted);
|
||||||
|
@@ -2071,7 +2161,8 @@ static int ath10k_htt_rx_handle_amsdu(st
|
||||||
|
ath10k_htt_rx_h_unchain(ar, &amsdu, &drop_cnt, &unchain_cnt);
|
||||||
|
|
||||||
|
ath10k_htt_rx_h_filter(ar, &amsdu, rx_status, &drop_cnt_filter);
|
||||||
|
- ath10k_htt_rx_h_mpdu(ar, &amsdu, rx_status, true, first_hdr, &err);
|
||||||
|
+ ath10k_htt_rx_h_mpdu(ar, &amsdu, rx_status, true, first_hdr, &err, 0,
|
||||||
|
+ false);
|
||||||
|
msdus_to_queue = skb_queue_len(&amsdu);
|
||||||
|
ath10k_htt_rx_h_enqueue(ar, &amsdu, rx_status);
|
||||||
|
|
||||||
|
@@ -3027,7 +3118,7 @@ static int ath10k_htt_rx_in_ord_ind(stru
|
||||||
|
ath10k_htt_rx_h_ppdu(ar, &amsdu, status, vdev_id);
|
||||||
|
ath10k_htt_rx_h_filter(ar, &amsdu, status, NULL);
|
||||||
|
ath10k_htt_rx_h_mpdu(ar, &amsdu, status, false, NULL,
|
||||||
|
- NULL);
|
||||||
|
+ NULL, peer_id, frag);
|
||||||
|
ath10k_htt_rx_h_enqueue(ar, &amsdu, status);
|
||||||
|
break;
|
||||||
|
case -EAGAIN:
|
@ -0,0 +1,66 @@
|
|||||||
|
From: Wen Gong <wgong@codeaurora.org>
|
||||||
|
Date: Tue, 11 May 2021 20:02:53 +0200
|
||||||
|
Subject: [PATCH] ath10k: drop fragments with multicast DA for PCIe
|
||||||
|
|
||||||
|
Fragmentation is not used with multicast frames. Discard unexpected
|
||||||
|
fragments with multicast DA. This fixes CVE-2020-26145.
|
||||||
|
|
||||||
|
Tested-on: QCA6174 hw3.2 PCI WLAN.RM.4.4.1-00110-QCARMSWP-1
|
||||||
|
|
||||||
|
Cc: stable@vger.kernel.org
|
||||||
|
Signed-off-by: Wen Gong <wgong@codeaurora.org>
|
||||||
|
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
|
||||||
|
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||||
|
---
|
||||||
|
|
||||||
|
--- a/drivers/net/wireless/ath/ath10k/htt_rx.c
|
||||||
|
+++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
|
||||||
|
@@ -1768,6 +1768,16 @@ static u64 ath10k_htt_rx_h_get_pn(struct
|
||||||
|
return pn;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static bool ath10k_htt_rx_h_frag_multicast_check(struct ath10k *ar,
|
||||||
|
+ struct sk_buff *skb,
|
||||||
|
+ u16 offset)
|
||||||
|
+{
|
||||||
|
+ struct ieee80211_hdr *hdr;
|
||||||
|
+
|
||||||
|
+ hdr = (struct ieee80211_hdr *)(skb->data + offset);
|
||||||
|
+ return !is_multicast_ether_addr(hdr->addr1);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static bool ath10k_htt_rx_h_frag_pn_check(struct ath10k *ar,
|
||||||
|
struct sk_buff *skb,
|
||||||
|
u16 peer_id,
|
||||||
|
@@ -1839,7 +1849,7 @@ static void ath10k_htt_rx_h_mpdu(struct
|
||||||
|
bool is_decrypted;
|
||||||
|
bool is_mgmt;
|
||||||
|
u32 attention;
|
||||||
|
- bool frag_pn_check = true;
|
||||||
|
+ bool frag_pn_check = true, multicast_check = true;
|
||||||
|
|
||||||
|
if (skb_queue_empty(amsdu))
|
||||||
|
return;
|
||||||
|
@@ -1946,13 +1956,20 @@ static void ath10k_htt_rx_h_mpdu(struct
|
||||||
|
0,
|
||||||
|
enctype);
|
||||||
|
|
||||||
|
- if (!frag_pn_check) {
|
||||||
|
- /* Discard the fragment with invalid PN */
|
||||||
|
+ if (frag)
|
||||||
|
+ multicast_check = ath10k_htt_rx_h_frag_multicast_check(ar,
|
||||||
|
+ msdu,
|
||||||
|
+ 0);
|
||||||
|
+
|
||||||
|
+ if (!frag_pn_check || !multicast_check) {
|
||||||
|
+ /* Discard the fragment with invalid PN or multicast DA
|
||||||
|
+ */
|
||||||
|
temp = msdu->prev;
|
||||||
|
__skb_unlink(msdu, amsdu);
|
||||||
|
dev_kfree_skb_any(msdu);
|
||||||
|
msdu = temp;
|
||||||
|
frag_pn_check = true;
|
||||||
|
+ multicast_check = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,40 @@
|
|||||||
|
From: Wen Gong <wgong@codeaurora.org>
|
||||||
|
Date: Tue, 11 May 2021 20:02:54 +0200
|
||||||
|
Subject: [PATCH] ath10k: drop fragments with multicast DA for SDIO
|
||||||
|
|
||||||
|
Fragmentation is not used with multicast frames. Discard unexpected
|
||||||
|
fragments with multicast DA. This fixes CVE-2020-26145.
|
||||||
|
|
||||||
|
Tested-on: QCA6174 hw3.2 SDIO WLAN.RMH.4.4.1-00049
|
||||||
|
|
||||||
|
Cc: stable@vger.kernel.org
|
||||||
|
Signed-off-by: Wen Gong <wgong@codeaurora.org>
|
||||||
|
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
|
||||||
|
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||||
|
---
|
||||||
|
|
||||||
|
--- a/drivers/net/wireless/ath/ath10k/htt_rx.c
|
||||||
|
+++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
|
||||||
|
@@ -2617,6 +2617,13 @@ static bool ath10k_htt_rx_proc_rx_frag_i
|
||||||
|
rx_desc = (struct htt_hl_rx_desc *)(skb->data + tot_hdr_len);
|
||||||
|
rx_desc_info = __le32_to_cpu(rx_desc->info);
|
||||||
|
|
||||||
|
+ hdr = (struct ieee80211_hdr *)((u8 *)rx_desc + rx_hl->fw_desc.len);
|
||||||
|
+
|
||||||
|
+ if (is_multicast_ether_addr(hdr->addr1)) {
|
||||||
|
+ /* Discard the fragment with multicast DA */
|
||||||
|
+ goto err;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if (!MS(rx_desc_info, HTT_RX_DESC_HL_INFO_ENCRYPTED)) {
|
||||||
|
spin_unlock_bh(&ar->data_lock);
|
||||||
|
return ath10k_htt_rx_proc_rx_ind_hl(htt, &resp->rx_ind_hl, skb,
|
||||||
|
@@ -2624,8 +2631,6 @@ static bool ath10k_htt_rx_proc_rx_frag_i
|
||||||
|
HTT_RX_NON_TKIP_MIC);
|
||||||
|
}
|
||||||
|
|
||||||
|
- hdr = (struct ieee80211_hdr *)((u8 *)rx_desc + rx_hl->fw_desc.len);
|
||||||
|
-
|
||||||
|
if (ieee80211_has_retry(hdr->frame_control))
|
||||||
|
goto err;
|
||||||
|
|
@ -0,0 +1,54 @@
|
|||||||
|
From: Wen Gong <wgong@codeaurora.org>
|
||||||
|
Date: Tue, 11 May 2021 20:02:55 +0200
|
||||||
|
Subject: [PATCH] ath10k: drop MPDU which has discard flag set by firmware
|
||||||
|
for SDIO
|
||||||
|
|
||||||
|
When the discard flag is set by the firmware for an MPDU, it should be
|
||||||
|
dropped. This allows a mitigation for CVE-2020-24588 to be implemented
|
||||||
|
in the firmware.
|
||||||
|
|
||||||
|
Tested-on: QCA6174 hw3.2 SDIO WLAN.RMH.4.4.1-00049
|
||||||
|
|
||||||
|
Cc: stable@vger.kernel.org
|
||||||
|
Signed-off-by: Wen Gong <wgong@codeaurora.org>
|
||||||
|
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
|
||||||
|
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||||
|
---
|
||||||
|
|
||||||
|
--- a/drivers/net/wireless/ath/ath10k/htt_rx.c
|
||||||
|
+++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
|
||||||
|
@@ -2312,6 +2312,11 @@ static bool ath10k_htt_rx_proc_rx_ind_hl
|
||||||
|
fw_desc = &rx->fw_desc;
|
||||||
|
rx_desc_len = fw_desc->len;
|
||||||
|
|
||||||
|
+ if (fw_desc->u.bits.discard) {
|
||||||
|
+ ath10k_dbg(ar, ATH10K_DBG_HTT, "htt discard mpdu\n");
|
||||||
|
+ goto err;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
/* I have not yet seen any case where num_mpdu_ranges > 1.
|
||||||
|
* qcacld does not seem handle that case either, so we introduce the
|
||||||
|
* same limitiation here as well.
|
||||||
|
--- a/drivers/net/wireless/ath/ath10k/rx_desc.h
|
||||||
|
+++ b/drivers/net/wireless/ath/ath10k/rx_desc.h
|
||||||
|
@@ -1282,7 +1282,19 @@ struct fw_rx_desc_base {
|
||||||
|
#define FW_RX_DESC_UDP (1 << 6)
|
||||||
|
|
||||||
|
struct fw_rx_desc_hl {
|
||||||
|
- u8 info0;
|
||||||
|
+ union {
|
||||||
|
+ struct {
|
||||||
|
+ u8 discard:1,
|
||||||
|
+ forward:1,
|
||||||
|
+ any_err:1,
|
||||||
|
+ dup_err:1,
|
||||||
|
+ reserved:1,
|
||||||
|
+ inspect:1,
|
||||||
|
+ extension:2;
|
||||||
|
+ } bits;
|
||||||
|
+ u8 info0;
|
||||||
|
+ } u;
|
||||||
|
+
|
||||||
|
u8 version;
|
||||||
|
u8 len;
|
||||||
|
u8 flags;
|
@ -0,0 +1,48 @@
|
|||||||
|
From: Wen Gong <wgong@codeaurora.org>
|
||||||
|
Date: Tue, 11 May 2021 20:02:56 +0200
|
||||||
|
Subject: [PATCH] ath10k: Fix TKIP Michael MIC verification for PCIe
|
||||||
|
|
||||||
|
TKIP Michael MIC was not verified properly for PCIe cases since the
|
||||||
|
validation steps in ieee80211_rx_h_michael_mic_verify() in mac80211 did
|
||||||
|
not get fully executed due to unexpected flag values in
|
||||||
|
ieee80211_rx_status.
|
||||||
|
|
||||||
|
Fix this by setting the flags property to meet mac80211 expectations for
|
||||||
|
performing Michael MIC validation there. This fixes CVE-2020-26141. It
|
||||||
|
does the same as ath10k_htt_rx_proc_rx_ind_hl() for SDIO which passed
|
||||||
|
MIC verification case. This applies only to QCA6174/QCA9377 PCIe.
|
||||||
|
|
||||||
|
Tested-on: QCA6174 hw3.2 PCI WLAN.RM.4.4.1-00110-QCARMSWP-1
|
||||||
|
|
||||||
|
Cc: stable@vger.kernel.org
|
||||||
|
Signed-off-by: Wen Gong <wgong@codeaurora.org>
|
||||||
|
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
|
||||||
|
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||||
|
---
|
||||||
|
|
||||||
|
--- a/drivers/net/wireless/ath/ath10k/htt_rx.c
|
||||||
|
+++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
|
||||||
|
@@ -1974,6 +1974,11 @@ static void ath10k_htt_rx_h_mpdu(struct
|
||||||
|
}
|
||||||
|
|
||||||
|
ath10k_htt_rx_h_csum_offload(msdu);
|
||||||
|
+
|
||||||
|
+ if (frag && !fill_crypt_header &&
|
||||||
|
+ enctype == HTT_RX_MPDU_ENCRYPT_TKIP_WPA)
|
||||||
|
+ status->flag &= ~RX_FLAG_MMIC_STRIPPED;
|
||||||
|
+
|
||||||
|
ath10k_htt_rx_h_undecap(ar, msdu, status, first_hdr, enctype,
|
||||||
|
is_decrypted);
|
||||||
|
|
||||||
|
@@ -1991,6 +1996,11 @@ static void ath10k_htt_rx_h_mpdu(struct
|
||||||
|
|
||||||
|
hdr = (void *)msdu->data;
|
||||||
|
hdr->frame_control &= ~__cpu_to_le16(IEEE80211_FCTL_PROTECTED);
|
||||||
|
+
|
||||||
|
+ if (frag && !fill_crypt_header &&
|
||||||
|
+ enctype == HTT_RX_MPDU_ENCRYPT_TKIP_WPA)
|
||||||
|
+ status->flag &= ~RX_FLAG_IV_STRIPPED &
|
||||||
|
+ ~RX_FLAG_MMIC_STRIPPED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,109 @@
|
|||||||
|
From: Sriram R <srirrama@codeaurora.org>
|
||||||
|
Date: Tue, 11 May 2021 20:02:57 +0200
|
||||||
|
Subject: [PATCH] ath10k: Validate first subframe of A-MSDU before
|
||||||
|
processing the list
|
||||||
|
|
||||||
|
In certain scenarios a normal MSDU can be received as an A-MSDU when
|
||||||
|
the A-MSDU present bit of a QoS header gets flipped during reception.
|
||||||
|
Since this bit is unauthenticated, the hardware crypto engine can pass
|
||||||
|
the frame to the driver without any error indication.
|
||||||
|
|
||||||
|
This could result in processing unintended subframes collected in the
|
||||||
|
A-MSDU list. Hence, validate A-MSDU list by checking if the first frame
|
||||||
|
has a valid subframe header.
|
||||||
|
|
||||||
|
Comparing the non-aggregated MSDU and an A-MSDU, the fields of the first
|
||||||
|
subframe DA matches the LLC/SNAP header fields of a normal MSDU.
|
||||||
|
In order to avoid processing such frames, add a validation to
|
||||||
|
filter such A-MSDU frames where the first subframe header DA matches
|
||||||
|
with the LLC/SNAP header pattern.
|
||||||
|
|
||||||
|
Tested-on: QCA9984 hw1.0 PCI 10.4-3.10-00047
|
||||||
|
|
||||||
|
Cc: stable@vger.kernel.org
|
||||||
|
Signed-off-by: Sriram R <srirrama@codeaurora.org>
|
||||||
|
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
|
||||||
|
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||||
|
---
|
||||||
|
|
||||||
|
--- a/drivers/net/wireless/ath/ath10k/htt_rx.c
|
||||||
|
+++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
|
||||||
|
@@ -2108,14 +2108,62 @@ static void ath10k_htt_rx_h_unchain(stru
|
||||||
|
ath10k_unchain_msdu(amsdu, unchain_cnt);
|
||||||
|
}
|
||||||
|
|
||||||
|
+static bool ath10k_htt_rx_validate_amsdu(struct ath10k *ar,
|
||||||
|
+ struct sk_buff_head *amsdu)
|
||||||
|
+{
|
||||||
|
+ u8 *subframe_hdr;
|
||||||
|
+ struct sk_buff *first;
|
||||||
|
+ bool is_first, is_last;
|
||||||
|
+ struct htt_rx_desc *rxd;
|
||||||
|
+ struct ieee80211_hdr *hdr;
|
||||||
|
+ size_t hdr_len, crypto_len;
|
||||||
|
+ enum htt_rx_mpdu_encrypt_type enctype;
|
||||||
|
+ int bytes_aligned = ar->hw_params.decap_align_bytes;
|
||||||
|
+
|
||||||
|
+ first = skb_peek(amsdu);
|
||||||
|
+
|
||||||
|
+ rxd = (void *)first->data - sizeof(*rxd);
|
||||||
|
+ hdr = (void *)rxd->rx_hdr_status;
|
||||||
|
+
|
||||||
|
+ is_first = !!(rxd->msdu_end.common.info0 &
|
||||||
|
+ __cpu_to_le32(RX_MSDU_END_INFO0_FIRST_MSDU));
|
||||||
|
+ is_last = !!(rxd->msdu_end.common.info0 &
|
||||||
|
+ __cpu_to_le32(RX_MSDU_END_INFO0_LAST_MSDU));
|
||||||
|
+
|
||||||
|
+ /* Return in case of non-aggregated msdu */
|
||||||
|
+ if (is_first && is_last)
|
||||||
|
+ return true;
|
||||||
|
+
|
||||||
|
+ /* First msdu flag is not set for the first msdu of the list */
|
||||||
|
+ if (!is_first)
|
||||||
|
+ return false;
|
||||||
|
+
|
||||||
|
+ enctype = MS(__le32_to_cpu(rxd->mpdu_start.info0),
|
||||||
|
+ RX_MPDU_START_INFO0_ENCRYPT_TYPE);
|
||||||
|
+
|
||||||
|
+ hdr_len = ieee80211_hdrlen(hdr->frame_control);
|
||||||
|
+ crypto_len = ath10k_htt_rx_crypto_param_len(ar, enctype);
|
||||||
|
+
|
||||||
|
+ subframe_hdr = (u8 *)hdr + round_up(hdr_len, bytes_aligned) +
|
||||||
|
+ crypto_len;
|
||||||
|
+
|
||||||
|
+ /* Validate if the amsdu has a proper first subframe.
|
||||||
|
+ * There are chances a single msdu can be received as amsdu when
|
||||||
|
+ * the unauthenticated amsdu flag of a QoS header
|
||||||
|
+ * gets flipped in non-SPP AMSDU's, in such cases the first
|
||||||
|
+ * subframe has llc/snap header in place of a valid da.
|
||||||
|
+ * return false if the da matches rfc1042 pattern
|
||||||
|
+ */
|
||||||
|
+ if (ether_addr_equal(subframe_hdr, rfc1042_header))
|
||||||
|
+ return false;
|
||||||
|
+
|
||||||
|
+ return true;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static bool ath10k_htt_rx_amsdu_allowed(struct ath10k *ar,
|
||||||
|
struct sk_buff_head *amsdu,
|
||||||
|
struct ieee80211_rx_status *rx_status)
|
||||||
|
{
|
||||||
|
- /* FIXME: It might be a good idea to do some fuzzy-testing to drop
|
||||||
|
- * invalid/dangerous frames.
|
||||||
|
- */
|
||||||
|
-
|
||||||
|
if (!rx_status->freq) {
|
||||||
|
ath10k_dbg(ar, ATH10K_DBG_HTT, "no channel configured; ignoring frame(s)!\n");
|
||||||
|
return false;
|
||||||
|
@@ -2126,6 +2174,11 @@ static bool ath10k_htt_rx_amsdu_allowed(
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (!ath10k_htt_rx_validate_amsdu(ar, amsdu)) {
|
||||||
|
+ ath10k_dbg(ar, ATH10K_DBG_HTT, "invalid amsdu received\n");
|
||||||
|
+ return false;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
@ -82,7 +82,7 @@
|
|||||||
help
|
help
|
||||||
--- a/local-symbols
|
--- a/local-symbols
|
||||||
+++ b/local-symbols
|
+++ b/local-symbols
|
||||||
@@ -85,6 +85,7 @@ ADM8211=
|
@@ -86,6 +86,7 @@ ADM8211=
|
||||||
ATH_COMMON=
|
ATH_COMMON=
|
||||||
WLAN_VENDOR_ATH=
|
WLAN_VENDOR_ATH=
|
||||||
ATH_DEBUG=
|
ATH_DEBUG=
|
||||||
|
@ -371,7 +371,7 @@
|
|||||||
|
|
||||||
--- a/local-symbols
|
--- a/local-symbols
|
||||||
+++ b/local-symbols
|
+++ b/local-symbols
|
||||||
@@ -112,6 +112,7 @@ ATH9K_WOW=
|
@@ -113,6 +113,7 @@ ATH9K_WOW=
|
||||||
ATH9K_RFKILL=
|
ATH9K_RFKILL=
|
||||||
ATH9K_CHANNEL_CONTEXT=
|
ATH9K_CHANNEL_CONTEXT=
|
||||||
ATH9K_PCOEM=
|
ATH9K_PCOEM=
|
||||||
|
@ -26,7 +26,7 @@ Forwarded: https://patchwork.kernel.org/patch/11367055/
|
|||||||
|
|
||||||
--- a/drivers/net/wireless/ath/ath10k/htt.h
|
--- a/drivers/net/wireless/ath/ath10k/htt.h
|
||||||
+++ b/drivers/net/wireless/ath/ath10k/htt.h
|
+++ b/drivers/net/wireless/ath/ath10k/htt.h
|
||||||
@@ -2242,7 +2242,7 @@ struct htt_rx_chan_info {
|
@@ -2243,7 +2243,7 @@ struct htt_rx_chan_info {
|
||||||
* Should be: sizeof(struct htt_host_rx_desc) + max rx MSDU size,
|
* Should be: sizeof(struct htt_host_rx_desc) + max rx MSDU size,
|
||||||
* rounded up to a cache line size.
|
* rounded up to a cache line size.
|
||||||
*/
|
*/
|
||||||
|
@ -114,7 +114,7 @@ v13:
|
|||||||
ath10k_core-$(CONFIG_DEV_COREDUMP) += coredump.o
|
ath10k_core-$(CONFIG_DEV_COREDUMP) += coredump.o
|
||||||
--- a/local-symbols
|
--- a/local-symbols
|
||||||
+++ b/local-symbols
|
+++ b/local-symbols
|
||||||
@@ -145,6 +145,7 @@ ATH10K_DEBUG=
|
@@ -146,6 +146,7 @@ ATH10K_DEBUG=
|
||||||
ATH10K_DEBUGFS=
|
ATH10K_DEBUGFS=
|
||||||
ATH10K_SPECTRAL=
|
ATH10K_SPECTRAL=
|
||||||
ATH10K_THERMAL=
|
ATH10K_THERMAL=
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
--- a/local-symbols
|
--- a/local-symbols
|
||||||
+++ b/local-symbols
|
+++ b/local-symbols
|
||||||
@@ -332,6 +332,7 @@ RT2X00_LIB_FIRMWARE=
|
@@ -333,6 +333,7 @@ RT2X00_LIB_FIRMWARE=
|
||||||
RT2X00_LIB_CRYPTO=
|
RT2X00_LIB_CRYPTO=
|
||||||
RT2X00_LIB_LEDS=
|
RT2X00_LIB_LEDS=
|
||||||
RT2X00_LIB_DEBUGFS=
|
RT2X00_LIB_DEBUGFS=
|
||||||
|
@ -0,0 +1,69 @@
|
|||||||
|
From: Mathy Vanhoef <Mathy.Vanhoef@kuleuven.be>
|
||||||
|
Date: Tue, 11 May 2021 20:02:42 +0200
|
||||||
|
Subject: [PATCH] mac80211: assure all fragments are encrypted
|
||||||
|
|
||||||
|
Do not mix plaintext and encrypted fragments in protected Wi-Fi
|
||||||
|
networks. This fixes CVE-2020-26147.
|
||||||
|
|
||||||
|
Previously, an attacker was able to first forward a legitimate encrypted
|
||||||
|
fragment towards a victim, followed by a plaintext fragment. The
|
||||||
|
encrypted and plaintext fragment would then be reassembled. For further
|
||||||
|
details see Section 6.3 and Appendix D in the paper "Fragment and Forge:
|
||||||
|
Breaking Wi-Fi Through Frame Aggregation and Fragmentation".
|
||||||
|
|
||||||
|
Because of this change there are now two equivalent conditions in the
|
||||||
|
code to determine if a received fragment requires sequential PNs, so we
|
||||||
|
also move this test to a separate function to make the code easier to
|
||||||
|
maintain.
|
||||||
|
|
||||||
|
Cc: stable@vger.kernel.org
|
||||||
|
Signed-off-by: Mathy Vanhoef <Mathy.Vanhoef@kuleuven.be>
|
||||||
|
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||||
|
---
|
||||||
|
|
||||||
|
--- a/net/mac80211/rx.c
|
||||||
|
+++ b/net/mac80211/rx.c
|
||||||
|
@@ -2204,6 +2204,16 @@ ieee80211_reassemble_find(struct ieee802
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static bool requires_sequential_pn(struct ieee80211_rx_data *rx, __le16 fc)
|
||||||
|
+{
|
||||||
|
+ return rx->key &&
|
||||||
|
+ (rx->key->conf.cipher == WLAN_CIPHER_SUITE_CCMP ||
|
||||||
|
+ rx->key->conf.cipher == WLAN_CIPHER_SUITE_CCMP_256 ||
|
||||||
|
+ rx->key->conf.cipher == WLAN_CIPHER_SUITE_GCMP ||
|
||||||
|
+ rx->key->conf.cipher == WLAN_CIPHER_SUITE_GCMP_256) &&
|
||||||
|
+ ieee80211_has_protected(fc);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static ieee80211_rx_result debug_noinline
|
||||||
|
ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx)
|
||||||
|
{
|
||||||
|
@@ -2248,12 +2258,7 @@ ieee80211_rx_h_defragment(struct ieee802
|
||||||
|
/* This is the first fragment of a new frame. */
|
||||||
|
entry = ieee80211_reassemble_add(rx->sdata, frag, seq,
|
||||||
|
rx->seqno_idx, &(rx->skb));
|
||||||
|
- if (rx->key &&
|
||||||
|
- (rx->key->conf.cipher == WLAN_CIPHER_SUITE_CCMP ||
|
||||||
|
- rx->key->conf.cipher == WLAN_CIPHER_SUITE_CCMP_256 ||
|
||||||
|
- rx->key->conf.cipher == WLAN_CIPHER_SUITE_GCMP ||
|
||||||
|
- rx->key->conf.cipher == WLAN_CIPHER_SUITE_GCMP_256) &&
|
||||||
|
- ieee80211_has_protected(fc)) {
|
||||||
|
+ if (requires_sequential_pn(rx, fc)) {
|
||||||
|
int queue = rx->security_idx;
|
||||||
|
|
||||||
|
/* Store CCMP/GCMP PN so that we can verify that the
|
||||||
|
@@ -2295,11 +2300,7 @@ ieee80211_rx_h_defragment(struct ieee802
|
||||||
|
u8 pn[IEEE80211_CCMP_PN_LEN], *rpn;
|
||||||
|
int queue;
|
||||||
|
|
||||||
|
- if (!rx->key ||
|
||||||
|
- (rx->key->conf.cipher != WLAN_CIPHER_SUITE_CCMP &&
|
||||||
|
- rx->key->conf.cipher != WLAN_CIPHER_SUITE_CCMP_256 &&
|
||||||
|
- rx->key->conf.cipher != WLAN_CIPHER_SUITE_GCMP &&
|
||||||
|
- rx->key->conf.cipher != WLAN_CIPHER_SUITE_GCMP_256))
|
||||||
|
+ if (!requires_sequential_pn(rx, fc))
|
||||||
|
return RX_DROP_UNUSABLE;
|
||||||
|
memcpy(pn, entry->last_pn, IEEE80211_CCMP_PN_LEN);
|
||||||
|
for (i = IEEE80211_CCMP_PN_LEN - 1; i >= 0; i--) {
|
@ -0,0 +1,87 @@
|
|||||||
|
From: Mathy Vanhoef <Mathy.Vanhoef@kuleuven.be>
|
||||||
|
Date: Tue, 11 May 2021 20:02:43 +0200
|
||||||
|
Subject: [PATCH] mac80211: prevent mixed key and fragment cache attacks
|
||||||
|
|
||||||
|
Simultaneously prevent mixed key attacks (CVE-2020-24587) and fragment
|
||||||
|
cache attacks (CVE-2020-24586). This is accomplished by assigning a
|
||||||
|
unique color to every key (per interface) and using this to track which
|
||||||
|
key was used to decrypt a fragment. When reassembling frames, it is
|
||||||
|
now checked whether all fragments were decrypted using the same key.
|
||||||
|
|
||||||
|
To assure that fragment cache attacks are also prevented, the ID that is
|
||||||
|
assigned to keys is unique even over (re)associations and (re)connects.
|
||||||
|
This means fragments separated by a (re)association or (re)connect will
|
||||||
|
not be reassembled. Because mac80211 now also prevents the reassembly of
|
||||||
|
mixed encrypted and plaintext fragments, all cache attacks are prevented.
|
||||||
|
|
||||||
|
Cc: stable@vger.kernel.org
|
||||||
|
Signed-off-by: Mathy Vanhoef <Mathy.Vanhoef@kuleuven.be>
|
||||||
|
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||||
|
---
|
||||||
|
|
||||||
|
--- a/net/mac80211/ieee80211_i.h
|
||||||
|
+++ b/net/mac80211/ieee80211_i.h
|
||||||
|
@@ -97,6 +97,7 @@ struct ieee80211_fragment_entry {
|
||||||
|
u8 rx_queue;
|
||||||
|
bool check_sequential_pn; /* needed for CCMP/GCMP */
|
||||||
|
u8 last_pn[6]; /* PN of the last fragment if CCMP was used */
|
||||||
|
+ unsigned int key_color;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
--- a/net/mac80211/key.c
|
||||||
|
+++ b/net/mac80211/key.c
|
||||||
|
@@ -799,6 +799,7 @@ int ieee80211_key_link(struct ieee80211_
|
||||||
|
struct ieee80211_sub_if_data *sdata,
|
||||||
|
struct sta_info *sta)
|
||||||
|
{
|
||||||
|
+ static atomic_t key_color = ATOMIC_INIT(0);
|
||||||
|
struct ieee80211_key *old_key;
|
||||||
|
int idx = key->conf.keyidx;
|
||||||
|
bool pairwise = key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE;
|
||||||
|
@@ -850,6 +851,12 @@ int ieee80211_key_link(struct ieee80211_
|
||||||
|
key->sdata = sdata;
|
||||||
|
key->sta = sta;
|
||||||
|
|
||||||
|
+ /*
|
||||||
|
+ * Assign a unique ID to every key so we can easily prevent mixed
|
||||||
|
+ * key and fragment cache attacks.
|
||||||
|
+ */
|
||||||
|
+ key->color = atomic_inc_return(&key_color);
|
||||||
|
+
|
||||||
|
increment_tailroom_need_count(sdata);
|
||||||
|
|
||||||
|
ret = ieee80211_key_replace(sdata, sta, pairwise, old_key, key);
|
||||||
|
--- a/net/mac80211/key.h
|
||||||
|
+++ b/net/mac80211/key.h
|
||||||
|
@@ -128,6 +128,8 @@ struct ieee80211_key {
|
||||||
|
} debugfs;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
+ unsigned int color;
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* key config, must be last because it contains key
|
||||||
|
* material as variable length member
|
||||||
|
--- a/net/mac80211/rx.c
|
||||||
|
+++ b/net/mac80211/rx.c
|
||||||
|
@@ -2265,6 +2265,7 @@ ieee80211_rx_h_defragment(struct ieee802
|
||||||
|
* next fragment has a sequential PN value.
|
||||||
|
*/
|
||||||
|
entry->check_sequential_pn = true;
|
||||||
|
+ entry->key_color = rx->key->color;
|
||||||
|
memcpy(entry->last_pn,
|
||||||
|
rx->key->u.ccmp.rx_pn[queue],
|
||||||
|
IEEE80211_CCMP_PN_LEN);
|
||||||
|
@@ -2302,6 +2303,11 @@ ieee80211_rx_h_defragment(struct ieee802
|
||||||
|
|
||||||
|
if (!requires_sequential_pn(rx, fc))
|
||||||
|
return RX_DROP_UNUSABLE;
|
||||||
|
+
|
||||||
|
+ /* Prevent mixed key and fragment cache attacks */
|
||||||
|
+ if (entry->key_color != rx->key->color)
|
||||||
|
+ return RX_DROP_UNUSABLE;
|
||||||
|
+
|
||||||
|
memcpy(pn, entry->last_pn, IEEE80211_CCMP_PN_LEN);
|
||||||
|
for (i = IEEE80211_CCMP_PN_LEN - 1; i >= 0; i--) {
|
||||||
|
pn[i]++;
|
@ -0,0 +1,66 @@
|
|||||||
|
From: Mathy Vanhoef <Mathy.Vanhoef@kuleuven.be>
|
||||||
|
Date: Tue, 11 May 2021 20:02:44 +0200
|
||||||
|
Subject: [PATCH] mac80211: properly handle A-MSDUs that start with an
|
||||||
|
RFC 1042 header
|
||||||
|
|
||||||
|
Properly parse A-MSDUs whose first 6 bytes happen to equal a rfc1042
|
||||||
|
header. This can occur in practice when the destination MAC address
|
||||||
|
equals AA:AA:03:00:00:00. More importantly, this simplifies the next
|
||||||
|
patch to mitigate A-MSDU injection attacks.
|
||||||
|
|
||||||
|
Cc: stable@vger.kernel.org
|
||||||
|
Signed-off-by: Mathy Vanhoef <Mathy.Vanhoef@kuleuven.be>
|
||||||
|
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||||
|
---
|
||||||
|
|
||||||
|
--- a/include/net/cfg80211.h
|
||||||
|
+++ b/include/net/cfg80211.h
|
||||||
|
@@ -5628,7 +5628,7 @@ unsigned int ieee80211_get_mesh_hdrlen(s
|
||||||
|
*/
|
||||||
|
int ieee80211_data_to_8023_exthdr(struct sk_buff *skb, struct ethhdr *ehdr,
|
||||||
|
const u8 *addr, enum nl80211_iftype iftype,
|
||||||
|
- u8 data_offset);
|
||||||
|
+ u8 data_offset, bool is_amsdu);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ieee80211_data_to_8023 - convert an 802.11 data frame to 802.3
|
||||||
|
@@ -5640,7 +5640,7 @@ int ieee80211_data_to_8023_exthdr(struct
|
||||||
|
static inline int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr,
|
||||||
|
enum nl80211_iftype iftype)
|
||||||
|
{
|
||||||
|
- return ieee80211_data_to_8023_exthdr(skb, NULL, addr, iftype, 0);
|
||||||
|
+ return ieee80211_data_to_8023_exthdr(skb, NULL, addr, iftype, 0, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
--- a/net/mac80211/rx.c
|
||||||
|
+++ b/net/mac80211/rx.c
|
||||||
|
@@ -2696,7 +2696,7 @@ __ieee80211_rx_h_amsdu(struct ieee80211_
|
||||||
|
if (ieee80211_data_to_8023_exthdr(skb, ðhdr,
|
||||||
|
rx->sdata->vif.addr,
|
||||||
|
rx->sdata->vif.type,
|
||||||
|
- data_offset))
|
||||||
|
+ data_offset, true))
|
||||||
|
return RX_DROP_UNUSABLE;
|
||||||
|
|
||||||
|
ieee80211_amsdu_to_8023s(skb, &frame_list, dev->dev_addr,
|
||||||
|
--- a/net/wireless/util.c
|
||||||
|
+++ b/net/wireless/util.c
|
||||||
|
@@ -541,7 +541,7 @@ EXPORT_SYMBOL(ieee80211_get_mesh_hdrlen)
|
||||||
|
|
||||||
|
int ieee80211_data_to_8023_exthdr(struct sk_buff *skb, struct ethhdr *ehdr,
|
||||||
|
const u8 *addr, enum nl80211_iftype iftype,
|
||||||
|
- u8 data_offset)
|
||||||
|
+ u8 data_offset, bool is_amsdu)
|
||||||
|
{
|
||||||
|
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
|
||||||
|
struct {
|
||||||
|
@@ -629,7 +629,7 @@ int ieee80211_data_to_8023_exthdr(struct
|
||||||
|
skb_copy_bits(skb, hdrlen, &payload, sizeof(payload));
|
||||||
|
tmp.h_proto = payload.proto;
|
||||||
|
|
||||||
|
- if (likely((ether_addr_equal(payload.hdr, rfc1042_header) &&
|
||||||
|
+ if (likely((!is_amsdu && ether_addr_equal(payload.hdr, rfc1042_header) &&
|
||||||
|
tmp.h_proto != htons(ETH_P_AARP) &&
|
||||||
|
tmp.h_proto != htons(ETH_P_IPX)) ||
|
||||||
|
ether_addr_equal(payload.hdr, bridge_tunnel_header)))
|
@ -0,0 +1,40 @@
|
|||||||
|
From: Mathy Vanhoef <Mathy.Vanhoef@kuleuven.be>
|
||||||
|
Date: Tue, 11 May 2021 20:02:45 +0200
|
||||||
|
Subject: [PATCH] cfg80211: mitigate A-MSDU aggregation attacks
|
||||||
|
|
||||||
|
Mitigate A-MSDU injection attacks (CVE-2020-24588) by detecting if the
|
||||||
|
destination address of a subframe equals an RFC1042 (i.e., LLC/SNAP)
|
||||||
|
header, and if so dropping the complete A-MSDU frame. This mitigates
|
||||||
|
known attacks, although new (unknown) aggregation-based attacks may
|
||||||
|
remain possible.
|
||||||
|
|
||||||
|
This defense works because in A-MSDU aggregation injection attacks, a
|
||||||
|
normal encrypted Wi-Fi frame is turned into an A-MSDU frame. This means
|
||||||
|
the first 6 bytes of the first A-MSDU subframe correspond to an RFC1042
|
||||||
|
header. In other words, the destination MAC address of the first A-MSDU
|
||||||
|
subframe contains the start of an RFC1042 header during an aggregation
|
||||||
|
attack. We can detect this and thereby prevent this specific attack.
|
||||||
|
For details, see Section 7.2 of "Fragment and Forge: Breaking Wi-Fi
|
||||||
|
Through Frame Aggregation and Fragmentation".
|
||||||
|
|
||||||
|
Note that for kernel 4.9 and above this patch depends on "mac80211:
|
||||||
|
properly handle A-MSDUs that start with a rfc1042 header". Otherwise
|
||||||
|
this patch has no impact and attacks will remain possible.
|
||||||
|
|
||||||
|
Cc: stable@vger.kernel.org
|
||||||
|
Signed-off-by: Mathy Vanhoef <Mathy.Vanhoef@kuleuven.be>
|
||||||
|
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||||
|
---
|
||||||
|
|
||||||
|
--- a/net/wireless/util.c
|
||||||
|
+++ b/net/wireless/util.c
|
||||||
|
@@ -775,6 +775,9 @@ void ieee80211_amsdu_to_8023s(struct sk_
|
||||||
|
remaining = skb->len - offset;
|
||||||
|
if (subframe_len > remaining)
|
||||||
|
goto purge;
|
||||||
|
+ /* mitigate A-MSDU aggregation injection attacks */
|
||||||
|
+ if (ether_addr_equal(eth.h_dest, rfc1042_header))
|
||||||
|
+ goto purge;
|
||||||
|
|
||||||
|
offset += sizeof(struct ethhdr);
|
||||||
|
last = remaining <= subframe_len + padding;
|
@ -0,0 +1,54 @@
|
|||||||
|
From: Johannes Berg <johannes.berg@intel.com>
|
||||||
|
Date: Tue, 11 May 2021 20:02:46 +0200
|
||||||
|
Subject: [PATCH] mac80211: drop A-MSDUs on old ciphers
|
||||||
|
|
||||||
|
With old ciphers (WEP and TKIP) we shouldn't be using A-MSDUs
|
||||||
|
since A-MSDUs are only supported if we know that they are, and
|
||||||
|
the only practical way for that is HT support which doesn't
|
||||||
|
support old ciphers.
|
||||||
|
|
||||||
|
However, we would normally accept them anyway. Since we check
|
||||||
|
the MMIC before deaggregating A-MSDUs, and the A-MSDU bit in
|
||||||
|
the QoS header is not protected in TKIP (or WEP), this enables
|
||||||
|
attacks similar to CVE-2020-24588. To prevent that, drop A-MSDUs
|
||||||
|
completely with old ciphers.
|
||||||
|
|
||||||
|
Cc: stable@vger.kernel.org
|
||||||
|
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||||
|
---
|
||||||
|
|
||||||
|
--- a/net/mac80211/rx.c
|
||||||
|
+++ b/net/mac80211/rx.c
|
||||||
|
@@ -6,7 +6,7 @@
|
||||||
|
* Copyright 2007-2010 Johannes Berg <johannes@sipsolutions.net>
|
||||||
|
* Copyright 2013-2014 Intel Mobile Communications GmbH
|
||||||
|
* Copyright(c) 2015 - 2017 Intel Deutschland GmbH
|
||||||
|
- * Copyright (C) 2018-2020 Intel Corporation
|
||||||
|
+ * Copyright (C) 2018-2021 Intel Corporation
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/jiffies.h>
|
||||||
|
@@ -2753,6 +2753,23 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx
|
||||||
|
if (is_multicast_ether_addr(hdr->addr1))
|
||||||
|
return RX_DROP_UNUSABLE;
|
||||||
|
|
||||||
|
+ if (rx->key) {
|
||||||
|
+ /*
|
||||||
|
+ * We should not receive A-MSDUs on pre-HT connections,
|
||||||
|
+ * and HT connections cannot use old ciphers. Thus drop
|
||||||
|
+ * them, as in those cases we couldn't even have SPP
|
||||||
|
+ * A-MSDUs or such.
|
||||||
|
+ */
|
||||||
|
+ switch (rx->key->conf.cipher) {
|
||||||
|
+ case WLAN_CIPHER_SUITE_WEP40:
|
||||||
|
+ case WLAN_CIPHER_SUITE_WEP104:
|
||||||
|
+ case WLAN_CIPHER_SUITE_TKIP:
|
||||||
|
+ return RX_DROP_UNUSABLE;
|
||||||
|
+ default:
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
return __ieee80211_rx_h_amsdu(rx, 0);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,313 @@
|
|||||||
|
From: Johannes Berg <johannes.berg@intel.com>
|
||||||
|
Date: Tue, 11 May 2021 20:02:47 +0200
|
||||||
|
Subject: [PATCH] mac80211: add fragment cache to sta_info
|
||||||
|
|
||||||
|
Prior patches protected against fragmentation cache attacks
|
||||||
|
by coloring keys, but this shows that it can lead to issues
|
||||||
|
when multiple stations use the same sequence number. Add a
|
||||||
|
fragment cache to struct sta_info (in addition to the one in
|
||||||
|
the interface) to separate fragments for different stations
|
||||||
|
properly.
|
||||||
|
|
||||||
|
This then automatically clear most of the fragment cache when a
|
||||||
|
station disconnects (or reassociates) from an AP, or when client
|
||||||
|
interfaces disconnect from the network, etc.
|
||||||
|
|
||||||
|
On the way, also fix the comment there since this brings us in line
|
||||||
|
with the recommendation in 802.11-2016 ("An AP should support ...").
|
||||||
|
Additionally, remove a useless condition (since there's no problem
|
||||||
|
purging an already empty list).
|
||||||
|
|
||||||
|
Cc: stable@vger.kernel.org
|
||||||
|
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||||
|
---
|
||||||
|
|
||||||
|
--- a/net/mac80211/ieee80211_i.h
|
||||||
|
+++ b/net/mac80211/ieee80211_i.h
|
||||||
|
@@ -50,12 +50,6 @@ struct ieee80211_local;
|
||||||
|
#define IEEE80211_ENCRYPT_HEADROOM 8
|
||||||
|
#define IEEE80211_ENCRYPT_TAILROOM 18
|
||||||
|
|
||||||
|
-/* IEEE 802.11 (Ch. 9.5 Defragmentation) requires support for concurrent
|
||||||
|
- * reception of at least three fragmented frames. This limit can be increased
|
||||||
|
- * by changing this define, at the cost of slower frame reassembly and
|
||||||
|
- * increased memory use (about 2 kB of RAM per entry). */
|
||||||
|
-#define IEEE80211_FRAGMENT_MAX 4
|
||||||
|
-
|
||||||
|
/* power level hasn't been configured (or set to automatic) */
|
||||||
|
#define IEEE80211_UNSET_POWER_LEVEL INT_MIN
|
||||||
|
|
||||||
|
@@ -88,19 +82,6 @@ extern const u8 ieee80211_ac_to_qos_mask
|
||||||
|
|
||||||
|
#define IEEE80211_MAX_NAN_INSTANCE_ID 255
|
||||||
|
|
||||||
|
-struct ieee80211_fragment_entry {
|
||||||
|
- struct sk_buff_head skb_list;
|
||||||
|
- unsigned long first_frag_time;
|
||||||
|
- u16 seq;
|
||||||
|
- u16 extra_len;
|
||||||
|
- u16 last_frag;
|
||||||
|
- u8 rx_queue;
|
||||||
|
- bool check_sequential_pn; /* needed for CCMP/GCMP */
|
||||||
|
- u8 last_pn[6]; /* PN of the last fragment if CCMP was used */
|
||||||
|
- unsigned int key_color;
|
||||||
|
-};
|
||||||
|
-
|
||||||
|
-
|
||||||
|
struct ieee80211_bss {
|
||||||
|
u32 device_ts_beacon, device_ts_presp;
|
||||||
|
|
||||||
|
@@ -912,9 +893,7 @@ struct ieee80211_sub_if_data {
|
||||||
|
|
||||||
|
char name[IFNAMSIZ];
|
||||||
|
|
||||||
|
- /* Fragment table for host-based reassembly */
|
||||||
|
- struct ieee80211_fragment_entry fragments[IEEE80211_FRAGMENT_MAX];
|
||||||
|
- unsigned int fragment_next;
|
||||||
|
+ struct ieee80211_fragment_cache frags;
|
||||||
|
|
||||||
|
/* TID bitmap for NoAck policy */
|
||||||
|
u16 noack_map;
|
||||||
|
@@ -2329,4 +2308,7 @@ u32 ieee80211_calc_expected_tx_airtime(s
|
||||||
|
#define debug_noinline
|
||||||
|
#endif
|
||||||
|
|
||||||
|
+void ieee80211_init_frag_cache(struct ieee80211_fragment_cache *cache);
|
||||||
|
+void ieee80211_destroy_frag_cache(struct ieee80211_fragment_cache *cache);
|
||||||
|
+
|
||||||
|
#endif /* IEEE80211_I_H */
|
||||||
|
--- a/net/mac80211/iface.c
|
||||||
|
+++ b/net/mac80211/iface.c
|
||||||
|
@@ -8,7 +8,7 @@
|
||||||
|
* Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
|
||||||
|
* Copyright 2013-2014 Intel Mobile Communications GmbH
|
||||||
|
* Copyright (c) 2016 Intel Deutschland GmbH
|
||||||
|
- * Copyright (C) 2018-2020 Intel Corporation
|
||||||
|
+ * Copyright (C) 2018-2021 Intel Corporation
|
||||||
|
*/
|
||||||
|
#include <linux/slab.h>
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
@@ -679,16 +679,12 @@ static void ieee80211_set_multicast_list
|
||||||
|
*/
|
||||||
|
static void ieee80211_teardown_sdata(struct ieee80211_sub_if_data *sdata)
|
||||||
|
{
|
||||||
|
- int i;
|
||||||
|
-
|
||||||
|
/* free extra data */
|
||||||
|
ieee80211_free_keys(sdata, false);
|
||||||
|
|
||||||
|
ieee80211_debugfs_remove_netdev(sdata);
|
||||||
|
|
||||||
|
- for (i = 0; i < IEEE80211_FRAGMENT_MAX; i++)
|
||||||
|
- __skb_queue_purge(&sdata->fragments[i].skb_list);
|
||||||
|
- sdata->fragment_next = 0;
|
||||||
|
+ ieee80211_destroy_frag_cache(&sdata->frags);
|
||||||
|
|
||||||
|
if (ieee80211_vif_is_mesh(&sdata->vif))
|
||||||
|
ieee80211_mesh_teardown_sdata(sdata);
|
||||||
|
@@ -2038,8 +2034,7 @@ int ieee80211_if_add(struct ieee80211_lo
|
||||||
|
sdata->wdev.wiphy = local->hw.wiphy;
|
||||||
|
sdata->local = local;
|
||||||
|
|
||||||
|
- for (i = 0; i < IEEE80211_FRAGMENT_MAX; i++)
|
||||||
|
- skb_queue_head_init(&sdata->fragments[i].skb_list);
|
||||||
|
+ ieee80211_init_frag_cache(&sdata->frags);
|
||||||
|
|
||||||
|
INIT_LIST_HEAD(&sdata->key_list);
|
||||||
|
|
||||||
|
--- a/net/mac80211/rx.c
|
||||||
|
+++ b/net/mac80211/rx.c
|
||||||
|
@@ -2133,19 +2133,34 @@ ieee80211_rx_h_decrypt(struct ieee80211_
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
+void ieee80211_init_frag_cache(struct ieee80211_fragment_cache *cache)
|
||||||
|
+{
|
||||||
|
+ int i;
|
||||||
|
+
|
||||||
|
+ for (i = 0; i < ARRAY_SIZE(cache->entries); i++)
|
||||||
|
+ skb_queue_head_init(&cache->entries[i].skb_list);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void ieee80211_destroy_frag_cache(struct ieee80211_fragment_cache *cache)
|
||||||
|
+{
|
||||||
|
+ int i;
|
||||||
|
+
|
||||||
|
+ for (i = 0; i < ARRAY_SIZE(cache->entries); i++)
|
||||||
|
+ __skb_queue_purge(&cache->entries[i].skb_list);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static inline struct ieee80211_fragment_entry *
|
||||||
|
-ieee80211_reassemble_add(struct ieee80211_sub_if_data *sdata,
|
||||||
|
+ieee80211_reassemble_add(struct ieee80211_fragment_cache *cache,
|
||||||
|
unsigned int frag, unsigned int seq, int rx_queue,
|
||||||
|
struct sk_buff **skb)
|
||||||
|
{
|
||||||
|
struct ieee80211_fragment_entry *entry;
|
||||||
|
|
||||||
|
- entry = &sdata->fragments[sdata->fragment_next++];
|
||||||
|
- if (sdata->fragment_next >= IEEE80211_FRAGMENT_MAX)
|
||||||
|
- sdata->fragment_next = 0;
|
||||||
|
+ entry = &cache->entries[cache->next++];
|
||||||
|
+ if (cache->next >= IEEE80211_FRAGMENT_MAX)
|
||||||
|
+ cache->next = 0;
|
||||||
|
|
||||||
|
- if (!skb_queue_empty(&entry->skb_list))
|
||||||
|
- __skb_queue_purge(&entry->skb_list);
|
||||||
|
+ __skb_queue_purge(&entry->skb_list);
|
||||||
|
|
||||||
|
__skb_queue_tail(&entry->skb_list, *skb); /* no need for locking */
|
||||||
|
*skb = NULL;
|
||||||
|
@@ -2160,14 +2175,14 @@ ieee80211_reassemble_add(struct ieee8021
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline struct ieee80211_fragment_entry *
|
||||||
|
-ieee80211_reassemble_find(struct ieee80211_sub_if_data *sdata,
|
||||||
|
+ieee80211_reassemble_find(struct ieee80211_fragment_cache *cache,
|
||||||
|
unsigned int frag, unsigned int seq,
|
||||||
|
int rx_queue, struct ieee80211_hdr *hdr)
|
||||||
|
{
|
||||||
|
struct ieee80211_fragment_entry *entry;
|
||||||
|
int i, idx;
|
||||||
|
|
||||||
|
- idx = sdata->fragment_next;
|
||||||
|
+ idx = cache->next;
|
||||||
|
for (i = 0; i < IEEE80211_FRAGMENT_MAX; i++) {
|
||||||
|
struct ieee80211_hdr *f_hdr;
|
||||||
|
struct sk_buff *f_skb;
|
||||||
|
@@ -2176,7 +2191,7 @@ ieee80211_reassemble_find(struct ieee802
|
||||||
|
if (idx < 0)
|
||||||
|
idx = IEEE80211_FRAGMENT_MAX - 1;
|
||||||
|
|
||||||
|
- entry = &sdata->fragments[idx];
|
||||||
|
+ entry = &cache->entries[idx];
|
||||||
|
if (skb_queue_empty(&entry->skb_list) || entry->seq != seq ||
|
||||||
|
entry->rx_queue != rx_queue ||
|
||||||
|
entry->last_frag + 1 != frag)
|
||||||
|
@@ -2217,6 +2232,7 @@ static bool requires_sequential_pn(struc
|
||||||
|
static ieee80211_rx_result debug_noinline
|
||||||
|
ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx)
|
||||||
|
{
|
||||||
|
+ struct ieee80211_fragment_cache *cache = &rx->sdata->frags;
|
||||||
|
struct ieee80211_hdr *hdr;
|
||||||
|
u16 sc;
|
||||||
|
__le16 fc;
|
||||||
|
@@ -2238,6 +2254,9 @@ ieee80211_rx_h_defragment(struct ieee802
|
||||||
|
goto out_no_led;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (rx->sta)
|
||||||
|
+ cache = &rx->sta->frags;
|
||||||
|
+
|
||||||
|
if (likely(!ieee80211_has_morefrags(fc) && frag == 0))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
@@ -2256,7 +2275,7 @@ ieee80211_rx_h_defragment(struct ieee802
|
||||||
|
|
||||||
|
if (frag == 0) {
|
||||||
|
/* This is the first fragment of a new frame. */
|
||||||
|
- entry = ieee80211_reassemble_add(rx->sdata, frag, seq,
|
||||||
|
+ entry = ieee80211_reassemble_add(cache, frag, seq,
|
||||||
|
rx->seqno_idx, &(rx->skb));
|
||||||
|
if (requires_sequential_pn(rx, fc)) {
|
||||||
|
int queue = rx->security_idx;
|
||||||
|
@@ -2284,7 +2303,7 @@ ieee80211_rx_h_defragment(struct ieee802
|
||||||
|
/* This is a fragment for a frame that should already be pending in
|
||||||
|
* fragment cache. Add this fragment to the end of the pending entry.
|
||||||
|
*/
|
||||||
|
- entry = ieee80211_reassemble_find(rx->sdata, frag, seq,
|
||||||
|
+ entry = ieee80211_reassemble_find(cache, frag, seq,
|
||||||
|
rx->seqno_idx, hdr);
|
||||||
|
if (!entry) {
|
||||||
|
I802_DEBUG_INC(rx->local->rx_handlers_drop_defrag);
|
||||||
|
--- a/net/mac80211/sta_info.c
|
||||||
|
+++ b/net/mac80211/sta_info.c
|
||||||
|
@@ -4,7 +4,7 @@
|
||||||
|
* Copyright 2006-2007 Jiri Benc <jbenc@suse.cz>
|
||||||
|
* Copyright 2013-2014 Intel Mobile Communications GmbH
|
||||||
|
* Copyright (C) 2015 - 2017 Intel Deutschland GmbH
|
||||||
|
- * Copyright (C) 2018-2020 Intel Corporation
|
||||||
|
+ * Copyright (C) 2018-2021 Intel Corporation
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/module.h>
|
||||||
|
@@ -393,6 +393,8 @@ struct sta_info *sta_info_alloc(struct i
|
||||||
|
|
||||||
|
u64_stats_init(&sta->rx_stats.syncp);
|
||||||
|
|
||||||
|
+ ieee80211_init_frag_cache(&sta->frags);
|
||||||
|
+
|
||||||
|
sta->sta_state = IEEE80211_STA_NONE;
|
||||||
|
|
||||||
|
/* Mark TID as unreserved */
|
||||||
|
@@ -1103,6 +1105,8 @@ static void __sta_info_destroy_part2(str
|
||||||
|
|
||||||
|
ieee80211_sta_debugfs_remove(sta);
|
||||||
|
|
||||||
|
+ ieee80211_destroy_frag_cache(&sta->frags);
|
||||||
|
+
|
||||||
|
cleanup_single_sta(sta);
|
||||||
|
}
|
||||||
|
|
||||||
|
--- a/net/mac80211/sta_info.h
|
||||||
|
+++ b/net/mac80211/sta_info.h
|
||||||
|
@@ -3,7 +3,7 @@
|
||||||
|
* Copyright 2002-2005, Devicescape Software, Inc.
|
||||||
|
* Copyright 2013-2014 Intel Mobile Communications GmbH
|
||||||
|
* Copyright(c) 2015-2017 Intel Deutschland GmbH
|
||||||
|
- * Copyright(c) 2020 Intel Corporation
|
||||||
|
+ * Copyright(c) 2020-2021 Intel Corporation
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef STA_INFO_H
|
||||||
|
@@ -439,6 +439,33 @@ struct ieee80211_sta_rx_stats {
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
+ * IEEE 802.11-2016 (10.6 "Defragmentation") recommends support for "concurrent
|
||||||
|
+ * reception of at least one MSDU per access category per associated STA"
|
||||||
|
+ * on APs, or "at least one MSDU per access category" on other interface types.
|
||||||
|
+ *
|
||||||
|
+ * This limit can be increased by changing this define, at the cost of slower
|
||||||
|
+ * frame reassembly and increased memory use while fragments are pending.
|
||||||
|
+ */
|
||||||
|
+#define IEEE80211_FRAGMENT_MAX 4
|
||||||
|
+
|
||||||
|
+struct ieee80211_fragment_entry {
|
||||||
|
+ struct sk_buff_head skb_list;
|
||||||
|
+ unsigned long first_frag_time;
|
||||||
|
+ u16 seq;
|
||||||
|
+ u16 extra_len;
|
||||||
|
+ u16 last_frag;
|
||||||
|
+ u8 rx_queue;
|
||||||
|
+ bool check_sequential_pn; /* needed for CCMP/GCMP */
|
||||||
|
+ u8 last_pn[6]; /* PN of the last fragment if CCMP was used */
|
||||||
|
+ unsigned int key_color;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+struct ieee80211_fragment_cache {
|
||||||
|
+ struct ieee80211_fragment_entry entries[IEEE80211_FRAGMENT_MAX];
|
||||||
|
+ unsigned int next;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
* The bandwidth threshold below which the per-station CoDel parameters will be
|
||||||
|
* scaled to be more lenient (to prevent starvation of slow stations). This
|
||||||
|
* value will be scaled by the number of active stations when it is being
|
||||||
|
@@ -531,6 +558,7 @@ struct ieee80211_sta_rx_stats {
|
||||||
|
* @status_stats.last_ack_signal: last ACK signal
|
||||||
|
* @status_stats.ack_signal_filled: last ACK signal validity
|
||||||
|
* @status_stats.avg_ack_signal: average ACK signal
|
||||||
|
+ * @frags: fragment cache
|
||||||
|
*/
|
||||||
|
struct sta_info {
|
||||||
|
/* General information, mostly static */
|
||||||
|
@@ -639,6 +667,8 @@ struct sta_info {
|
||||||
|
|
||||||
|
struct cfg80211_chan_def tdls_chandef;
|
||||||
|
|
||||||
|
+ struct ieee80211_fragment_cache frags;
|
||||||
|
+
|
||||||
|
/* keep last! */
|
||||||
|
struct ieee80211_sta sta;
|
||||||
|
};
|
@ -0,0 +1,109 @@
|
|||||||
|
From: Johannes Berg <johannes.berg@intel.com>
|
||||||
|
Date: Tue, 11 May 2021 20:02:48 +0200
|
||||||
|
Subject: [PATCH] mac80211: check defrag PN against current frame
|
||||||
|
|
||||||
|
As pointed out by Mathy Vanhoef, we implement the RX PN check
|
||||||
|
on fragmented frames incorrectly - we check against the last
|
||||||
|
received PN prior to the new frame, rather than to the one in
|
||||||
|
this frame itself.
|
||||||
|
|
||||||
|
Prior patches addressed the security issue here, but in order
|
||||||
|
to be able to reason better about the code, fix it to really
|
||||||
|
compare against the current frame's PN, not the last stored
|
||||||
|
one.
|
||||||
|
|
||||||
|
Cc: stable@vger.kernel.org
|
||||||
|
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||||
|
---
|
||||||
|
|
||||||
|
--- a/net/mac80211/ieee80211_i.h
|
||||||
|
+++ b/net/mac80211/ieee80211_i.h
|
||||||
|
@@ -227,8 +227,15 @@ struct ieee80211_rx_data {
|
||||||
|
*/
|
||||||
|
int security_idx;
|
||||||
|
|
||||||
|
- u32 tkip_iv32;
|
||||||
|
- u16 tkip_iv16;
|
||||||
|
+ union {
|
||||||
|
+ struct {
|
||||||
|
+ u32 iv32;
|
||||||
|
+ u16 iv16;
|
||||||
|
+ } tkip;
|
||||||
|
+ struct {
|
||||||
|
+ u8 pn[IEEE80211_CCMP_PN_LEN];
|
||||||
|
+ } ccm_gcm;
|
||||||
|
+ };
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ieee80211_csa_settings {
|
||||||
|
--- a/net/mac80211/rx.c
|
||||||
|
+++ b/net/mac80211/rx.c
|
||||||
|
@@ -2318,7 +2318,6 @@ ieee80211_rx_h_defragment(struct ieee802
|
||||||
|
if (entry->check_sequential_pn) {
|
||||||
|
int i;
|
||||||
|
u8 pn[IEEE80211_CCMP_PN_LEN], *rpn;
|
||||||
|
- int queue;
|
||||||
|
|
||||||
|
if (!requires_sequential_pn(rx, fc))
|
||||||
|
return RX_DROP_UNUSABLE;
|
||||||
|
@@ -2333,8 +2332,8 @@ ieee80211_rx_h_defragment(struct ieee802
|
||||||
|
if (pn[i])
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
- queue = rx->security_idx;
|
||||||
|
- rpn = rx->key->u.ccmp.rx_pn[queue];
|
||||||
|
+
|
||||||
|
+ rpn = rx->ccm_gcm.pn;
|
||||||
|
if (memcmp(pn, rpn, IEEE80211_CCMP_PN_LEN))
|
||||||
|
return RX_DROP_UNUSABLE;
|
||||||
|
memcpy(entry->last_pn, pn, IEEE80211_CCMP_PN_LEN);
|
||||||
|
--- a/net/mac80211/wpa.c
|
||||||
|
+++ b/net/mac80211/wpa.c
|
||||||
|
@@ -3,6 +3,7 @@
|
||||||
|
* Copyright 2002-2004, Instant802 Networks, Inc.
|
||||||
|
* Copyright 2008, Jouni Malinen <j@w1.fi>
|
||||||
|
* Copyright (C) 2016-2017 Intel Deutschland GmbH
|
||||||
|
+ * Copyright (C) 2020-2021 Intel Corporation
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/netdevice.h>
|
||||||
|
@@ -167,8 +168,8 @@ ieee80211_rx_h_michael_mic_verify(struct
|
||||||
|
|
||||||
|
update_iv:
|
||||||
|
/* update IV in key information to be able to detect replays */
|
||||||
|
- rx->key->u.tkip.rx[rx->security_idx].iv32 = rx->tkip_iv32;
|
||||||
|
- rx->key->u.tkip.rx[rx->security_idx].iv16 = rx->tkip_iv16;
|
||||||
|
+ rx->key->u.tkip.rx[rx->security_idx].iv32 = rx->tkip.iv32;
|
||||||
|
+ rx->key->u.tkip.rx[rx->security_idx].iv16 = rx->tkip.iv16;
|
||||||
|
|
||||||
|
return RX_CONTINUE;
|
||||||
|
|
||||||
|
@@ -294,8 +295,8 @@ ieee80211_crypto_tkip_decrypt(struct iee
|
||||||
|
key, skb->data + hdrlen,
|
||||||
|
skb->len - hdrlen, rx->sta->sta.addr,
|
||||||
|
hdr->addr1, hwaccel, rx->security_idx,
|
||||||
|
- &rx->tkip_iv32,
|
||||||
|
- &rx->tkip_iv16);
|
||||||
|
+ &rx->tkip.iv32,
|
||||||
|
+ &rx->tkip.iv16);
|
||||||
|
if (res != TKIP_DECRYPT_OK)
|
||||||
|
return RX_DROP_UNUSABLE;
|
||||||
|
|
||||||
|
@@ -552,6 +553,8 @@ ieee80211_crypto_ccmp_decrypt(struct iee
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(key->u.ccmp.rx_pn[queue], pn, IEEE80211_CCMP_PN_LEN);
|
||||||
|
+ if (unlikely(ieee80211_is_frag(hdr)))
|
||||||
|
+ memcpy(rx->ccm_gcm.pn, pn, IEEE80211_CCMP_PN_LEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Remove CCMP header and MIC */
|
||||||
|
@@ -782,6 +785,8 @@ ieee80211_crypto_gcmp_decrypt(struct iee
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(key->u.gcmp.rx_pn[queue], pn, IEEE80211_GCMP_PN_LEN);
|
||||||
|
+ if (unlikely(ieee80211_is_frag(hdr)))
|
||||||
|
+ memcpy(rx->ccm_gcm.pn, pn, IEEE80211_CCMP_PN_LEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Remove GCMP header and MIC */
|
@ -0,0 +1,62 @@
|
|||||||
|
From: Johannes Berg <johannes.berg@intel.com>
|
||||||
|
Date: Tue, 11 May 2021 20:02:49 +0200
|
||||||
|
Subject: [PATCH] mac80211: prevent attacks on TKIP/WEP as well
|
||||||
|
|
||||||
|
Similar to the issues fixed in previous patches, TKIP and WEP
|
||||||
|
should be protected even if for TKIP we have the Michael MIC
|
||||||
|
protecting it, and WEP is broken anyway.
|
||||||
|
|
||||||
|
However, this also somewhat protects potential other algorithms
|
||||||
|
that drivers might implement.
|
||||||
|
|
||||||
|
Cc: stable@vger.kernel.org
|
||||||
|
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||||
|
---
|
||||||
|
|
||||||
|
--- a/net/mac80211/rx.c
|
||||||
|
+++ b/net/mac80211/rx.c
|
||||||
|
@@ -2284,6 +2284,7 @@ ieee80211_rx_h_defragment(struct ieee802
|
||||||
|
* next fragment has a sequential PN value.
|
||||||
|
*/
|
||||||
|
entry->check_sequential_pn = true;
|
||||||
|
+ entry->is_protected = true;
|
||||||
|
entry->key_color = rx->key->color;
|
||||||
|
memcpy(entry->last_pn,
|
||||||
|
rx->key->u.ccmp.rx_pn[queue],
|
||||||
|
@@ -2296,6 +2297,9 @@ ieee80211_rx_h_defragment(struct ieee802
|
||||||
|
sizeof(rx->key->u.gcmp.rx_pn[queue]));
|
||||||
|
BUILD_BUG_ON(IEEE80211_CCMP_PN_LEN !=
|
||||||
|
IEEE80211_GCMP_PN_LEN);
|
||||||
|
+ } else if (rx->key && ieee80211_has_protected(fc)) {
|
||||||
|
+ entry->is_protected = true;
|
||||||
|
+ entry->key_color = rx->key->color;
|
||||||
|
}
|
||||||
|
return RX_QUEUED;
|
||||||
|
}
|
||||||
|
@@ -2337,6 +2341,14 @@ ieee80211_rx_h_defragment(struct ieee802
|
||||||
|
if (memcmp(pn, rpn, IEEE80211_CCMP_PN_LEN))
|
||||||
|
return RX_DROP_UNUSABLE;
|
||||||
|
memcpy(entry->last_pn, pn, IEEE80211_CCMP_PN_LEN);
|
||||||
|
+ } else if (entry->is_protected &&
|
||||||
|
+ (!rx->key || !ieee80211_has_protected(fc) ||
|
||||||
|
+ rx->key->color != entry->key_color)) {
|
||||||
|
+ /* Drop this as a mixed key or fragment cache attack, even
|
||||||
|
+ * if for TKIP Michael MIC should protect us, and WEP is a
|
||||||
|
+ * lost cause anyway.
|
||||||
|
+ */
|
||||||
|
+ return RX_DROP_UNUSABLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
skb_pull(rx->skb, ieee80211_hdrlen(fc));
|
||||||
|
--- a/net/mac80211/sta_info.h
|
||||||
|
+++ b/net/mac80211/sta_info.h
|
||||||
|
@@ -455,7 +455,8 @@ struct ieee80211_fragment_entry {
|
||||||
|
u16 extra_len;
|
||||||
|
u16 last_frag;
|
||||||
|
u8 rx_queue;
|
||||||
|
- bool check_sequential_pn; /* needed for CCMP/GCMP */
|
||||||
|
+ u8 check_sequential_pn:1, /* needed for CCMP/GCMP */
|
||||||
|
+ is_protected:1;
|
||||||
|
u8 last_pn[6]; /* PN of the last fragment if CCMP was used */
|
||||||
|
unsigned int key_color;
|
||||||
|
};
|
@ -0,0 +1,94 @@
|
|||||||
|
From: Johannes Berg <johannes.berg@intel.com>
|
||||||
|
Date: Tue, 11 May 2021 20:02:50 +0200
|
||||||
|
Subject: [PATCH] mac80211: do not accept/forward invalid EAPOL frames
|
||||||
|
|
||||||
|
EAPOL frames are used for authentication and key management between the
|
||||||
|
AP and each individual STA associated in the BSS. Those frames are not
|
||||||
|
supposed to be sent by one associated STA to another associated STA
|
||||||
|
(either unicast for broadcast/multicast).
|
||||||
|
|
||||||
|
Similarly, in 802.11 they're supposed to be sent to the authenticator
|
||||||
|
(AP) address.
|
||||||
|
|
||||||
|
Since it is possible for unexpected EAPOL frames to result in misbehavior
|
||||||
|
in supplicant implementations, it is better for the AP to not allow such
|
||||||
|
cases to be forwarded to other clients either directly, or indirectly if
|
||||||
|
the AP interface is part of a bridge.
|
||||||
|
|
||||||
|
Accept EAPOL (control port) frames only if they're transmitted to the
|
||||||
|
own address, or, due to interoperability concerns, to the PAE group
|
||||||
|
address.
|
||||||
|
|
||||||
|
Disable forwarding of EAPOL (or well, the configured control port
|
||||||
|
protocol) frames back to wireless medium in all cases. Previously, these
|
||||||
|
frames were accepted from fully authenticated and authorized stations
|
||||||
|
and also from unauthenticated stations for one of the cases.
|
||||||
|
|
||||||
|
Additionally, to avoid forwarding by the bridge, rewrite the PAE group
|
||||||
|
address case to the local MAC address.
|
||||||
|
|
||||||
|
Cc: stable@vger.kernel.org
|
||||||
|
Co-developed-by: Jouni Malinen <jouni@codeaurora.org>
|
||||||
|
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
|
||||||
|
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||||
|
---
|
||||||
|
|
||||||
|
--- a/net/mac80211/rx.c
|
||||||
|
+++ b/net/mac80211/rx.c
|
||||||
|
@@ -2541,13 +2541,13 @@ static bool ieee80211_frame_allowed(stru
|
||||||
|
struct ethhdr *ehdr = (struct ethhdr *) rx->skb->data;
|
||||||
|
|
||||||
|
/*
|
||||||
|
- * Allow EAPOL frames to us/the PAE group address regardless
|
||||||
|
- * of whether the frame was encrypted or not.
|
||||||
|
+ * Allow EAPOL frames to us/the PAE group address regardless of
|
||||||
|
+ * whether the frame was encrypted or not, and always disallow
|
||||||
|
+ * all other destination addresses for them.
|
||||||
|
*/
|
||||||
|
- if (ehdr->h_proto == rx->sdata->control_port_protocol &&
|
||||||
|
- (ether_addr_equal(ehdr->h_dest, rx->sdata->vif.addr) ||
|
||||||
|
- ether_addr_equal(ehdr->h_dest, pae_group_addr)))
|
||||||
|
- return true;
|
||||||
|
+ if (unlikely(ehdr->h_proto == rx->sdata->control_port_protocol))
|
||||||
|
+ return ether_addr_equal(ehdr->h_dest, rx->sdata->vif.addr) ||
|
||||||
|
+ ether_addr_equal(ehdr->h_dest, pae_group_addr);
|
||||||
|
|
||||||
|
if (ieee80211_802_1x_port_control(rx) ||
|
||||||
|
ieee80211_drop_unencrypted(rx, fc))
|
||||||
|
@@ -2572,8 +2572,28 @@ static void ieee80211_deliver_skb_to_loc
|
||||||
|
cfg80211_rx_control_port(dev, skb, noencrypt);
|
||||||
|
dev_kfree_skb(skb);
|
||||||
|
} else {
|
||||||
|
+ struct ethhdr *ehdr = (void *)skb_mac_header(skb);
|
||||||
|
+
|
||||||
|
memset(skb->cb, 0, sizeof(skb->cb));
|
||||||
|
|
||||||
|
+ /*
|
||||||
|
+ * 802.1X over 802.11 requires that the authenticator address
|
||||||
|
+ * be used for EAPOL frames. However, 802.1X allows the use of
|
||||||
|
+ * the PAE group address instead. If the interface is part of
|
||||||
|
+ * a bridge and we pass the frame with the PAE group address,
|
||||||
|
+ * then the bridge will forward it to the network (even if the
|
||||||
|
+ * client was not associated yet), which isn't supposed to
|
||||||
|
+ * happen.
|
||||||
|
+ * To avoid that, rewrite the destination address to our own
|
||||||
|
+ * address, so that the authenticator (e.g. hostapd) will see
|
||||||
|
+ * the frame, but bridge won't forward it anywhere else. Note
|
||||||
|
+ * that due to earlier filtering, the only other address can
|
||||||
|
+ * be the PAE group address.
|
||||||
|
+ */
|
||||||
|
+ if (unlikely(skb->protocol == sdata->control_port_protocol &&
|
||||||
|
+ !ether_addr_equal(ehdr->h_dest, sdata->vif.addr)))
|
||||||
|
+ ether_addr_copy(ehdr->h_dest, sdata->vif.addr);
|
||||||
|
+
|
||||||
|
/* deliver to local stack */
|
||||||
|
if (rx->list)
|
||||||
|
#if LINUX_VERSION_IS_GEQ(4,19,0)
|
||||||
|
@@ -2617,6 +2637,7 @@ ieee80211_deliver_skb(struct ieee80211_r
|
||||||
|
if ((sdata->vif.type == NL80211_IFTYPE_AP ||
|
||||||
|
sdata->vif.type == NL80211_IFTYPE_AP_VLAN) &&
|
||||||
|
!(sdata->flags & IEEE80211_SDATA_DONT_BRIDGE_PACKETS) &&
|
||||||
|
+ ehdr->h_proto != rx->sdata->control_port_protocol &&
|
||||||
|
(sdata->vif.type != NL80211_IFTYPE_AP_VLAN || !sdata->u.vlan.sta)) {
|
||||||
|
if (is_multicast_ether_addr(ehdr->h_dest) &&
|
||||||
|
ieee80211_vif_get_num_mcast_if(sdata) != 0) {
|
@ -0,0 +1,68 @@
|
|||||||
|
From: Wen Gong <wgong@codeaurora.org>
|
||||||
|
Date: Tue, 11 May 2021 20:02:51 +0200
|
||||||
|
Subject: [PATCH] mac80211: extend protection against mixed key and
|
||||||
|
fragment cache attacks
|
||||||
|
|
||||||
|
For some chips/drivers, e.g., QCA6174 with ath10k, the decryption is
|
||||||
|
done by the hardware, and the Protected bit in the Frame Control field
|
||||||
|
is cleared in the lower level driver before the frame is passed to
|
||||||
|
mac80211. In such cases, the condition for ieee80211_has_protected() is
|
||||||
|
not met in ieee80211_rx_h_defragment() of mac80211 and the new security
|
||||||
|
validation steps are not executed.
|
||||||
|
|
||||||
|
Extend mac80211 to cover the case where the Protected bit has been
|
||||||
|
cleared, but the frame is indicated as having been decrypted by the
|
||||||
|
hardware. This extends protection against mixed key and fragment cache
|
||||||
|
attack for additional drivers/chips. This fixes CVE-2020-24586 and
|
||||||
|
CVE-2020-24587 for such cases.
|
||||||
|
|
||||||
|
Tested-on: QCA6174 hw3.2 PCI WLAN.RM.4.4.1-00110-QCARMSWP-1
|
||||||
|
|
||||||
|
Cc: stable@vger.kernel.org
|
||||||
|
Signed-off-by: Wen Gong <wgong@codeaurora.org>
|
||||||
|
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
|
||||||
|
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||||
|
---
|
||||||
|
|
||||||
|
--- a/net/mac80211/rx.c
|
||||||
|
+++ b/net/mac80211/rx.c
|
||||||
|
@@ -2239,6 +2239,7 @@ ieee80211_rx_h_defragment(struct ieee802
|
||||||
|
unsigned int frag, seq;
|
||||||
|
struct ieee80211_fragment_entry *entry;
|
||||||
|
struct sk_buff *skb;
|
||||||
|
+ struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb);
|
||||||
|
|
||||||
|
hdr = (struct ieee80211_hdr *)rx->skb->data;
|
||||||
|
fc = hdr->frame_control;
|
||||||
|
@@ -2297,7 +2298,9 @@ ieee80211_rx_h_defragment(struct ieee802
|
||||||
|
sizeof(rx->key->u.gcmp.rx_pn[queue]));
|
||||||
|
BUILD_BUG_ON(IEEE80211_CCMP_PN_LEN !=
|
||||||
|
IEEE80211_GCMP_PN_LEN);
|
||||||
|
- } else if (rx->key && ieee80211_has_protected(fc)) {
|
||||||
|
+ } else if (rx->key &&
|
||||||
|
+ (ieee80211_has_protected(fc) ||
|
||||||
|
+ (status->flag & RX_FLAG_DECRYPTED))) {
|
||||||
|
entry->is_protected = true;
|
||||||
|
entry->key_color = rx->key->color;
|
||||||
|
}
|
||||||
|
@@ -2342,13 +2345,19 @@ ieee80211_rx_h_defragment(struct ieee802
|
||||||
|
return RX_DROP_UNUSABLE;
|
||||||
|
memcpy(entry->last_pn, pn, IEEE80211_CCMP_PN_LEN);
|
||||||
|
} else if (entry->is_protected &&
|
||||||
|
- (!rx->key || !ieee80211_has_protected(fc) ||
|
||||||
|
+ (!rx->key ||
|
||||||
|
+ (!ieee80211_has_protected(fc) &&
|
||||||
|
+ !(status->flag & RX_FLAG_DECRYPTED)) ||
|
||||||
|
rx->key->color != entry->key_color)) {
|
||||||
|
/* Drop this as a mixed key or fragment cache attack, even
|
||||||
|
* if for TKIP Michael MIC should protect us, and WEP is a
|
||||||
|
* lost cause anyway.
|
||||||
|
*/
|
||||||
|
return RX_DROP_UNUSABLE;
|
||||||
|
+ } else if (entry->is_protected && rx->key &&
|
||||||
|
+ entry->key_color != rx->key->color &&
|
||||||
|
+ (status->flag & RX_FLAG_DECRYPTED)) {
|
||||||
|
+ return RX_DROP_UNUSABLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
skb_pull(rx->skb, ieee80211_hdrlen(fc));
|
@ -87,7 +87,7 @@
|
|||||||
CFG80211_TESTMODE_CMD(ieee80211_testmode_cmd)
|
CFG80211_TESTMODE_CMD(ieee80211_testmode_cmd)
|
||||||
--- a/net/mac80211/ieee80211_i.h
|
--- a/net/mac80211/ieee80211_i.h
|
||||||
+++ b/net/mac80211/ieee80211_i.h
|
+++ b/net/mac80211/ieee80211_i.h
|
||||||
@@ -1403,6 +1403,7 @@ struct ieee80211_local {
|
@@ -1390,6 +1390,7 @@ struct ieee80211_local {
|
||||||
int dynamic_ps_forced_timeout;
|
int dynamic_ps_forced_timeout;
|
||||||
|
|
||||||
int user_power_level; /* in dBm, for all interfaces */
|
int user_power_level; /* in dBm, for all interfaces */
|
||||||
|
@ -8,9 +8,9 @@ PKG_LICENSE_FILES:=
|
|||||||
|
|
||||||
PKG_SOURCE_URL:=https://github.com/openwrt/mt76
|
PKG_SOURCE_URL:=https://github.com/openwrt/mt76
|
||||||
PKG_SOURCE_PROTO:=git
|
PKG_SOURCE_PROTO:=git
|
||||||
PKG_SOURCE_DATE:=2021-05-10
|
PKG_SOURCE_DATE:=2021-05-13
|
||||||
PKG_SOURCE_VERSION:=ff8bbe22dd87d86b69be7d5619d88fd187ce3017
|
PKG_SOURCE_VERSION:=e969ab10a03403e6c869e91d4d41a71c6340657b
|
||||||
PKG_MIRROR_HASH:=aaaac3f9ec2c7836254f594696179369dd7e42c2ded8fb4ad62fbf5359f8c875
|
PKG_MIRROR_HASH:=eb57d82267d5765c270fc394ad81baacd8d02cde859f813236ad76a89c5ea944
|
||||||
|
|
||||||
PKG_MAINTAINER:=Felix Fietkau <nbd@nbd.name>
|
PKG_MAINTAINER:=Felix Fietkau <nbd@nbd.name>
|
||||||
PKG_BUILD_PARALLEL:=1
|
PKG_BUILD_PARALLEL:=1
|
||||||
|
@ -324,7 +324,7 @@ endif
|
|||||||
|
|
||||||
OPENSSL_TARGET:=linux-$(call qstrip,$(CONFIG_ARCH))-openwrt
|
OPENSSL_TARGET:=linux-$(call qstrip,$(CONFIG_ARCH))-openwrt
|
||||||
|
|
||||||
STAMP_CONFIGURED := $(STAMP_CONFIGURED)_$(shell echo $(OPENSSL_OPTIONS) | mkhash md5)
|
STAMP_CONFIGURED := $(STAMP_CONFIGURED)_$(shell echo $(OPENSSL_OPTIONS) | $(MKHASH) md5)
|
||||||
|
|
||||||
define Build/Configure
|
define Build/Configure
|
||||||
(cd $(PKG_BUILD_DIR); \
|
(cd $(PKG_BUILD_DIR); \
|
||||||
|
@ -37,7 +37,7 @@ PKG_CONFIG_DEPENDS:= \
|
|||||||
include $(INCLUDE_DIR)/package.mk
|
include $(INCLUDE_DIR)/package.mk
|
||||||
|
|
||||||
ifneq ($(DUMP),1)
|
ifneq ($(DUMP),1)
|
||||||
STAMP_CONFIGURED:=$(strip $(STAMP_CONFIGURED))_$(shell echo $(CONFIG_TARGET_INIT_PATH) | mkhash md5)
|
STAMP_CONFIGURED:=$(strip $(STAMP_CONFIGURED))_$(shell echo $(CONFIG_TARGET_INIT_PATH) | $(MKHASH) md5)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
define Package/dropbear/Default
|
define Package/dropbear/Default
|
||||||
|
@ -28,7 +28,7 @@ include $(INCLUDE_DIR)/package.mk
|
|||||||
ifeq ($(DUMP),)
|
ifeq ($(DUMP),)
|
||||||
-include $(LINUX_DIR)/.config
|
-include $(LINUX_DIR)/.config
|
||||||
include $(INCLUDE_DIR)/netfilter.mk
|
include $(INCLUDE_DIR)/netfilter.mk
|
||||||
STAMP_CONFIGURED:=$(strip $(STAMP_CONFIGURED))_$(shell grep 'NETFILTER' $(LINUX_DIR)/.config | mkhash md5)
|
STAMP_CONFIGURED:=$(strip $(STAMP_CONFIGURED))_$(shell grep 'NETFILTER' $(LINUX_DIR)/.config | $(MKHASH) md5)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ include $(INCLUDE_DIR)/package.mk
|
|||||||
include $(INCLUDE_DIR)/cmake.mk
|
include $(INCLUDE_DIR)/cmake.mk
|
||||||
|
|
||||||
ifeq ($(DUMP),)
|
ifeq ($(DUMP),)
|
||||||
STAMP_CONFIGURED:=$(strip $(STAMP_CONFIGURED))_$(shell echo $(CONFIG_TARGET_INIT_PATH) | mkhash md5)
|
STAMP_CONFIGURED:=$(strip $(STAMP_CONFIGURED))_$(shell echo $(CONFIG_TARGET_INIT_PATH) | $(MKHASH) md5)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
CMAKE_OPTIONS += -DEARLY_PATH="$(TARGET_INIT_PATH)"
|
CMAKE_OPTIONS += -DEARLY_PATH="$(TARGET_INIT_PATH)"
|
||||||
|
@ -8,14 +8,14 @@
|
|||||||
include $(TOPDIR)/rules.mk
|
include $(TOPDIR)/rules.mk
|
||||||
|
|
||||||
PKG_NAME:=busybox
|
PKG_NAME:=busybox
|
||||||
PKG_VERSION:=1.33.0
|
PKG_VERSION:=1.33.1
|
||||||
PKG_RELEASE:=3
|
PKG_RELEASE:=1
|
||||||
PKG_FLAGS:=essential
|
PKG_FLAGS:=essential
|
||||||
|
|
||||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
|
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
|
||||||
PKG_SOURCE_URL:=https://www.busybox.net/downloads \
|
PKG_SOURCE_URL:=https://www.busybox.net/downloads \
|
||||||
http://sources.buildroot.net
|
http://sources.buildroot.net
|
||||||
PKG_HASH:=d568681c91a85edc6710770cebc1e80e042ad74d305b5c2e6d57a5f3de3b8fbd
|
PKG_HASH:=12cec6bd2b16d8a9446dd16130f2b92982f1819f6e1c5f5887b6db03f5660d28
|
||||||
|
|
||||||
PKG_BUILD_DEPENDS:=BUSYBOX_CONFIG_PAM:libpam
|
PKG_BUILD_DEPENDS:=BUSYBOX_CONFIG_PAM:libpam
|
||||||
PKG_BUILD_PARALLEL:=1
|
PKG_BUILD_PARALLEL:=1
|
||||||
@ -38,7 +38,7 @@ endif
|
|||||||
include $(INCLUDE_DIR)/package.mk
|
include $(INCLUDE_DIR)/package.mk
|
||||||
|
|
||||||
ifeq ($(DUMP),)
|
ifeq ($(DUMP),)
|
||||||
STAMP_CONFIGURED:=$(strip $(STAMP_CONFIGURED))_$(shell grep '^CONFIG_BUSYBOX_' $(TOPDIR)/.config | mkhash md5)
|
STAMP_CONFIGURED:=$(strip $(STAMP_CONFIGURED))_$(shell grep '^CONFIG_BUSYBOX_' $(TOPDIR)/.config | $(MKHASH) md5)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# All files provided by busybox will serve as fallback alternatives by opkg.
|
# All files provided by busybox will serve as fallback alternatives by opkg.
|
||||||
|
@ -1,40 +0,0 @@
|
|||||||
From 67cc582d4289c5de521d11b08307c8ab26ee1e28 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Denys Vlasenko <vda.linux@googlemail.com>
|
|
||||||
Date: Sun, 3 Jan 2021 10:55:39 +0100
|
|
||||||
Subject: ash: make a strdup copy of $HISTFILE for line editing
|
|
||||||
|
|
||||||
Otherwise if $HISTFILE is unset or reassigned, bad things can happen.
|
|
||||||
|
|
||||||
function old new delta
|
|
||||||
ash_main 1210 1218 +8
|
|
||||||
|
|
||||||
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
|
|
||||||
---
|
|
||||||
shell/ash.c | 4 ++--
|
|
||||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/shell/ash.c b/shell/ash.c
|
|
||||||
index f16d7fb6a..ecbfbf091 100644
|
|
||||||
--- a/shell/ash.c
|
|
||||||
+++ b/shell/ash.c
|
|
||||||
@@ -14499,7 +14499,7 @@ int ash_main(int argc UNUSED_PARAM, char **argv)
|
|
||||||
|
|
||||||
if (sflag || minusc == NULL) {
|
|
||||||
#if MAX_HISTORY > 0 && ENABLE_FEATURE_EDITING_SAVEHISTORY
|
|
||||||
- if (iflag) {
|
|
||||||
+ if (line_input_state) {
|
|
||||||
const char *hp = lookupvar("HISTFILE");
|
|
||||||
if (!hp) {
|
|
||||||
hp = lookupvar("HOME");
|
|
||||||
@@ -14513,7 +14513,7 @@ int ash_main(int argc UNUSED_PARAM, char **argv)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (hp)
|
|
||||||
- line_input_state->hist_file = hp;
|
|
||||||
+ line_input_state->hist_file = xstrdup(hp);
|
|
||||||
# if ENABLE_FEATURE_SH_HISTFILESIZE
|
|
||||||
hp = lookupvar("HISTFILESIZE");
|
|
||||||
line_input_state->max_history = size_from_HISTFILESIZE(hp);
|
|
||||||
--
|
|
||||||
cgit v1.2.1
|
|
||||||
|
|
@ -1,26 +0,0 @@
|
|||||||
From 89358a7131d3e75c74af834bb117b4fad7914983 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Denys Vlasenko <vda.linux@googlemail.com>
|
|
||||||
Date: Tue, 2 Feb 2021 13:48:21 +0100
|
|
||||||
Subject: traceroute: fix option parsing
|
|
||||||
|
|
||||||
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
|
|
||||||
---
|
|
||||||
networking/traceroute.c | 2 +-
|
|
||||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/networking/traceroute.c b/networking/traceroute.c
|
|
||||||
index 3f1a9ab46..29f5e480b 100644
|
|
||||||
--- a/networking/traceroute.c
|
|
||||||
+++ b/networking/traceroute.c
|
|
||||||
@@ -896,7 +896,7 @@ traceroute_init(int op, char **argv)
|
|
||||||
|
|
||||||
op |= getopt32(argv, "^"
|
|
||||||
OPT_STRING
|
|
||||||
- "\0" "-1:x-x" /* minimum 1 arg */
|
|
||||||
+ "\0" "-1" /* minimum 1 arg */
|
|
||||||
, &tos_str, &device, &max_ttl_str, &port_str, &nprobes_str
|
|
||||||
, &source, &waittime_str, &pausemsecs_str, &first_ttl_str
|
|
||||||
);
|
|
||||||
--
|
|
||||||
cgit v1.2.1
|
|
||||||
|
|
@ -1,52 +0,0 @@
|
|||||||
From f25d254dfd4243698c31a4f3153d4ac72aa9e9bd Mon Sep 17 00:00:00 2001
|
|
||||||
From: Samuel Sapalski <samuel.sapalski@nokia.com>
|
|
||||||
Date: Wed, 3 Mar 2021 16:31:22 +0100
|
|
||||||
Subject: decompress_gunzip: Fix DoS if gzip is corrupt
|
|
||||||
|
|
||||||
On certain corrupt gzip files, huft_build will set the error bit on
|
|
||||||
the result pointer. If afterwards abort_unzip is called huft_free
|
|
||||||
might run into a segmentation fault or an invalid pointer to
|
|
||||||
free(p).
|
|
||||||
|
|
||||||
In order to mitigate this, we check in huft_free if the error bit
|
|
||||||
is set and clear it before the linked list is freed.
|
|
||||||
|
|
||||||
Signed-off-by: Samuel Sapalski <samuel.sapalski@nokia.com>
|
|
||||||
Signed-off-by: Peter Kaestle <peter.kaestle@nokia.com>
|
|
||||||
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
|
|
||||||
---
|
|
||||||
archival/libarchive/decompress_gunzip.c | 12 ++++++++++--
|
|
||||||
1 file changed, 10 insertions(+), 2 deletions(-)
|
|
||||||
|
|
||||||
--- a/archival/libarchive/decompress_gunzip.c
|
|
||||||
+++ b/archival/libarchive/decompress_gunzip.c
|
|
||||||
@@ -220,10 +220,20 @@ static const uint8_t border[] ALIGN1 = {
|
|
||||||
* each table.
|
|
||||||
* t: table to free
|
|
||||||
*/
|
|
||||||
+#define BAD_HUFT(p) ((uintptr_t)(p) & 1)
|
|
||||||
+#define ERR_RET ((huft_t*)(uintptr_t)1)
|
|
||||||
static void huft_free(huft_t *p)
|
|
||||||
{
|
|
||||||
huft_t *q;
|
|
||||||
|
|
||||||
+ /*
|
|
||||||
+ * If 'p' has the error bit set we have to clear it, otherwise we might run
|
|
||||||
+ * into a segmentation fault or an invalid pointer to free(p)
|
|
||||||
+ */
|
|
||||||
+ if (BAD_HUFT(p)) {
|
|
||||||
+ p = (huft_t*)((uintptr_t)(p) ^ (uintptr_t)(ERR_RET));
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
/* Go through linked list, freeing from the malloced (t[-1]) address. */
|
|
||||||
while (p) {
|
|
||||||
q = (--p)->v.t;
|
|
||||||
@@ -289,8 +299,6 @@ static unsigned fill_bitbuffer(STATE_PAR
|
|
||||||
* or a valid pointer to a Huffman table, ORed with 0x1 if incompete table
|
|
||||||
* is given: "fixed inflate" decoder feeds us such data.
|
|
||||||
*/
|
|
||||||
-#define BAD_HUFT(p) ((uintptr_t)(p) & 1)
|
|
||||||
-#define ERR_RET ((huft_t*)(uintptr_t)1)
|
|
||||||
static huft_t* huft_build(const unsigned *b, const unsigned n,
|
|
||||||
const unsigned s, const struct cp_ext *cp_ext,
|
|
||||||
unsigned *m)
|
|
@ -1,11 +0,0 @@
|
|||||||
--- a/libbb/update_passwd.c
|
|
||||||
+++ b/libbb/update_passwd.c
|
|
||||||
@@ -48,7 +48,7 @@ static void check_selinux_update_passwd(
|
|
||||||
bb_simple_error_msg_and_die("SELinux: access denied");
|
|
||||||
}
|
|
||||||
if (ENABLE_FEATURE_CLEAN_UP)
|
|
||||||
- freecon(context);
|
|
||||||
+ freecon(seuser);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
# define check_selinux_update_passwd(username) ((void)0)
|
|
@ -34,7 +34,7 @@ Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|||||||
# However, on *other platforms* it fails when some of those flags
|
# However, on *other platforms* it fails when some of those flags
|
||||||
--- /dev/null
|
--- /dev/null
|
||||||
+++ b/networking/nslookup_lede.c
|
+++ b/networking/nslookup_lede.c
|
||||||
@@ -0,0 +1,914 @@
|
@@ -0,0 +1,934 @@
|
||||||
+/*
|
+/*
|
||||||
+ * nslookup_lede - musl compatible replacement for busybox nslookup
|
+ * nslookup_lede - musl compatible replacement for busybox nslookup
|
||||||
+ *
|
+ *
|
||||||
@ -128,6 +128,7 @@ Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|||||||
+ { ns_t_cname, "CNAME" },
|
+ { ns_t_cname, "CNAME" },
|
||||||
+ { ns_t_mx, "MX" },
|
+ { ns_t_mx, "MX" },
|
||||||
+ { ns_t_txt, "TXT" },
|
+ { ns_t_txt, "TXT" },
|
||||||
|
+ { ns_t_srv, "SRV" },
|
||||||
+ { ns_t_ptr, "PTR" },
|
+ { ns_t_ptr, "PTR" },
|
||||||
+ { ns_t_any, "ANY" },
|
+ { ns_t_any, "ANY" },
|
||||||
+ { }
|
+ { }
|
||||||
@ -259,6 +260,25 @@ Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|||||||
+ }
|
+ }
|
||||||
+ break;
|
+ break;
|
||||||
+
|
+
|
||||||
|
+ case ns_t_srv:
|
||||||
|
+ if (rdlen < 6) {
|
||||||
|
+ //printf("SRV record too short\n");
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ cp = ns_rr_rdata(rr);
|
||||||
|
+ n = ns_name_uncompress(ns_msg_base(handle), ns_msg_end(handle),
|
||||||
|
+ cp + 6, dname, sizeof(dname));
|
||||||
|
+
|
||||||
|
+ if (n < 0) {
|
||||||
|
+ //printf("Unable to uncompress domain: %s\n", strerror(errno));
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ printf("%s\tservice = %hu %hu %hu %s\n", ns_rr_name(rr),
|
||||||
|
+ ns_get16(cp), ns_get16(cp + 2), ns_get16(cp + 4), dname);
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
+ case ns_t_soa:
|
+ case ns_t_soa:
|
||||||
+ if (rdlen < 20) {
|
+ if (rdlen < 20) {
|
||||||
+ //fprintf(stderr, "SOA record too short\n");
|
+ //fprintf(stderr, "SOA record too short\n");
|
||||||
|
7
rules.mk
7
rules.mk
@ -27,7 +27,7 @@ empty:=
|
|||||||
space:= $(empty) $(empty)
|
space:= $(empty) $(empty)
|
||||||
comma:=,
|
comma:=,
|
||||||
merge=$(subst $(space),,$(1))
|
merge=$(subst $(space),,$(1))
|
||||||
confvar=$(shell echo '$(foreach v,$(1),$(v)=$(subst ','\'',$($(v))))' | $(STAGING_DIR_HOST)/bin/mkhash md5)
|
confvar=$(shell echo '$(foreach v,$(1),$(v)=$(subst ','\'',$($(v))))' | $(MKHASH) md5)
|
||||||
strip_last=$(patsubst %.$(lastword $(subst .,$(space),$(1))),%,$(1))
|
strip_last=$(patsubst %.$(lastword $(subst .,$(space),$(1))),%,$(1))
|
||||||
|
|
||||||
paren_left = (
|
paren_left = (
|
||||||
@ -266,6 +266,9 @@ TARGET_CXX:=$(TARGET_CROSS)g++
|
|||||||
KPATCH:=$(SCRIPT_DIR)/patch-kernel.sh
|
KPATCH:=$(SCRIPT_DIR)/patch-kernel.sh
|
||||||
SED:=$(STAGING_DIR_HOST)/bin/sed -i -e
|
SED:=$(STAGING_DIR_HOST)/bin/sed -i -e
|
||||||
ESED:=$(STAGING_DIR_HOST)/bin/sed -E -i -e
|
ESED:=$(STAGING_DIR_HOST)/bin/sed -E -i -e
|
||||||
|
MKHASH:=$(STAGING_DIR_HOST)/bin/mkhash
|
||||||
|
# MKHASH is used in /scripts, so we export it here.
|
||||||
|
export MKHASH
|
||||||
CP:=cp -fpR
|
CP:=cp -fpR
|
||||||
LN:=ln -sf
|
LN:=ln -sf
|
||||||
XARGS:=xargs -r
|
XARGS:=xargs -r
|
||||||
@ -399,7 +402,7 @@ endef
|
|||||||
# $(2) => If set, recurse into subdirectories
|
# $(2) => If set, recurse into subdirectories
|
||||||
define sha256sums
|
define sha256sums
|
||||||
(cd $(1); find . $(if $(2),,-maxdepth 1) -type f -not -name 'sha256sums' -printf "%P\n" | sort | \
|
(cd $(1); find . $(if $(2),,-maxdepth 1) -type f -not -name 'sha256sums' -printf "%P\n" | sort | \
|
||||||
xargs -r $(STAGING_DIR_HOST)/bin/mkhash -n sha256 | sed -ne 's!^\(.*\) \(.*\)$$!\1 *\2!p' > sha256sums)
|
xargs -r $(MKHASH) -n sha256 | sed -ne 's!^\(.*\) \(.*\)$$!\1 *\2!p' > sha256sums)
|
||||||
endef
|
endef
|
||||||
|
|
||||||
# file extension
|
# file extension
|
||||||
|
@ -63,7 +63,7 @@ while [ "$#" -gt 1 ]
|
|||||||
|
|
||||||
[ ! -f "$file" ] && echo "$ME: Not a valid file: $file" && usage
|
[ ! -f "$file" ] && echo "$ME: Not a valid file: $file" && usage
|
||||||
FILES="$FILES $file"
|
FILES="$FILES $file"
|
||||||
md5=$(mkhash md5 "$file")
|
md5=$($MKHASH md5 "$file")
|
||||||
printf "%-32s%08x%32s" "$filename" $(stat -c "%s" "$file") "${md5%% *}" >> "${IMG_TMP_OUT}"
|
printf "%-32s%08x%32s" "$filename" $(stat -c "%s" "$file") "${md5%% *}" >> "${IMG_TMP_OUT}"
|
||||||
shift 2
|
shift 2
|
||||||
done
|
done
|
||||||
|
@ -16,7 +16,7 @@ dd if="$1" of="$kern" bs=$BLKSZ conv=sync 2>/dev/null
|
|||||||
dd if="$2" of="$root" bs=$BLKSZ conv=sync 2>/dev/null
|
dd if="$2" of="$root" bs=$BLKSZ conv=sync 2>/dev/null
|
||||||
|
|
||||||
# Calculate md5sum over combined kernel and rootfs image.
|
# Calculate md5sum over combined kernel and rootfs image.
|
||||||
md5=$(cat "$kern" "$root" | mkhash md5)
|
md5=$(cat "$kern" "$root" | $MKHASH md5)
|
||||||
|
|
||||||
# Write image header followed by kernel and rootfs image.
|
# Write image header followed by kernel and rootfs image.
|
||||||
# The header is padded to 64k, format is:
|
# The header is padded to 64k, format is:
|
||||||
|
@ -65,8 +65,8 @@ sub hash_cmd() {
|
|||||||
my $len = length($file_hash);
|
my $len = length($file_hash);
|
||||||
my $cmd;
|
my $cmd;
|
||||||
|
|
||||||
$len == 64 and return "mkhash sha256";
|
$len == 64 and return "$ENV{'MKHASH'} sha256";
|
||||||
$len == 32 and return "mkhash md5";
|
$len == 32 and return "$ENV{'MKHASH'} md5";
|
||||||
return undef;
|
return undef;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -316,4 +316,3 @@ while (!-f "$target/$filename") {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$SIG{INT} = \&cleanup;
|
$SIG{INT} = \&cleanup;
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ for pkg in `find $pkg_dir -name '*.ipk' | sort`; do
|
|||||||
[[ "$name" = "libc" ]] && continue
|
[[ "$name" = "libc" ]] && continue
|
||||||
echo "Generating index for package $pkg" >&2
|
echo "Generating index for package $pkg" >&2
|
||||||
file_size=$(stat -L -c%s $pkg)
|
file_size=$(stat -L -c%s $pkg)
|
||||||
sha256sum=$(mkhash sha256 $pkg)
|
sha256sum=$($MKHASH sha256 $pkg)
|
||||||
# Take pains to make variable value sed-safe
|
# Take pains to make variable value sed-safe
|
||||||
sed_safe_pkg=`echo $pkg | sed -e 's/^\.\///g' -e 's/\\//\\\\\\//g'`
|
sed_safe_pkg=`echo $pkg | sed -e 's/^\.\///g' -e 's/\\//\\\\\\//g'`
|
||||||
tar -xzOf $pkg ./control.tar.gz | tar xzOf - ./control | sed -e "s/^Description:/Filename: $sed_safe_pkg\\
|
tar -xzOf $pkg ./control.tar.gz | tar xzOf - ./control | sed -e "s/^Description:/Filename: $sed_safe_pkg\\
|
||||||
|
@ -54,8 +54,8 @@ esac
|
|||||||
CHECK_BS=65536
|
CHECK_BS=65536
|
||||||
|
|
||||||
KERNEL_SIZE=$(stat -c%s "$KERNEL_PATH")
|
KERNEL_SIZE=$(stat -c%s "$KERNEL_PATH")
|
||||||
KERNEL_MD5=$(mkhash md5 $KERNEL_PATH)
|
KERNEL_MD5=$($MKHASH md5 $KERNEL_PATH)
|
||||||
KERNEL_SHA256=$(mkhash sha256 $KERNEL_PATH)
|
KERNEL_SHA256=$($MKHASH sha256 $KERNEL_PATH)
|
||||||
KERNEL_PART_SIZE_KB=$((KERNEL_SIZE / 1024))
|
KERNEL_PART_SIZE_KB=$((KERNEL_SIZE / 1024))
|
||||||
KERNEL_PART_SIZE=$(printf $SIZE_FORMAT $(($KERNEL_PART_SIZE_KB * $SIZE_FACTOR)))
|
KERNEL_PART_SIZE=$(printf $SIZE_FORMAT $(($KERNEL_PART_SIZE_KB * $SIZE_FACTOR)))
|
||||||
|
|
||||||
@ -63,9 +63,9 @@ ROOTFS_FLASH_ADDR=$(addr=$(($KERNEL_FLASH_ADDR + ($KERNEL_PART_SIZE_KB * 1024)))
|
|||||||
ROOTFS_SIZE=$(stat -c%s "$ROOTFS_PATH")
|
ROOTFS_SIZE=$(stat -c%s "$ROOTFS_PATH")
|
||||||
ROOTFS_SQUASHFS_SIZE=$((ROOTFS_SIZE-4))
|
ROOTFS_SQUASHFS_SIZE=$((ROOTFS_SIZE-4))
|
||||||
ROOTFS_CHECK_BLOCKS=$((ROOTFS_SQUASHFS_SIZE / CHECK_BS))
|
ROOTFS_CHECK_BLOCKS=$((ROOTFS_SQUASHFS_SIZE / CHECK_BS))
|
||||||
ROOTFS_MD5=$(dd if=$ROOTFS_PATH bs=$CHECK_BS count=$ROOTFS_CHECK_BLOCKS 2>&- | mkhash md5)
|
ROOTFS_MD5=$(dd if=$ROOTFS_PATH bs=$CHECK_BS count=$ROOTFS_CHECK_BLOCKS 2>&- | $MKHASH md5)
|
||||||
ROOTFS_MD5_FULL=$(mkhash md5 $ROOTFS_PATH)
|
ROOTFS_MD5_FULL=$($MKHASH md5 $ROOTFS_PATH)
|
||||||
ROOTFS_SHA256_FULL=$(mkhash sha256 $ROOTFS_PATH)
|
ROOTFS_SHA256_FULL=$($MKHASH sha256 $ROOTFS_PATH)
|
||||||
ROOTFS_CHECK_SIZE=$(printf '0x%x' $ROOTFS_SQUASHFS_SIZE)
|
ROOTFS_CHECK_SIZE=$(printf '0x%x' $ROOTFS_SQUASHFS_SIZE)
|
||||||
ROOTFS_PART_SIZE_KB=$(($MAX_PART_SIZE - $KERNEL_PART_SIZE_KB))
|
ROOTFS_PART_SIZE_KB=$(($MAX_PART_SIZE - $KERNEL_PART_SIZE_KB))
|
||||||
ROOTFS_PART_SIZE=$(printf $SIZE_FORMAT $(($ROOTFS_PART_SIZE_KB * $SIZE_FACTOR)))
|
ROOTFS_PART_SIZE=$(printf $SIZE_FORMAT $(($ROOTFS_PART_SIZE_KB * $SIZE_FACTOR)))
|
||||||
|
@ -35,7 +35,7 @@ define Build/addpattern
|
|||||||
endef
|
endef
|
||||||
|
|
||||||
define Build/append-md5sum-bin
|
define Build/append-md5sum-bin
|
||||||
$(STAGING_DIR_HOST)/bin/mkhash md5 $@ | sed 's/../\\\\x&/g' |\
|
$(MKHASH) md5 $@ | sed 's/../\\\\x&/g' |\
|
||||||
xargs echo -ne >> $@
|
xargs echo -ne >> $@
|
||||||
endef
|
endef
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ Signed-off-by: David Bauer <mail@david-bauer.net>
|
|||||||
|
|
||||||
--- a/drivers/mtd/mtdpart.c
|
--- a/drivers/mtd/mtdpart.c
|
||||||
+++ b/drivers/mtd/mtdpart.c
|
+++ b/drivers/mtd/mtdpart.c
|
||||||
@@ -474,7 +474,7 @@ static int __del_mtd_partitions(struct m
|
@@ -331,7 +331,7 @@ static int __del_mtd_partitions(struct m
|
||||||
|
|
||||||
list_for_each_entry_safe(child, next, &mtd->partitions, part.node) {
|
list_for_each_entry_safe(child, next, &mtd->partitions, part.node) {
|
||||||
if (mtd_has_partitions(child))
|
if (mtd_has_partitions(child))
|
@ -697,10 +697,13 @@ int __init rb_hardconfig_init(struct kobject *rb_kobj)
|
|||||||
|
|
||||||
hc_buflen = mtd->size;
|
hc_buflen = mtd->size;
|
||||||
hc_buf = kmalloc(hc_buflen, GFP_KERNEL);
|
hc_buf = kmalloc(hc_buflen, GFP_KERNEL);
|
||||||
if (!hc_buf)
|
if (!hc_buf) {
|
||||||
|
put_mtd_device(mtd);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
ret = mtd_read(mtd, 0, hc_buflen, &bytes_read, hc_buf);
|
ret = mtd_read(mtd, 0, hc_buflen, &bytes_read, hc_buf);
|
||||||
|
put_mtd_device(mtd);
|
||||||
|
|
||||||
if (ret)
|
if (ret)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
@ -686,6 +686,8 @@ static ssize_t sc_commit_store(struct kobject *kobj, struct kobj_attribute *attr
|
|||||||
}
|
}
|
||||||
write_unlock(&sc_bufrwl);
|
write_unlock(&sc_bufrwl);
|
||||||
|
|
||||||
|
put_mtd_device(mtd);
|
||||||
|
|
||||||
if (ret)
|
if (ret)
|
||||||
goto mtdfail;
|
goto mtdfail;
|
||||||
|
|
||||||
@ -721,10 +723,13 @@ int __init rb_softconfig_init(struct kobject *rb_kobj)
|
|||||||
|
|
||||||
sc_buflen = mtd->size;
|
sc_buflen = mtd->size;
|
||||||
sc_buf = kmalloc(sc_buflen, GFP_KERNEL);
|
sc_buf = kmalloc(sc_buflen, GFP_KERNEL);
|
||||||
if (!sc_buf)
|
if (!sc_buf) {
|
||||||
|
put_mtd_device(mtd);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
ret = mtd_read(mtd, 0, sc_buflen, &bytes_read, sc_buf);
|
ret = mtd_read(mtd, 0, sc_buflen, &bytes_read, sc_buf);
|
||||||
|
put_mtd_device(mtd);
|
||||||
|
|
||||||
if (ret)
|
if (ret)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
@ -2,15 +2,12 @@
|
|||||||
|
|
||||||
START=99
|
START=99
|
||||||
|
|
||||||
. /lib/upgrade/asrock.sh
|
. "$IPKG_INSTROOT/lib/upgrade/asrock.sh"
|
||||||
|
|
||||||
boot() {
|
boot() {
|
||||||
case $(board_name) in
|
case $(board_name) in
|
||||||
asrock,g10)
|
asrock,g10)
|
||||||
asrock_bootconfig_mangle "bootcheck"
|
asrock_bootconfig_mangle "bootcheck" && reboot
|
||||||
if [ $? -eq 0 ]; then
|
|
||||||
reboot
|
|
||||||
fi
|
|
||||||
;;
|
;;
|
||||||
edgecore,ecw5410)
|
edgecore,ecw5410)
|
||||||
fw_setenv bootcount 0
|
fw_setenv bootcount 0
|
||||||
|
@ -91,7 +91,7 @@ endef
|
|||||||
|
|
||||||
define Build/netis-tail
|
define Build/netis-tail
|
||||||
echo -n $(1) >> $@
|
echo -n $(1) >> $@
|
||||||
echo -n $(UIMAGE_NAME)-yun | $(STAGING_DIR_HOST)/bin/mkhash md5 | \
|
echo -n $(UIMAGE_NAME)-yun | $(MKHASH) md5 | \
|
||||||
sed 's/../\\\\x&/g' | xargs echo -ne >> $@
|
sed 's/../\\\\x&/g' | xargs echo -ne >> $@
|
||||||
endef
|
endef
|
||||||
|
|
||||||
|
@ -9,9 +9,9 @@ DEVICE_VARS += DLINK_ROM_ID DLINK_FAMILY_MEMBER DLINK_FIRMWARE_SIZE DLINK_IMAGE_
|
|||||||
define Build/elecom-header
|
define Build/elecom-header
|
||||||
cp $@ $(KDIR)/v_0.0.0.bin
|
cp $@ $(KDIR)/v_0.0.0.bin
|
||||||
( \
|
( \
|
||||||
mkhash md5 $(KDIR)/v_0.0.0.bin && \
|
$(MKHASH) md5 $(KDIR)/v_0.0.0.bin && \
|
||||||
echo 458 \
|
echo 458 \
|
||||||
) | mkhash md5 > $(KDIR)/v_0.0.0.md5
|
) | $(MKHASH) md5 > $(KDIR)/v_0.0.0.md5
|
||||||
$(STAGING_DIR_HOST)/bin/tar -c \
|
$(STAGING_DIR_HOST)/bin/tar -c \
|
||||||
$(if $(SOURCE_DATE_EPOCH),--mtime=@$(SOURCE_DATE_EPOCH)) \
|
$(if $(SOURCE_DATE_EPOCH),--mtime=@$(SOURCE_DATE_EPOCH)) \
|
||||||
--owner=0 --group=0 -f $@ -C $(KDIR) v_0.0.0.bin v_0.0.0.md5
|
--owner=0 --group=0 -f $@ -C $(KDIR) v_0.0.0.bin v_0.0.0.md5
|
||||||
|
@ -13,7 +13,7 @@ define Build/elecom-wrc-gs-factory
|
|||||||
$(eval product=$(word 1,$(1)))
|
$(eval product=$(word 1,$(1)))
|
||||||
$(eval version=$(word 2,$(1)))
|
$(eval version=$(word 2,$(1)))
|
||||||
$(eval hash_opt=$(word 3,$(1)))
|
$(eval hash_opt=$(word 3,$(1)))
|
||||||
$(STAGING_DIR_HOST)/bin/mkhash md5 $(hash_opt) $@ >> $@
|
$(MKHASH) md5 $(hash_opt) $@ >> $@
|
||||||
( \
|
( \
|
||||||
echo -n "ELECOM $(product) v$(version)" | \
|
echo -n "ELECOM $(product) v$(version)" | \
|
||||||
dd bs=32 count=1 conv=sync; \
|
dd bs=32 count=1 conv=sync; \
|
||||||
@ -61,13 +61,13 @@ define Build/ubnt-erx-factory-image
|
|||||||
$(TAR) -cf $(1) --transform='s/^.*/compat/' $(1).compat; \
|
$(TAR) -cf $(1) --transform='s/^.*/compat/' $(1).compat; \
|
||||||
\
|
\
|
||||||
$(TAR) -rf $(1) --transform='s/^.*/vmlinux.tmp/' $(KDIR)/tmp/$(KERNEL_INITRAMFS_IMAGE); \
|
$(TAR) -rf $(1) --transform='s/^.*/vmlinux.tmp/' $(KDIR)/tmp/$(KERNEL_INITRAMFS_IMAGE); \
|
||||||
mkhash md5 $(KDIR)/tmp/$(KERNEL_INITRAMFS_IMAGE) > $(1).md5; \
|
$(MKHASH) md5 $(KDIR)/tmp/$(KERNEL_INITRAMFS_IMAGE) > $(1).md5; \
|
||||||
$(TAR) -rf $(1) --transform='s/^.*/vmlinux.tmp.md5/' $(1).md5; \
|
$(TAR) -rf $(1) --transform='s/^.*/vmlinux.tmp.md5/' $(1).md5; \
|
||||||
\
|
\
|
||||||
echo "dummy" > $(1).rootfs; \
|
echo "dummy" > $(1).rootfs; \
|
||||||
$(TAR) -rf $(1) --transform='s/^.*/squashfs.tmp/' $(1).rootfs; \
|
$(TAR) -rf $(1) --transform='s/^.*/squashfs.tmp/' $(1).rootfs; \
|
||||||
\
|
\
|
||||||
mkhash md5 $(1).rootfs > $(1).md5; \
|
$(MKHASH) md5 $(1).rootfs > $(1).md5; \
|
||||||
$(TAR) -rf $(1) --transform='s/^.*/squashfs.tmp.md5/' $(1).md5; \
|
$(TAR) -rf $(1) --transform='s/^.*/squashfs.tmp.md5/' $(1).md5; \
|
||||||
\
|
\
|
||||||
echo '$(BOARD) $(VERSION_CODE) $(VERSION_NUMBER)' > $(1).version; \
|
echo '$(BOARD) $(VERSION_CODE) $(VERSION_NUMBER)' > $(1).version; \
|
||||||
|
Loading…
x
Reference in New Issue
Block a user