diff --git a/8139cp-set-ring-address-after-enabling-C-mode.patch b/8139cp-set-ring-address-after-enabling-C-mode.patch deleted file mode 100644 index 33bd340..0000000 --- a/8139cp-set-ring-address-after-enabling-C-mode.patch +++ /dev/null @@ -1,100 +0,0 @@ -From a9dbe40fc10cea2efe6e1ff9e03c62dd7579c5ba Mon Sep 17 00:00:00 2001 -From: David Woodhouse -Date: Wed, 21 Nov 2012 10:27:19 +0000 -Subject: [PATCH] 8139cp: set ring address after enabling C+ mode - -This fixes (for me) a regression introduced by commit b01af457 ("8139cp: -set ring address before enabling receiver"). That commit configured the -descriptor ring addresses earlier in the initialisation sequence, in -order to avoid the possibility of triggering stray DMA before the -correct address had been set up. - -Unfortunately, it seems that the hardware will scribble garbage into the -TxRingAddr registers when we enable "plus mode" Tx in the CpCmd -register. Observed on a Traverse Geos router board. - -To deal with this, while not reintroducing the problem which led to the -original commit, we augment cp_start_hw() to write to the CpCmd register -*first*, then set the descriptor ring addresses, and then finally to -enable Rx and Tx in the original 8139 Cmd register. The datasheet -actually indicates that we should enable Tx/Rx in the Cmd register -*before* configuring the descriptor addresses, but that would appear to -re-introduce the problem that the offending commit b01af457 was trying -to solve. And this variant appears to work fine on real hardware. - -Signed-off-by: David Woodhouse -Cc: stable@kernel.org [3.5+] -Signed-off-by: David S. Miller ---- - drivers/net/ethernet/realtek/8139cp.c | 40 +++++++++++++++++++++++---------- - 1 files changed, 28 insertions(+), 12 deletions(-) - -diff --git a/drivers/net/ethernet/realtek/8139cp.c b/drivers/net/ethernet/realtek/8139cp.c -index 1c81825..5166d94 100644 ---- a/drivers/net/ethernet/realtek/8139cp.c -+++ b/drivers/net/ethernet/realtek/8139cp.c -@@ -957,7 +957,35 @@ static void cp_reset_hw (struct cp_private *cp) - - static inline void cp_start_hw (struct cp_private *cp) - { -+ dma_addr_t ring_dma; -+ - cpw16(CpCmd, cp->cpcmd); -+ -+ /* -+ * These (at least TxRingAddr) need to be configured after the -+ * corresponding bits in CpCmd are enabled. Datasheet v1.6 §6.33 -+ * (C+ Command Register) recommends that these and more be configured -+ * *after* the [RT]xEnable bits in CpCmd are set. And on some hardware -+ * it's been observed that the TxRingAddr is actually reset to garbage -+ * when C+ mode Tx is enabled in CpCmd. -+ */ -+ cpw32_f(HiTxRingAddr, 0); -+ cpw32_f(HiTxRingAddr + 4, 0); -+ -+ ring_dma = cp->ring_dma; -+ cpw32_f(RxRingAddr, ring_dma & 0xffffffff); -+ cpw32_f(RxRingAddr + 4, (ring_dma >> 16) >> 16); -+ -+ ring_dma += sizeof(struct cp_desc) * CP_RX_RING_SIZE; -+ cpw32_f(TxRingAddr, ring_dma & 0xffffffff); -+ cpw32_f(TxRingAddr + 4, (ring_dma >> 16) >> 16); -+ -+ /* -+ * Strictly speaking, the datasheet says this should be enabled -+ * *before* setting the descriptor addresses. But what, then, would -+ * prevent it from doing DMA to random unconfigured addresses? -+ * This variant appears to work fine. -+ */ - cpw8(Cmd, RxOn | TxOn); - } - -@@ -969,7 +997,6 @@ static void cp_enable_irq(struct cp_private *cp) - static void cp_init_hw (struct cp_private *cp) - { - struct net_device *dev = cp->dev; -- dma_addr_t ring_dma; - - cp_reset_hw(cp); - -@@ -979,17 +1006,6 @@ static void cp_init_hw (struct cp_private *cp) - cpw32_f (MAC0 + 0, le32_to_cpu (*(__le32 *) (dev->dev_addr + 0))); - cpw32_f (MAC0 + 4, le32_to_cpu (*(__le32 *) (dev->dev_addr + 4))); - -- cpw32_f(HiTxRingAddr, 0); -- cpw32_f(HiTxRingAddr + 4, 0); -- -- ring_dma = cp->ring_dma; -- cpw32_f(RxRingAddr, ring_dma & 0xffffffff); -- cpw32_f(RxRingAddr + 4, (ring_dma >> 16) >> 16); -- -- ring_dma += sizeof(struct cp_desc) * CP_RX_RING_SIZE; -- cpw32_f(TxRingAddr, ring_dma & 0xffffffff); -- cpw32_f(TxRingAddr + 4, (ring_dma >> 16) >> 16); -- - cp_start_hw(cp); - cpw8(TxThresh, 0x06); /* XXX convert magic num to a constant */ - --- -1.7.6.5 - diff --git a/Bluetooth-Add-support-for-BCM20702A0.patch b/Bluetooth-Add-support-for-BCM20702A0.patch deleted file mode 100644 index 99178d7..0000000 --- a/Bluetooth-Add-support-for-BCM20702A0.patch +++ /dev/null @@ -1,43 +0,0 @@ -From a5f86c3423428c8e28b6501d0e9c3929ca91f07d Mon Sep 17 00:00:00 2001 -From: Jeff Cook -Date: Fri, 9 Nov 2012 16:39:48 -0700 -Subject: [PATCH 2/2] Bluetooth: Add support for BCM20702A0 [0b05, 17b5] - -Vendor-specific ID for BCM20702A0. -Support for bluetooth over Asus Wi-Fi GO!, included with Asus P8Z77-V -Deluxe. - -T: Bus=07 Lev=02 Prnt=02 Port=00 Cnt=01 Dev#= 3 Spd=12 MxCh= 0 -D: Ver= 2.00 Cls=ff(vend.) Sub=01 Prot=01 MxPS=64 #Cfgs= 1 -P: Vendor=0b05 ProdID=17b5 Rev=01.12 -S: Manufacturer=Broadcom Corp -S: Product=BCM20702A0 -S: SerialNumber=94DBC98AC113 -C: #Ifs= 4 Cfg#= 1 Atr=e0 MxPwr=0mA -I: If#= 0 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=01 Prot=01 Driver=(none) -I: If#= 1 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=01 Prot=01 Driver=(none) -I: If#= 2 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=(none) -I: If#= 3 Alt= 0 #EPs= 0 Cls=fe(app. ) Sub=01 Prot=01 Driver=(none) - -Cc: stable@vger.kernel.org -Signed-off-by: Jeff Cook -Signed-off-by: Gustavo Padovan ---- - drivers/bluetooth/btusb.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c -index b167944..6dc44ff 100644 ---- a/drivers/bluetooth/btusb.c -+++ b/drivers/bluetooth/btusb.c -@@ -96,6 +96,7 @@ static struct usb_device_id btusb_table[] = { - { USB_DEVICE(0x0c10, 0x0000) }, - - /* Broadcom BCM20702A0 */ -+ { USB_DEVICE(0x0b05, 0x17b5) }, - { USB_DEVICE(0x04ca, 0x2003) }, - { USB_DEVICE(0x0489, 0xe042) }, - { USB_DEVICE(0x413c, 0x8197) }, --- -1.8.0 - diff --git a/Revert-8139cp-revert-set-ring-address-before-enabling.patch b/Revert-8139cp-revert-set-ring-address-before-enabling.patch deleted file mode 100644 index 6ed20c4..0000000 --- a/Revert-8139cp-revert-set-ring-address-before-enabling.patch +++ /dev/null @@ -1,59 +0,0 @@ -From 071e3ef4a94a021b16a2912f3885c86f4ff36b49 Mon Sep 17 00:00:00 2001 -From: "David S. Miller" -Date: Sun, 25 Nov 2012 15:52:09 -0500 -Subject: [PATCH] Revert "8139cp: revert "set ring address before enabling - receiver"" - -This reverts commit b26623dab7eeb1e9f5898c7a49458789dd492f20. - -This reverts the revert, in net-next we'll try another scheme -to fix this bug using patches from David Woodhouse. - -Signed-off-by: David S. Miller ---- - drivers/net/ethernet/realtek/8139cp.c | 22 +++++++++++----------- - 1 files changed, 11 insertions(+), 11 deletions(-) - -diff --git a/drivers/net/ethernet/realtek/8139cp.c b/drivers/net/ethernet/realtek/8139cp.c -index b01f83a..1c81825 100644 ---- a/drivers/net/ethernet/realtek/8139cp.c -+++ b/drivers/net/ethernet/realtek/8139cp.c -@@ -979,6 +979,17 @@ static void cp_init_hw (struct cp_private *cp) - cpw32_f (MAC0 + 0, le32_to_cpu (*(__le32 *) (dev->dev_addr + 0))); - cpw32_f (MAC0 + 4, le32_to_cpu (*(__le32 *) (dev->dev_addr + 4))); - -+ cpw32_f(HiTxRingAddr, 0); -+ cpw32_f(HiTxRingAddr + 4, 0); -+ -+ ring_dma = cp->ring_dma; -+ cpw32_f(RxRingAddr, ring_dma & 0xffffffff); -+ cpw32_f(RxRingAddr + 4, (ring_dma >> 16) >> 16); -+ -+ ring_dma += sizeof(struct cp_desc) * CP_RX_RING_SIZE; -+ cpw32_f(TxRingAddr, ring_dma & 0xffffffff); -+ cpw32_f(TxRingAddr + 4, (ring_dma >> 16) >> 16); -+ - cp_start_hw(cp); - cpw8(TxThresh, 0x06); /* XXX convert magic num to a constant */ - -@@ -992,17 +1003,6 @@ static void cp_init_hw (struct cp_private *cp) - - cpw8(Config5, cpr8(Config5) & PMEStatus); - -- cpw32_f(HiTxRingAddr, 0); -- cpw32_f(HiTxRingAddr + 4, 0); -- -- ring_dma = cp->ring_dma; -- cpw32_f(RxRingAddr, ring_dma & 0xffffffff); -- cpw32_f(RxRingAddr + 4, (ring_dma >> 16) >> 16); -- -- ring_dma += sizeof(struct cp_desc) * CP_RX_RING_SIZE; -- cpw32_f(TxRingAddr, ring_dma & 0xffffffff); -- cpw32_f(TxRingAddr + 4, (ring_dma >> 16) >> 16); -- - cpw16(MultiIntr, 0); - - cpw8_f(Cfg9346, Cfg9346_Lock); --- -1.7.6.5 - diff --git a/config-arm-generic b/config-arm-generic index 89fc435..9e97725 100644 --- a/config-arm-generic +++ b/config-arm-generic @@ -63,6 +63,7 @@ CONFIG_SCHED_SMT=y CONFIG_RCU_FANOUT=32 CONFIG_CPU_IDLE=y +# CONFIG_CPU_IDLE_MULTIPLE_DRIVERS is not set # CONFIG_CPU_IDLE_GOV_LADDER is not set CONFIG_CPU_IDLE_GOV_MENU=y diff --git a/config-generic b/config-generic index a27aedd..9bf766a 100644 --- a/config-generic +++ b/config-generic @@ -4,6 +4,8 @@ CONFIG_MMU=y CONFIG_SMP=y CONFIG_HOTPLUG_CPU=y +# CONFIG_BOOTPARAM_HOTPLUG_CPU0 is not set +# CONFIG_DEBUG_HOTPLUG_CPU0 is not set CONFIG_LOCALVERSION="" CONFIG_CROSS_COMPILE="" CONFIG_DEFAULT_HOSTNAME="(none)" @@ -124,6 +126,7 @@ CONFIG_MMC_BLOCK_MINORS=8 CONFIG_MMC_BLOCK_BOUNCE=y CONFIG_MMC_SDHCI=m CONFIG_MMC_SDHCI_PCI=m +CONFIG_MMC_SDHCI_ACPI=m CONFIG_MMC_SDRICOH_CS=m CONFIG_MMC_TIFM_SD=m CONFIG_MMC_WBSD=m @@ -132,6 +135,7 @@ CONFIG_MMC_SDHCI_PLTFM=m CONFIG_MMC_CB710=m CONFIG_MMC_RICOH_MMC=y CONFIG_MMC_USHC=m +CONFIG_MMC_REALTEK_PCI=m CONFIG_MMC_VUB300=m CONFIG_CB710_CORE=m @@ -340,6 +344,7 @@ CONFIG_SCSI_SRP=m CONFIG_SCSI_SRP_ATTRS=m CONFIG_SCSI_TGT=m CONFIG_SCSI_ISCI=m +CONFIG_SCSI_CHELSIO_FCOE=m CONFIG_SCSI_DH=y CONFIG_SCSI_DH_RDAC=m @@ -416,6 +421,9 @@ CONFIG_SCSI_MVSAS_TASKLET=y CONFIG_SCSI_MPT2SAS=m CONFIG_SCSI_MPT2SAS_MAX_SGE=128 CONFIG_SCSI_MPT2SAS_LOGGING=y +CONFIG_SCSI_MPT3SAS=m +CONFIG_SCSI_MPT3SAS_MAX_SGE=128 +CONFIG_SCSI_MPT3SAS_LOGGING=y CONFIG_SCSI_UFSHCD=m @@ -607,6 +615,7 @@ CONFIG_FIREWIRE_SBP2=m CONFIG_FIREWIRE_NET=m CONFIG_FIREWIRE_OHCI_DEBUG=y CONFIG_FIREWIRE_NOSY=m +CONFIG_FIREWIRE_SERIAL=m # CONFIG_FIREWIRE_OHCI_REMOTE_DMA is not set # @@ -977,9 +986,11 @@ CONFIG_IP_SCTP=m CONFIG_NET_SCTPPROBE=m # CONFIG_SCTP_DBG_MSG is not set # CONFIG_SCTP_DBG_OBJCNT is not set -# CONFIG_SCTP_HMAC_NONE is not set -CONFIG_SCTP_HMAC_SHA1=y -# CONFIG_SCTP_HMAC_MD5 is not set +CONFIG_SCTP_DEFAULT_COOKIE_HMAC_SHA1=y +# CONFIG_SCTP_DEFAULT_COOKIE_HMAC_MD5 is not set +# CONFIG_SCTP_DEFAULT_COOKIE_HMAC_NONE is not set +CONFIG_SCTP_COOKIE_HMAC_MD5=y +CONFIG_SCTP_COOKIE_HMAC_SHA1=y CONFIG_ATM=m CONFIG_VLAN_8021Q=m CONFIG_VLAN_8021Q_GVRP=y @@ -1077,6 +1088,7 @@ CONFIG_DCB=y CONFIG_DNS_RESOLVER=m CONFIG_BATMAN_ADV=m CONFIG_BATMAN_ADV_BLA=y +CONFIG_BATMAN_ADV_DAT=y # CONFIG_BATMAN_ADV_DEBUG is not set CONFIG_OPENVSWITCH=m CONFIG_NETPRIO_CGROUP=m @@ -1187,6 +1199,9 @@ CONFIG_ATL2=m CONFIG_ATL1=m CONFIG_ATL1C=m CONFIG_ATL1E=m +CONFIG_NET_CADENCE=y +CONFIG_ARM_AT91_ETHER=m +CONFIG_MACB=m CONFIG_NET_VENDOR_BROCADE=y CONFIG_BNA=m @@ -1257,6 +1272,7 @@ CONFIG_IXGBE_PTP=y # CONFIG_NET_VENDOR_I825XX is not set CONFIG_NET_VENDOR_MARVELL=y +CONFIG_MVMDIO=m CONFIG_SKGE=m # CONFIG_SKGE_DEBUG is not set CONFIG_SKGE_GENESIS=y @@ -1483,6 +1499,7 @@ CONFIG_WIMAX_I2400M_DEBUG_LEVEL=8 # CONFIG_ADM8211 is not set CONFIG_ATH_COMMON=m +CONFIG_ATH_CARDS=m CONFIG_ATH5K=m CONFIG_ATH5K_DEBUG=y # CONFIG_ATH5K_TRACER is not set @@ -1490,6 +1507,7 @@ CONFIG_ATH6KL=m CONFIG_ATH6KL_DEBUG=y CONFIG_ATH6KL_SDIO=m CONFIG_ATH6KL_USB=m +CONFIG_AR5523=m CONFIG_ATH9K=m CONFIG_ATH9K_PCI=y CONFIG_ATH9K_AHB=y @@ -1530,6 +1548,7 @@ CONFIG_BRCMFMAC=m CONFIG_BRCMFMAC_SDIO=y CONFIG_BRCMFMAC_SDIO_OOB=y CONFIG_BRCMFMAC_USB=y +# CONFIG_BRCM_TRACING is not set # CONFIG_BRCMISCAN is not set # CONFIG_BRCMDBG is not set # CONFIG_HERMES is not set @@ -1613,6 +1632,7 @@ CONFIG_RTL8192CE=m CONFIG_RTL8192SE=m CONFIG_RTL8192CU=m CONFIG_RTL8192DE=m +CONFIG_RTL8723AE=m CONFIG_MWIFIEX=m CONFIG_MWIFIEX_SDIO=m @@ -1923,6 +1943,7 @@ CONFIG_SERIO_SERPORT=y CONFIG_SERIO_RAW=m CONFIG_SERIO_ALTERA_PS2=m # CONFIG_SERIO_PS2MULT is not set +CONFIG_SERIO_ARC_PS2=m # CONFIG_SERIO_CT82C710 is not set # CONFIG_SERIO_PARKBD is not set @@ -2034,9 +2055,12 @@ CONFIG_TOUCHSCREEN_W90X900=m CONFIG_TOUCHSCREEN_ST1232=m CONFIG_TOUCHSCREEN_ATMEL_MXT=m # CONFIG_TOUCHSCREEN_MAX11801 is not set +CONFIG_TOUCHSCREEN_AUO_PIXCIR=m +CONFIG_TOUCHSCREEN_TI_AM335X_TSC=m CONFIG_INPUT_MISC=y CONFIG_INPUT_PCSPKR=m +CONFIG_INPUT_RETU_PWRBUTTON=m CONFIG_INPUT_UINPUT=m CONFIG_INPUT_WISTRON_BTNS=m CONFIG_INPUT_ATLAS_BTNS=m @@ -2160,6 +2184,8 @@ CONFIG_I2C_ALGOPCA=m # CONFIG_I2C_NFORCE2_S4985 is not set # CONFIG_I2C_INTEL_MID is not set # CONFIG_I2C_EG20T is not set +# CONFIG_I2C_CBUS_GPIO is not set +CONFIG_I2C_VIPERBOARD=m CONFIG_EEPROM_AT24=m CONFIG_EEPROM_LEGACY=m @@ -2330,6 +2356,8 @@ CONFIG_SENSORS_MAX197=m # CONFIG_PCH_PHUB is not set # CONFIG_SERIAL_PCH_UART is not set # CONFIG_USB_SWITCH_FSA9480 is not set +CONFIG_SERIAL_ARC=m +CONFIG_SERIAL_ARC_NR_PORTS=1 CONFIG_W1=m CONFIG_W1_CON=y @@ -2442,6 +2470,7 @@ CONFIG_RTC_DRV_RS5C372=m # CONFIG_RTC_DRV_SA1100 is not set # CONFIG_RTC_DRV_TEST is not set CONFIG_RTC_DRV_X1205=m +CONFIG_RTC_DRV_PCF8523=m CONFIG_RTC_DRV_V3020=m CONFIG_RTC_DRV_DS2404=m CONFIG_RTC_DRV_STK17TA8=m @@ -2662,6 +2691,7 @@ CONFIG_DVB_BT8XX=m CONFIG_DVB_BUDGET_CORE=m CONFIG_DVB_PLUTO2=m CONFIG_SMS_SIANO_MDTV=m +CONFIG_SMS_SIANO_RC=y CONFIG_MEDIA_SUBDRV_AUTOSELECT=y CONFIG_SMS_USB_DRV=m CONFIG_SMS_SDIO_DRV=m @@ -3035,6 +3065,7 @@ CONFIG_SND_USB_6FIRE=m CONFIG_SND_FIREWIRE=y CONFIG_SND_FIREWIRE_SPEAKERS=m CONFIG_SND_ISIGHT=m +CONFIG_SND_SCS1X=m # # Open Sound System @@ -3122,6 +3153,7 @@ CONFIG_USB_HID=y CONFIG_HID_SUPPORT=y CONFIG_HID=y +CONFIG_I2C_HID=m CONFIG_HID_BATTERY_STRENGTH=y # debugging default is y upstream now CONFIG_HIDRAW=y @@ -3152,6 +3184,7 @@ CONFIG_HID_PS3REMOTE=m CONFIG_HID_PRODIKEYS=m CONFIG_HID_DRAGONRISE=m CONFIG_HID_GYRATION=m +CONFIG_HID_ICADE=m CONFIG_HID_TWINHAN=m CONFIG_HID_ORTEK=m CONFIG_HID_PANTHERLORD=m @@ -3283,6 +3316,7 @@ CONFIG_USB_NET_RNDIS_HOST=m CONFIG_USB_NET_CDC_SUBSET=m CONFIG_USB_NET_CDC_EEM=m CONFIG_USB_NET_CDC_NCM=m +CONFIG_USB_NET_CDC_MBIM=m CONFIG_USB_NET_ZAURUS=m CONFIG_USB_NET_CX82310_ETH=m CONFIG_USB_NET_INT51X1=m @@ -3402,6 +3436,7 @@ CONFIG_USB_SEVSEG=m CONFIG_USB_ALI_M5632=y CONFIG_USB_APPLEDISPLAY=m # CONFIG_OMAP_USB2 is not set +CONFIG_USB_RCAR_PHY=m CONFIG_USB_ATM=m CONFIG_USB_CXACRU=m # CONFIG_USB_C67X00_HCD is not set @@ -3462,6 +3497,7 @@ CONFIG_SSB_PCMCIAHOST=y # CONFIG_SSB_SILENT is not set # CONFIG_SSB_DEBUG is not set CONFIG_SSB_DRIVER_PCICORE=y +CONFIG_SSB_DRIVER_GPIO=y # Multifunction USB devices # CONFIG_MFD_PCF50633 is not set @@ -3478,6 +3514,10 @@ CONFIG_MFD_SUPPORT=y CONFIG_MFD_VX855=m CONFIG_MFD_SM501=m CONFIG_MFD_SM501_GPIO=y +CONFIG_MFD_RTSX_PCI=m +CONFIG_MFD_TI_AM335X_TSCADC=m +CONFIG_MFD_VIPERBOARD=m +CONFIG_MFD_RETU=m # CONFIG_MFD_TC6393XB is not set # CONFIG_MFD_WM8400 is not set # CONFIG_MFD_WM8350_I2C is not set @@ -3639,6 +3679,7 @@ CONFIG_9P_FS_POSIX_ACL=y CONFIG_FUSE_FS=m # CONFIG_OMFS_FS is not set CONFIG_CUSE=m +# CONFIG_F2FS_FS is not set # # Network File Systems @@ -3678,6 +3719,7 @@ CONFIG_CIFS_POSIX=y CONFIG_CIFS_FSCACHE=y CONFIG_CIFS_ACL=y CONFIG_CIFS_WEAK_PW_HASH=y +# CONFIG_CIFS_DEBUG is not set # CONFIG_CIFS_DEBUG2 is not set CONFIG_CIFS_DFS_UPCALL=y CONFIG_CIFS_NFSD_EXPORT=y @@ -4060,6 +4102,11 @@ CONFIG_KEXEC=y CONFIG_HWMON=y # CONFIG_HWMON_DEBUG_CHIP is not set CONFIG_THERMAL_HWMON=y +# CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE is not set +# CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE is not set +CONFIG_FAIR_SHARE=y +CONFIG_STEP_WISE=y +# CONFIG_USER_SPACE is not set # CONFIG_CPU_THERMAL is not set CONFIG_INOTIFY=y @@ -4136,6 +4183,7 @@ CONFIG_SND_INDIGOIOX=m CONFIG_SND_INDIGODJX=m # CONFIG_SND_SOC is not set +CONFIG_BALLOON_COMPACTION=y CONFIG_COMPACTION=y CONFIG_MIGRATION=y CONFIG_NEW_LEDS=y @@ -4247,6 +4295,8 @@ CONFIG_APM_POWER=m # CONFIG_CHARGER_LP8727 is not set # CONFIG_CHARGER_GPIO is not set # CONFIG_CHARGER_PCF50633 is not set +# CONFIG_CHARGER_BQ2415X is not set +CONFIG_POWER_RESET=y # CONFIG_PDA_POWER is not set @@ -4256,6 +4306,7 @@ CONFIG_UIO=m CONFIG_UIO_CIF=m # CONFIG_UIO_PDRV is not set # CONFIG_UIO_PDRV_GENIRQ is not set +# CONFIG_UIO_DMEM_GENIRQ is not set CONFIG_UIO_AEC=m CONFIG_UIO_SERCOS3=m CONFIG_UIO_PCI_GENERIC=m @@ -4290,6 +4341,8 @@ CONFIG_NOZOMI=m # CONFIG_TPS65010 is not set CONFIG_INPUT_APANEL=m +CONFIG_INPUT_GP2A=m +# CONFIG_INPUT_GPIO_TILT_POLLED is not set # CONFIG_INTEL_MENLOW is not set CONFIG_ENCLOSURE_SERVICES=m @@ -4303,6 +4356,7 @@ CONFIG_MSPRO_BLOCK=m CONFIG_MEMSTICK_TIFM_MS=m CONFIG_MEMSTICK_JMICRON_38X=m CONFIG_MEMSTICK_R592=m +CONFIG_MEMSTICK_REALTEK_PCI=m CONFIG_ACCESSIBILITY=y CONFIG_A11Y_BRAILLE_CONSOLE=y @@ -4423,6 +4477,7 @@ CONFIG_ALTERA_STAPL=m # CONFIG_BPCTL is not set # CONFIG_CED1401 is not set # CONFIG_DGRP is not set +# CONFIG_SB105X is not set # END OF STAGING # @@ -4450,8 +4505,9 @@ CONFIG_LSM_MMAP_MIN_ADDR=65536 CONFIG_STRIP_ASM_SYMS=y # CONFIG_RCU_FANOUT_EXACT is not set -# FIXME: Revisit FAST_NO_HZ after 3.5 -# CONFIG_RCU_FAST_NO_HZ is not set +# FIXME: Revisit FAST_NO_HZ after it's fixed +# CONFIG_RCU_FAST_NO_HZ is not setA +# CONFIG_RCU_NOCB_CPU is not set CONFIG_RCU_CPU_STALL_TIMEOUT=60 # CONFIG_RCU_TORTURE_TEST is not set # CONFIG_RCU_TRACE is not set @@ -4508,6 +4564,9 @@ CONFIG_GPIO_SYSFS=y # CONFIG_GPIO_CS5535 is not set # CONFIG_GPIO_ADP5588 is not set # CONFIG_GPIO_IT8761E is not set +# CONFIG SB105x is not set +# CONFIG_GPIO_TS5500 is not set +CONFIG_GPIO_VIPERBOARD=m # CONFIG_GPIO_MAX7300 is not set # CONFIG_UCB1400_CORE is not set # CONFIG_TPS6105X is not set @@ -4559,6 +4618,7 @@ CONFIG_BCMA_BLOCKIO=y CONFIG_BCMA_HOST_PCI_POSSIBLE=y CONFIG_BCMA_HOST_PCI=y CONFIG_BCMA_DRIVER_GMAC_CMN=y +CONFIG_BCMA_DRIVER_GPIO=y # CONFIG_BCMA_DEBUG is not set # CONFIG_GOOGLE_FIRMWARE is not set diff --git a/config-x86-generic b/config-x86-generic index 1716194..0850b10 100644 --- a/config-x86-generic +++ b/config-x86-generic @@ -78,6 +78,7 @@ CONFIG_ACPI_SLEEP=y CONFIG_ACPI_THERMAL=y CONFIG_ACPI_TOSHIBA=m CONFIG_ACPI_VIDEO=m +CONFIG_ACPI_INITRD_TABLE_OVERRIDE=y # FIXME: Next two are deprecated. Remove them when they disappear upstream # CONFIG_ACPI_PROCFS_POWER is not set # CONFIG_ACPI_PROC_EVENT is not set @@ -282,6 +283,7 @@ CONFIG_MTD_CK804XROM=m CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y CONFIG_CPU_IDLE=y +# CONFIG_CPU_IDLE_MULTIPLE_DRIVERS is not set # CONFIG_CPU_IDLE_GOV_LADDER is not set CONFIG_CPU_IDLE_GOV_MENU=y @@ -411,6 +413,7 @@ CONFIG_HYPERV_UTILS=m CONFIG_HID_HYPERV_MOUSE=m CONFIG_HYPERV_NET=m CONFIG_HYPERV_STORAGE=m +CONFIG_HYPERV_BALLOON=m # Depends on HOTPLUG_PCI_PCIE CONFIG_BLK_DEV_PCIESSD_MTIP32XX=m diff --git a/config-x86_64-generic b/config-x86_64-generic index 6003f11..e10d785 100644 --- a/config-x86_64-generic +++ b/config-x86_64-generic @@ -13,6 +13,8 @@ CONFIG_AMD_NUMA=y CONFIG_X86_64_ACPI_NUMA=y # CONFIG_NUMA_EMU is not set # CONFIG_X86_NUMACHIP is not set +CONFIG_NUMA_BALANCING_DEFAULT_ENABLED=y +CONFIG_NUMA_BALANCING=y CONFIG_NR_CPUS=128 CONFIG_PHYSICAL_START=0x1000000 @@ -50,6 +52,7 @@ CONFIG_CRYPTO_CAST5_AVX_X86_64=m CONFIG_CRYPTO_CAST6_AVX_X86_64=m CONFIG_CRYPTO_SERPENT_AVX_X86_64=m CONFIG_CRYPTO_TWOFISH_AVX_X86_64=m +CONFIG_CRYPTO_CAMELLIA_AESNI_AVX_X86_64=m # CONFIG_I2C_ALI1535 is not set # CONFIG_I2C_ALI1563 is not set @@ -69,6 +72,7 @@ CONFIG_SPARSEMEM=y CONFIG_HAVE_MEMORY_PRESENT=y CONFIG_SPARSEMEM_EXTREME=y CONFIG_SPARSEMEM_VMEMMAP=y +# CONFIG_MOVABLE_NODE is not set # CONFIG_MEMORY_HOTPLUG is not set # CONFIG_MEMORY_HOTREMOVE is not set diff --git a/efivarfs-3.7.patch b/efivarfs-3.7.patch deleted file mode 100644 index 3009107..0000000 --- a/efivarfs-3.7.patch +++ /dev/null @@ -1,1630 +0,0 @@ -From cb6f23ee9601297c3c70d0cfe3d77dfde9bd119d Mon Sep 17 00:00:00 2001 -From: Matthew Garrett -Date: Fri, 5 Oct 2012 13:54:56 +0800 -Subject: [PATCH 01/17] efi: Add support for a UEFI variable filesystem - -The existing EFI variables code only supports variables of up to 1024 -bytes. This limitation existed in version 0.99 of the EFI specification, -but was removed before any full releases. Since variables can now be -larger than a single page, sysfs isn't the best interface for this. So, -instead, let's add a filesystem. Variables can be read, written and -created, with the first 4 bytes of each variable representing its UEFI -attributes. The create() method doesn't actually commit to flash since -zero-length variables can't exist per-spec. - -Updates from Jeremy Kerr . - -Signed-off-by: Matthew Garrett -Signed-off-by: Jeremy Kerr -Signed-off-by: Matt Fleming ---- - drivers/firmware/efivars.c | 384 ++++++++++++++++++++++++++++++++++++++++++++- - include/linux/efi.h | 5 + - 2 files changed, 383 insertions(+), 6 deletions(-) - -diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c -index d10c987..b605c48 100644 ---- a/drivers/firmware/efivars.c -+++ b/drivers/firmware/efivars.c -@@ -80,6 +80,10 @@ - #include - #include - -+#include -+#include -+#include -+ - #include - - #define EFIVARS_VERSION "0.08" -@@ -91,6 +95,7 @@ MODULE_LICENSE("GPL"); - MODULE_VERSION(EFIVARS_VERSION); - - #define DUMP_NAME_LEN 52 -+#define GUID_LEN 37 - - /* - * The maximum size of VariableName + Data = 1024 -@@ -108,7 +113,6 @@ struct efi_variable { - __u32 Attributes; - } __attribute__((packed)); - -- - struct efivar_entry { - struct efivars *efivars; - struct efi_variable var; -@@ -122,6 +126,9 @@ struct efivar_attribute { - ssize_t (*store)(struct efivar_entry *entry, const char *buf, size_t count); - }; - -+static struct efivars __efivars; -+static struct efivar_operations ops; -+ - #define PSTORE_EFI_ATTRIBUTES \ - (EFI_VARIABLE_NON_VOLATILE | \ - EFI_VARIABLE_BOOTSERVICE_ACCESS | \ -@@ -629,14 +636,380 @@ static struct kobj_type efivar_ktype = { - .default_attrs = def_attrs, - }; - --static struct pstore_info efi_pstore_info; -- - static inline void - efivar_unregister(struct efivar_entry *var) - { - kobject_put(&var->kobj); - } - -+static int efivarfs_file_open(struct inode *inode, struct file *file) -+{ -+ file->private_data = inode->i_private; -+ return 0; -+} -+ -+static ssize_t efivarfs_file_write(struct file *file, -+ const char __user *userbuf, size_t count, loff_t *ppos) -+{ -+ struct efivar_entry *var = file->private_data; -+ struct efivars *efivars; -+ efi_status_t status; -+ void *data; -+ u32 attributes; -+ struct inode *inode = file->f_mapping->host; -+ int datasize = count - sizeof(attributes); -+ -+ if (count < sizeof(attributes)) -+ return -EINVAL; -+ -+ data = kmalloc(datasize, GFP_KERNEL); -+ -+ if (!data) -+ return -ENOMEM; -+ -+ efivars = var->efivars; -+ -+ if (copy_from_user(&attributes, userbuf, sizeof(attributes))) { -+ count = -EFAULT; -+ goto out; -+ } -+ -+ if (attributes & ~(EFI_VARIABLE_MASK)) { -+ count = -EINVAL; -+ goto out; -+ } -+ -+ if (copy_from_user(data, userbuf + sizeof(attributes), datasize)) { -+ count = -EFAULT; -+ goto out; -+ } -+ -+ if (validate_var(&var->var, data, datasize) == false) { -+ count = -EINVAL; -+ goto out; -+ } -+ -+ status = efivars->ops->set_variable(var->var.VariableName, -+ &var->var.VendorGuid, -+ attributes, datasize, -+ data); -+ -+ switch (status) { -+ case EFI_SUCCESS: -+ mutex_lock(&inode->i_mutex); -+ i_size_write(inode, count); -+ mutex_unlock(&inode->i_mutex); -+ break; -+ case EFI_INVALID_PARAMETER: -+ count = -EINVAL; -+ break; -+ case EFI_OUT_OF_RESOURCES: -+ count = -ENOSPC; -+ break; -+ case EFI_DEVICE_ERROR: -+ count = -EIO; -+ break; -+ case EFI_WRITE_PROTECTED: -+ count = -EROFS; -+ break; -+ case EFI_SECURITY_VIOLATION: -+ count = -EACCES; -+ break; -+ case EFI_NOT_FOUND: -+ count = -ENOENT; -+ break; -+ default: -+ count = -EINVAL; -+ break; -+ } -+out: -+ kfree(data); -+ -+ return count; -+} -+ -+static ssize_t efivarfs_file_read(struct file *file, char __user *userbuf, -+ size_t count, loff_t *ppos) -+{ -+ struct efivar_entry *var = file->private_data; -+ struct efivars *efivars = var->efivars; -+ efi_status_t status; -+ unsigned long datasize = 0; -+ u32 attributes; -+ void *data; -+ ssize_t size; -+ -+ status = efivars->ops->get_variable(var->var.VariableName, -+ &var->var.VendorGuid, -+ &attributes, &datasize, NULL); -+ -+ if (status != EFI_BUFFER_TOO_SMALL) -+ return 0; -+ -+ data = kmalloc(datasize + 4, GFP_KERNEL); -+ -+ if (!data) -+ return 0; -+ -+ status = efivars->ops->get_variable(var->var.VariableName, -+ &var->var.VendorGuid, -+ &attributes, &datasize, -+ (data + 4)); -+ -+ if (status != EFI_SUCCESS) -+ return 0; -+ -+ memcpy(data, &attributes, 4); -+ size = simple_read_from_buffer(userbuf, count, ppos, -+ data, datasize + 4); -+ kfree(data); -+ -+ return size; -+} -+ -+static void efivarfs_evict_inode(struct inode *inode) -+{ -+ clear_inode(inode); -+} -+ -+static const struct super_operations efivarfs_ops = { -+ .statfs = simple_statfs, -+ .drop_inode = generic_delete_inode, -+ .evict_inode = efivarfs_evict_inode, -+ .show_options = generic_show_options, -+}; -+ -+static struct super_block *efivarfs_sb; -+ -+static const struct inode_operations efivarfs_dir_inode_operations; -+ -+static const struct file_operations efivarfs_file_operations = { -+ .open = efivarfs_file_open, -+ .read = efivarfs_file_read, -+ .write = efivarfs_file_write, -+ .llseek = no_llseek, -+}; -+ -+static struct inode *efivarfs_get_inode(struct super_block *sb, -+ const struct inode *dir, int mode, dev_t dev) -+{ -+ struct inode *inode = new_inode(sb); -+ -+ if (inode) { -+ inode->i_ino = get_next_ino(); -+ inode->i_uid = inode->i_gid = 0; -+ inode->i_mode = mode; -+ inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; -+ switch (mode & S_IFMT) { -+ case S_IFREG: -+ inode->i_fop = &efivarfs_file_operations; -+ break; -+ case S_IFDIR: -+ inode->i_op = &efivarfs_dir_inode_operations; -+ inode->i_fop = &simple_dir_operations; -+ inc_nlink(inode); -+ break; -+ } -+ } -+ return inode; -+} -+ -+static void efivarfs_hex_to_guid(const char *str, efi_guid_t *guid) -+{ -+ guid->b[0] = hex_to_bin(str[6]) << 4 | hex_to_bin(str[7]); -+ guid->b[1] = hex_to_bin(str[4]) << 4 | hex_to_bin(str[5]); -+ guid->b[2] = hex_to_bin(str[2]) << 4 | hex_to_bin(str[3]); -+ guid->b[3] = hex_to_bin(str[0]) << 4 | hex_to_bin(str[1]); -+ guid->b[4] = hex_to_bin(str[11]) << 4 | hex_to_bin(str[12]); -+ guid->b[5] = hex_to_bin(str[9]) << 4 | hex_to_bin(str[10]); -+ guid->b[6] = hex_to_bin(str[16]) << 4 | hex_to_bin(str[17]); -+ guid->b[7] = hex_to_bin(str[14]) << 4 | hex_to_bin(str[15]); -+ guid->b[8] = hex_to_bin(str[19]) << 4 | hex_to_bin(str[20]); -+ guid->b[9] = hex_to_bin(str[21]) << 4 | hex_to_bin(str[22]); -+ guid->b[10] = hex_to_bin(str[24]) << 4 | hex_to_bin(str[25]); -+ guid->b[11] = hex_to_bin(str[26]) << 4 | hex_to_bin(str[27]); -+ guid->b[12] = hex_to_bin(str[28]) << 4 | hex_to_bin(str[29]); -+ guid->b[13] = hex_to_bin(str[30]) << 4 | hex_to_bin(str[31]); -+ guid->b[14] = hex_to_bin(str[32]) << 4 | hex_to_bin(str[33]); -+ guid->b[15] = hex_to_bin(str[34]) << 4 | hex_to_bin(str[35]); -+} -+ -+static int efivarfs_create(struct inode *dir, struct dentry *dentry, -+ umode_t mode, bool excl) -+{ -+ struct inode *inode = efivarfs_get_inode(dir->i_sb, dir, mode, 0); -+ struct efivars *efivars = &__efivars; -+ struct efivar_entry *var; -+ int namelen, i = 0, err = 0; -+ -+ if (dentry->d_name.len < 38) -+ return -EINVAL; -+ -+ if (!inode) -+ return -ENOSPC; -+ -+ var = kzalloc(sizeof(struct efivar_entry), GFP_KERNEL); -+ -+ if (!var) -+ return -ENOMEM; -+ -+ namelen = dentry->d_name.len - GUID_LEN; -+ -+ efivarfs_hex_to_guid(dentry->d_name.name + namelen + 1, -+ &var->var.VendorGuid); -+ -+ for (i = 0; i < namelen; i++) -+ var->var.VariableName[i] = dentry->d_name.name[i]; -+ -+ var->var.VariableName[i] = '\0'; -+ -+ inode->i_private = var; -+ var->efivars = efivars; -+ var->kobj.kset = efivars->kset; -+ -+ err = kobject_init_and_add(&var->kobj, &efivar_ktype, NULL, "%s", -+ dentry->d_name.name); -+ if (err) -+ goto out; -+ -+ kobject_uevent(&var->kobj, KOBJ_ADD); -+ spin_lock(&efivars->lock); -+ list_add(&var->list, &efivars->list); -+ spin_unlock(&efivars->lock); -+ d_instantiate(dentry, inode); -+ dget(dentry); -+out: -+ if (err) -+ kfree(var); -+ return err; -+} -+ -+static int efivarfs_unlink(struct inode *dir, struct dentry *dentry) -+{ -+ struct efivar_entry *var = dentry->d_inode->i_private; -+ struct efivars *efivars = var->efivars; -+ efi_status_t status; -+ -+ spin_lock(&efivars->lock); -+ -+ status = efivars->ops->set_variable(var->var.VariableName, -+ &var->var.VendorGuid, -+ 0, 0, NULL); -+ -+ if (status == EFI_SUCCESS || status == EFI_NOT_FOUND) { -+ list_del(&var->list); -+ spin_unlock(&efivars->lock); -+ efivar_unregister(var); -+ drop_nlink(dir); -+ dput(dentry); -+ return 0; -+ } -+ -+ spin_unlock(&efivars->lock); -+ return -EINVAL; -+}; -+ -+int efivarfs_fill_super(struct super_block *sb, void *data, int silent) -+{ -+ struct inode *inode = NULL; -+ struct dentry *root; -+ struct efivar_entry *entry, *n; -+ struct efivars *efivars = &__efivars; -+ int err; -+ -+ efivarfs_sb = sb; -+ -+ sb->s_maxbytes = MAX_LFS_FILESIZE; -+ sb->s_blocksize = PAGE_CACHE_SIZE; -+ sb->s_blocksize_bits = PAGE_CACHE_SHIFT; -+ sb->s_magic = PSTOREFS_MAGIC; -+ sb->s_op = &efivarfs_ops; -+ sb->s_time_gran = 1; -+ -+ inode = efivarfs_get_inode(sb, NULL, S_IFDIR | 0755, 0); -+ if (!inode) { -+ err = -ENOMEM; -+ goto fail; -+ } -+ inode->i_op = &efivarfs_dir_inode_operations; -+ -+ root = d_make_root(inode); -+ sb->s_root = root; -+ if (!root) { -+ err = -ENOMEM; -+ goto fail; -+ } -+ -+ list_for_each_entry_safe(entry, n, &efivars->list, list) { -+ struct inode *inode; -+ struct dentry *dentry, *root = efivarfs_sb->s_root; -+ char *name; -+ unsigned long size = 0; -+ int len, i; -+ -+ len = utf16_strlen(entry->var.VariableName); -+ -+ /* GUID plus trailing NULL */ -+ name = kmalloc(len + 38, GFP_ATOMIC); -+ -+ for (i = 0; i < len; i++) -+ name[i] = entry->var.VariableName[i] & 0xFF; -+ -+ name[len] = '-'; -+ -+ efi_guid_unparse(&entry->var.VendorGuid, name + len + 1); -+ -+ name[len+GUID_LEN] = '\0'; -+ -+ inode = efivarfs_get_inode(efivarfs_sb, root->d_inode, -+ S_IFREG | 0644, 0); -+ dentry = d_alloc_name(root, name); -+ -+ efivars->ops->get_variable(entry->var.VariableName, -+ &entry->var.VendorGuid, -+ &entry->var.Attributes, -+ &size, -+ NULL); -+ -+ mutex_lock(&inode->i_mutex); -+ inode->i_private = entry; -+ i_size_write(inode, size+4); -+ mutex_unlock(&inode->i_mutex); -+ d_add(dentry, inode); -+ } -+ -+ return 0; -+fail: -+ iput(inode); -+ return err; -+} -+ -+static struct dentry *efivarfs_mount(struct file_system_type *fs_type, -+ int flags, const char *dev_name, void *data) -+{ -+ return mount_single(fs_type, flags, data, efivarfs_fill_super); -+} -+ -+static void efivarfs_kill_sb(struct super_block *sb) -+{ -+ kill_litter_super(sb); -+ efivarfs_sb = NULL; -+} -+ -+static struct file_system_type efivarfs_type = { -+ .name = "efivarfs", -+ .mount = efivarfs_mount, -+ .kill_sb = efivarfs_kill_sb, -+}; -+ -+static const struct inode_operations efivarfs_dir_inode_operations = { -+ .lookup = simple_lookup, -+ .unlink = efivarfs_unlink, -+ .create = efivarfs_create, -+}; -+ -+static struct pstore_info efi_pstore_info; -+ - #ifdef CONFIG_PSTORE - - static int efi_pstore_open(struct pstore_info *psi) -@@ -1198,6 +1571,8 @@ int register_efivars(struct efivars *efivars, - pstore_register(&efivars->efi_pstore_info); - } - -+ register_filesystem(&efivarfs_type); -+ - out: - kfree(variable_name); - -@@ -1205,9 +1580,6 @@ out: - } - EXPORT_SYMBOL_GPL(register_efivars); - --static struct efivars __efivars; --static struct efivar_operations ops; -- - /* - * For now we register the efi subsystem with the firmware subsystem - * and the vars subsystem with the efi subsystem. In the future, it -diff --git a/include/linux/efi.h b/include/linux/efi.h -index 8670eb1..b2af157 100644 ---- a/include/linux/efi.h -+++ b/include/linux/efi.h -@@ -29,7 +29,12 @@ - #define EFI_UNSUPPORTED ( 3 | (1UL << (BITS_PER_LONG-1))) - #define EFI_BAD_BUFFER_SIZE ( 4 | (1UL << (BITS_PER_LONG-1))) - #define EFI_BUFFER_TOO_SMALL ( 5 | (1UL << (BITS_PER_LONG-1))) -+#define EFI_NOT_READY ( 6 | (1UL << (BITS_PER_LONG-1))) -+#define EFI_DEVICE_ERROR ( 7 | (1UL << (BITS_PER_LONG-1))) -+#define EFI_WRITE_PROTECTED ( 8 | (1UL << (BITS_PER_LONG-1))) -+#define EFI_OUT_OF_RESOURCES ( 9 | (1UL << (BITS_PER_LONG-1))) - #define EFI_NOT_FOUND (14 | (1UL << (BITS_PER_LONG-1))) -+#define EFI_SECURITY_VIOLATION (26 | (1UL << (BITS_PER_LONG-1))) - - typedef unsigned long efi_status_t; - typedef u8 efi_bool_t; --- -1.7.12.1 - - -From 2fc1dc88e97665c70f203f0132232ea55e8dd7eb Mon Sep 17 00:00:00 2001 -From: Jeremy Kerr -Date: Fri, 5 Oct 2012 13:54:56 +0800 -Subject: [PATCH 02/17] efi: Handle deletions and size changes in - efivarfs_write_file - -A write to an efivarfs file will not always result in a variable of -'count' size after the EFI SetVariable() call. We may have appended to -the existing data (ie, with the EFI_VARIABLE_APPEND_WRITE attribute), or -even have deleted the variable (with an authenticated variable update, -with a zero datasize). - -This change re-reads the updated variable from firmware, to check for -size changes and deletions. In the latter case, we need to drop the -dentry. - -Signed-off-by: Jeremy Kerr -Signed-off-by: Matt Fleming ---- - drivers/firmware/efivars.c | 49 ++++++++++++++++++++++++++++++++++++---------- - 1 file changed, 39 insertions(+), 10 deletions(-) - -diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c -index b605c48..d7658b4 100644 ---- a/drivers/firmware/efivars.c -+++ b/drivers/firmware/efivars.c -@@ -658,6 +658,7 @@ static ssize_t efivarfs_file_write(struct file *file, - u32 attributes; - struct inode *inode = file->f_mapping->host; - int datasize = count - sizeof(attributes); -+ unsigned long newdatasize; - - if (count < sizeof(attributes)) - return -EINVAL; -@@ -696,32 +697,60 @@ static ssize_t efivarfs_file_write(struct file *file, - - switch (status) { - case EFI_SUCCESS: -- mutex_lock(&inode->i_mutex); -- i_size_write(inode, count); -- mutex_unlock(&inode->i_mutex); - break; - case EFI_INVALID_PARAMETER: - count = -EINVAL; -- break; -+ goto out; - case EFI_OUT_OF_RESOURCES: - count = -ENOSPC; -- break; -+ goto out; - case EFI_DEVICE_ERROR: - count = -EIO; -- break; -+ goto out; - case EFI_WRITE_PROTECTED: - count = -EROFS; -- break; -+ goto out; - case EFI_SECURITY_VIOLATION: - count = -EACCES; -- break; -+ goto out; - case EFI_NOT_FOUND: - count = -ENOENT; -- break; -+ goto out; - default: - count = -EINVAL; -- break; -+ goto out; - } -+ -+ /* -+ * Writing to the variable may have caused a change in size (which -+ * could either be an append or an overwrite), or the variable to be -+ * deleted. Perform a GetVariable() so we can tell what actually -+ * happened. -+ */ -+ newdatasize = 0; -+ status = efivars->ops->get_variable(var->var.VariableName, -+ &var->var.VendorGuid, -+ NULL, &newdatasize, -+ NULL); -+ -+ if (status == EFI_BUFFER_TOO_SMALL) { -+ mutex_lock(&inode->i_mutex); -+ i_size_write(inode, newdatasize + sizeof(attributes)); -+ mutex_unlock(&inode->i_mutex); -+ -+ } else if (status == EFI_NOT_FOUND) { -+ spin_lock(&efivars->lock); -+ list_del(&var->list); -+ spin_unlock(&efivars->lock); -+ efivar_unregister(var); -+ drop_nlink(inode); -+ dput(file->f_dentry); -+ -+ } else { -+ pr_warn("efivarfs: inconsistent EFI variable implementation? " -+ "status = %lx\n", status); -+ } -+ - out: - kfree(data); - --- -1.7.12.1 - - -From c98611fc95672862950c9bc4d6a3a4c4453a3c3e Mon Sep 17 00:00:00 2001 -From: "Lee, Chun-Yi" -Date: Fri, 5 Oct 2012 13:54:56 +0800 -Subject: [PATCH 03/17] efi: add efivars kobject to efi sysfs folder - -UEFI variable filesystem need a new mount point, so this patch add -efivars kobject to efi_kobj for create a /sys/firmware/efi/efivars -folder. - -Cc: Matthew Garrett -Cc: H. Peter Anvin -Signed-off-by: Lee, Chun-Yi -Signed-off-by: Jeremy Kerr -Signed-off-by: Matt Fleming ---- - drivers/firmware/efivars.c | 9 +++++++++ - include/linux/efi.h | 1 + - 2 files changed, 10 insertions(+) - -diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c -index d7658b4..6793965 100644 ---- a/drivers/firmware/efivars.c -+++ b/drivers/firmware/efivars.c -@@ -1527,6 +1527,7 @@ void unregister_efivars(struct efivars *efivars) - sysfs_remove_bin_file(&efivars->kset->kobj, efivars->del_var); - kfree(efivars->new_var); - kfree(efivars->del_var); -+ kobject_put(efivars->kobject); - kset_unregister(efivars->kset); - } - EXPORT_SYMBOL_GPL(unregister_efivars); -@@ -1558,6 +1559,14 @@ int register_efivars(struct efivars *efivars, - goto out; - } - -+ efivars->kobject = kobject_create_and_add("efivars", parent_kobj); -+ if (!efivars->kobject) { -+ pr_err("efivars: Subsystem registration failed.\n"); -+ error = -ENOMEM; -+ kset_unregister(efivars->kset); -+ goto out; -+ } -+ - /* - * Per EFI spec, the maximum storage allocated for both - * the variable name and variable data is 1024 bytes. -diff --git a/include/linux/efi.h b/include/linux/efi.h -index b2af157..337aefb 100644 ---- a/include/linux/efi.h -+++ b/include/linux/efi.h -@@ -662,6 +662,7 @@ struct efivars { - spinlock_t lock; - struct list_head list; - struct kset *kset; -+ struct kobject *kobject; - struct bin_attribute *new_var, *del_var; - const struct efivar_operations *ops; - struct efivar_entry *walk_entry; --- -1.7.12.1 - - -From 8ef5f49da57087022f2031820ceb3b1c6101d76c Mon Sep 17 00:00:00 2001 -From: Matt Fleming -Date: Thu, 4 Oct 2012 09:57:31 +0100 -Subject: [PATCH 04/17] efivarfs: Add documentation for the EFI variable - filesystem - -Signed-off-by: Matt Fleming ---- - Documentation/filesystems/00-INDEX | 2 ++ - Documentation/filesystems/efivarfs.txt | 16 ++++++++++++++++ - 2 files changed, 18 insertions(+) - create mode 100644 Documentation/filesystems/efivarfs.txt - -diff --git a/Documentation/filesystems/00-INDEX b/Documentation/filesystems/00-INDEX -index 8c624a1..7b52ba7 100644 ---- a/Documentation/filesystems/00-INDEX -+++ b/Documentation/filesystems/00-INDEX -@@ -38,6 +38,8 @@ dnotify_test.c - - example program for dnotify - ecryptfs.txt - - docs on eCryptfs: stacked cryptographic filesystem for Linux. -+efivarfs.txt -+ - info for the efivarfs filesystem. - exofs.txt - - info, usage, mount options, design about EXOFS. - ext2.txt -diff --git a/Documentation/filesystems/efivarfs.txt b/Documentation/filesystems/efivarfs.txt -new file mode 100644 -index 0000000..c477af0 ---- /dev/null -+++ b/Documentation/filesystems/efivarfs.txt -@@ -0,0 +1,16 @@ -+ -+efivarfs - a (U)EFI variable filesystem -+ -+The efivarfs filesystem was created to address the shortcomings of -+using entries in sysfs to maintain EFI variables. The old sysfs EFI -+variables code only supported variables of up to 1024 bytes. This -+limitation existed in version 0.99 of the EFI specification, but was -+removed before any full releases. Since variables can now be larger -+than a single page, sysfs isn't the best interface for this. -+ -+Variables can be created, deleted and modified with the efivarfs -+filesystem. -+ -+efivarfs is typically mounted like this, -+ -+ mount -t efivarfs none /sys/firmware/efi/efivars --- -1.7.12.1 - - -From f69c39248e2f1eebf24f5ee55139602c56d15aec Mon Sep 17 00:00:00 2001 -From: Andy Whitcroft -Date: Thu, 11 Oct 2012 11:32:17 +0100 -Subject: [PATCH 05/17] efivarfs: efivarfs_file_read ensure we free data in - error paths - -Signed-off-by: Andy Whitcroft -Acked-by: Matthew Garrett -Acked-by: Jeremy Kerr -Signed-off-by: Matt Fleming ---- - drivers/firmware/efivars.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c -index 6793965..b7c9a32 100644 ---- a/drivers/firmware/efivars.c -+++ b/drivers/firmware/efivars.c -@@ -766,7 +766,7 @@ static ssize_t efivarfs_file_read(struct file *file, char __user *userbuf, - unsigned long datasize = 0; - u32 attributes; - void *data; -- ssize_t size; -+ ssize_t size = 0; - - status = efivars->ops->get_variable(var->var.VariableName, - &var->var.VendorGuid, -@@ -784,13 +784,13 @@ static ssize_t efivarfs_file_read(struct file *file, char __user *userbuf, - &var->var.VendorGuid, - &attributes, &datasize, - (data + 4)); -- - if (status != EFI_SUCCESS) -- return 0; -+ goto out_free; - - memcpy(data, &attributes, 4); - size = simple_read_from_buffer(userbuf, count, ppos, - data, datasize + 4); -+out_free: - kfree(data); - - return size; --- -1.7.12.1 - - -From 429136e16c7c43bbebb8b8030203161a2d3fc3ce Mon Sep 17 00:00:00 2001 -From: Andy Whitcroft -Date: Thu, 11 Oct 2012 11:32:18 +0100 -Subject: [PATCH 06/17] efivarfs: efivarfs_create() ensure we drop our - reference on inode on error - -Signed-off-by: Andy Whitcroft -Acked-by: Matthew Garrett -Acked-by: Jeremy Kerr -Signed-off-by: Matt Fleming ---- - drivers/firmware/efivars.c | 14 +++++++++----- - 1 file changed, 9 insertions(+), 5 deletions(-) - -diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c -index b7c9a32..6e5f367 100644 ---- a/drivers/firmware/efivars.c -+++ b/drivers/firmware/efivars.c -@@ -866,7 +866,7 @@ static void efivarfs_hex_to_guid(const char *str, efi_guid_t *guid) - static int efivarfs_create(struct inode *dir, struct dentry *dentry, - umode_t mode, bool excl) - { -- struct inode *inode = efivarfs_get_inode(dir->i_sb, dir, mode, 0); -+ struct inode *inode; - struct efivars *efivars = &__efivars; - struct efivar_entry *var; - int namelen, i = 0, err = 0; -@@ -874,13 +874,15 @@ static int efivarfs_create(struct inode *dir, struct dentry *dentry, - if (dentry->d_name.len < 38) - return -EINVAL; - -+ inode = efivarfs_get_inode(dir->i_sb, dir, mode, 0); - if (!inode) - return -ENOSPC; - - var = kzalloc(sizeof(struct efivar_entry), GFP_KERNEL); -- -- if (!var) -- return -ENOMEM; -+ if (!var) { -+ err = -ENOMEM; -+ goto out; -+ } - - namelen = dentry->d_name.len - GUID_LEN; - -@@ -908,8 +910,10 @@ static int efivarfs_create(struct inode *dir, struct dentry *dentry, - d_instantiate(dentry, inode); - dget(dentry); - out: -- if (err) -+ if (err) { - kfree(var); -+ iput(inode); -+ } - return err; - } - --- -1.7.12.1 - - -From 1a19268e8a4bae43c1feb3f71ee468c6bc70aca6 Mon Sep 17 00:00:00 2001 -From: Andy Whitcroft -Date: Thu, 11 Oct 2012 11:32:19 +0100 -Subject: [PATCH 07/17] efivarfs: efivarfs_fill_super() fix inode reference - counts - -When d_make_root() fails it will automatically drop the reference -on the root inode. We should not be doing so as well. - -Signed-off-by: Andy Whitcroft -Acked-by: Matthew Garrett -Acked-by: Jeremy Kerr -Signed-off-by: Matt Fleming ---- - drivers/firmware/efivars.c | 16 ++++------------ - 1 file changed, 4 insertions(+), 12 deletions(-) - -diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c -index 6e5f367..adfc486 100644 ---- a/drivers/firmware/efivars.c -+++ b/drivers/firmware/efivars.c -@@ -948,7 +948,6 @@ int efivarfs_fill_super(struct super_block *sb, void *data, int silent) - struct dentry *root; - struct efivar_entry *entry, *n; - struct efivars *efivars = &__efivars; -- int err; - - efivarfs_sb = sb; - -@@ -960,18 +959,14 @@ int efivarfs_fill_super(struct super_block *sb, void *data, int silent) - sb->s_time_gran = 1; - - inode = efivarfs_get_inode(sb, NULL, S_IFDIR | 0755, 0); -- if (!inode) { -- err = -ENOMEM; -- goto fail; -- } -+ if (!inode) -+ return -ENOMEM; - inode->i_op = &efivarfs_dir_inode_operations; - - root = d_make_root(inode); - sb->s_root = root; -- if (!root) { -- err = -ENOMEM; -- goto fail; -- } -+ if (!root) -+ return -ENOMEM; - - list_for_each_entry_safe(entry, n, &efivars->list, list) { - struct inode *inode; -@@ -1012,9 +1007,6 @@ int efivarfs_fill_super(struct super_block *sb, void *data, int silent) - } - - return 0; --fail: -- iput(inode); -- return err; - } - - static struct dentry *efivarfs_mount(struct file_system_type *fs_type, --- -1.7.12.1 - - -From f0d90a4024493aed6fc77ce5cd3b93f278fed9c0 Mon Sep 17 00:00:00 2001 -From: Andy Whitcroft -Date: Thu, 11 Oct 2012 11:32:20 +0100 -Subject: [PATCH 08/17] efivarfs: efivarfs_fill_super() ensure we free our - temporary name - -d_alloc_name() copies the passed name to new storage, once complete we -no longer need our name. - -Signed-off-by: Andy Whitcroft -Acked-by: Matthew Garrett -Acked-by: Jeremy Kerr -Signed-off-by: Matt Fleming ---- - drivers/firmware/efivars.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c -index adfc486..36b3dd6 100644 ---- a/drivers/firmware/efivars.c -+++ b/drivers/firmware/efivars.c -@@ -992,6 +992,8 @@ int efivarfs_fill_super(struct super_block *sb, void *data, int silent) - inode = efivarfs_get_inode(efivarfs_sb, root->d_inode, - S_IFREG | 0644, 0); - dentry = d_alloc_name(root, name); -+ /* copied by the above to local storage in the dentry. */ -+ kfree(name); - - efivars->ops->get_variable(entry->var.VariableName, - &entry->var.VendorGuid, --- -1.7.12.1 - - -From c4cf244c318218153200d0011d8ef0ebcf3146ea Mon Sep 17 00:00:00 2001 -From: Andy Whitcroft -Date: Thu, 11 Oct 2012 11:32:21 +0100 -Subject: [PATCH 09/17] efivarfs: efivarfs_fill_super() ensure we clean up - correctly on error - -Ensure we free both the name and inode on error when building the -individual variables. - -Signed-off-by: Andy Whitcroft -Acked-by: Matthew Garrett -Acked-by: Jeremy Kerr -Signed-off-by: Matt Fleming ---- - drivers/firmware/efivars.c | 20 ++++++++++++++++++-- - 1 file changed, 18 insertions(+), 2 deletions(-) - -diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c -index 36b3dd6..216086d 100644 ---- a/drivers/firmware/efivars.c -+++ b/drivers/firmware/efivars.c -@@ -948,6 +948,7 @@ int efivarfs_fill_super(struct super_block *sb, void *data, int silent) - struct dentry *root; - struct efivar_entry *entry, *n; - struct efivars *efivars = &__efivars; -+ char *name; - - efivarfs_sb = sb; - -@@ -969,16 +970,18 @@ int efivarfs_fill_super(struct super_block *sb, void *data, int silent) - return -ENOMEM; - - list_for_each_entry_safe(entry, n, &efivars->list, list) { -- struct inode *inode; - struct dentry *dentry, *root = efivarfs_sb->s_root; -- char *name; - unsigned long size = 0; - int len, i; - -+ inode = NULL; -+ - len = utf16_strlen(entry->var.VariableName); - - /* GUID plus trailing NULL */ - name = kmalloc(len + 38, GFP_ATOMIC); -+ if (!name) -+ goto fail; - - for (i = 0; i < len; i++) - name[i] = entry->var.VariableName[i] & 0xFF; -@@ -991,7 +994,13 @@ int efivarfs_fill_super(struct super_block *sb, void *data, int silent) - - inode = efivarfs_get_inode(efivarfs_sb, root->d_inode, - S_IFREG | 0644, 0); -+ if (!inode) -+ goto fail_name; -+ - dentry = d_alloc_name(root, name); -+ if (!dentry) -+ goto fail_inode; -+ - /* copied by the above to local storage in the dentry. */ - kfree(name); - -@@ -1009,6 +1018,13 @@ int efivarfs_fill_super(struct super_block *sb, void *data, int silent) - } - - return 0; -+ -+fail_inode: -+ iput(inode); -+fail_name: -+ kfree(name); -+fail: -+ return -ENOMEM; - } - - static struct dentry *efivarfs_mount(struct file_system_type *fs_type, --- -1.7.12.1 - - -From d3b7165568bcb50e4526c3dadda59e43f6681bc0 Mon Sep 17 00:00:00 2001 -From: Jeremy Kerr -Date: Thu, 11 Oct 2012 21:19:11 +0800 -Subject: [PATCH 10/17] efivarfs: Implement exclusive access for - {get,set}_variable - -Currently, efivarfs does not enforce exclusion over the get_variable and -set_variable operations. Section 7.1 of UEFI requires us to only allow a -single processor to enter {get,set}_variable services at once. - -This change acquires the efivars->lock over calls to these operations -from the efivarfs paths. - -Signed-off-by: Jeremy Kerr -Signed-off-by: Matt Fleming ---- - drivers/firmware/efivars.c | 68 +++++++++++++++++++++++++++++----------------- - 1 file changed, 43 insertions(+), 25 deletions(-) - -diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c -index 216086d..d478c56 100644 ---- a/drivers/firmware/efivars.c -+++ b/drivers/firmware/efivars.c -@@ -690,35 +690,45 @@ static ssize_t efivarfs_file_write(struct file *file, - goto out; - } - -+ /* -+ * The lock here protects the get_variable call, the conditional -+ * set_variable call, and removal of the variable from the efivars -+ * list (in the case of an authenticated delete). -+ */ -+ spin_lock(&efivars->lock); -+ - status = efivars->ops->set_variable(var->var.VariableName, - &var->var.VendorGuid, - attributes, datasize, - data); - -- switch (status) { -- case EFI_SUCCESS: -- break; -- case EFI_INVALID_PARAMETER: -- count = -EINVAL; -- goto out; -- case EFI_OUT_OF_RESOURCES: -- count = -ENOSPC; -- goto out; -- case EFI_DEVICE_ERROR: -- count = -EIO; -- goto out; -- case EFI_WRITE_PROTECTED: -- count = -EROFS; -- goto out; -- case EFI_SECURITY_VIOLATION: -- count = -EACCES; -- goto out; -- case EFI_NOT_FOUND: -- count = -ENOENT; -- goto out; -- default: -- count = -EINVAL; -- goto out; -+ if (status != EFI_SUCCESS) { -+ spin_unlock(&efivars->lock); -+ kfree(data); -+ -+ switch (status) { -+ case EFI_INVALID_PARAMETER: -+ count = -EINVAL; -+ break; -+ case EFI_OUT_OF_RESOURCES: -+ count = -ENOSPC; -+ break; -+ case EFI_DEVICE_ERROR: -+ count = -EIO; -+ break; -+ case EFI_WRITE_PROTECTED: -+ count = -EROFS; -+ break; -+ case EFI_SECURITY_VIOLATION: -+ count = -EACCES; -+ break; -+ case EFI_NOT_FOUND: -+ count = -ENOENT; -+ break; -+ default: -+ count = -EINVAL; -+ } -+ return count; - } - - /* -@@ -734,12 +744,12 @@ static ssize_t efivarfs_file_write(struct file *file, - NULL); - - if (status == EFI_BUFFER_TOO_SMALL) { -+ spin_unlock(&efivars->lock); - mutex_lock(&inode->i_mutex); - i_size_write(inode, newdatasize + sizeof(attributes)); - mutex_unlock(&inode->i_mutex); - - } else if (status == EFI_NOT_FOUND) { -- spin_lock(&efivars->lock); - list_del(&var->list); - spin_unlock(&efivars->lock); - efivar_unregister(var); -@@ -747,6 +757,7 @@ static ssize_t efivarfs_file_write(struct file *file, - dput(file->f_dentry); - - } else { -+ spin_unlock(&efivars->lock); - pr_warn("efivarfs: inconsistent EFI variable implementation? " - "status = %lx\n", status); - } -@@ -768,9 +779,11 @@ static ssize_t efivarfs_file_read(struct file *file, char __user *userbuf, - void *data; - ssize_t size = 0; - -+ spin_lock(&efivars->lock); - status = efivars->ops->get_variable(var->var.VariableName, - &var->var.VendorGuid, - &attributes, &datasize, NULL); -+ spin_unlock(&efivars->lock); - - if (status != EFI_BUFFER_TOO_SMALL) - return 0; -@@ -780,10 +793,13 @@ static ssize_t efivarfs_file_read(struct file *file, char __user *userbuf, - if (!data) - return 0; - -+ spin_lock(&efivars->lock); - status = efivars->ops->get_variable(var->var.VariableName, - &var->var.VendorGuid, - &attributes, &datasize, - (data + 4)); -+ spin_unlock(&efivars->lock); -+ - if (status != EFI_SUCCESS) - goto out_free; - -@@ -1004,11 +1020,13 @@ int efivarfs_fill_super(struct super_block *sb, void *data, int silent) - /* copied by the above to local storage in the dentry. */ - kfree(name); - -+ spin_lock(&efivars->lock); - efivars->ops->get_variable(entry->var.VariableName, - &entry->var.VendorGuid, - &entry->var.Attributes, - &size, - NULL); -+ spin_unlock(&efivars->lock); - - mutex_lock(&inode->i_mutex); - inode->i_private = entry; --- -1.7.12.1 - - -From 90a462e9cf439a1987e0f9434d1f615addcc1970 Mon Sep 17 00:00:00 2001 -From: Jeremy Kerr -Date: Fri, 19 Oct 2012 15:16:45 +0800 -Subject: [PATCH 11/17] efi: Clarify GUID length calculations - -At present, the handling of GUIDs in efivar file names isn't consistent. -We use GUID_LEN in some places, and 38 in others (GUID_LEN plus -separator), and implicitly use the presence of the trailing NUL. - -This change removes the trailing NUL from GUID_LEN, so that we're -explicitly adding it when required. We also replace magic numbers -with GUID_LEN, and clarify the comments where appropriate. - -We also fix the allocation size in efivar_create_sysfs_entry, where -we're allocating one byte too much, due to counting the trailing NUL -twice - once when calculating short_name_size, and once in the kzalloc. - -Signed-off-by: Jeremy Kerr -Signed-off-by: Matt Fleming ---- - drivers/firmware/efivars.c | 33 +++++++++++++++++++++++++-------- - 1 file changed, 25 insertions(+), 8 deletions(-) - -diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c -index d478c56..a93e401 100644 ---- a/drivers/firmware/efivars.c -+++ b/drivers/firmware/efivars.c -@@ -95,7 +95,12 @@ MODULE_LICENSE("GPL"); - MODULE_VERSION(EFIVARS_VERSION); - - #define DUMP_NAME_LEN 52 --#define GUID_LEN 37 -+ -+/* -+ * Length of a GUID string (strlen("aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee")) -+ * not including trailing NUL -+ */ -+#define GUID_LEN 36 - - /* - * The maximum size of VariableName + Data = 1024 -@@ -887,7 +892,11 @@ static int efivarfs_create(struct inode *dir, struct dentry *dentry, - struct efivar_entry *var; - int namelen, i = 0, err = 0; - -- if (dentry->d_name.len < 38) -+ /* -+ * We need a GUID, plus at least one letter for the variable name, -+ * plus the '-' separator -+ */ -+ if (dentry->d_name.len < GUID_LEN + 2) - return -EINVAL; - - inode = efivarfs_get_inode(dir->i_sb, dir, mode, 0); -@@ -900,7 +909,8 @@ static int efivarfs_create(struct inode *dir, struct dentry *dentry, - goto out; - } - -- namelen = dentry->d_name.len - GUID_LEN; -+ /* length of the variable name itself: remove GUID and separator */ -+ namelen = dentry->d_name.len - GUID_LEN - 1; - - efivarfs_hex_to_guid(dentry->d_name.name + namelen + 1, - &var->var.VendorGuid); -@@ -994,8 +1004,8 @@ int efivarfs_fill_super(struct super_block *sb, void *data, int silent) - - len = utf16_strlen(entry->var.VariableName); - -- /* GUID plus trailing NULL */ -- name = kmalloc(len + 38, GFP_ATOMIC); -+ /* name, plus '-', plus GUID, plus NUL*/ -+ name = kmalloc(len + 1 + GUID_LEN + 1, GFP_ATOMIC); - if (!name) - goto fail; - -@@ -1006,7 +1016,7 @@ int efivarfs_fill_super(struct super_block *sb, void *data, int silent) - - efi_guid_unparse(&entry->var.VendorGuid, name + len + 1); - -- name[len+GUID_LEN] = '\0'; -+ name[len+GUID_LEN+1] = '\0'; - - inode = efivarfs_get_inode(efivarfs_sb, root->d_inode, - S_IFREG | 0644, 0); -@@ -1435,11 +1445,18 @@ efivar_create_sysfs_entry(struct efivars *efivars, - efi_char16_t *variable_name, - efi_guid_t *vendor_guid) - { -- int i, short_name_size = variable_name_size / sizeof(efi_char16_t) + 38; -+ int i, short_name_size; - char *short_name; - struct efivar_entry *new_efivar; - -- short_name = kzalloc(short_name_size + 1, GFP_KERNEL); -+ /* -+ * Length of the variable bytes in ASCII, plus the '-' separator, -+ * plus the GUID, plus trailing NUL -+ */ -+ short_name_size = variable_name_size / sizeof(efi_char16_t) -+ + 1 + GUID_LEN + 1; -+ -+ short_name = kzalloc(short_name_size, GFP_KERNEL); - new_efivar = kzalloc(sizeof(struct efivar_entry), GFP_KERNEL); - - if (!short_name || !new_efivar) { --- -1.7.12.1 - - -From ecbf90823d85ebb41e68e6be01f476862d184825 Mon Sep 17 00:00:00 2001 -From: Matt Fleming -Date: Tue, 16 Oct 2012 15:58:07 +0100 -Subject: [PATCH 12/17] efivarfs: Return an error if we fail to read a - variable - -Instead of always returning 0 in efivarfs_file_read(), even when we -fail to successfully read the variable, convert the EFI status to -something meaningful and return that to the caller. This way the user -will have some hint as to why the read failed. - -Acked-by: Jeremy Kerr -Signed-off-by: Matt Fleming ---- - drivers/firmware/efivars.c | 62 +++++++++++++++++++++++++++------------------- - 1 file changed, 36 insertions(+), 26 deletions(-) - -diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c -index a93e401..277e426 100644 ---- a/drivers/firmware/efivars.c -+++ b/drivers/firmware/efivars.c -@@ -653,6 +653,36 @@ static int efivarfs_file_open(struct inode *inode, struct file *file) - return 0; - } - -+static int efi_status_to_err(efi_status_t status) -+{ -+ int err; -+ -+ switch (status) { -+ case EFI_INVALID_PARAMETER: -+ err = -EINVAL; -+ break; -+ case EFI_OUT_OF_RESOURCES: -+ err = -ENOSPC; -+ break; -+ case EFI_DEVICE_ERROR: -+ err = -EIO; -+ break; -+ case EFI_WRITE_PROTECTED: -+ err = -EROFS; -+ break; -+ case EFI_SECURITY_VIOLATION: -+ err = -EACCES; -+ break; -+ case EFI_NOT_FOUND: -+ err = -ENOENT; -+ break; -+ default: -+ err = -EINVAL; -+ } -+ -+ return err; -+} -+ - static ssize_t efivarfs_file_write(struct file *file, - const char __user *userbuf, size_t count, loff_t *ppos) - { -@@ -711,29 +741,7 @@ static ssize_t efivarfs_file_write(struct file *file, - spin_unlock(&efivars->lock); - kfree(data); - -- switch (status) { -- case EFI_INVALID_PARAMETER: -- count = -EINVAL; -- break; -- case EFI_OUT_OF_RESOURCES: -- count = -ENOSPC; -- break; -- case EFI_DEVICE_ERROR: -- count = -EIO; -- break; -- case EFI_WRITE_PROTECTED: -- count = -EROFS; -- break; -- case EFI_SECURITY_VIOLATION: -- count = -EACCES; -- break; -- case EFI_NOT_FOUND: -- count = -ENOENT; -- break; -- default: -- count = -EINVAL; -- } -- return count; -+ return efi_status_to_err(status); - } - - /* -@@ -791,12 +799,12 @@ static ssize_t efivarfs_file_read(struct file *file, char __user *userbuf, - spin_unlock(&efivars->lock); - - if (status != EFI_BUFFER_TOO_SMALL) -- return 0; -+ return efi_status_to_err(status); - - data = kmalloc(datasize + 4, GFP_KERNEL); - - if (!data) -- return 0; -+ return -ENOMEM; - - spin_lock(&efivars->lock); - status = efivars->ops->get_variable(var->var.VariableName, -@@ -805,8 +813,10 @@ static ssize_t efivarfs_file_read(struct file *file, char __user *userbuf, - (data + 4)); - spin_unlock(&efivars->lock); - -- if (status != EFI_SUCCESS) -+ if (status != EFI_SUCCESS) { -+ size = efi_status_to_err(status); - goto out_free; -+ } - - memcpy(data, &attributes, 4); - size = simple_read_from_buffer(userbuf, count, ppos, --- -1.7.12.1 - - -From 39210330739b943856ff21b29b4a0804f4e8349f Mon Sep 17 00:00:00 2001 -From: Matt Fleming -Date: Mon, 22 Oct 2012 15:23:29 +0100 -Subject: [PATCH 13/17] efivarfs: Replace magic number with sizeof(attributes) - -Seeing "+ 4" littered throughout the functions gets a bit -confusing. Use "sizeof(attributes)" which clearly explains what -quantity we're adding. - -Acked-by: Jeremy Kerr -Signed-off-by: Matt Fleming ---- - drivers/firmware/efivars.c | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - -diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c -index 277e426..2c04434 100644 ---- a/drivers/firmware/efivars.c -+++ b/drivers/firmware/efivars.c -@@ -801,7 +801,7 @@ static ssize_t efivarfs_file_read(struct file *file, char __user *userbuf, - if (status != EFI_BUFFER_TOO_SMALL) - return efi_status_to_err(status); - -- data = kmalloc(datasize + 4, GFP_KERNEL); -+ data = kmalloc(datasize + sizeof(attributes), GFP_KERNEL); - - if (!data) - return -ENOMEM; -@@ -810,7 +810,7 @@ static ssize_t efivarfs_file_read(struct file *file, char __user *userbuf, - status = efivars->ops->get_variable(var->var.VariableName, - &var->var.VendorGuid, - &attributes, &datasize, -- (data + 4)); -+ (data + sizeof(attributes))); - spin_unlock(&efivars->lock); - - if (status != EFI_SUCCESS) { -@@ -818,9 +818,9 @@ static ssize_t efivarfs_file_read(struct file *file, char __user *userbuf, - goto out_free; - } - -- memcpy(data, &attributes, 4); -+ memcpy(data, &attributes, sizeof(attributes)); - size = simple_read_from_buffer(userbuf, count, ppos, -- data, datasize + 4); -+ data, datasize + sizeof(attributes)); - out_free: - kfree(data); - --- -1.7.12.1 - - -From 5555f0af6294b3675a95a06da23101150644936d Mon Sep 17 00:00:00 2001 -From: Matt Fleming -Date: Mon, 22 Oct 2012 15:51:45 +0100 -Subject: [PATCH 14/17] efivarfs: Add unique magic number - -Using pstore's superblock magic number is no doubt going to cause -problems in the future. Give efivarfs its own magic number. - -Acked-by: Jeremy Kerr -Signed-off-by: Matt Fleming ---- - drivers/firmware/efivars.c | 2 +- - include/uapi/linux/magic.h | 1 + - 2 files changed, 2 insertions(+), 1 deletion(-) - -diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c -index 2c04434..3b0cf9a 100644 ---- a/drivers/firmware/efivars.c -+++ b/drivers/firmware/efivars.c -@@ -991,7 +991,7 @@ int efivarfs_fill_super(struct super_block *sb, void *data, int silent) - sb->s_maxbytes = MAX_LFS_FILESIZE; - sb->s_blocksize = PAGE_CACHE_SIZE; - sb->s_blocksize_bits = PAGE_CACHE_SHIFT; -- sb->s_magic = PSTOREFS_MAGIC; -+ sb->s_magic = EFIVARFS_MAGIC; - sb->s_op = &efivarfs_ops; - sb->s_time_gran = 1; - -diff --git a/include/uapi/linux/magic.h b/include/uapi/linux/magic.h -index e15192c..12f68c7 100644 ---- a/include/uapi/linux/magic.h -+++ b/include/uapi/linux/magic.h -@@ -27,6 +27,7 @@ - #define ISOFS_SUPER_MAGIC 0x9660 - #define JFFS2_SUPER_MAGIC 0x72b6 - #define PSTOREFS_MAGIC 0x6165676C -+#define EFIVARFS_MAGIC 0xde5e81e4 - - #define MINIX_SUPER_MAGIC 0x137F /* minix v1 fs, 14 char names */ - #define MINIX_SUPER_MAGIC2 0x138F /* minix v1 fs, 30 char names */ --- -1.7.12.1 - - -From a42845c67f2386b164d0c5d8220838d7faf5a409 Mon Sep 17 00:00:00 2001 -From: Matt Fleming -Date: Tue, 23 Oct 2012 12:35:43 +0100 -Subject: [PATCH 15/17] efivarfs: Make 'datasize' unsigned long - -There's no reason to declare 'datasize' as an int, since the majority -of the functions it's passed to expect an unsigned long anyway. Plus, -this way we avoid any sign problems during arithmetic. - -Acked-by: Jeremy Kerr -Signed-off-by: Matt Fleming ---- - drivers/firmware/efivars.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c -index 3b0cf9a..6a858d1 100644 ---- a/drivers/firmware/efivars.c -+++ b/drivers/firmware/efivars.c -@@ -692,7 +692,7 @@ static ssize_t efivarfs_file_write(struct file *file, - void *data; - u32 attributes; - struct inode *inode = file->f_mapping->host; -- int datasize = count - sizeof(attributes); -+ unsigned long datasize = count - sizeof(attributes); - unsigned long newdatasize; - - if (count < sizeof(attributes)) --- -1.7.12.1 - - -From a268bdf6d7ce623ea4bdfcf39aa52ed3fbfdfd65 Mon Sep 17 00:00:00 2001 -From: Matt Fleming -Date: Tue, 23 Oct 2012 12:41:03 +0100 -Subject: [PATCH 16/17] efivarfs: Return a consistent error when - efivarfs_get_inode() fails - -Instead of returning -ENOSPC if efivarfs_get_inode() fails we should -be returning -ENOMEM, since running out of memory is the only reason -it can fail. Furthermore, that's the error value used everywhere else -in this file. It's also less likely to confuse users that hit this -error case. - -Acked-by: Jeremy Kerr -Signed-off-by: Matt Fleming ---- - drivers/firmware/efivars.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c -index 6a858d1..58cec62 100644 ---- a/drivers/firmware/efivars.c -+++ b/drivers/firmware/efivars.c -@@ -911,7 +911,7 @@ static int efivarfs_create(struct inode *dir, struct dentry *dentry, - - inode = efivarfs_get_inode(dir->i_sb, dir, mode, 0); - if (!inode) -- return -ENOSPC; -+ return -ENOMEM; - - var = kzalloc(sizeof(struct efivar_entry), GFP_KERNEL); - if (!var) { --- -1.7.12.1 - - -From 9c3136c987175b179c0aa725d76cda156894f918 Mon Sep 17 00:00:00 2001 -From: Matt Fleming -Date: Fri, 26 Oct 2012 12:18:53 +0100 -Subject: [PATCH 17/17] efivarfs: Fix return value of efivarfs_file_write() - -We're stuffing a variable of type size_t (unsigned) into a ssize_t -(signed) which, even though both types should be the same number of -bits, it's just asking for sign issues to be introduced. - -Cc: Jeremy Kerr -Reported-by: Alan Cox -Signed-off-by: Matt Fleming ---- - drivers/firmware/efivars.c | 13 ++++++++----- - 1 file changed, 8 insertions(+), 5 deletions(-) - -diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c -index 58cec62..9ac9340 100644 ---- a/drivers/firmware/efivars.c -+++ b/drivers/firmware/efivars.c -@@ -694,6 +694,7 @@ static ssize_t efivarfs_file_write(struct file *file, - struct inode *inode = file->f_mapping->host; - unsigned long datasize = count - sizeof(attributes); - unsigned long newdatasize; -+ ssize_t bytes = 0; - - if (count < sizeof(attributes)) - return -EINVAL; -@@ -706,22 +707,22 @@ static ssize_t efivarfs_file_write(struct file *file, - efivars = var->efivars; - - if (copy_from_user(&attributes, userbuf, sizeof(attributes))) { -- count = -EFAULT; -+ bytes = -EFAULT; - goto out; - } - - if (attributes & ~(EFI_VARIABLE_MASK)) { -- count = -EINVAL; -+ bytes = -EINVAL; - goto out; - } - - if (copy_from_user(data, userbuf + sizeof(attributes), datasize)) { -- count = -EFAULT; -+ bytes = -EFAULT; - goto out; - } - - if (validate_var(&var->var, data, datasize) == false) { -- count = -EINVAL; -+ bytes = -EINVAL; - goto out; - } - -@@ -744,6 +745,8 @@ static ssize_t efivarfs_file_write(struct file *file, - return efi_status_to_err(status); - } - -+ bytes = count; -+ - /* - * Writing to the variable may have caused a change in size (which - * could either be an append or an overwrite), or the variable to be -@@ -778,7 +781,7 @@ static ssize_t efivarfs_file_write(struct file *file, - out: - kfree(data); - -- return count; -+ return bytes; - } - - static ssize_t efivarfs_file_read(struct file *file, char __user *userbuf, --- -1.7.12.1 - diff --git a/exec-do-not-leave-bprm-interp-on-stack.patch b/exec-do-not-leave-bprm-interp-on-stack.patch deleted file mode 100644 index 5198824..0000000 --- a/exec-do-not-leave-bprm-interp-on-stack.patch +++ /dev/null @@ -1,118 +0,0 @@ -From 6752ab4cb863fc63ed85f1ca78a42235c09fad83 Mon Sep 17 00:00:00 2001 -From: Kees Cook -Date: Mon, 26 Nov 2012 09:07:50 -0500 -Subject: [PATCH 1/2] exec: do not leave bprm->interp on stack - -If a series of scripts are executed, each triggering module loading via -unprintable bytes in the script header, kernel stack contents can leak -into the command line. - -Normally execution of binfmt_script and binfmt_misc happens recursively. -However, when modules are enabled, and unprintable bytes exist in the -bprm->buf, execution will restart after attempting to load matching binfmt -modules. Unfortunately, the logic in binfmt_script and binfmt_misc does -not expect to get restarted. They leave bprm->interp pointing to their -local stack. This means on restart bprm->interp is left pointing into -unused stack memory which can then be copied into the userspace argv -areas. - -After additional study, it seems that both recursion and restart remains -the desirable way to handle exec with scripts, misc, and modules. As -such, we need to protect the changes to interp. - -This changes the logic to require allocation for any changes to the -bprm->interp. To avoid adding a new kmalloc to every exec, the default -value is left as-is. Only when passing through binfmt_script or -binfmt_misc does an allocation take place. - -For a proof of concept, see DoTest.sh from: -http://www.halfdog.net/Security/2012/LinuxKernelBinfmtScriptStackDataDisclosure/ - -Signed-off-by: Kees Cook -Cc: halfdog -Cc: P J P -Cc: Alexander Viro -Cc: -Signed-off-by: Andrew Morton ---- - fs/binfmt_misc.c | 5 ++++- - fs/binfmt_script.c | 4 +++- - fs/exec.c | 15 +++++++++++++++ - include/linux/binfmts.h | 1 + - 4 files changed, 23 insertions(+), 2 deletions(-) - -diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c -index 790b3cd..772428d 100644 ---- a/fs/binfmt_misc.c -+++ b/fs/binfmt_misc.c -@@ -176,7 +176,10 @@ static int load_misc_binary(struct linux_binprm *bprm, struct pt_regs *regs) - goto _error; - bprm->argc ++; - -- bprm->interp = iname; /* for binfmt_script */ -+ /* Update interp in case binfmt_script needs it. */ -+ retval = bprm_change_interp(iname, bprm); -+ if (retval < 0) -+ goto _error; - - interp_file = open_exec (iname); - retval = PTR_ERR (interp_file); -diff --git a/fs/binfmt_script.c b/fs/binfmt_script.c -index d3b8c1f..df49d48 100644 ---- a/fs/binfmt_script.c -+++ b/fs/binfmt_script.c -@@ -82,7 +82,9 @@ static int load_script(struct linux_binprm *bprm,struct pt_regs *regs) - retval = copy_strings_kernel(1, &i_name, bprm); - if (retval) return retval; - bprm->argc++; -- bprm->interp = interp; -+ retval = bprm_change_interp(interp, bprm); -+ if (retval < 0) -+ return retval; - - /* - * OK, now restart the process with the interpreter's dentry. -diff --git a/fs/exec.c b/fs/exec.c -index 0039055..c6e6de4 100644 ---- a/fs/exec.c -+++ b/fs/exec.c -@@ -1175,9 +1175,24 @@ void free_bprm(struct linux_binprm *bprm) - mutex_unlock(¤t->signal->cred_guard_mutex); - abort_creds(bprm->cred); - } -+ /* If a binfmt changed the interp, free it. */ -+ if (bprm->interp != bprm->filename) -+ kfree(bprm->interp); - kfree(bprm); - } - -+int bprm_change_interp(char *interp, struct linux_binprm *bprm) -+{ -+ /* If a binfmt changed the interp, free it first. */ -+ if (bprm->interp != bprm->filename) -+ kfree(bprm->interp); -+ bprm->interp = kstrdup(interp, GFP_KERNEL); -+ if (!bprm->interp) -+ return -ENOMEM; -+ return 0; -+} -+EXPORT_SYMBOL(bprm_change_interp); -+ - /* - * install the new credentials for this executable - */ -diff --git a/include/linux/binfmts.h b/include/linux/binfmts.h -index cfcc6bf..de0628e 100644 ---- a/include/linux/binfmts.h -+++ b/include/linux/binfmts.h -@@ -114,6 +114,7 @@ extern int setup_arg_pages(struct linux_binprm * bprm, - unsigned long stack_top, - int executable_stack); - extern int bprm_mm_init(struct linux_binprm *bprm); -+extern int bprm_change_interp(char *interp, struct linux_binprm *bprm); - extern int copy_strings_kernel(int argc, const char *const *argv, - struct linux_binprm *bprm); - extern int prepare_bprm_creds(struct linux_binprm *bprm); --- -1.8.0 - diff --git a/exec-use-eloop-for-max-recursion-depth.patch b/exec-use-eloop-for-max-recursion-depth.patch deleted file mode 100644 index a3c4888..0000000 --- a/exec-use-eloop-for-max-recursion-depth.patch +++ /dev/null @@ -1,144 +0,0 @@ -From ba1b23d05259e31d30a78017cdfbc010dcb08aa6 Mon Sep 17 00:00:00 2001 -From: Kees Cook -Date: Mon, 26 Nov 2012 09:02:11 -0500 -Subject: [PATCH 2/2] exec: use -ELOOP for max recursion depth - -To avoid an explosion of request_module calls on a chain of abusive -scripts, fail maximum recursion with -ELOOP instead of -ENOEXEC. As soon -as maximum recursion depth is hit, the error will fail all the way back -up the chain, aborting immediately. - -This also has the side-effect of stopping the user's shell from attempting -to reexecute the top-level file as a shell script. As seen in the -dash source: - - if (cmd != path_bshell && errno == ENOEXEC) { - *argv-- = cmd; - *argv = cmd = path_bshell; - goto repeat; - } - -The above logic was designed for running scripts automatically that lacked -the "#!" header, not to re-try failed recursion. On a legitimate -ENOEXEC, -things continue to behave as the shell expects. - -Additionally, when tracking recursion, the binfmt handlers should not be -involved. The recursion being tracked is the depth of calls through -search_binary_handler(), so that function should be exclusively responsible -for tracking the depth. - -Signed-off-by: Kees Cook -Cc: halfdog -Cc: P J P -Cc: Alexander Viro -Signed-off-by: Andrew Morton ---- - fs/binfmt_em86.c | 1 - - fs/binfmt_misc.c | 6 ------ - fs/binfmt_script.c | 4 +--- - fs/exec.c | 10 +++++----- - include/linux/binfmts.h | 2 -- - 5 files changed, 6 insertions(+), 17 deletions(-) - -diff --git a/fs/binfmt_em86.c b/fs/binfmt_em86.c -index 2790c7e..575796a 100644 ---- a/fs/binfmt_em86.c -+++ b/fs/binfmt_em86.c -@@ -42,7 +42,6 @@ static int load_em86(struct linux_binprm *bprm,struct pt_regs *regs) - return -ENOEXEC; - } - -- bprm->recursion_depth++; /* Well, the bang-shell is implicit... */ - allow_write_access(bprm->file); - fput(bprm->file); - bprm->file = NULL; -diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c -index 772428d..f0f1a06 100644 ---- a/fs/binfmt_misc.c -+++ b/fs/binfmt_misc.c -@@ -117,10 +117,6 @@ static int load_misc_binary(struct linux_binprm *bprm, struct pt_regs *regs) - if (!enabled) - goto _ret; - -- retval = -ENOEXEC; -- if (bprm->recursion_depth > BINPRM_MAX_RECURSION) -- goto _ret; -- - /* to keep locking time low, we copy the interpreter string */ - read_lock(&entries_lock); - fmt = check_file(bprm); -@@ -200,8 +196,6 @@ static int load_misc_binary(struct linux_binprm *bprm, struct pt_regs *regs) - if (retval < 0) - goto _error; - -- bprm->recursion_depth++; -- - retval = search_binary_handler (bprm, regs); - if (retval < 0) - goto _error; -diff --git a/fs/binfmt_script.c b/fs/binfmt_script.c -index df49d48..8ae4be1 100644 ---- a/fs/binfmt_script.c -+++ b/fs/binfmt_script.c -@@ -22,15 +22,13 @@ static int load_script(struct linux_binprm *bprm,struct pt_regs *regs) - char interp[BINPRM_BUF_SIZE]; - int retval; - -- if ((bprm->buf[0] != '#') || (bprm->buf[1] != '!') || -- (bprm->recursion_depth > BINPRM_MAX_RECURSION)) -+ if ((bprm->buf[0] != '#') || (bprm->buf[1] != '!')) - return -ENOEXEC; - /* - * This section does the #! interpretation. - * Sorta complicated, but hopefully it will work. -TYT - */ - -- bprm->recursion_depth++; - allow_write_access(bprm->file); - fput(bprm->file); - bprm->file = NULL; -diff --git a/fs/exec.c b/fs/exec.c -index c6e6de4..85c1f9e 100644 ---- a/fs/exec.c -+++ b/fs/exec.c -@@ -1371,6 +1371,10 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs) - struct linux_binfmt *fmt; - pid_t old_pid, old_vpid; - -+ /* This allows 4 levels of binfmt rewrites before failing hard. */ -+ if (depth > 5) -+ return -ELOOP; -+ - retval = security_bprm_check(bprm); - if (retval) - return retval; -@@ -1395,12 +1399,8 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs) - if (!try_module_get(fmt->module)) - continue; - read_unlock(&binfmt_lock); -+ bprm->recursion_depth = depth + 1; - retval = fn(bprm, regs); -- /* -- * Restore the depth counter to its starting value -- * in this call, so we don't have to rely on every -- * load_binary function to restore it on return. -- */ - bprm->recursion_depth = depth; - if (retval >= 0) { - if (depth == 0) { -diff --git a/include/linux/binfmts.h b/include/linux/binfmts.h -index de0628e..54135f6 100644 ---- a/include/linux/binfmts.h -+++ b/include/linux/binfmts.h -@@ -54,8 +54,6 @@ struct linux_binprm { - #define BINPRM_FLAGS_EXECFD_BIT 1 - #define BINPRM_FLAGS_EXECFD (1 << BINPRM_FLAGS_EXECFD_BIT) - --#define BINPRM_MAX_RECURSION 4 -- - /* Function parameter for binfmt->coredump */ - struct coredump_params { - siginfo_t *siginfo; --- -1.8.0 - diff --git a/handle-efi-roms.patch b/handle-efi-roms.patch deleted file mode 100644 index bc08054..0000000 --- a/handle-efi-roms.patch +++ /dev/null @@ -1,388 +0,0 @@ -diff -ur linux-3.6.0-0.rc2.git2.1.fc18.x86_64/arch/x86/boot/compressed/eboot.c ../kernel-3.5.fc18.bak/linux-3.6.0-0.rc2.git2.1.fc18.x86_64/arch/x86/boot/compressed/eboot.c ---- linux-3.6.0-0.rc2.git2.1.fc18.x86_64/arch/x86/boot/compressed/eboot.c 2012-08-22 15:26:32.485522068 -0400 -+++ ../kernel-3.5.fc18.bak/linux-3.6.0-0.rc2.git2.1.fc18.x86_64/arch/x86/boot/compressed/eboot.c 2012-08-22 15:25:40.529244868 -0400 -@@ -8,6 +8,7 @@ - * ----------------------------------------------------------------------- */ - - #include -+#include - #include - #include - #include -@@ -243,6 +244,121 @@ - *size = len; - } - -+static efi_status_t setup_efi_pci(struct boot_params *params) -+{ -+ efi_pci_io_protocol *pci; -+ efi_status_t status; -+ void **pci_handle; -+ efi_guid_t pci_proto = EFI_PCI_IO_PROTOCOL_GUID; -+ unsigned long nr_pci, size = 0; -+ int i; -+ struct setup_data *data; -+ -+ data = (struct setup_data *)params->hdr.setup_data; -+ -+ while (data && data->next) -+ data = (struct setup_data *)data->next; -+ -+ status = efi_call_phys5(sys_table->boottime->locate_handle, -+ EFI_LOCATE_BY_PROTOCOL, &pci_proto, -+ NULL, &size, pci_handle); -+ -+ if (status == EFI_BUFFER_TOO_SMALL) { -+ status = efi_call_phys3(sys_table->boottime->allocate_pool, -+ EFI_LOADER_DATA, size, &pci_handle); -+ -+ if (status != EFI_SUCCESS) -+ return status; -+ -+ status = efi_call_phys5(sys_table->boottime->locate_handle, -+ EFI_LOCATE_BY_PROTOCOL, &pci_proto, -+ NULL, &size, pci_handle); -+ } -+ -+ if (status != EFI_SUCCESS) -+ goto free_handle; -+ -+ nr_pci = size / sizeof(void *); -+ for (i = 0; i < nr_pci; i++) { -+ void *h = pci_handle[i]; -+ uint64_t attributes; -+ struct pci_setup_rom *rom; -+ -+ status = efi_call_phys3(sys_table->boottime->handle_protocol, -+ h, &pci_proto, &pci); -+ -+ if (status != EFI_SUCCESS) -+ continue; -+ -+ if (!pci) -+ continue; -+ -+ status = efi_call_phys4(pci->attributes, pci, -+ EfiPciIoAttributeOperationGet, 0, -+ &attributes); -+ -+ if (status != EFI_SUCCESS) -+ continue; -+ -+ if (!attributes & EFI_PCI_IO_ATTRIBUTE_EMBEDDED_ROM) -+ continue; -+ -+ if (!pci->romimage || !pci->romsize) -+ continue; -+ -+ size = pci->romsize + sizeof(*rom); -+ -+ status = efi_call_phys3(sys_table->boottime->allocate_pool, -+ EFI_LOADER_DATA, size, &rom); -+ -+ if (status != EFI_SUCCESS) -+ continue; -+ -+ rom->data.type = SETUP_PCI; -+ rom->data.len = size - sizeof(struct setup_data); -+ rom->data.next = NULL; -+ rom->pcilen = pci->romsize; -+ -+ status = efi_call_phys5(pci->pci.read, pci, -+ EfiPciIoWidthUint16, PCI_VENDOR_ID, -+ 1, &(rom->vendor)); -+ -+ if (status != EFI_SUCCESS) -+ goto free_struct; -+ -+ status = efi_call_phys5(pci->pci.read, pci, -+ EfiPciIoWidthUint16, PCI_DEVICE_ID, -+ 1, &(rom->devid)); -+ -+ if (status != EFI_SUCCESS) -+ goto free_struct; -+ -+ status = efi_call_phys5(pci->get_location, pci, -+ &(rom->segment), &(rom->bus), -+ &(rom->device), &(rom->function)); -+ -+ if (status != EFI_SUCCESS) -+ goto free_struct; -+ -+ memcpy(rom->romdata, pci->romimage, pci->romsize); -+ -+ if (data) -+ data->next = (uint64_t)rom; -+ else -+ params->hdr.setup_data = (uint64_t)rom; -+ -+ data = (struct setup_data *)rom; -+ -+ continue; -+ free_struct: -+ efi_call_phys1(sys_table->boottime->free_pool, rom); -+ } -+ -+free_handle: -+ efi_call_phys1(sys_table->boottime->free_pool, pci_handle); -+ return status; -+} -+ - /* - * See if we have Graphics Output Protocol - */ -@@ -1052,6 +1171,8 @@ - - setup_graphics(boot_params); - -+ setup_efi_pci(boot_params); -+ - status = efi_call_phys3(sys_table->boottime->allocate_pool, - EFI_LOADER_DATA, sizeof(*gdt), - (void **)&gdt); -diff -ur linux-3.6.0-0.rc2.git2.1.fc18.x86_64/arch/x86/include/asm/bootparam.h ../kernel-3.5.fc18.bak/linux-3.6.0-0.rc2.git2.1.fc18.x86_64/arch/x86/include/asm/bootparam.h ---- linux-3.6.0-0.rc2.git2.1.fc18.x86_64/arch/x86/include/asm/bootparam.h 2012-08-22 15:26:32.485522068 -0400 -+++ ../kernel-3.5.fc18.bak/linux-3.6.0-0.rc2.git2.1.fc18.x86_64/arch/x86/include/asm/bootparam.h 2012-08-22 15:25:40.530244882 -0400 -@@ -13,6 +13,7 @@ - #define SETUP_NONE 0 - #define SETUP_E820_EXT 1 - #define SETUP_DTB 2 -+#define SETUP_PCI 3 - - /* extensible setup data list node */ - struct setup_data { -diff -ur linux-3.6.0-0.rc2.git2.1.fc18.x86_64/arch/x86/include/asm/pci.h ../kernel-3.5.fc18.bak/linux-3.6.0-0.rc2.git2.1.fc18.x86_64/arch/x86/include/asm/pci.h ---- linux-3.6.0-0.rc2.git2.1.fc18.x86_64/arch/x86/include/asm/pci.h 2012-07-21 16:58:29.000000000 -0400 -+++ ../kernel-3.5.fc18.bak/linux-3.6.0-0.rc2.git2.1.fc18.x86_64/arch/x86/include/asm/pci.h 2012-08-22 15:25:40.530244882 -0400 -@@ -171,4 +171,16 @@ - } - #endif - -+struct pci_setup_rom { -+ struct setup_data data; -+ uint16_t vendor; -+ uint16_t devid; -+ uint64_t pcilen; -+ unsigned long segment; -+ unsigned long bus; -+ unsigned long device; -+ unsigned long function; -+ uint8_t romdata[0]; -+}; -+ - #endif /* _ASM_X86_PCI_H */ -diff -ur linux-3.6.0-0.rc2.git2.1.fc18.x86_64/arch/x86/pci/common.c ../kernel-3.5.fc18.bak/linux-3.6.0-0.rc2.git2.1.fc18.x86_64/arch/x86/pci/common.c ---- linux-3.6.0-0.rc2.git2.1.fc18.x86_64/arch/x86/pci/common.c 2012-08-22 15:24:45.477951182 -0400 -+++ ../kernel-3.5.fc18.bak/linux-3.6.0-0.rc2.git2.1.fc18.x86_64/arch/x86/pci/common.c 2012-08-22 15:25:40.530244882 -0400 -@@ -17,6 +17,7 @@ - #include - #include - #include -+#include - - unsigned int pci_probe = PCI_PROBE_BIOS | PCI_PROBE_CONF1 | PCI_PROBE_CONF2 | - PCI_PROBE_MMCONF; -@@ -608,6 +609,38 @@ - return (pci_probe & PCI_ASSIGN_ALL_BUSSES) ? 1 : 0; - } - -+int pcibios_add_device(struct pci_dev *dev) -+{ -+ struct setup_data *data; -+ struct pci_setup_rom *rom; -+ u64 pa_data; -+ -+ if (boot_params.hdr.version < 0x0209) -+ return 0; -+ -+ pa_data = boot_params.hdr.setup_data; -+ while (pa_data) { -+ data = phys_to_virt(pa_data); -+ -+ if (data->type == SETUP_PCI) { -+ rom = (struct pci_setup_rom *)data; -+ -+ if ((pci_domain_nr(dev->bus) == rom->segment) && -+ (dev->bus->number == rom->bus) && -+ (PCI_SLOT(dev->devfn) == rom->device) && -+ (PCI_FUNC(dev->devfn) == rom->function) && -+ (dev->vendor == rom->vendor) && -+ (dev->device == rom->devid)) { -+ dev->rom = (void *)(pa_data + -+ offsetof(struct pci_setup_rom, romdata)); -+ dev->romlen = rom->pcilen; -+ } -+ } -+ pa_data = data->next; -+ } -+ return 0; -+} -+ - int pcibios_enable_device(struct pci_dev *dev, int mask) - { - int err; -diff -ur linux-3.6.0-0.rc2.git2.1.fc18.x86_64/drivers/pci/bus.c ../kernel-3.5.fc18.bak/linux-3.6.0-0.rc2.git2.1.fc18.x86_64/drivers/pci/bus.c ---- linux-3.6.0-0.rc2.git2.1.fc18.x86_64/drivers/pci/bus.c 2012-08-22 15:24:47.425961575 -0400 -+++ ../kernel-3.5.fc18.bak/linux-3.6.0-0.rc2.git2.1.fc18.x86_64/drivers/pci/bus.c 2012-08-22 15:26:20.147456241 -0400 -@@ -166,6 +166,11 @@ - int retval; - - pci_fixup_device(pci_fixup_final, dev); -+ -+ retval = pcibios_add_device(dev); -+ if (retval) -+ return retval; -+ - retval = device_add(&dev->dev); - if (retval) - return retval; -diff -ur linux-3.6.0-0.rc2.git2.1.fc18.x86_64/drivers/pci/pci.c ../kernel-3.5.fc18.bak/linux-3.6.0-0.rc2.git2.1.fc18.x86_64/drivers/pci/pci.c ---- linux-3.6.0-0.rc2.git2.1.fc18.x86_64/drivers/pci/pci.c 2012-08-22 15:24:47.432961612 -0400 -+++ ../kernel-3.5.fc18.bak/linux-3.6.0-0.rc2.git2.1.fc18.x86_64/drivers/pci/pci.c 2012-08-22 15:25:40.531244893 -0400 -@@ -1385,6 +1385,19 @@ - dr->pinned = 1; - } - -+/* -+ * pcibios_add_device - provide arch specific hooks when adding device dev -+ * @dev: the PCI device being added -+ * -+ * Permits the platform to provide architecture specific functionality when -+ * devices are added. This is the default implementation. Architecture -+ * implementations can override this. -+ */ -+int __attribute__ ((weak)) pcibios_add_device (struct pci_dev *dev) -+{ -+ return 0; -+} -+ - /** - * pcibios_disable_device - disable arch specific PCI resources for device dev - * @dev: the PCI device to disable -diff -ur linux-3.6.0-0.rc2.git2.1.fc18.x86_64/drivers/pci/rom.c ../kernel-3.5.fc18.bak/linux-3.6.0-0.rc2.git2.1.fc18.x86_64/drivers/pci/rom.c ---- linux-3.6.0-0.rc2.git2.1.fc18.x86_64/drivers/pci/rom.c 2012-07-21 16:58:29.000000000 -0400 -+++ ../kernel-3.5.fc18.bak/linux-3.6.0-0.rc2.git2.1.fc18.x86_64/drivers/pci/rom.c 2012-08-22 15:25:40.531244893 -0400 -@@ -126,6 +126,12 @@ - /* primary video rom always starts here */ - start = (loff_t)0xC0000; - *size = 0x20000; /* cover C000:0 through E000:0 */ -+ /* -+ * Some devices may provide ROMs via a source other than the BAR -+ */ -+ } else if (pdev->rom && pdev->romlen) { -+ *size = pdev->romlen; -+ return phys_to_virt(pdev->rom); - } else { - if (res->flags & - (IORESOURCE_ROM_COPY | IORESOURCE_ROM_BIOS_COPY)) { -@@ -219,7 +225,8 @@ - if (res->flags & (IORESOURCE_ROM_COPY | IORESOURCE_ROM_BIOS_COPY)) - return; - -- iounmap(rom); -+ if (!pdev->rom || !pdev->romlen) -+ iounmap(rom); - - /* Disable again before continuing, leave enabled if pci=rom */ - if (!(res->flags & (IORESOURCE_ROM_ENABLE | IORESOURCE_ROM_SHADOW))) -diff -ur linux-3.6.0-0.rc2.git2.1.fc18.x86_64/include/linux/efi.h ../kernel-3.5.fc18.bak/linux-3.6.0-0.rc2.git2.1.fc18.x86_64/include/linux/efi.h ---- linux-3.6.0-0.rc2.git2.1.fc18.x86_64/include/linux/efi.h 2012-08-22 15:24:49.550972911 -0400 -+++ ../kernel-3.5.fc18.bak/linux-3.6.0-0.rc2.git2.1.fc18.x86_64/include/linux/efi.h 2012-08-22 15:25:40.533244906 -0400 -@@ -196,6 +196,77 @@ - void *create_event_ex; - } efi_boot_services_t; - -+typedef enum { -+ EfiPciIoWidthUint8, -+ EfiPciIoWidthUint16, -+ EfiPciIoWidthUint32, -+ EfiPciIoWidthUint64, -+ EfiPciIoWidthFifoUint8, -+ EfiPciIoWidthFifoUint16, -+ EfiPciIoWidthFifoUint32, -+ EfiPciIoWidthFifoUint64, -+ EfiPciIoWidthFillUint8, -+ EfiPciIoWidthFillUint16, -+ EfiPciIoWidthFillUint32, -+ EfiPciIoWidthFillUint64, -+ EfiPciIoWidthMaximum -+} EFI_PCI_IO_PROTOCOL_WIDTH; -+ -+typedef enum { -+ EfiPciIoAttributeOperationGet, -+ EfiPciIoAttributeOperationSet, -+ EfiPciIoAttributeOperationEnable, -+ EfiPciIoAttributeOperationDisable, -+ EfiPciIoAttributeOperationSupported, -+ EfiPciIoAttributeOperationMaximum -+} EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION; -+ -+ -+typedef struct { -+ void *read; -+ void *write; -+} efi_pci_io_protocol_access_t; -+ -+typedef struct { -+ void *poll_mem; -+ void *poll_io; -+ efi_pci_io_protocol_access_t mem; -+ efi_pci_io_protocol_access_t io; -+ efi_pci_io_protocol_access_t pci; -+ void *copy_mem; -+ void *map; -+ void *unmap; -+ void *allocate_buffer; -+ void *free_buffer; -+ void *flush; -+ void *get_location; -+ void *attributes; -+ void *get_bar_attributes; -+ void *set_bar_attributes; -+ uint64_t romsize; -+ void *romimage; -+} efi_pci_io_protocol; -+ -+#define EFI_PCI_IO_ATTRIBUTE_ISA_MOTHERBOARD_IO 0x0001 -+#define EFI_PCI_IO_ATTRIBUTE_ISA_IO 0x0002 -+#define EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO 0x0004 -+#define EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY 0x0008 -+#define EFI_PCI_IO_ATTRIBUTE_VGA_IO 0x0010 -+#define EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO 0x0020 -+#define EFI_PCI_IO_ATTRIBUTE_IDE_SECONDARY_IO 0x0040 -+#define EFI_PCI_IO_ATTRIBUTE_MEMORY_WRITE_COMBINE 0x0080 -+#define EFI_PCI_IO_ATTRIBUTE_IO 0x0100 -+#define EFI_PCI_IO_ATTRIBUTE_MEMORY 0x0200 -+#define EFI_PCI_IO_ATTRIBUTE_BUS_MASTER 0x0400 -+#define EFI_PCI_IO_ATTRIBUTE_MEMORY_CACHED 0x0800 -+#define EFI_PCI_IO_ATTRIBUTE_MEMORY_DISABLE 0x1000 -+#define EFI_PCI_IO_ATTRIBUTE_EMBEDDED_DEVICE 0x2000 -+#define EFI_PCI_IO_ATTRIBUTE_EMBEDDED_ROM 0x4000 -+#define EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE 0x8000 -+#define EFI_PCI_IO_ATTRIBUTE_ISA_IO_16 0x10000 -+#define EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO_16 0x20000 -+#define EFI_PCI_IO_ATTRIBUTE_VGA_IO_16 0x40000 -+ - /* - * Types and defines for EFI ResetSystem - */ -diff -ur linux-3.6.0-0.rc2.git2.1.fc18.x86_64/include/linux/pci.h ../kernel-3.5.fc18.bak/linux-3.6.0-0.rc2.git2.1.fc18.x86_64/include/linux/pci.h ---- linux-3.6.0-0.rc2.git2.1.fc18.x86_64/include/linux/pci.h 2012-08-22 15:24:48.703968392 -0400 -+++ ../kernel-3.5.fc18.bak/linux-3.6.0-0.rc2.git2.1.fc18.x86_64/include/linux/pci.h 2012-08-22 15:25:40.534244910 -0400 -@@ -355,6 +355,8 @@ - }; - struct pci_ats *ats; /* Address Translation Service */ - #endif -+ void *rom; /* Physical pointer to ROM if it's not from the BAR */ -+ size_t romlen; /* Length of ROM if it's not from the BAR */ - }; - - static inline struct pci_dev *pci_physfn(struct pci_dev *dev) -@@ -1582,6 +1584,7 @@ - void pcibios_set_master(struct pci_dev *dev); - int pcibios_set_pcie_reset_state(struct pci_dev *dev, - enum pcie_reset_state state); -+int pcibios_add_device(struct pci_dev *dev); - - #ifdef CONFIG_PCI_MMCONFIG - extern void __init pci_mmcfg_early_init(void); diff --git a/kernel.spec b/kernel.spec index 140c977..92f286b 100644 --- a/kernel.spec +++ b/kernel.spec @@ -6,7 +6,7 @@ Summary: The Linux kernel # For a stable, released kernel, released_kernel should be 1. For rawhide # and/or a kernel built from an rc or git snapshot, released_kernel should # be 0. -%global released_kernel 1 +%global released_kernel 0 # Sign modules on x86. Make sure the config files match this setting if more # architectures are added. @@ -62,7 +62,7 @@ Summary: The Linux kernel # For non-released -rc kernels, this will be appended after the rcX and # gitX tags, so a 3 here would become part of release "0.rcX.gitX.3" # -%global baserelease 7 +%global baserelease 1 %global fedora_build %{baserelease} # base_sublevel is the kernel version we're starting with and patching @@ -93,9 +93,9 @@ Summary: The Linux kernel # The next upstream release sublevel (base_sublevel+1) %define upstream_sublevel %(echo $((%{base_sublevel} + 1))) # The rc snapshot level -%define rcrev 8 +%define rcrev 2 # The git snapshot level -%define gitrev 0 +%define gitrev 1 # Set rpm version accordingly %define rpmversion 3.%{upstream_sublevel}.0 %endif @@ -654,8 +654,6 @@ Patch04: linux-2.6-compile-fixes.patch # build tweak for build ID magic, even for -vanilla Patch05: linux-2.6-makefile-after_link.patch -Patch06: power-x86-destdir.patch - %if !%{nopatches} @@ -690,14 +688,9 @@ Patch700: linux-2.6-e1000-ich9-montevina.patch Patch800: linux-2.6-crash-driver.patch # crypto/ -Patch900: modsign-post-KS-jwb.patch # secure boot -Patch1000: secure-boot-20121212.patch -Patch1001: efivarfs-3.7.patch - -# Improve PCI support on UEFI -Patch1100: handle-efi-roms.patch +Patch1000: secure-boot-20130104.patch # virt + ksm patches @@ -763,21 +756,9 @@ Patch22001: selinux-apply-different-permission-to-ptrace-child.patch # Build patch, should go away Patch22070: irqnr-build.patch -#rhbz 874791 -Patch22125: Bluetooth-Add-support-for-BCM20702A0.patch - #rhbz 859485 Patch21226: vt-Drop-K_OFF-for-VC_MUTE.patch -#rhbz CVE-2012-4530 868285 880147 -Patch21228: exec-do-not-leave-bprm-interp-on-stack.patch -Patch21229: exec-use-eloop-for-max-recursion-depth.patch - -#rhbz 851278 -Patch21234: Revert-8139cp-revert-set-ring-address-before-enabling.patch -Patch21232: 8139cp-set-ring-address-after-enabling-C-mode.patch -Patch21233: 8139cp-re-enable-interrupts-after-tx-timeout.patch - #rhbz 883414 Patch21236: mac80211-fix-ibss-scanning.patch @@ -1333,8 +1314,6 @@ ApplyPatch linux-2.6-makefile-after_link.patch # ApplyOptionalPatch linux-2.6-compile-fixes.patch -ApplyPatch power-x86-destdir.patch - %if !%{nopatches} # revert patches from upstream that conflict or that we get via other means @@ -1352,11 +1331,11 @@ ApplyPatch vmbugon-warnon.patch # ApplyPatch arm-export-read_current_timer.patch ApplyPatch arm-allnoconfig-error-__LINUX_ARM_ARCH__-undeclared.patch -ApplyPatch arm-omapdrm-fixinc.patch +# ApplyPatch arm-omapdrm-fixinc.patch ApplyPatch arm-imx-fixdrm.patch -ApplyPatch arm-tegra-nvec-kconfig.patch +# ApplyPatch arm-tegra-nvec-kconfig.patch ApplyPatch arm-tegra-usb-no-reset-linux33.patch -ApplyPatch arm-tegra-sdhci-module-fix.patch +# ApplyPatch arm-tegra-sdhci-module-fix.patch # # bugfixes to drivers and filesystems @@ -1424,14 +1403,9 @@ ApplyPatch linux-2.6-crash-driver.patch ApplyPatch linux-2.6-e1000-ich9-montevina.patch # crypto/ -ApplyPatch modsign-post-KS-jwb.patch # secure boot -ApplyPatch efivarfs-3.7.patch -ApplyPatch secure-boot-20121212.patch - -# Improved PCI support for UEFI -ApplyPatch handle-efi-roms.patch +ApplyPatch secure-boot-20130104.patch # Assorted Virt Fixes @@ -1481,21 +1455,9 @@ ApplyPatch selinux-apply-different-permission-to-ptrace-child.patch #Build patch, should go away ApplyPatch irqnr-build.patch -#rhbz 874791 -ApplyPatch Bluetooth-Add-support-for-BCM20702A0.patch - #rhbz 859485 ApplyPatch vt-Drop-K_OFF-for-VC_MUTE.patch -#rhbz CVE-2012-4530 868285 880147 -ApplyPatch exec-do-not-leave-bprm-interp-on-stack.patch -ApplyPatch exec-use-eloop-for-max-recursion-depth.patch - -#rhbz 851278 -ApplyPatch Revert-8139cp-revert-set-ring-address-before-enabling.patch -ApplyPatch 8139cp-set-ring-address-after-enabling-C-mode.patch -ApplyPatch 8139cp-re-enable-interrupts-after-tx-timeout.patch - #rhbz 883414 ApplyPatch mac80211-fix-ibss-scanning.patch @@ -2368,6 +2330,12 @@ fi # ||----w | # || || %changelog +* Fri Jan 04 2013 Justin M. Forbes - 3.8.0-0.rc2.git1.1 +- Linux v3.8-rc2-116-g5f243b9 + +* Thu Jan 03 2013 Justin M. Forbes +- Initial 3.8-rc2 rebase + * Wed Jan 02 2013 Josh Boyer - BR the hostname package (rhbz 886113) diff --git a/modsign-post-KS-jwb.patch b/modsign-post-KS-jwb.patch deleted file mode 100644 index 1bafd22..0000000 --- a/modsign-post-KS-jwb.patch +++ /dev/null @@ -1,78 +0,0 @@ -From 56713a28675b966e027a824a0130b80dffab209f Mon Sep 17 00:00:00 2001 -From: Josh Boyer -Date: Mon, 5 Nov 2012 09:09:24 +1030 -Subject: [PATCH] MODSIGN: Add modules_sign make target - -If CONFIG_MODULE_SIG is set, and 'make modules_sign' is called then this -patch will cause the modules to get a signature appended. The make target -is intended to be run after 'make modules_install', and will modify the -modules in-place in the installed location. It can be used to produce -signed modules after they have been processed by distribution build -scripts. - -Signed-off-by: Josh Boyer -Signed-off-by: Rusty Russell (minor typo fix) ---- - Makefile | 6 ++++++ - scripts/Makefile.modsign | 32 ++++++++++++++++++++++++++++++++ - 2 files changed, 38 insertions(+), 0 deletions(-) - create mode 100644 scripts/Makefile.modsign - -diff --git a/Makefile b/Makefile -index 42d0e56..253aa1b 100644 ---- a/Makefile -+++ b/Makefile -@@ -981,6 +981,12 @@ _modinst_post: _modinst_ - $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.fwinst obj=firmware __fw_modinst - $(call cmd,depmod) - -+ifeq ($(CONFIG_MODULE_SIG), y) -+PHONY += modules_sign -+modules_sign: -+ $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modsign -+endif -+ - else # CONFIG_MODULES - - # Modules not configured -diff --git a/scripts/Makefile.modsign b/scripts/Makefile.modsign -new file mode 100644 -index 0000000..abfda62 ---- /dev/null -+++ b/scripts/Makefile.modsign -@@ -0,0 +1,32 @@ -+# ========================================================================== -+# Signing modules -+# ========================================================================== -+ -+PHONY := __modsign -+__modsign: -+ -+include scripts/Kbuild.include -+ -+__modules := $(sort $(shell grep -h '\.ko' /dev/null $(wildcard $(MODVERDIR)/*.mod))) -+modules := $(patsubst %.o,%.ko,$(wildcard $(__modules:.ko=.o))) -+ -+PHONY += $(modules) -+__modsign: $(modules) -+ @: -+ -+quiet_cmd_sign_ko = SIGN [M] $(2)/$(notdir $@) -+ cmd_sign_ko = $(mod_sign_cmd) $(2)/$(notdir $@) -+ -+# Modules built outside the kernel source tree go into extra by default -+INSTALL_MOD_DIR ?= extra -+ext-mod-dir = $(INSTALL_MOD_DIR)$(subst $(patsubst %/,%,$(KBUILD_EXTMOD)),,$(@D)) -+ -+modinst_dir = $(if $(KBUILD_EXTMOD),$(ext-mod-dir),kernel/$(@D)) -+ -+$(modules): -+ $(call cmd,sign_ko,$(MODLIB)/$(modinst_dir)) -+ -+# Declare the contents of the .PHONY variable as phony. We keep that -+# information in a variable se we can use it in if_changed and friends. -+ -+.PHONY: $(PHONY) --- -1.7.7.6 - diff --git a/power-x86-destdir.patch b/power-x86-destdir.patch deleted file mode 100644 index 9766531..0000000 --- a/power-x86-destdir.patch +++ /dev/null @@ -1,35 +0,0 @@ -diff --git a/tools/power/x86/turbostat/Makefile b/tools/power/x86/turbostat/Makefile -index f856495..984cc00 100644 ---- a/tools/power/x86/turbostat/Makefile -+++ b/tools/power/x86/turbostat/Makefile -@@ -1,3 +1,5 @@ -+DESTDIR ?= -+ - turbostat : turbostat.c - CFLAGS += -Wall - -@@ -5,5 +7,5 @@ clean : - rm -f turbostat - - install : -- install turbostat /usr/bin/turbostat -- install turbostat.8 /usr/share/man/man8 -+ install turbostat ${DESTDIR}/usr/bin/turbostat -+ install turbostat.8 ${DESTDIR}/usr/share/man/man8 -diff --git a/tools/power/x86/x86_energy_perf_policy/Makefile b/tools/power/x86/x86_energy_perf_policy/Makefile -index f458237..f9824f0 100644 ---- a/tools/power/x86/x86_energy_perf_policy/Makefile -+++ b/tools/power/x86/x86_energy_perf_policy/Makefile -@@ -1,8 +1,10 @@ -+DESTDIR ?= -+ - x86_energy_perf_policy : x86_energy_perf_policy.c - - clean : - rm -f x86_energy_perf_policy - - install : -- install x86_energy_perf_policy /usr/bin/ -- install x86_energy_perf_policy.8 /usr/share/man/man8/ -+ install x86_energy_perf_policy ${DESTDIR}/usr/bin/ -+ install x86_energy_perf_policy.8 ${DESTDIR}/usr/share/man/man8/ diff --git a/secure-boot-20121212.patch b/secure-boot-20121212.patch deleted file mode 100644 index 387302b..0000000 --- a/secure-boot-20121212.patch +++ /dev/null @@ -1,1452 +0,0 @@ -From d510ea864f470d96aafb75d0de7f09450407095e Mon Sep 17 00:00:00 2001 -From: Matthew Garrett -Date: Thu, 20 Sep 2012 10:40:56 -0400 -Subject: [PATCH 01/20] Secure boot: Add new capability - -Secure boot adds certain policy requirements, including that root must not -be able to do anything that could cause the kernel to execute arbitrary code. -The simplest way to handle this would seem to be to add a new capability -and gate various functionality on that. We'll then strip it from the initial -capability set if required. - -Signed-off-by: Matthew Garrett ---- - include/uapi/linux/capability.h | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - -diff --git a/include/uapi/linux/capability.h b/include/uapi/linux/capability.h -index ba478fa..7109e65 100644 ---- a/include/uapi/linux/capability.h -+++ b/include/uapi/linux/capability.h -@@ -343,7 +343,11 @@ struct vfs_cap_data { - - #define CAP_BLOCK_SUSPEND 36 - --#define CAP_LAST_CAP CAP_BLOCK_SUSPEND -+/* Allow things that trivially permit root to modify the running kernel */ -+ -+#define CAP_COMPROMISE_KERNEL 37 -+ -+#define CAP_LAST_CAP CAP_COMPROMISE_KERNEL - - #define cap_valid(x) ((x) >= 0 && (x) <= CAP_LAST_CAP) - --- -1.8.0.1 - - -From a07ae01ac4b304ac7f0e2b5d4193519f1a9eee8d Mon Sep 17 00:00:00 2001 -From: Matthew Garrett -Date: Thu, 20 Sep 2012 10:40:57 -0400 -Subject: [PATCH 02/20] PCI: Lock down BAR access in secure boot environments - -Any hardware that can potentially generate DMA has to be locked down from -userspace in order to avoid it being possible for an attacker to cause -arbitrary kernel behaviour. Default to paranoid - in future we can -potentially relax this for sufficiently IOMMU-isolated devices. - -Signed-off-by: Matthew Garrett ---- - drivers/pci/pci-sysfs.c | 9 +++++++++ - drivers/pci/proc.c | 8 +++++++- - drivers/pci/syscall.c | 2 +- - 3 files changed, 17 insertions(+), 2 deletions(-) - -diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c -index f39378d..1db1e74 100644 ---- a/drivers/pci/pci-sysfs.c -+++ b/drivers/pci/pci-sysfs.c -@@ -546,6 +546,9 @@ pci_write_config(struct file* filp, struct kobject *kobj, - loff_t init_off = off; - u8 *data = (u8*) buf; - -+ if (!capable(CAP_COMPROMISE_KERNEL)) -+ return -EPERM; -+ - if (off > dev->cfg_size) - return 0; - if (off + count > dev->cfg_size) { -@@ -852,6 +855,9 @@ pci_mmap_resource(struct kobject *kobj, struct bin_attribute *attr, - resource_size_t start, end; - int i; - -+ if (!capable(CAP_COMPROMISE_KERNEL)) -+ return -EPERM; -+ - for (i = 0; i < PCI_ROM_RESOURCE; i++) - if (res == &pdev->resource[i]) - break; -@@ -959,6 +965,9 @@ pci_write_resource_io(struct file *filp, struct kobject *kobj, - struct bin_attribute *attr, char *buf, - loff_t off, size_t count) - { -+ if (!capable(CAP_COMPROMISE_KERNEL)) -+ return -EPERM; -+ - return pci_resource_io(filp, kobj, attr, buf, off, count, true); - } - -diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c -index 9b8505c..35580bc 100644 ---- a/drivers/pci/proc.c -+++ b/drivers/pci/proc.c -@@ -139,6 +139,9 @@ proc_bus_pci_write(struct file *file, const char __user *buf, size_t nbytes, lof - int size = dp->size; - int cnt; - -+ if (!capable(CAP_COMPROMISE_KERNEL)) -+ return -EPERM; -+ - if (pos >= size) - return 0; - if (nbytes >= size) -@@ -219,6 +222,9 @@ static long proc_bus_pci_ioctl(struct file *file, unsigned int cmd, - #endif /* HAVE_PCI_MMAP */ - int ret = 0; - -+ if (!capable(CAP_COMPROMISE_KERNEL)) -+ return -EPERM; -+ - switch (cmd) { - case PCIIOC_CONTROLLER: - ret = pci_domain_nr(dev->bus); -@@ -259,7 +265,7 @@ static int proc_bus_pci_mmap(struct file *file, struct vm_area_struct *vma) - struct pci_filp_private *fpriv = file->private_data; - int i, ret; - -- if (!capable(CAP_SYS_RAWIO)) -+ if (!capable(CAP_SYS_RAWIO) || !capable(CAP_COMPROMISE_KERNEL)) - return -EPERM; - - /* Make sure the caller is mapping a real resource for this device */ -diff --git a/drivers/pci/syscall.c b/drivers/pci/syscall.c -index e1c1ec5..97e785f 100644 ---- a/drivers/pci/syscall.c -+++ b/drivers/pci/syscall.c -@@ -92,7 +92,7 @@ SYSCALL_DEFINE5(pciconfig_write, unsigned long, bus, unsigned long, dfn, - u32 dword; - int err = 0; - -- if (!capable(CAP_SYS_ADMIN)) -+ if (!capable(CAP_SYS_ADMIN) || !capable(CAP_COMPROMISE_KERNEL)) - return -EPERM; - - dev = pci_get_bus_and_slot(bus, dfn); --- -1.8.0.1 - - -From 1b5a1b53577992b32a3f51b18aa07cb9b300a3b1 Mon Sep 17 00:00:00 2001 -From: Matthew Garrett -Date: Thu, 20 Sep 2012 10:40:58 -0400 -Subject: [PATCH 03/20] x86: Lock down IO port access in secure boot - environments - -IO port access would permit users to gain access to PCI configuration -registers, which in turn (on a lot of hardware) give access to MMIO register -space. This would potentially permit root to trigger arbitrary DMA, so lock -it down by default. - -Signed-off-by: Matthew Garrett ---- - arch/x86/kernel/ioport.c | 4 ++-- - drivers/char/mem.c | 3 +++ - 2 files changed, 5 insertions(+), 2 deletions(-) - -diff --git a/arch/x86/kernel/ioport.c b/arch/x86/kernel/ioport.c -index 8c96897..a2578c4 100644 ---- a/arch/x86/kernel/ioport.c -+++ b/arch/x86/kernel/ioport.c -@@ -28,7 +28,7 @@ asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on) - - if ((from + num <= from) || (from + num > IO_BITMAP_BITS)) - return -EINVAL; -- if (turn_on && !capable(CAP_SYS_RAWIO)) -+ if (turn_on && (!capable(CAP_SYS_RAWIO) || !capable(CAP_COMPROMISE_KERNEL))) - return -EPERM; - - /* -@@ -102,7 +102,7 @@ long sys_iopl(unsigned int level, struct pt_regs *regs) - return -EINVAL; - /* Trying to gain more privileges? */ - if (level > old) { -- if (!capable(CAP_SYS_RAWIO)) -+ if (!capable(CAP_SYS_RAWIO) || !capable(CAP_COMPROMISE_KERNEL)) - return -EPERM; - } - regs->flags = (regs->flags & ~X86_EFLAGS_IOPL) | (level << 12); -diff --git a/drivers/char/mem.c b/drivers/char/mem.c -index 0537903..47501fc 100644 ---- a/drivers/char/mem.c -+++ b/drivers/char/mem.c -@@ -597,6 +597,9 @@ static ssize_t write_port(struct file *file, const char __user *buf, - unsigned long i = *ppos; - const char __user * tmp = buf; - -+ if (!capable(CAP_COMPROMISE_KERNEL)) -+ return -EPERM; -+ - if (!access_ok(VERIFY_READ, buf, count)) - return -EFAULT; - while (count-- > 0 && i < 65536) { --- -1.8.0.1 - - -From 09c266136915eb1f4a9b36423b7ba65e3d024de4 Mon Sep 17 00:00:00 2001 -From: Matthew Garrett -Date: Thu, 20 Sep 2012 10:40:59 -0400 -Subject: [PATCH 04/20] ACPI: Limit access to custom_method - -It must be impossible for even root to get code executed in kernel context -under a secure boot environment. custom_method effectively allows arbitrary -access to system memory, so it needs to have a capability check here. - -Signed-off-by: Matthew Garrett ---- - drivers/acpi/custom_method.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/drivers/acpi/custom_method.c b/drivers/acpi/custom_method.c -index 5d42c24..247d58b 100644 ---- a/drivers/acpi/custom_method.c -+++ b/drivers/acpi/custom_method.c -@@ -29,6 +29,9 @@ static ssize_t cm_write(struct file *file, const char __user * user_buf, - struct acpi_table_header table; - acpi_status status; - -+ if (!capable(CAP_COMPROMISE_KERNEL)) -+ return -EPERM; -+ - if (!(*ppos)) { - /* parse the table header to get the table length */ - if (count <= sizeof(struct acpi_table_header)) --- -1.8.0.1 - - -From f3e9cb16e5ab3e680ec3ef464682c52371bbbbe3 Mon Sep 17 00:00:00 2001 -From: Matthew Garrett -Date: Thu, 20 Sep 2012 10:41:00 -0400 -Subject: [PATCH 05/20] asus-wmi: Restrict debugfs interface - -We have no way of validating what all of the Asus WMI methods do on a -given machine, and there's a risk that some will allow hardware state to -be manipulated in such a way that arbitrary code can be executed in the -kernel. Add a capability check to prevent that. - -Signed-off-by: Matthew Garrett ---- - drivers/platform/x86/asus-wmi.c | 9 +++++++++ - 1 file changed, 9 insertions(+) - -diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c -index c0e9ff4..3c10167 100644 ---- a/drivers/platform/x86/asus-wmi.c -+++ b/drivers/platform/x86/asus-wmi.c -@@ -1521,6 +1521,9 @@ static int show_dsts(struct seq_file *m, void *data) - int err; - u32 retval = -1; - -+ if (!capable(CAP_COMPROMISE_KERNEL)) -+ return -EPERM; -+ - err = asus_wmi_get_devstate(asus, asus->debug.dev_id, &retval); - - if (err < 0) -@@ -1537,6 +1540,9 @@ static int show_devs(struct seq_file *m, void *data) - int err; - u32 retval = -1; - -+ if (!capable(CAP_COMPROMISE_KERNEL)) -+ return -EPERM; -+ - err = asus_wmi_set_devstate(asus->debug.dev_id, asus->debug.ctrl_param, - &retval); - -@@ -1561,6 +1567,9 @@ static int show_call(struct seq_file *m, void *data) - union acpi_object *obj; - acpi_status status; - -+ if (!capable(CAP_COMPROMISE_KERNEL)) -+ return -EPERM; -+ - status = wmi_evaluate_method(ASUS_WMI_MGMT_GUID, - 1, asus->debug.method_id, - &input, &output); --- -1.8.0.1 - - -From 23372d2a40135aca7a6d73511bd88790b598b489 Mon Sep 17 00:00:00 2001 -From: Matthew Garrett -Date: Thu, 20 Sep 2012 10:41:01 -0400 -Subject: [PATCH 06/20] Restrict /dev/mem and /dev/kmem in secure boot setups - -Allowing users to write to address space makes it possible for the kernel -to be subverted. Restrict this when we need to protect the kernel. - -Signed-off-by: Matthew Garrett ---- - drivers/char/mem.c | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/drivers/char/mem.c b/drivers/char/mem.c -index 47501fc..8817cdc 100644 ---- a/drivers/char/mem.c -+++ b/drivers/char/mem.c -@@ -158,6 +158,9 @@ static ssize_t write_mem(struct file *file, const char __user *buf, - unsigned long copied; - void *ptr; - -+ if (!capable(CAP_COMPROMISE_KERNEL)) -+ return -EPERM; -+ - if (!valid_phys_addr_range(p, count)) - return -EFAULT; - -@@ -530,6 +533,9 @@ static ssize_t write_kmem(struct file *file, const char __user *buf, - char * kbuf; /* k-addr because vwrite() takes vmlist_lock rwlock */ - int err = 0; - -+ if (!capable(CAP_COMPROMISE_KERNEL)) -+ return -EPERM; -+ - if (p < (unsigned long) high_memory) { - unsigned long to_write = min_t(unsigned long, count, - (unsigned long)high_memory - p); --- -1.8.0.1 - - -From a0c80b01e80a1f6484a2a2811b4a212322494614 Mon Sep 17 00:00:00 2001 -From: Josh Boyer -Date: Thu, 20 Sep 2012 10:41:02 -0400 -Subject: [PATCH 07/20] Secure boot: Add a dummy kernel parameter that will - switch on Secure Boot mode - -This forcibly drops CAP_COMPROMISE_KERNEL from both cap_permitted and cap_bset -in the init_cred struct, which everything else inherits from. This works on -any machine and can be used to develop even if the box doesn't have UEFI. - -Signed-off-by: Josh Boyer ---- - Documentation/kernel-parameters.txt | 7 +++++++ - kernel/cred.c | 17 +++++++++++++++++ - 2 files changed, 24 insertions(+) - -diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt -index 9776f06..0d6c28d 100644 ---- a/Documentation/kernel-parameters.txt -+++ b/Documentation/kernel-parameters.txt -@@ -2599,6 +2599,13 @@ bytes respectively. Such letter suffixes can also be entirely omitted. - Note: increases power consumption, thus should only be - enabled if running jitter sensitive (HPC/RT) workloads. - -+ secureboot_enable= -+ [KNL] Enables an emulated UEFI Secure Boot mode. This -+ locks down various aspects of the kernel guarded by the -+ CAP_COMPROMISE_KERNEL capability. This includes things -+ like /dev/mem, IO port access, and other areas. It can -+ be used on non-UEFI machines for testing purposes. -+ - security= [SECURITY] Choose a security module to enable at boot. - If this boot parameter is not specified, only the first - security module asking for security registration will be -diff --git a/kernel/cred.c b/kernel/cred.c -index 48cea3d..3f5be65 100644 ---- a/kernel/cred.c -+++ b/kernel/cred.c -@@ -623,6 +623,23 @@ void __init cred_init(void) - 0, SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL); - } - -+void __init secureboot_enable() -+{ -+ pr_info("Secure boot enabled\n"); -+ cap_lower((&init_cred)->cap_bset, CAP_COMPROMISE_KERNEL); -+ cap_lower((&init_cred)->cap_permitted, CAP_COMPROMISE_KERNEL); -+} -+ -+/* Dummy Secure Boot enable option to fake out UEFI SB=1 */ -+static int __init secureboot_enable_opt(char *str) -+{ -+ int sb_enable = !!simple_strtol(str, NULL, 0); -+ if (sb_enable) -+ secureboot_enable(); -+ return 1; -+} -+__setup("secureboot_enable=", secureboot_enable_opt); -+ - /** - * prepare_kernel_cred - Prepare a set of credentials for a kernel service - * @daemon: A userspace daemon to be used as a reference --- -1.8.0.1 - - -From 640f088c49da87a344417f58d3faa72d63a4f6ed Mon Sep 17 00:00:00 2001 -From: Matthew Garrett -Date: Thu, 20 Sep 2012 10:41:03 -0400 -Subject: [PATCH 08/20] efi: Enable secure boot lockdown automatically when - enabled in firmware - -The firmware has a set of flags that indicate whether secure boot is enabled -and enforcing. Use them to indicate whether the kernel should lock itself -down. - -Signed-off-by: Matthew Garrett ---- - Documentation/x86/zero-page.txt | 2 ++ - arch/x86/boot/compressed/eboot.c | 32 ++++++++++++++++++++++++++++++++ - arch/x86/include/asm/bootparam.h | 3 ++- - arch/x86/kernel/setup.c | 3 +++ - include/linux/cred.h | 2 ++ - 5 files changed, 41 insertions(+), 1 deletion(-) - -diff --git a/Documentation/x86/zero-page.txt b/Documentation/x86/zero-page.txt -index cf5437d..7f9ed48 100644 ---- a/Documentation/x86/zero-page.txt -+++ b/Documentation/x86/zero-page.txt -@@ -27,6 +27,8 @@ Offset Proto Name Meaning - 1E9/001 ALL eddbuf_entries Number of entries in eddbuf (below) - 1EA/001 ALL edd_mbr_sig_buf_entries Number of entries in edd_mbr_sig_buffer - (below) -+1EB/001 ALL kbd_status Numlock is enabled -+1EC/001 ALL secure_boot Kernel should enable secure boot lockdowns - 290/040 ALL edd_mbr_sig_buffer EDD MBR signatures - 2D0/A00 ALL e820_map E820 memory map table - (array of struct e820entry) -diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c -index e87b0ca..260cace 100644 ---- a/arch/x86/boot/compressed/eboot.c -+++ b/arch/x86/boot/compressed/eboot.c -@@ -732,6 +732,36 @@ fail: - return status; - } - -+static int get_secure_boot(efi_system_table_t *_table) -+{ -+ u8 sb, setup; -+ unsigned long datasize = sizeof(sb); -+ efi_guid_t var_guid = EFI_GLOBAL_VARIABLE_GUID; -+ efi_status_t status; -+ -+ status = efi_call_phys5(sys_table->runtime->get_variable, -+ L"SecureBoot", &var_guid, NULL, &datasize, &sb); -+ -+ if (status != EFI_SUCCESS) -+ return 0; -+ -+ if (sb == 0) -+ return 0; -+ -+ -+ status = efi_call_phys5(sys_table->runtime->get_variable, -+ L"SetupMode", &var_guid, NULL, &datasize, -+ &setup); -+ -+ if (status != EFI_SUCCESS) -+ return 0; -+ -+ if (setup == 1) -+ return 0; -+ -+ return 1; -+} -+ - /* - * Because the x86 boot code expects to be passed a boot_params we - * need to create one ourselves (usually the bootloader would create -@@ -1026,6 +1056,8 @@ struct boot_params *efi_main(void *handle, efi_system_table_t *_table, - if (sys_table->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE) - goto fail; - -+ boot_params->secure_boot = get_secure_boot(sys_table); -+ - setup_graphics(boot_params); - - status = efi_call_phys3(sys_table->boottime->allocate_pool, -diff --git a/arch/x86/include/asm/bootparam.h b/arch/x86/include/asm/bootparam.h -index 2ad874c..c7338e0 100644 ---- a/arch/x86/include/asm/bootparam.h -+++ b/arch/x86/include/asm/bootparam.h -@@ -114,7 +114,8 @@ struct boot_params { - __u8 eddbuf_entries; /* 0x1e9 */ - __u8 edd_mbr_sig_buf_entries; /* 0x1ea */ - __u8 kbd_status; /* 0x1eb */ -- __u8 _pad6[5]; /* 0x1ec */ -+ __u8 secure_boot; /* 0x1ec */ -+ __u8 _pad6[4]; /* 0x1ed */ - struct setup_header hdr; /* setup header */ /* 0x1f1 */ - __u8 _pad7[0x290-0x1f1-sizeof(struct setup_header)]; - __u32 edd_mbr_sig_buffer[EDD_MBR_SIG_MAX]; /* 0x290 */ -diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c -index ca45696..800673d 100644 ---- a/arch/x86/kernel/setup.c -+++ b/arch/x86/kernel/setup.c -@@ -962,6 +962,9 @@ void __init setup_arch(char **cmdline_p) - - io_delay_init(); - -+ if (boot_params.secure_boot) -+ secureboot_enable(); -+ - /* - * Parse the ACPI tables for possible boot-time SMP configuration. - */ -diff --git a/include/linux/cred.h b/include/linux/cred.h -index ebbed2c..a24faf1 100644 ---- a/include/linux/cred.h -+++ b/include/linux/cred.h -@@ -170,6 +170,8 @@ extern int set_security_override_from_ctx(struct cred *, const char *); - extern int set_create_files_as(struct cred *, struct inode *); - extern void __init cred_init(void); - -+extern void secureboot_enable(void); -+ - /* - * check for validity of credentials - */ --- -1.8.0.1 - - -From 994d895b5b684fc53c3b43dda9aee460c1f526f2 Mon Sep 17 00:00:00 2001 -From: Josh Boyer -Date: Thu, 20 Sep 2012 10:41:04 -0400 -Subject: [PATCH 09/20] acpi: Ignore acpi_rsdp kernel parameter in a secure - boot environment - -This option allows userspace to pass the RSDP address to the kernel. This -could potentially be used to circumvent the secure boot trust model. -We ignore the setting if we don't have the CAP_COMPROMISE_KERNEL capability. - -Signed-off-by: Josh Boyer ---- - drivers/acpi/osl.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c -index 9eaf708..f94341b 100644 ---- a/drivers/acpi/osl.c -+++ b/drivers/acpi/osl.c -@@ -246,7 +246,7 @@ early_param("acpi_rsdp", setup_acpi_rsdp); - acpi_physical_address __init acpi_os_get_root_pointer(void) - { - #ifdef CONFIG_KEXEC -- if (acpi_rsdp) -+ if (acpi_rsdp && capable(CAP_COMPROMISE_KERNEL)) - return acpi_rsdp; - #endif - --- -1.8.0.1 - - -From c80aaf3eee3cb6b0d1a051e418ee99cd238c868c Mon Sep 17 00:00:00 2001 -From: Josh Boyer -Date: Thu, 20 Sep 2012 10:41:05 -0400 -Subject: [PATCH 10/20] SELinux: define mapping for new Secure Boot capability - -Add the name of the new Secure Boot capability. This allows SELinux -policies to properly map CAP_COMPROMISE_KERNEL to the appropriate -capability class. - -Signed-off-by: Josh Boyer ---- - security/selinux/include/classmap.h | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/security/selinux/include/classmap.h b/security/selinux/include/classmap.h -index df2de54..70e2834 100644 ---- a/security/selinux/include/classmap.h -+++ b/security/selinux/include/classmap.h -@@ -146,8 +146,8 @@ struct security_class_mapping secclass_map[] = { - { "memprotect", { "mmap_zero", NULL } }, - { "peer", { "recv", NULL } }, - { "capability2", -- { "mac_override", "mac_admin", "syslog", "wake_alarm", "block_suspend", -- NULL } }, -+ { "mac_override", "mac_admin", "syslog", "wake_alarm", -+ "block_suspend", "compromise_kernel", NULL } }, - { "kernel_service", { "use_as_override", "create_files_as", NULL } }, - { "tun_socket", - { COMMON_SOCK_PERMS, NULL } }, --- -1.8.0.1 - - -From 26352bcb92468233dd960b5d02ba1db344df72b9 Mon Sep 17 00:00:00 2001 -From: Matthew Garrett -Date: Tue, 4 Sep 2012 11:55:13 -0400 -Subject: [PATCH 11/20] kexec: Disable in a secure boot environment - -kexec could be used as a vector for a malicious user to use a signed kernel -to circumvent the secure boot trust model. In the long run we'll want to -support signed kexec payloads, but for the moment we should just disable -loading entirely in that situation. - -Signed-off-by: Matthew Garrett ---- - kernel/kexec.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/kernel/kexec.c b/kernel/kexec.c -index 5e4bd78..dd464e0 100644 ---- a/kernel/kexec.c -+++ b/kernel/kexec.c -@@ -943,7 +943,7 @@ SYSCALL_DEFINE4(kexec_load, unsigned long, entry, unsigned long, nr_segments, - int result; - - /* We only trust the superuser with rebooting the system. */ -- if (!capable(CAP_SYS_BOOT)) -+ if (!capable(CAP_SYS_BOOT) || !capable(CAP_COMPROMISE_KERNEL)) - return -EPERM; - - /* --- -1.8.0.1 - - -From c03c68adceaec9656c55c47190fb4243bf903b40 Mon Sep 17 00:00:00 2001 -From: Josh Boyer -Date: Mon, 25 Jun 2012 21:29:46 -0400 -Subject: [PATCH 12/20] Documentation: kernel-parameters.txt remove - capability.disable - -Remove the documentation for capability.disable. The code supporting this -parameter was removed with: - - commit 5915eb53861c5776cfec33ca4fcc1fd20d66dd27 - Author: Miklos Szeredi - Date: Thu Jul 3 20:56:05 2008 +0200 - - security: remove dummy module - -Signed-off-by: Josh Boyer ---- - Documentation/kernel-parameters.txt | 6 ------ - 1 file changed, 6 deletions(-) - -diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt -index 0d6c28d..d9af501 100644 ---- a/Documentation/kernel-parameters.txt -+++ b/Documentation/kernel-parameters.txt -@@ -446,12 +446,6 @@ bytes respectively. Such letter suffixes can also be entirely omitted. - possible to determine what the correct size should be. - This option provides an override for these situations. - -- capability.disable= -- [SECURITY] Disable capabilities. This would normally -- be used only if an alternative security model is to be -- configured. Potentially dangerous and should only be -- used if you are entirely sure of the consequences. -- - ccw_timeout_log [S390] - See Documentation/s390/CommonIO for details. - --- -1.8.0.1 - - -From 3f1bda64d2c7b369e2833bd32cd1f3ba6c90348f Mon Sep 17 00:00:00 2001 -From: Josh Boyer -Date: Fri, 5 Oct 2012 10:12:48 -0400 -Subject: [PATCH 13/20] modsign: Always enforce module signing in a Secure Boot - environment - -If a machine is booted into a Secure Boot environment, we need to -protect the trust model. This requires that all modules be signed -with a key that is in the kernel's _modsign keyring. The checks for -this are already done via the 'sig_enforce' module parameter. Make -this visible within the kernel and force it to be true. - -Signed-off-by: Josh Boyer ---- - kernel/cred.c | 8 ++++++++ - kernel/module.c | 4 ++-- - 2 files changed, 10 insertions(+), 2 deletions(-) - -diff --git a/kernel/cred.c b/kernel/cred.c -index 3f5be65..a381e27 100644 ---- a/kernel/cred.c -+++ b/kernel/cred.c -@@ -623,11 +623,19 @@ void __init cred_init(void) - 0, SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL); - } - -+#ifdef CONFIG_MODULE_SIG -+extern bool sig_enforce; -+#endif -+ - void __init secureboot_enable() - { - pr_info("Secure boot enabled\n"); - cap_lower((&init_cred)->cap_bset, CAP_COMPROMISE_KERNEL); - cap_lower((&init_cred)->cap_permitted, CAP_COMPROMISE_KERNEL); -+#ifdef CONFIG_MODULE_SIG -+ /* Enable module signature enforcing */ -+ sig_enforce = true; -+#endif - } - - /* Dummy Secure Boot enable option to fake out UEFI SB=1 */ -diff --git a/kernel/module.c b/kernel/module.c -index 6e48c3a..6d5d2aa 100644 ---- a/kernel/module.c -+++ b/kernel/module.c -@@ -106,9 +106,9 @@ struct list_head *kdb_modules = &modules; /* kdb needs the list of modules */ - - #ifdef CONFIG_MODULE_SIG - #ifdef CONFIG_MODULE_SIG_FORCE --static bool sig_enforce = true; -+bool sig_enforce = true; - #else --static bool sig_enforce = false; -+bool sig_enforce = false; - - static int param_set_bool_enable_only(const char *val, - const struct kernel_param *kp) --- -1.8.0.1 - - -From e6e3ec77b2fa037b32829e7f5ee468ad8a62dd05 Mon Sep 17 00:00:00 2001 -From: Dave Howells -Date: Tue, 23 Oct 2012 09:30:54 -0400 -Subject: [PATCH 14/20] Add EFI signature data types, such as are used for - containing hashes, keys and certificates for cryptographic verification. - -Signed-off-by: David Howells ---- - include/linux/efi.h | 20 ++++++++++++++++++++ - 1 file changed, 20 insertions(+) - -diff --git a/include/linux/efi.h b/include/linux/efi.h -index 337aefb..a01f8a7 100644 ---- a/include/linux/efi.h -+++ b/include/linux/efi.h -@@ -317,6 +317,12 @@ typedef efi_status_t efi_query_capsule_caps_t(efi_capsule_header_t **capsules, - #define EFI_FILE_SYSTEM_GUID \ - EFI_GUID( 0x964e5b22, 0x6459, 0x11d2, 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b ) - -+#define EFI_CERT_SHA256_GUID \ -+ EFI_GUID( 0xc1c41626, 0x504c, 0x4092, 0xac, 0xa9, 0x41, 0xf9, 0x36, 0x93, 0x43, 0x28 ) -+ -+#define EFI_CERT_X509_GUID \ -+ EFI_GUID( 0xa5c059a1, 0x94e4, 0x4aa7, 0x87, 0xb5, 0xab, 0x15, 0x5c, 0x2b, 0xf0, 0x72 ) -+ - typedef struct { - efi_guid_t guid; - u64 table; -@@ -452,6 +458,20 @@ typedef struct { - - #define EFI_INVALID_TABLE_ADDR (~0UL) - -+typedef struct { -+ efi_guid_t signature_owner; -+ u8 signature_data[]; -+} efi_signature_data_t; -+ -+typedef struct { -+ efi_guid_t signature_type; -+ u32 signature_list_size; -+ u32 signature_header_size; -+ u32 signature_size; -+ u8 signature_header[]; -+ /* efi_signature_data_t signatures[][] */ -+} efi_signature_list_t; -+ - /* - * All runtime access to EFI goes through this structure: - */ --- -1.8.0.1 - - -From c2542256f632a22232cf02d5fd64568a5afa4516 Mon Sep 17 00:00:00 2001 -From: Dave Howells -Date: Tue, 23 Oct 2012 09:36:28 -0400 -Subject: [PATCH 15/20] Add an EFI signature blob parser and key loader. X.509 - certificates are loaded into the specified keyring as asymmetric type keys. - -Signed-off-by: David Howells ---- - crypto/asymmetric_keys/Kconfig | 7 +++ - crypto/asymmetric_keys/Makefile | 1 + - crypto/asymmetric_keys/efi_parser.c | 107 ++++++++++++++++++++++++++++++++++++ - include/linux/efi.h | 4 ++ - 4 files changed, 119 insertions(+) - create mode 100644 crypto/asymmetric_keys/efi_parser.c - -diff --git a/crypto/asymmetric_keys/Kconfig b/crypto/asymmetric_keys/Kconfig -index 6d2c2ea..eb53fc3 100644 ---- a/crypto/asymmetric_keys/Kconfig -+++ b/crypto/asymmetric_keys/Kconfig -@@ -35,4 +35,11 @@ config X509_CERTIFICATE_PARSER - data and provides the ability to instantiate a crypto key from a - public key packet found inside the certificate. - -+config EFI_SIGNATURE_LIST_PARSER -+ bool "EFI signature list parser" -+ select X509_CERTIFICATE_PARSER -+ help -+ This option provides support for parsing EFI signature lists for -+ X.509 certificates and turning them into keys. -+ - endif # ASYMMETRIC_KEY_TYPE -diff --git a/crypto/asymmetric_keys/Makefile b/crypto/asymmetric_keys/Makefile -index 0727204..cd8388e 100644 ---- a/crypto/asymmetric_keys/Makefile -+++ b/crypto/asymmetric_keys/Makefile -@@ -8,6 +8,7 @@ asymmetric_keys-y := asymmetric_type.o signature.o - - obj-$(CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE) += public_key.o - obj-$(CONFIG_PUBLIC_KEY_ALGO_RSA) += rsa.o -+obj-$(CONFIG_EFI_SIGNATURE_LIST_PARSER) += efi_parser.o - - # - # X.509 Certificate handling -diff --git a/crypto/asymmetric_keys/efi_parser.c b/crypto/asymmetric_keys/efi_parser.c -new file mode 100644 -index 0000000..59b859a ---- /dev/null -+++ b/crypto/asymmetric_keys/efi_parser.c -@@ -0,0 +1,107 @@ -+/* EFI signature/key/certificate list parser -+ * -+ * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved. -+ * Written by David Howells (dhowells@redhat.com) -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public Licence -+ * as published by the Free Software Foundation; either version -+ * 2 of the Licence, or (at your option) any later version. -+ */ -+ -+#define pr_fmt(fmt) "EFI: "fmt -+#include -+#include -+#include -+#include -+#include -+ -+static __initdata efi_guid_t efi_cert_x509_guid = EFI_CERT_X509_GUID; -+ -+/** -+ * parse_efi_signature_list - Parse an EFI signature list for certificates -+ * @data: The data blob to parse -+ * @size: The size of the data blob -+ * @keyring: The keyring to add extracted keys to -+ */ -+int __init parse_efi_signature_list(const void *data, size_t size, struct key *keyring) -+{ -+ unsigned offs = 0; -+ size_t lsize, esize, hsize, elsize; -+ -+ pr_devel("-->%s(,%zu)\n", __func__, size); -+ -+ while (size > 0) { -+ efi_signature_list_t list; -+ const efi_signature_data_t *elem; -+ key_ref_t key; -+ -+ if (size < sizeof(list)) -+ return -EBADMSG; -+ -+ memcpy(&list, data, sizeof(list)); -+ pr_devel("LIST[%04x] guid=%pUl ls=%x hs=%x ss=%x\n", -+ offs, -+ list.signature_type.b, list.signature_list_size, -+ list.signature_header_size, list.signature_size); -+ -+ lsize = list.signature_list_size; -+ hsize = list.signature_header_size; -+ esize = list.signature_size; -+ elsize = lsize - sizeof(list) - hsize; -+ -+ if (lsize > size) { -+ pr_devel("<--%s() = -EBADMSG [overrun @%x]\n", -+ __func__, offs); -+ return -EBADMSG; -+ } -+ if (lsize < sizeof(list) || -+ lsize - sizeof(list) < hsize || -+ esize < sizeof(*elem) || -+ elsize < esize || -+ elsize % esize != 0) { -+ pr_devel("- bad size combo @%x\n", offs); -+ continue; -+ } -+ -+ if (efi_guidcmp(list.signature_type, efi_cert_x509_guid) != 0) { -+ data += lsize; -+ size -= lsize; -+ offs += lsize; -+ continue; -+ } -+ -+ data += sizeof(list) + hsize; -+ size -= sizeof(list) + hsize; -+ offs += sizeof(list) + hsize; -+ -+ for (; elsize > 0; elsize -= esize) { -+ elem = data; -+ -+ pr_devel("ELEM[%04x]\n", offs); -+ -+ key = key_create_or_update( -+ make_key_ref(keyring, 1), -+ "asymmetric", -+ NULL, -+ &elem->signature_data, -+ esize - sizeof(*elem), -+ (KEY_POS_ALL & ~KEY_POS_SETATTR) | -+ KEY_USR_VIEW, -+ KEY_ALLOC_NOT_IN_QUOTA); -+ -+ if (IS_ERR(key)) -+ pr_err("Problem loading in-kernel X.509 certificate (%ld)\n", -+ PTR_ERR(key)); -+ else -+ pr_notice("Loaded cert '%s'\n", -+ key_ref_to_ptr(key)->description); -+ -+ data += esize; -+ size -= esize; -+ offs += esize; -+ } -+ } -+ -+ return 0; -+} -diff --git a/include/linux/efi.h b/include/linux/efi.h -index a01f8a7..44a7faa 100644 ---- a/include/linux/efi.h -+++ b/include/linux/efi.h -@@ -541,6 +541,10 @@ extern int efi_set_rtc_mmss(unsigned long nowtime); - extern void efi_reserve_boot_services(void); - extern struct efi_memory_map memmap; - -+struct key; -+extern int __init parse_efi_signature_list(const void *data, size_t size, -+ struct key *keyring); -+ - /** - * efi_range_is_wc - check the WC bit on an address range - * @start: starting kvirt address --- -1.8.0.1 - - -From a418e6fdd2aa946a30cf1bee5c9540d03d626981 Mon Sep 17 00:00:00 2001 -From: Josh Boyer -Date: Fri, 26 Oct 2012 12:29:49 -0400 -Subject: [PATCH 16/20] EFI: Add in-kernel variable to determine if Secure Boot - is enabled - -There are a few cases where in-kernel functions may need to know if -Secure Boot is enabled. The added capability check cannot be used as the -kernel can't drop it's own capabilites, so we add a global variable -similar to efi_enabled so they can determine if Secure Boot is enabled. - -Signed-off-by: Josh Boyer ---- - arch/x86/kernel/setup.c | 6 +++++- - arch/x86/platform/efi/efi.c | 2 ++ - include/linux/efi.h | 3 +++ - 3 files changed, 10 insertions(+), 1 deletion(-) - -diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c -index 800673d..cf8823b 100644 ---- a/arch/x86/kernel/setup.c -+++ b/arch/x86/kernel/setup.c -@@ -962,8 +962,12 @@ void __init setup_arch(char **cmdline_p) - - io_delay_init(); - -- if (boot_params.secure_boot) -+ if (boot_params.secure_boot) { - secureboot_enable(); -+#ifdef CONFIG_EFI -+ secure_boot_enabled = 1; -+#endif -+ } - - /* - * Parse the ACPI tables for possible boot-time SMP configuration. -diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c -index ad44391..d22bfeb 100644 ---- a/arch/x86/platform/efi/efi.c -+++ b/arch/x86/platform/efi/efi.c -@@ -54,6 +54,8 @@ - int efi_enabled; - EXPORT_SYMBOL(efi_enabled); - -+int secure_boot_enabled; -+ - struct efi __read_mostly efi = { - .mps = EFI_INVALID_TABLE_ADDR, - .acpi = EFI_INVALID_TABLE_ADDR, -diff --git a/include/linux/efi.h b/include/linux/efi.h -index 44a7faa..b5403ae 100644 ---- a/include/linux/efi.h -+++ b/include/linux/efi.h -@@ -578,11 +578,14 @@ extern int __init efi_setup_pcdp_console(char *); - # ifdef CONFIG_X86 - extern int efi_enabled; - extern bool efi_64bit; -+ extern int secure_boot_enabled; - # else - # define efi_enabled 1 -+# define secure_boot_enabled 0 - # endif - #else - # define efi_enabled 0 -+# define secure_boot_enabled 0 - #endif - - /* --- -1.8.0.1 - - -From f6d05f0974f6a7667ebbbf91624678bcf32169ae Mon Sep 17 00:00:00 2001 -From: Josh Boyer -Date: Fri, 26 Oct 2012 12:36:24 -0400 -Subject: [PATCH 17/20] MODSIGN: Add module certificate blacklist keyring - -This adds an additional keyring that is used to store certificates that -are blacklisted. This keyring is searched first when loading signed modules -and if the module's certificate is found, it will refuse to load. This is -useful in cases where third party certificates are used for module signing. - -Signed-off-by: Josh Boyer ---- - init/Kconfig | 8 ++++++++ - kernel/modsign_pubkey.c | 17 +++++++++++++++++ - kernel/module-internal.h | 3 +++ - kernel/module_signing.c | 14 +++++++++++++- - 4 files changed, 41 insertions(+), 1 deletion(-) - -diff --git a/init/Kconfig b/init/Kconfig -index 6fdd6e3..7a9bf00 100644 ---- a/init/Kconfig -+++ b/init/Kconfig -@@ -1602,6 +1602,14 @@ config MODULE_SIG_FORCE - Reject unsigned modules or signed modules for which we don't have a - key. Without this, such modules will simply taint the kernel. - -+config MODULE_SIG_BLACKLIST -+ bool "Support for blacklisting module signature certificates" -+ depends on MODULE_SIG -+ help -+ This adds support for keeping a blacklist of certificates that -+ should not pass module signature verification. If a module is -+ signed with something in this keyring, the load will be rejected. -+ - choice - prompt "Which hash algorithm should modules be signed with?" - depends on MODULE_SIG -diff --git a/kernel/modsign_pubkey.c b/kernel/modsign_pubkey.c -index 767e559..3bfb7ed 100644 ---- a/kernel/modsign_pubkey.c -+++ b/kernel/modsign_pubkey.c -@@ -17,6 +17,9 @@ - #include "module-internal.h" - - struct key *modsign_keyring; -+#ifdef CONFIG_MODULE_SIG_BLACKLIST -+struct key *modsign_blacklist; -+#endif - - extern __initdata const u8 modsign_certificate_list[]; - extern __initdata const u8 modsign_certificate_list_end[]; -@@ -52,6 +55,20 @@ static __init int module_verify_init(void) - if (key_instantiate_and_link(modsign_keyring, NULL, 0, NULL, NULL) < 0) - panic("Can't instantiate module signing keyring\n"); - -+#ifdef CONFIG_MODULE_SIG_BLACKLIST -+ modsign_blacklist = key_alloc(&key_type_keyring, ".modsign_blacklist", -+ KUIDT_INIT(0), KGIDT_INIT(0), -+ current_cred(), -+ (KEY_POS_ALL & ~KEY_POS_SETATTR) | -+ KEY_USR_VIEW | KEY_USR_READ, -+ KEY_ALLOC_NOT_IN_QUOTA); -+ if (IS_ERR(modsign_blacklist)) -+ panic("Can't allocate module signing blacklist keyring\n"); -+ -+ if (key_instantiate_and_link(modsign_blacklist, NULL, 0, NULL, NULL) < 0) -+ panic("Can't instantiate module signing blacklist keyring\n"); -+#endif -+ - return 0; - } - -diff --git a/kernel/module-internal.h b/kernel/module-internal.h -index 24f9247..51a8380 100644 ---- a/kernel/module-internal.h -+++ b/kernel/module-internal.h -@@ -10,5 +10,8 @@ - */ - - extern struct key *modsign_keyring; -+#ifdef CONFIG_MODULE_SIG_BLACKLIST -+extern struct key *modsign_blacklist; -+#endif - - extern int mod_verify_sig(const void *mod, unsigned long *_modlen); -diff --git a/kernel/module_signing.c b/kernel/module_signing.c -index f2970bd..8ab83a6 100644 ---- a/kernel/module_signing.c -+++ b/kernel/module_signing.c -@@ -132,7 +132,7 @@ static int mod_extract_mpi_array(struct public_key_signature *pks, - static struct key *request_asymmetric_key(const char *signer, size_t signer_len, - const u8 *key_id, size_t key_id_len) - { -- key_ref_t key; -+ key_ref_t key, blacklist; - size_t i; - char *id, *q; - -@@ -157,6 +157,18 @@ static struct key *request_asymmetric_key(const char *signer, size_t signer_len, - - pr_debug("Look up: \"%s\"\n", id); - -+#ifdef CONFIG_MODULE_SIG_BLACKLIST -+ blacklist = keyring_search(make_key_ref(modsign_blacklist, 1), -+ &key_type_asymmetric, id); -+ if (!IS_ERR(blacklist)) { -+ /* module is signed with a cert in the blacklist. reject */ -+ pr_err("Module key '%s' is in blacklist\n", id); -+ key_ref_put(blacklist); -+ kfree(id); -+ return ERR_PTR(-EKEYREJECTED); -+ } -+#endif -+ - key = keyring_search(make_key_ref(modsign_keyring, 1), - &key_type_asymmetric, id); - if (IS_ERR(key)) --- -1.8.0.1 - - -From ff0ed221fe8d5a46a9bc36323ca8fb6f75c22a83 Mon Sep 17 00:00:00 2001 -From: Josh Boyer -Date: Fri, 26 Oct 2012 12:42:16 -0400 -Subject: [PATCH 18/20] MODSIGN: Import certificates from UEFI Secure Boot - -Secure Boot stores a list of allowed certificates in the 'db' variable. -This imports those certificates into the module signing keyring. This -allows for a third party signing certificate to be used in conjunction -with signed modules. By importing the public certificate into the 'db' -variable, a user can allow a module signed with that certificate to -load. The shim UEFI bootloader has a similar certificate list stored -in the 'MokListRT' variable. We import those as well. - -In the opposite case, Secure Boot maintains a list of disallowed -certificates in the 'dbx' variable. We load those certificates into -the newly introduced module blacklist keyring and forbid any module -signed with those from loading. - -Signed-off-by: Josh Boyer ---- - include/linux/efi.h | 6 ++++ - init/Kconfig | 9 ++++++ - kernel/Makefile | 3 ++ - kernel/modsign_uefi.c | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++ - 4 files changed, 108 insertions(+) - create mode 100644 kernel/modsign_uefi.c - -diff --git a/include/linux/efi.h b/include/linux/efi.h -index b5403ae..bba53e3 100644 ---- a/include/linux/efi.h -+++ b/include/linux/efi.h -@@ -323,6 +323,12 @@ typedef efi_status_t efi_query_capsule_caps_t(efi_capsule_header_t **capsules, - #define EFI_CERT_X509_GUID \ - EFI_GUID( 0xa5c059a1, 0x94e4, 0x4aa7, 0x87, 0xb5, 0xab, 0x15, 0x5c, 0x2b, 0xf0, 0x72 ) - -+#define EFI_IMAGE_SECURITY_DATABASE_GUID \ -+ EFI_GUID( 0xd719b2cb, 0x3d3a, 0x4596, 0xa3, 0xbc, 0xda, 0xd0, 0x0e, 0x67, 0x65, 0x6f ) -+ -+#define EFI_SHIM_LOCK_GUID \ -+ EFI_GUID( 0x605dab50, 0xe046, 0x4300, 0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23 ) -+ - typedef struct { - efi_guid_t guid; - u64 table; -diff --git a/init/Kconfig b/init/Kconfig -index 7a9bf00..51aa170 100644 ---- a/init/Kconfig -+++ b/init/Kconfig -@@ -1610,6 +1610,15 @@ config MODULE_SIG_BLACKLIST - should not pass module signature verification. If a module is - signed with something in this keyring, the load will be rejected. - -+config MODULE_SIG_UEFI -+ bool "Allow modules signed with certs stored in UEFI" -+ depends on MODULE_SIG && MODULE_SIG_BLACKLIST && EFI -+ select EFI_SIGNATURE_LIST_PARSER -+ help -+ This will import certificates stored in UEFI and allow modules -+ signed with those to be loaded. It will also disallow loading -+ of modules stored in the UEFI dbx variable. -+ - choice - prompt "Which hash algorithm should modules be signed with?" - depends on MODULE_SIG -diff --git a/kernel/Makefile b/kernel/Makefile -index 86e3285..12e17ab 100644 ---- a/kernel/Makefile -+++ b/kernel/Makefile -@@ -55,6 +55,7 @@ obj-$(CONFIG_PROVE_LOCKING) += spinlock.o - obj-$(CONFIG_UID16) += uid16.o - obj-$(CONFIG_MODULES) += module.o - obj-$(CONFIG_MODULE_SIG) += module_signing.o modsign_pubkey.o -+obj-$(CONFIG_MODULE_SIG_UEFI) += modsign_uefi.o - obj-$(CONFIG_KALLSYMS) += kallsyms.o - obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o - obj-$(CONFIG_KEXEC) += kexec.o -@@ -113,6 +114,8 @@ obj-$(CONFIG_JUMP_LABEL) += jump_label.o - - $(obj)/configs.o: $(obj)/config_data.h - -+$(obj)/modsign_uefi.o: KBUILD_CFLAGS += -fshort-wchar -+ - # config_data.h contains the same information as ikconfig.h but gzipped. - # Info from config_data can be extracted from /proc/config* - targets += config_data.gz -diff --git a/kernel/modsign_uefi.c b/kernel/modsign_uefi.c -new file mode 100644 -index 0000000..76a5a34 ---- /dev/null -+++ b/kernel/modsign_uefi.c -@@ -0,0 +1,90 @@ -+#include -+#include -+#include -+#include -+#include -+#include -+#include "module-internal.h" -+ -+static __init void *get_cert_list(efi_char16_t *name, efi_guid_t *guid, unsigned long *size) -+{ -+ efi_status_t status; -+ unsigned long lsize = 4; -+ unsigned long tmpdb[4]; -+ void *db = NULL; -+ -+ status = efi.get_variable(name, guid, NULL, &lsize, &tmpdb); -+ if (status != EFI_BUFFER_TOO_SMALL) { -+ pr_err("Couldn't get size: 0x%lx\n", status); -+ return NULL; -+ } -+ -+ db = kmalloc(lsize, GFP_KERNEL); -+ if (!db) { -+ pr_err("Couldn't allocate memory for uefi cert list\n"); -+ goto out; -+ } -+ -+ status = efi.get_variable(name, guid, NULL, &lsize, db); -+ if (status != EFI_SUCCESS) { -+ kfree(db); -+ db = NULL; -+ pr_err("Error reading db var: 0x%lx\n", status); -+ } -+out: -+ *size = lsize; -+ return db; -+} -+ -+/* -+ * * Load the certs contained in the UEFI databases -+ * */ -+static int __init load_uefi_certs(void) -+{ -+ efi_guid_t secure_var = EFI_IMAGE_SECURITY_DATABASE_GUID; -+ efi_guid_t mok_var = EFI_SHIM_LOCK_GUID; -+ void *db = NULL, *dbx = NULL, *mok = NULL; -+ unsigned long dbsize = 0, dbxsize = 0, moksize = 0; -+ int rc = 0; -+ -+ /* Check if SB is enabled and just return if not */ -+ if (!secure_boot_enabled) -+ return 0; -+ -+ /* Get db, MokListRT, and dbx. They might not exist, so it isn't -+ * an error if we can't get them. -+ */ -+ db = get_cert_list(L"db", &secure_var, &dbsize); -+ if (!db) { -+ pr_err("MODSIGN: Couldn't get UEFI db list\n"); -+ } else { -+ rc = parse_efi_signature_list(db, dbsize, modsign_keyring); -+ if (rc) -+ pr_err("Couldn't parse db signatures: %d\n", rc); -+ kfree(db); -+ } -+ -+ mok = get_cert_list(L"MokListRT", &mok_var, &moksize); -+ if (!mok) { -+ pr_info("MODSIGN: Couldn't get UEFI MokListRT\n"); -+ } else { -+ rc = parse_efi_signature_list(mok, moksize, modsign_keyring); -+ if (rc) -+ pr_err("Couldn't parse MokListRT signatures: %d\n", rc); -+ kfree(mok); -+ } -+ -+ dbx = get_cert_list(L"dbx", &secure_var, &dbxsize); -+ if (!dbx) { -+ pr_info("MODSIGN: Couldn't get UEFI dbx list\n"); -+ } else { -+ rc = parse_efi_signature_list(dbx, dbxsize, -+ modsign_blacklist); -+ if (rc) -+ pr_err("Couldn't parse dbx signatures: %d\n", rc); -+ kfree(dbx); -+ } -+ -+ return rc; -+} -+late_initcall(load_uefi_certs); --- -1.8.0.1 - - -From 7d5629a2000d9dc92da91d2f1258af748e89cfd7 Mon Sep 17 00:00:00 2001 -From: Josh Boyer -Date: Fri, 26 Oct 2012 14:02:09 -0400 -Subject: [PATCH 19/20] hibernate: Disable in a Secure Boot environment - -There is currently no way to verify the resume image when returning -from hibernate. This might compromise the secure boot trust model, -so until we can work with signed hibernate images we disable it in -a Secure Boot environment. - -Signed-off-by: Josh Boyer ---- - kernel/power/hibernate.c | 14 +++++++++++++- - kernel/power/main.c | 4 +++- - kernel/power/user.c | 3 +++ - 3 files changed, 19 insertions(+), 2 deletions(-) - -diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c -index b26f5f1..f04343b 100644 ---- a/kernel/power/hibernate.c -+++ b/kernel/power/hibernate.c -@@ -632,6 +632,10 @@ int hibernate(void) - { - int error; - -+ if (!capable(CAP_COMPROMISE_KERNEL)) { -+ return -EPERM; -+ } -+ - lock_system_sleep(); - /* The snapshot device should not be opened while we're running */ - if (!atomic_add_unless(&snapshot_device_available, -1, 0)) { -@@ -723,7 +727,7 @@ static int software_resume(void) - /* - * If the user said "noresume".. bail out early. - */ -- if (noresume) -+ if (noresume || !capable(CAP_COMPROMISE_KERNEL)) - return 0; - - /* -@@ -889,6 +893,11 @@ static ssize_t disk_show(struct kobject *kobj, struct kobj_attribute *attr, - int i; - char *start = buf; - -+ if (!capable(CAP_COMPROMISE_KERNEL)) { -+ buf += sprintf(buf, "[%s]\n", "disabled"); -+ return buf-start; -+ } -+ - for (i = HIBERNATION_FIRST; i <= HIBERNATION_MAX; i++) { - if (!hibernation_modes[i]) - continue; -@@ -923,6 +932,9 @@ static ssize_t disk_store(struct kobject *kobj, struct kobj_attribute *attr, - char *p; - int mode = HIBERNATION_INVALID; - -+ if (!capable(CAP_COMPROMISE_KERNEL)) -+ return -EPERM; -+ - p = memchr(buf, '\n', n); - len = p ? p - buf : n; - -diff --git a/kernel/power/main.c b/kernel/power/main.c -index f458238..72580c1 100644 ---- a/kernel/power/main.c -+++ b/kernel/power/main.c -@@ -301,7 +301,9 @@ static ssize_t state_show(struct kobject *kobj, struct kobj_attribute *attr, - } - #endif - #ifdef CONFIG_HIBERNATION -- s += sprintf(s, "%s\n", "disk"); -+ if (capable(CAP_COMPROMISE_KERNEL)) { -+ s += sprintf(s, "%s\n", "disk"); -+ } - #else - if (s != buf) - /* convert the last space to a newline */ -diff --git a/kernel/power/user.c b/kernel/power/user.c -index 4ed81e7..b11a0f4 100644 ---- a/kernel/power/user.c -+++ b/kernel/power/user.c -@@ -48,6 +48,9 @@ static int snapshot_open(struct inode *inode, struct file *filp) - struct snapshot_data *data; - int error; - -+ if (!capable(CAP_COMPROMISE_KERNEL)) -+ return -EPERM; -+ - lock_system_sleep(); - - if (!atomic_add_unless(&snapshot_device_available, -1, 0)) { --- -1.8.0.1 - - -From 81adc779dba0f45f10b5ff307bd55832305f1112 Mon Sep 17 00:00:00 2001 -From: Josh Boyer -Date: Wed, 12 Dec 2012 11:48:49 -0500 -Subject: [PATCH 20/20] Don't soft lockup on bad EFI signature lists - -If a signature list is read from an UEFI variable and that contains bogus -data, we can go into an infinite loop in efi_parse_signature_list. Notably, -if one of the entries in the list has a signature_size that is larger than -the actual signature size, it will fail the elsize < esize test. Simply -continuing in the loop without modifying the data or size variables just -leads to the same list entry being parsed repeatedly. - -Since the data is bogus, but we can't tell which value is actually -incorrect, we need to stop parsing the list. Just return -EBADMSG instead. - -Signed-off-by: Josh Boyer ---- - crypto/asymmetric_keys/efi_parser.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/crypto/asymmetric_keys/efi_parser.c b/crypto/asymmetric_keys/efi_parser.c -index 59b859a..a0b8a3a 100644 ---- a/crypto/asymmetric_keys/efi_parser.c -+++ b/crypto/asymmetric_keys/efi_parser.c -@@ -61,7 +61,7 @@ int __init parse_efi_signature_list(const void *data, size_t size, struct key *k - elsize < esize || - elsize % esize != 0) { - pr_devel("- bad size combo @%x\n", offs); -- continue; -+ return -EBADMSG; - } - - if (efi_guidcmp(list.signature_type, efi_cert_x509_guid) != 0) { --- -1.8.0.1 - diff --git a/secure-boot-20130104.patch b/secure-boot-20130104.patch new file mode 100644 index 0000000..a20851a --- /dev/null +++ b/secure-boot-20130104.patch @@ -0,0 +1,1375 @@ +From 627d53fc0ed9c59fe79788e9101db814d096fdfd Mon Sep 17 00:00:00 2001 +From: Matthew Garrett +Date: Thu, 20 Sep 2012 10:40:56 -0400 +Subject: [PATCH 01/18] Secure boot: Add new capability + +Secure boot adds certain policy requirements, including that root must not +be able to do anything that could cause the kernel to execute arbitrary code. +The simplest way to handle this would seem to be to add a new capability +and gate various functionality on that. We'll then strip it from the initial +capability set if required. + +Signed-off-by: Matthew Garrett +--- + include/uapi/linux/capability.h | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/include/uapi/linux/capability.h b/include/uapi/linux/capability.h +index ba478fa..7109e65 100644 +--- a/include/uapi/linux/capability.h ++++ b/include/uapi/linux/capability.h +@@ -343,7 +343,11 @@ struct vfs_cap_data { + + #define CAP_BLOCK_SUSPEND 36 + +-#define CAP_LAST_CAP CAP_BLOCK_SUSPEND ++/* Allow things that trivially permit root to modify the running kernel */ ++ ++#define CAP_COMPROMISE_KERNEL 37 ++ ++#define CAP_LAST_CAP CAP_COMPROMISE_KERNEL + + #define cap_valid(x) ((x) >= 0 && (x) <= CAP_LAST_CAP) + +-- +1.8.0.1 + + +From 959fc919f8b9a94c1db9b9ba73901a23b1a81db5 Mon Sep 17 00:00:00 2001 +From: Josh Boyer +Date: Thu, 20 Sep 2012 10:41:05 -0400 +Subject: [PATCH 02/18] SELinux: define mapping for new Secure Boot capability + +Add the name of the new Secure Boot capability. This allows SELinux +policies to properly map CAP_COMPROMISE_KERNEL to the appropriate +capability class. + +Signed-off-by: Josh Boyer +--- + security/selinux/include/classmap.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/security/selinux/include/classmap.h b/security/selinux/include/classmap.h +index df2de54..70e2834 100644 +--- a/security/selinux/include/classmap.h ++++ b/security/selinux/include/classmap.h +@@ -146,8 +146,8 @@ struct security_class_mapping secclass_map[] = { + { "memprotect", { "mmap_zero", NULL } }, + { "peer", { "recv", NULL } }, + { "capability2", +- { "mac_override", "mac_admin", "syslog", "wake_alarm", "block_suspend", +- NULL } }, ++ { "mac_override", "mac_admin", "syslog", "wake_alarm", ++ "block_suspend", "compromise_kernel", NULL } }, + { "kernel_service", { "use_as_override", "create_files_as", NULL } }, + { "tun_socket", + { COMMON_SOCK_PERMS, NULL } }, +-- +1.8.0.1 + + +From fc74142ccd8b8fd53fc92032c3cbfaa78e398133 Mon Sep 17 00:00:00 2001 +From: Josh Boyer +Date: Thu, 20 Sep 2012 10:41:02 -0400 +Subject: [PATCH 03/18] Secure boot: Add a dummy kernel parameter that will + switch on Secure Boot mode + +This forcibly drops CAP_COMPROMISE_KERNEL from both cap_permitted and cap_bset +in the init_cred struct, which everything else inherits from. This works on +any machine and can be used to develop even if the box doesn't have UEFI. + +Signed-off-by: Josh Boyer +--- + Documentation/kernel-parameters.txt | 7 +++++++ + kernel/cred.c | 17 +++++++++++++++++ + 2 files changed, 24 insertions(+) + +diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt +index 363e348..832b39b 100644 +--- a/Documentation/kernel-parameters.txt ++++ b/Documentation/kernel-parameters.txt +@@ -2654,6 +2654,13 @@ bytes respectively. Such letter suffixes can also be entirely omitted. + Note: increases power consumption, thus should only be + enabled if running jitter sensitive (HPC/RT) workloads. + ++ secureboot_enable= ++ [KNL] Enables an emulated UEFI Secure Boot mode. This ++ locks down various aspects of the kernel guarded by the ++ CAP_COMPROMISE_KERNEL capability. This includes things ++ like /dev/mem, IO port access, and other areas. It can ++ be used on non-UEFI machines for testing purposes. ++ + security= [SECURITY] Choose a security module to enable at boot. + If this boot parameter is not specified, only the first + security module asking for security registration will be +diff --git a/kernel/cred.c b/kernel/cred.c +index e0573a4..c3f4e3e 100644 +--- a/kernel/cred.c ++++ b/kernel/cred.c +@@ -565,6 +565,23 @@ void __init cred_init(void) + 0, SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL); + } + ++void __init secureboot_enable() ++{ ++ pr_info("Secure boot enabled\n"); ++ cap_lower((&init_cred)->cap_bset, CAP_COMPROMISE_KERNEL); ++ cap_lower((&init_cred)->cap_permitted, CAP_COMPROMISE_KERNEL); ++} ++ ++/* Dummy Secure Boot enable option to fake out UEFI SB=1 */ ++static int __init secureboot_enable_opt(char *str) ++{ ++ int sb_enable = !!simple_strtol(str, NULL, 0); ++ if (sb_enable) ++ secureboot_enable(); ++ return 1; ++} ++__setup("secureboot_enable=", secureboot_enable_opt); ++ + /** + * prepare_kernel_cred - Prepare a set of credentials for a kernel service + * @daemon: A userspace daemon to be used as a reference +-- +1.8.0.1 + + +From 5118ce1d16d6b3b00ad9f54ec1a5847fefe0e059 Mon Sep 17 00:00:00 2001 +From: Matthew Garrett +Date: Thu, 20 Sep 2012 10:41:03 -0400 +Subject: [PATCH 04/18] efi: Enable secure boot lockdown automatically when + enabled in firmware + +The firmware has a set of flags that indicate whether secure boot is enabled +and enforcing. Use them to indicate whether the kernel should lock itself +down. + +Signed-off-by: Matthew Garrett +--- + Documentation/x86/zero-page.txt | 2 ++ + arch/x86/boot/compressed/eboot.c | 32 ++++++++++++++++++++++++++++++++ + arch/x86/include/uapi/asm/bootparam.h | 3 ++- + arch/x86/kernel/setup.c | 3 +++ + include/linux/cred.h | 2 ++ + 5 files changed, 41 insertions(+), 1 deletion(-) + +diff --git a/Documentation/x86/zero-page.txt b/Documentation/x86/zero-page.txt +index cf5437d..7f9ed48 100644 +--- a/Documentation/x86/zero-page.txt ++++ b/Documentation/x86/zero-page.txt +@@ -27,6 +27,8 @@ Offset Proto Name Meaning + 1E9/001 ALL eddbuf_entries Number of entries in eddbuf (below) + 1EA/001 ALL edd_mbr_sig_buf_entries Number of entries in edd_mbr_sig_buffer + (below) ++1EB/001 ALL kbd_status Numlock is enabled ++1EC/001 ALL secure_boot Kernel should enable secure boot lockdowns + 290/040 ALL edd_mbr_sig_buffer EDD MBR signatures + 2D0/A00 ALL e820_map E820 memory map table + (array of struct e820entry) +diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c +index b1942e2..1201907 100644 +--- a/arch/x86/boot/compressed/eboot.c ++++ b/arch/x86/boot/compressed/eboot.c +@@ -848,6 +848,36 @@ fail: + return status; + } + ++static int get_secure_boot(efi_system_table_t *_table) ++{ ++ u8 sb, setup; ++ unsigned long datasize = sizeof(sb); ++ efi_guid_t var_guid = EFI_GLOBAL_VARIABLE_GUID; ++ efi_status_t status; ++ ++ status = efi_call_phys5(sys_table->runtime->get_variable, ++ L"SecureBoot", &var_guid, NULL, &datasize, &sb); ++ ++ if (status != EFI_SUCCESS) ++ return 0; ++ ++ if (sb == 0) ++ return 0; ++ ++ ++ status = efi_call_phys5(sys_table->runtime->get_variable, ++ L"SetupMode", &var_guid, NULL, &datasize, ++ &setup); ++ ++ if (status != EFI_SUCCESS) ++ return 0; ++ ++ if (setup == 1) ++ return 0; ++ ++ return 1; ++} ++ + /* + * Because the x86 boot code expects to be passed a boot_params we + * need to create one ourselves (usually the bootloader would create +@@ -1142,6 +1172,8 @@ struct boot_params *efi_main(void *handle, efi_system_table_t *_table, + if (sys_table->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE) + goto fail; + ++ boot_params->secure_boot = get_secure_boot(sys_table); ++ + setup_graphics(boot_params); + + setup_efi_pci(boot_params); +diff --git a/arch/x86/include/uapi/asm/bootparam.h b/arch/x86/include/uapi/asm/bootparam.h +index 92862cd..422e056 100644 +--- a/arch/x86/include/uapi/asm/bootparam.h ++++ b/arch/x86/include/uapi/asm/bootparam.h +@@ -115,7 +115,8 @@ struct boot_params { + __u8 eddbuf_entries; /* 0x1e9 */ + __u8 edd_mbr_sig_buf_entries; /* 0x1ea */ + __u8 kbd_status; /* 0x1eb */ +- __u8 _pad6[5]; /* 0x1ec */ ++ __u8 secure_boot; /* 0x1ec */ ++ __u8 _pad6[4]; /* 0x1ed */ + struct setup_header hdr; /* setup header */ /* 0x1f1 */ + __u8 _pad7[0x290-0x1f1-sizeof(struct setup_header)]; + __u32 edd_mbr_sig_buffer[EDD_MBR_SIG_MAX]; /* 0x290 */ +diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c +index 23ddd55..94203e5 100644 +--- a/arch/x86/kernel/setup.c ++++ b/arch/x86/kernel/setup.c +@@ -962,6 +962,9 @@ void __init setup_arch(char **cmdline_p) + + io_delay_init(); + ++ if (boot_params.secure_boot) ++ secureboot_enable(); ++ + /* + * Parse the ACPI tables for possible boot-time SMP configuration. + */ +diff --git a/include/linux/cred.h b/include/linux/cred.h +index abb2cd5..4f9dea1 100644 +--- a/include/linux/cred.h ++++ b/include/linux/cred.h +@@ -157,6 +157,8 @@ extern int set_security_override_from_ctx(struct cred *, const char *); + extern int set_create_files_as(struct cred *, struct inode *); + extern void __init cred_init(void); + ++extern void secureboot_enable(void); ++ + /* + * check for validity of credentials + */ +-- +1.8.0.1 + + +From adfec2043a2fb091f9f7da6dffdf1cf5aa1bdc3f Mon Sep 17 00:00:00 2001 +From: Josh Boyer +Date: Fri, 26 Oct 2012 12:29:49 -0400 +Subject: [PATCH 05/18] EFI: Add in-kernel variable to determine if Secure Boot + is enabled + +There are a few cases where in-kernel functions may need to know if +Secure Boot is enabled. The added capability check cannot be used as the +kernel can't drop it's own capabilites, so we add a global variable +similar to efi_enabled so they can determine if Secure Boot is enabled. + +Signed-off-by: Josh Boyer +--- + arch/x86/kernel/setup.c | 6 +++++- + arch/x86/platform/efi/efi.c | 2 ++ + include/linux/efi.h | 3 +++ + 3 files changed, 10 insertions(+), 1 deletion(-) + +diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c +index 94203e5..2b89b38 100644 +--- a/arch/x86/kernel/setup.c ++++ b/arch/x86/kernel/setup.c +@@ -962,8 +962,12 @@ void __init setup_arch(char **cmdline_p) + + io_delay_init(); + +- if (boot_params.secure_boot) ++ if (boot_params.secure_boot) { + secureboot_enable(); ++#ifdef CONFIG_EFI ++ secure_boot_enabled = 1; ++#endif ++ } + + /* + * Parse the ACPI tables for possible boot-time SMP configuration. +diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c +index ad44391..d22bfeb 100644 +--- a/arch/x86/platform/efi/efi.c ++++ b/arch/x86/platform/efi/efi.c +@@ -54,6 +54,8 @@ + int efi_enabled; + EXPORT_SYMBOL(efi_enabled); + ++int secure_boot_enabled; ++ + struct efi __read_mostly efi = { + .mps = EFI_INVALID_TABLE_ADDR, + .acpi = EFI_INVALID_TABLE_ADDR, +diff --git a/include/linux/efi.h b/include/linux/efi.h +index 8b84916..7a1a53c 100644 +--- a/include/linux/efi.h ++++ b/include/linux/efi.h +@@ -625,11 +625,14 @@ extern int __init efi_setup_pcdp_console(char *); + # ifdef CONFIG_X86 + extern int efi_enabled; + extern bool efi_64bit; ++ extern int secure_boot_enabled; + # else + # define efi_enabled 1 ++# define secure_boot_enabled 0 + # endif + #else + # define efi_enabled 0 ++# define secure_boot_enabled 0 + #endif + + /* +-- +1.8.0.1 + + +From 32c1c8077fe00d38db0e01b2200d17ab6c9b7263 Mon Sep 17 00:00:00 2001 +From: Dave Howells +Date: Tue, 23 Oct 2012 09:30:54 -0400 +Subject: [PATCH 06/18] Add EFI signature data types + +Add the data types that are used for containing hashes, keys and certificates +for cryptographic verification. + +Signed-off-by: David Howells +--- + include/linux/efi.h | 20 ++++++++++++++++++++ + 1 file changed, 20 insertions(+) + +diff --git a/include/linux/efi.h b/include/linux/efi.h +index 7a1a53c..887b9f3 100644 +--- a/include/linux/efi.h ++++ b/include/linux/efi.h +@@ -388,6 +388,12 @@ typedef efi_status_t efi_query_capsule_caps_t(efi_capsule_header_t **capsules, + #define EFI_FILE_SYSTEM_GUID \ + EFI_GUID( 0x964e5b22, 0x6459, 0x11d2, 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b ) + ++#define EFI_CERT_SHA256_GUID \ ++ EFI_GUID( 0xc1c41626, 0x504c, 0x4092, 0xac, 0xa9, 0x41, 0xf9, 0x36, 0x93, 0x43, 0x28 ) ++ ++#define EFI_CERT_X509_GUID \ ++ EFI_GUID( 0xa5c059a1, 0x94e4, 0x4aa7, 0x87, 0xb5, 0xab, 0x15, 0x5c, 0x2b, 0xf0, 0x72 ) ++ + typedef struct { + efi_guid_t guid; + u64 table; +@@ -523,6 +529,20 @@ typedef struct { + + #define EFI_INVALID_TABLE_ADDR (~0UL) + ++typedef struct { ++ efi_guid_t signature_owner; ++ u8 signature_data[]; ++} efi_signature_data_t; ++ ++typedef struct { ++ efi_guid_t signature_type; ++ u32 signature_list_size; ++ u32 signature_header_size; ++ u32 signature_size; ++ u8 signature_header[]; ++ /* efi_signature_data_t signatures[][] */ ++} efi_signature_list_t; ++ + /* + * All runtime access to EFI goes through this structure: + */ +-- +1.8.0.1 + + +From a270b377f37b16022625fe499f47b51ec29edce4 Mon Sep 17 00:00:00 2001 +From: Dave Howells +Date: Tue, 23 Oct 2012 09:36:28 -0400 +Subject: [PATCH 07/18] Add an EFI signature blob parser and key loader. + +X.509 certificates are loaded into the specified keyring as asymmetric type +keys. + +Signed-off-by: David Howells +--- + crypto/asymmetric_keys/Kconfig | 7 +++ + crypto/asymmetric_keys/Makefile | 1 + + crypto/asymmetric_keys/efi_parser.c | 107 ++++++++++++++++++++++++++++++++++++ + include/linux/efi.h | 4 ++ + 4 files changed, 119 insertions(+) + create mode 100644 crypto/asymmetric_keys/efi_parser.c + +diff --git a/crypto/asymmetric_keys/Kconfig b/crypto/asymmetric_keys/Kconfig +index 6d2c2ea..eb53fc3 100644 +--- a/crypto/asymmetric_keys/Kconfig ++++ b/crypto/asymmetric_keys/Kconfig +@@ -35,4 +35,11 @@ config X509_CERTIFICATE_PARSER + data and provides the ability to instantiate a crypto key from a + public key packet found inside the certificate. + ++config EFI_SIGNATURE_LIST_PARSER ++ bool "EFI signature list parser" ++ select X509_CERTIFICATE_PARSER ++ help ++ This option provides support for parsing EFI signature lists for ++ X.509 certificates and turning them into keys. ++ + endif # ASYMMETRIC_KEY_TYPE +diff --git a/crypto/asymmetric_keys/Makefile b/crypto/asymmetric_keys/Makefile +index 0727204..cd8388e 100644 +--- a/crypto/asymmetric_keys/Makefile ++++ b/crypto/asymmetric_keys/Makefile +@@ -8,6 +8,7 @@ asymmetric_keys-y := asymmetric_type.o signature.o + + obj-$(CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE) += public_key.o + obj-$(CONFIG_PUBLIC_KEY_ALGO_RSA) += rsa.o ++obj-$(CONFIG_EFI_SIGNATURE_LIST_PARSER) += efi_parser.o + + # + # X.509 Certificate handling +diff --git a/crypto/asymmetric_keys/efi_parser.c b/crypto/asymmetric_keys/efi_parser.c +new file mode 100644 +index 0000000..a0b8a3a +--- /dev/null ++++ b/crypto/asymmetric_keys/efi_parser.c +@@ -0,0 +1,107 @@ ++/* EFI signature/key/certificate list parser ++ * ++ * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved. ++ * Written by David Howells (dhowells@redhat.com) ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public Licence ++ * as published by the Free Software Foundation; either version ++ * 2 of the Licence, or (at your option) any later version. ++ */ ++ ++#define pr_fmt(fmt) "EFI: "fmt ++#include ++#include ++#include ++#include ++#include ++ ++static __initdata efi_guid_t efi_cert_x509_guid = EFI_CERT_X509_GUID; ++ ++/** ++ * parse_efi_signature_list - Parse an EFI signature list for certificates ++ * @data: The data blob to parse ++ * @size: The size of the data blob ++ * @keyring: The keyring to add extracted keys to ++ */ ++int __init parse_efi_signature_list(const void *data, size_t size, struct key *keyring) ++{ ++ unsigned offs = 0; ++ size_t lsize, esize, hsize, elsize; ++ ++ pr_devel("-->%s(,%zu)\n", __func__, size); ++ ++ while (size > 0) { ++ efi_signature_list_t list; ++ const efi_signature_data_t *elem; ++ key_ref_t key; ++ ++ if (size < sizeof(list)) ++ return -EBADMSG; ++ ++ memcpy(&list, data, sizeof(list)); ++ pr_devel("LIST[%04x] guid=%pUl ls=%x hs=%x ss=%x\n", ++ offs, ++ list.signature_type.b, list.signature_list_size, ++ list.signature_header_size, list.signature_size); ++ ++ lsize = list.signature_list_size; ++ hsize = list.signature_header_size; ++ esize = list.signature_size; ++ elsize = lsize - sizeof(list) - hsize; ++ ++ if (lsize > size) { ++ pr_devel("<--%s() = -EBADMSG [overrun @%x]\n", ++ __func__, offs); ++ return -EBADMSG; ++ } ++ if (lsize < sizeof(list) || ++ lsize - sizeof(list) < hsize || ++ esize < sizeof(*elem) || ++ elsize < esize || ++ elsize % esize != 0) { ++ pr_devel("- bad size combo @%x\n", offs); ++ return -EBADMSG; ++ } ++ ++ if (efi_guidcmp(list.signature_type, efi_cert_x509_guid) != 0) { ++ data += lsize; ++ size -= lsize; ++ offs += lsize; ++ continue; ++ } ++ ++ data += sizeof(list) + hsize; ++ size -= sizeof(list) + hsize; ++ offs += sizeof(list) + hsize; ++ ++ for (; elsize > 0; elsize -= esize) { ++ elem = data; ++ ++ pr_devel("ELEM[%04x]\n", offs); ++ ++ key = key_create_or_update( ++ make_key_ref(keyring, 1), ++ "asymmetric", ++ NULL, ++ &elem->signature_data, ++ esize - sizeof(*elem), ++ (KEY_POS_ALL & ~KEY_POS_SETATTR) | ++ KEY_USR_VIEW, ++ KEY_ALLOC_NOT_IN_QUOTA); ++ ++ if (IS_ERR(key)) ++ pr_err("Problem loading in-kernel X.509 certificate (%ld)\n", ++ PTR_ERR(key)); ++ else ++ pr_notice("Loaded cert '%s'\n", ++ key_ref_to_ptr(key)->description); ++ ++ data += esize; ++ size -= esize; ++ offs += esize; ++ } ++ } ++ ++ return 0; ++} +diff --git a/include/linux/efi.h b/include/linux/efi.h +index 887b9f3..6b78779 100644 +--- a/include/linux/efi.h ++++ b/include/linux/efi.h +@@ -612,6 +612,10 @@ extern int efi_set_rtc_mmss(unsigned long nowtime); + extern void efi_reserve_boot_services(void); + extern struct efi_memory_map memmap; + ++struct key; ++extern int __init parse_efi_signature_list(const void *data, size_t size, ++ struct key *keyring); ++ + /** + * efi_range_is_wc - check the WC bit on an address range + * @start: starting kvirt address +-- +1.8.0.1 + + +From cd19cf4fd5f2f8f1d423a48af845cad163170bc2 Mon Sep 17 00:00:00 2001 +From: Josh Boyer +Date: Fri, 26 Oct 2012 12:36:24 -0400 +Subject: [PATCH 08/18] MODSIGN: Add module certificate blacklist keyring + +This adds an additional keyring that is used to store certificates that +are blacklisted. This keyring is searched first when loading signed modules +and if the module's certificate is found, it will refuse to load. This is +useful in cases where third party certificates are used for module signing. + +Signed-off-by: Josh Boyer +--- + init/Kconfig | 8 ++++++++ + kernel/modsign_pubkey.c | 14 ++++++++++++++ + kernel/module-internal.h | 3 +++ + kernel/module_signing.c | 14 +++++++++++++- + 4 files changed, 38 insertions(+), 1 deletion(-) + +diff --git a/init/Kconfig b/init/Kconfig +index 7d30240..4a0705e 100644 +--- a/init/Kconfig ++++ b/init/Kconfig +@@ -1665,6 +1665,14 @@ config MODULE_SIG_FORCE + Reject unsigned modules or signed modules for which we don't have a + key. Without this, such modules will simply taint the kernel. + ++config MODULE_SIG_BLACKLIST ++ bool "Support for blacklisting module signature certificates" ++ depends on MODULE_SIG ++ help ++ This adds support for keeping a blacklist of certificates that ++ should not pass module signature verification. If a module is ++ signed with something in this keyring, the load will be rejected. ++ + choice + prompt "Which hash algorithm should modules be signed with?" + depends on MODULE_SIG +diff --git a/kernel/modsign_pubkey.c b/kernel/modsign_pubkey.c +index 2b6e699..4cd408d 100644 +--- a/kernel/modsign_pubkey.c ++++ b/kernel/modsign_pubkey.c +@@ -17,6 +17,9 @@ + #include "module-internal.h" + + struct key *modsign_keyring; ++#ifdef CONFIG_MODULE_SIG_BLACKLIST ++struct key *modsign_blacklist; ++#endif + + extern __initdata const u8 modsign_certificate_list[]; + extern __initdata const u8 modsign_certificate_list_end[]; +@@ -43,6 +46,17 @@ static __init int module_verify_init(void) + if (IS_ERR(modsign_keyring)) + panic("Can't allocate module signing keyring\n"); + ++#ifdef CONFIG_MODULE_SIG_BLACKLIST ++ modsign_blacklist = keyring_alloc(".modsign_blacklist", ++ KUIDT_INIT(0), KGIDT_INIT(0), ++ current_cred(), ++ (KEY_POS_ALL & ~KEY_POS_SETATTR) | ++ KEY_USR_VIEW | KEY_USR_READ, ++ KEY_ALLOC_NOT_IN_QUOTA, NULL); ++ if (IS_ERR(modsign_blacklist)) ++ panic("Can't allocate module signing blacklist keyring\n"); ++#endif ++ + return 0; + } + +diff --git a/kernel/module-internal.h b/kernel/module-internal.h +index 24f9247..51a8380 100644 +--- a/kernel/module-internal.h ++++ b/kernel/module-internal.h +@@ -10,5 +10,8 @@ + */ + + extern struct key *modsign_keyring; ++#ifdef CONFIG_MODULE_SIG_BLACKLIST ++extern struct key *modsign_blacklist; ++#endif + + extern int mod_verify_sig(const void *mod, unsigned long *_modlen); +diff --git a/kernel/module_signing.c b/kernel/module_signing.c +index f2970bd..4654e94 100644 +--- a/kernel/module_signing.c ++++ b/kernel/module_signing.c +@@ -132,7 +132,7 @@ static int mod_extract_mpi_array(struct public_key_signature *pks, + static struct key *request_asymmetric_key(const char *signer, size_t signer_len, + const u8 *key_id, size_t key_id_len) + { +- key_ref_t key; ++ key_ref_t key, blacklist; + size_t i; + char *id, *q; + +@@ -157,6 +157,18 @@ static struct key *request_asymmetric_key(const char *signer, size_t signer_len, + + pr_debug("Look up: \"%s\"\n", id); + ++#ifdef CONFIG_MODULE_SIG_BLACKLIST ++ blacklist = keyring_search(make_key_ref(modsign_blacklist, 1), ++ &key_type_asymmetric, id); ++ if (!IS_ERR(blacklist)) { ++ /* module is signed with a cert in the blacklist. reject */ ++ pr_err("Module key '%s' is in blacklist\n", id); ++ key_ref_put(blacklist); ++ kfree(id); ++ return ERR_PTR(-EKEYREJECTED); ++ } ++#endif ++ + key = keyring_search(make_key_ref(modsign_keyring, 1), + &key_type_asymmetric, id); + if (IS_ERR(key)) +-- +1.8.0.1 + + +From a407acb4318d02658ba2447e653561ab9b1c3a99 Mon Sep 17 00:00:00 2001 +From: Josh Boyer +Date: Fri, 26 Oct 2012 12:42:16 -0400 +Subject: [PATCH 09/18] MODSIGN: Import certificates from UEFI Secure Boot + +Secure Boot stores a list of allowed certificates in the 'db' variable. +This imports those certificates into the module signing keyring. This +allows for a third party signing certificate to be used in conjunction +with signed modules. By importing the public certificate into the 'db' +variable, a user can allow a module signed with that certificate to +load. The shim UEFI bootloader has a similar certificate list stored +in the 'MokListRT' variable. We import those as well. + +In the opposite case, Secure Boot maintains a list of disallowed +certificates in the 'dbx' variable. We load those certificates into +the newly introduced module blacklist keyring and forbid any module +signed with those from loading. + +Signed-off-by: Josh Boyer +--- + include/linux/efi.h | 6 ++++ + init/Kconfig | 9 ++++++ + kernel/Makefile | 3 ++ + kernel/modsign_uefi.c | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++ + 4 files changed, 108 insertions(+) + create mode 100644 kernel/modsign_uefi.c + +diff --git a/include/linux/efi.h b/include/linux/efi.h +index 6b78779..a395dff 100644 +--- a/include/linux/efi.h ++++ b/include/linux/efi.h +@@ -394,6 +394,12 @@ typedef efi_status_t efi_query_capsule_caps_t(efi_capsule_header_t **capsules, + #define EFI_CERT_X509_GUID \ + EFI_GUID( 0xa5c059a1, 0x94e4, 0x4aa7, 0x87, 0xb5, 0xab, 0x15, 0x5c, 0x2b, 0xf0, 0x72 ) + ++#define EFI_IMAGE_SECURITY_DATABASE_GUID \ ++ EFI_GUID( 0xd719b2cb, 0x3d3a, 0x4596, 0xa3, 0xbc, 0xda, 0xd0, 0x0e, 0x67, 0x65, 0x6f ) ++ ++#define EFI_SHIM_LOCK_GUID \ ++ EFI_GUID( 0x605dab50, 0xe046, 0x4300, 0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23 ) ++ + typedef struct { + efi_guid_t guid; + u64 table; +diff --git a/init/Kconfig b/init/Kconfig +index 4a0705e..984b316 100644 +--- a/init/Kconfig ++++ b/init/Kconfig +@@ -1673,6 +1673,15 @@ config MODULE_SIG_BLACKLIST + should not pass module signature verification. If a module is + signed with something in this keyring, the load will be rejected. + ++config MODULE_SIG_UEFI ++ bool "Allow modules signed with certs stored in UEFI" ++ depends on MODULE_SIG && MODULE_SIG_BLACKLIST && EFI ++ select EFI_SIGNATURE_LIST_PARSER ++ help ++ This will import certificates stored in UEFI and allow modules ++ signed with those to be loaded. It will also disallow loading ++ of modules stored in the UEFI dbx variable. ++ + choice + prompt "Which hash algorithm should modules be signed with?" + depends on MODULE_SIG +diff --git a/kernel/Makefile b/kernel/Makefile +index 6c072b6..8848829 100644 +--- a/kernel/Makefile ++++ b/kernel/Makefile +@@ -55,6 +55,7 @@ obj-$(CONFIG_PROVE_LOCKING) += spinlock.o + obj-$(CONFIG_UID16) += uid16.o + obj-$(CONFIG_MODULES) += module.o + obj-$(CONFIG_MODULE_SIG) += module_signing.o modsign_pubkey.o modsign_certificate.o ++obj-$(CONFIG_MODULE_SIG_UEFI) += modsign_uefi.o + obj-$(CONFIG_KALLSYMS) += kallsyms.o + obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o + obj-$(CONFIG_KEXEC) += kexec.o +@@ -114,6 +115,8 @@ obj-$(CONFIG_CONTEXT_TRACKING) += context_tracking.o + + $(obj)/configs.o: $(obj)/config_data.h + ++$(obj)/modsign_uefi.o: KBUILD_CFLAGS += -fshort-wchar ++ + # config_data.h contains the same information as ikconfig.h but gzipped. + # Info from config_data can be extracted from /proc/config* + targets += config_data.gz +diff --git a/kernel/modsign_uefi.c b/kernel/modsign_uefi.c +new file mode 100644 +index 0000000..76a5a34 +--- /dev/null ++++ b/kernel/modsign_uefi.c +@@ -0,0 +1,90 @@ ++#include ++#include ++#include ++#include ++#include ++#include ++#include "module-internal.h" ++ ++static __init void *get_cert_list(efi_char16_t *name, efi_guid_t *guid, unsigned long *size) ++{ ++ efi_status_t status; ++ unsigned long lsize = 4; ++ unsigned long tmpdb[4]; ++ void *db = NULL; ++ ++ status = efi.get_variable(name, guid, NULL, &lsize, &tmpdb); ++ if (status != EFI_BUFFER_TOO_SMALL) { ++ pr_err("Couldn't get size: 0x%lx\n", status); ++ return NULL; ++ } ++ ++ db = kmalloc(lsize, GFP_KERNEL); ++ if (!db) { ++ pr_err("Couldn't allocate memory for uefi cert list\n"); ++ goto out; ++ } ++ ++ status = efi.get_variable(name, guid, NULL, &lsize, db); ++ if (status != EFI_SUCCESS) { ++ kfree(db); ++ db = NULL; ++ pr_err("Error reading db var: 0x%lx\n", status); ++ } ++out: ++ *size = lsize; ++ return db; ++} ++ ++/* ++ * * Load the certs contained in the UEFI databases ++ * */ ++static int __init load_uefi_certs(void) ++{ ++ efi_guid_t secure_var = EFI_IMAGE_SECURITY_DATABASE_GUID; ++ efi_guid_t mok_var = EFI_SHIM_LOCK_GUID; ++ void *db = NULL, *dbx = NULL, *mok = NULL; ++ unsigned long dbsize = 0, dbxsize = 0, moksize = 0; ++ int rc = 0; ++ ++ /* Check if SB is enabled and just return if not */ ++ if (!secure_boot_enabled) ++ return 0; ++ ++ /* Get db, MokListRT, and dbx. They might not exist, so it isn't ++ * an error if we can't get them. ++ */ ++ db = get_cert_list(L"db", &secure_var, &dbsize); ++ if (!db) { ++ pr_err("MODSIGN: Couldn't get UEFI db list\n"); ++ } else { ++ rc = parse_efi_signature_list(db, dbsize, modsign_keyring); ++ if (rc) ++ pr_err("Couldn't parse db signatures: %d\n", rc); ++ kfree(db); ++ } ++ ++ mok = get_cert_list(L"MokListRT", &mok_var, &moksize); ++ if (!mok) { ++ pr_info("MODSIGN: Couldn't get UEFI MokListRT\n"); ++ } else { ++ rc = parse_efi_signature_list(mok, moksize, modsign_keyring); ++ if (rc) ++ pr_err("Couldn't parse MokListRT signatures: %d\n", rc); ++ kfree(mok); ++ } ++ ++ dbx = get_cert_list(L"dbx", &secure_var, &dbxsize); ++ if (!dbx) { ++ pr_info("MODSIGN: Couldn't get UEFI dbx list\n"); ++ } else { ++ rc = parse_efi_signature_list(dbx, dbxsize, ++ modsign_blacklist); ++ if (rc) ++ pr_err("Couldn't parse dbx signatures: %d\n", rc); ++ kfree(dbx); ++ } ++ ++ return rc; ++} ++late_initcall(load_uefi_certs); +-- +1.8.0.1 + + +From 289a4c7fae985fbb476f4b0d3b008fab5a6f71a9 Mon Sep 17 00:00:00 2001 +From: Matthew Garrett +Date: Thu, 20 Sep 2012 10:40:57 -0400 +Subject: [PATCH 10/18] PCI: Lock down BAR access in secure boot environments + +Any hardware that can potentially generate DMA has to be locked down from +userspace in order to avoid it being possible for an attacker to cause +arbitrary kernel behaviour. Default to paranoid - in future we can +potentially relax this for sufficiently IOMMU-isolated devices. + +Signed-off-by: Matthew Garrett +--- + drivers/pci/pci-sysfs.c | 9 +++++++++ + drivers/pci/proc.c | 8 +++++++- + drivers/pci/syscall.c | 2 +- + 3 files changed, 17 insertions(+), 2 deletions(-) + +diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c +index 9c6e9bb..b966089 100644 +--- a/drivers/pci/pci-sysfs.c ++++ b/drivers/pci/pci-sysfs.c +@@ -622,6 +622,9 @@ pci_write_config(struct file* filp, struct kobject *kobj, + loff_t init_off = off; + u8 *data = (u8*) buf; + ++ if (!capable(CAP_COMPROMISE_KERNEL)) ++ return -EPERM; ++ + if (off > dev->cfg_size) + return 0; + if (off + count > dev->cfg_size) { +@@ -928,6 +931,9 @@ pci_mmap_resource(struct kobject *kobj, struct bin_attribute *attr, + resource_size_t start, end; + int i; + ++ if (!capable(CAP_COMPROMISE_KERNEL)) ++ return -EPERM; ++ + for (i = 0; i < PCI_ROM_RESOURCE; i++) + if (res == &pdev->resource[i]) + break; +@@ -1035,6 +1041,9 @@ pci_write_resource_io(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, char *buf, + loff_t off, size_t count) + { ++ if (!capable(CAP_COMPROMISE_KERNEL)) ++ return -EPERM; ++ + return pci_resource_io(filp, kobj, attr, buf, off, count, true); + } + +diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c +index 9b8505c..35580bc 100644 +--- a/drivers/pci/proc.c ++++ b/drivers/pci/proc.c +@@ -139,6 +139,9 @@ proc_bus_pci_write(struct file *file, const char __user *buf, size_t nbytes, lof + int size = dp->size; + int cnt; + ++ if (!capable(CAP_COMPROMISE_KERNEL)) ++ return -EPERM; ++ + if (pos >= size) + return 0; + if (nbytes >= size) +@@ -219,6 +222,9 @@ static long proc_bus_pci_ioctl(struct file *file, unsigned int cmd, + #endif /* HAVE_PCI_MMAP */ + int ret = 0; + ++ if (!capable(CAP_COMPROMISE_KERNEL)) ++ return -EPERM; ++ + switch (cmd) { + case PCIIOC_CONTROLLER: + ret = pci_domain_nr(dev->bus); +@@ -259,7 +265,7 @@ static int proc_bus_pci_mmap(struct file *file, struct vm_area_struct *vma) + struct pci_filp_private *fpriv = file->private_data; + int i, ret; + +- if (!capable(CAP_SYS_RAWIO)) ++ if (!capable(CAP_SYS_RAWIO) || !capable(CAP_COMPROMISE_KERNEL)) + return -EPERM; + + /* Make sure the caller is mapping a real resource for this device */ +diff --git a/drivers/pci/syscall.c b/drivers/pci/syscall.c +index e1c1ec5..97e785f 100644 +--- a/drivers/pci/syscall.c ++++ b/drivers/pci/syscall.c +@@ -92,7 +92,7 @@ SYSCALL_DEFINE5(pciconfig_write, unsigned long, bus, unsigned long, dfn, + u32 dword; + int err = 0; + +- if (!capable(CAP_SYS_ADMIN)) ++ if (!capable(CAP_SYS_ADMIN) || !capable(CAP_COMPROMISE_KERNEL)) + return -EPERM; + + dev = pci_get_bus_and_slot(bus, dfn); +-- +1.8.0.1 + + +From 2ba88cf9227f38b0681a59a93ba809a624d5ca57 Mon Sep 17 00:00:00 2001 +From: Matthew Garrett +Date: Thu, 20 Sep 2012 10:40:58 -0400 +Subject: [PATCH 11/18] x86: Lock down IO port access in secure boot + environments + +IO port access would permit users to gain access to PCI configuration +registers, which in turn (on a lot of hardware) give access to MMIO register +space. This would potentially permit root to trigger arbitrary DMA, so lock +it down by default. + +Signed-off-by: Matthew Garrett +--- + arch/x86/kernel/ioport.c | 4 ++-- + drivers/char/mem.c | 3 +++ + 2 files changed, 5 insertions(+), 2 deletions(-) + +diff --git a/arch/x86/kernel/ioport.c b/arch/x86/kernel/ioport.c +index 8c96897..a2578c4 100644 +--- a/arch/x86/kernel/ioport.c ++++ b/arch/x86/kernel/ioport.c +@@ -28,7 +28,7 @@ asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on) + + if ((from + num <= from) || (from + num > IO_BITMAP_BITS)) + return -EINVAL; +- if (turn_on && !capable(CAP_SYS_RAWIO)) ++ if (turn_on && (!capable(CAP_SYS_RAWIO) || !capable(CAP_COMPROMISE_KERNEL))) + return -EPERM; + + /* +@@ -102,7 +102,7 @@ long sys_iopl(unsigned int level, struct pt_regs *regs) + return -EINVAL; + /* Trying to gain more privileges? */ + if (level > old) { +- if (!capable(CAP_SYS_RAWIO)) ++ if (!capable(CAP_SYS_RAWIO) || !capable(CAP_COMPROMISE_KERNEL)) + return -EPERM; + } + regs->flags = (regs->flags & ~X86_EFLAGS_IOPL) | (level << 12); +diff --git a/drivers/char/mem.c b/drivers/char/mem.c +index c6fa3bc..fc28099 100644 +--- a/drivers/char/mem.c ++++ b/drivers/char/mem.c +@@ -597,6 +597,9 @@ static ssize_t write_port(struct file *file, const char __user *buf, + unsigned long i = *ppos; + const char __user * tmp = buf; + ++ if (!capable(CAP_COMPROMISE_KERNEL)) ++ return -EPERM; ++ + if (!access_ok(VERIFY_READ, buf, count)) + return -EFAULT; + while (count-- > 0 && i < 65536) { +-- +1.8.0.1 + + +From 49b64dbdd09cdea74b42e488766f4bb6dad098d1 Mon Sep 17 00:00:00 2001 +From: Matthew Garrett +Date: Thu, 20 Sep 2012 10:40:59 -0400 +Subject: [PATCH 12/18] ACPI: Limit access to custom_method + +It must be impossible for even root to get code executed in kernel context +under a secure boot environment. custom_method effectively allows arbitrary +access to system memory, so it needs to have a capability check here. + +Signed-off-by: Matthew Garrett +--- + drivers/acpi/custom_method.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/acpi/custom_method.c b/drivers/acpi/custom_method.c +index 5d42c24..247d58b 100644 +--- a/drivers/acpi/custom_method.c ++++ b/drivers/acpi/custom_method.c +@@ -29,6 +29,9 @@ static ssize_t cm_write(struct file *file, const char __user * user_buf, + struct acpi_table_header table; + acpi_status status; + ++ if (!capable(CAP_COMPROMISE_KERNEL)) ++ return -EPERM; ++ + if (!(*ppos)) { + /* parse the table header to get the table length */ + if (count <= sizeof(struct acpi_table_header)) +-- +1.8.0.1 + + +From 7317c00a377490a270267b7311dead7c2fb4fc4c Mon Sep 17 00:00:00 2001 +From: Matthew Garrett +Date: Thu, 20 Sep 2012 10:41:00 -0400 +Subject: [PATCH 13/18] asus-wmi: Restrict debugfs interface + +We have no way of validating what all of the Asus WMI methods do on a +given machine, and there's a risk that some will allow hardware state to +be manipulated in such a way that arbitrary code can be executed in the +kernel. Add a capability check to prevent that. + +Signed-off-by: Matthew Garrett +--- + drivers/platform/x86/asus-wmi.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c +index f80ae4d..059195f 100644 +--- a/drivers/platform/x86/asus-wmi.c ++++ b/drivers/platform/x86/asus-wmi.c +@@ -1521,6 +1521,9 @@ static int show_dsts(struct seq_file *m, void *data) + int err; + u32 retval = -1; + ++ if (!capable(CAP_COMPROMISE_KERNEL)) ++ return -EPERM; ++ + err = asus_wmi_get_devstate(asus, asus->debug.dev_id, &retval); + + if (err < 0) +@@ -1537,6 +1540,9 @@ static int show_devs(struct seq_file *m, void *data) + int err; + u32 retval = -1; + ++ if (!capable(CAP_COMPROMISE_KERNEL)) ++ return -EPERM; ++ + err = asus_wmi_set_devstate(asus->debug.dev_id, asus->debug.ctrl_param, + &retval); + +@@ -1561,6 +1567,9 @@ static int show_call(struct seq_file *m, void *data) + union acpi_object *obj; + acpi_status status; + ++ if (!capable(CAP_COMPROMISE_KERNEL)) ++ return -EPERM; ++ + status = wmi_evaluate_method(ASUS_WMI_MGMT_GUID, + 1, asus->debug.method_id, + &input, &output); +-- +1.8.0.1 + + +From dc5b32fcb170a0ef921bc83979a6fc5b23ccddb9 Mon Sep 17 00:00:00 2001 +From: Matthew Garrett +Date: Thu, 20 Sep 2012 10:41:01 -0400 +Subject: [PATCH 14/18] Restrict /dev/mem and /dev/kmem in secure boot setups + +Allowing users to write to address space makes it possible for the kernel +to be subverted. Restrict this when we need to protect the kernel. + +Signed-off-by: Matthew Garrett +--- + drivers/char/mem.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/drivers/char/mem.c b/drivers/char/mem.c +index fc28099..b5df7a8 100644 +--- a/drivers/char/mem.c ++++ b/drivers/char/mem.c +@@ -158,6 +158,9 @@ static ssize_t write_mem(struct file *file, const char __user *buf, + unsigned long copied; + void *ptr; + ++ if (!capable(CAP_COMPROMISE_KERNEL)) ++ return -EPERM; ++ + if (!valid_phys_addr_range(p, count)) + return -EFAULT; + +@@ -530,6 +533,9 @@ static ssize_t write_kmem(struct file *file, const char __user *buf, + char * kbuf; /* k-addr because vwrite() takes vmlist_lock rwlock */ + int err = 0; + ++ if (!capable(CAP_COMPROMISE_KERNEL)) ++ return -EPERM; ++ + if (p < (unsigned long) high_memory) { + unsigned long to_write = min_t(unsigned long, count, + (unsigned long)high_memory - p); +-- +1.8.0.1 + + +From 780002e8d091621db933d4daf29ee471a44a5a4a Mon Sep 17 00:00:00 2001 +From: Josh Boyer +Date: Thu, 20 Sep 2012 10:41:04 -0400 +Subject: [PATCH 15/18] acpi: Ignore acpi_rsdp kernel parameter in a secure + boot environment + +This option allows userspace to pass the RSDP address to the kernel. This +could potentially be used to circumvent the secure boot trust model. +We ignore the setting if we don't have the CAP_COMPROMISE_KERNEL capability. + +Signed-off-by: Josh Boyer +--- + drivers/acpi/osl.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c +index 3ff2678..794d78b 100644 +--- a/drivers/acpi/osl.c ++++ b/drivers/acpi/osl.c +@@ -246,7 +246,7 @@ early_param("acpi_rsdp", setup_acpi_rsdp); + acpi_physical_address __init acpi_os_get_root_pointer(void) + { + #ifdef CONFIG_KEXEC +- if (acpi_rsdp) ++ if (acpi_rsdp && capable(CAP_COMPROMISE_KERNEL)) + return acpi_rsdp; + #endif + +-- +1.8.0.1 + + +From 56c6202ad8bc40114bf2bf9b8067e5d6b3be33e9 Mon Sep 17 00:00:00 2001 +From: Matthew Garrett +Date: Tue, 4 Sep 2012 11:55:13 -0400 +Subject: [PATCH 16/18] kexec: Disable in a secure boot environment + +kexec could be used as a vector for a malicious user to use a signed kernel +to circumvent the secure boot trust model. In the long run we'll want to +support signed kexec payloads, but for the moment we should just disable +loading entirely in that situation. + +Signed-off-by: Matthew Garrett +--- + kernel/kexec.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/kernel/kexec.c b/kernel/kexec.c +index 5e4bd78..dd464e0 100644 +--- a/kernel/kexec.c ++++ b/kernel/kexec.c +@@ -943,7 +943,7 @@ SYSCALL_DEFINE4(kexec_load, unsigned long, entry, unsigned long, nr_segments, + int result; + + /* We only trust the superuser with rebooting the system. */ +- if (!capable(CAP_SYS_BOOT)) ++ if (!capable(CAP_SYS_BOOT) || !capable(CAP_COMPROMISE_KERNEL)) + return -EPERM; + + /* +-- +1.8.0.1 + + +From d0cf848b67ae89fed7e5ddb417cf57c83b2e187c Mon Sep 17 00:00:00 2001 +From: Josh Boyer +Date: Fri, 5 Oct 2012 10:12:48 -0400 +Subject: [PATCH 17/18] modsign: Always enforce module signing in a Secure Boot + environment + +If a machine is booted into a Secure Boot environment, we need to +protect the trust model. This requires that all modules be signed +with a key that is in the kernel's _modsign keyring. The checks for +this are already done via the 'sig_enforce' module parameter. Make +this visible within the kernel and force it to be true. + +Signed-off-by: Josh Boyer +--- + kernel/cred.c | 8 ++++++++ + kernel/module.c | 4 ++-- + 2 files changed, 10 insertions(+), 2 deletions(-) + +diff --git a/kernel/cred.c b/kernel/cred.c +index c3f4e3e..c5554e0 100644 +--- a/kernel/cred.c ++++ b/kernel/cred.c +@@ -565,11 +565,19 @@ void __init cred_init(void) + 0, SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL); + } + ++#ifdef CONFIG_MODULE_SIG ++extern bool sig_enforce; ++#endif ++ + void __init secureboot_enable() + { + pr_info("Secure boot enabled\n"); + cap_lower((&init_cred)->cap_bset, CAP_COMPROMISE_KERNEL); + cap_lower((&init_cred)->cap_permitted, CAP_COMPROMISE_KERNEL); ++#ifdef CONFIG_MODULE_SIG ++ /* Enable module signature enforcing */ ++ sig_enforce = true; ++#endif + } + + /* Dummy Secure Boot enable option to fake out UEFI SB=1 */ +diff --git a/kernel/module.c b/kernel/module.c +index a50172e..11a08cf 100644 +--- a/kernel/module.c ++++ b/kernel/module.c +@@ -109,9 +109,9 @@ struct list_head *kdb_modules = &modules; /* kdb needs the list of modules */ + + #ifdef CONFIG_MODULE_SIG + #ifdef CONFIG_MODULE_SIG_FORCE +-static bool sig_enforce = true; ++bool sig_enforce = true; + #else +-static bool sig_enforce = false; ++bool sig_enforce = false; + + static int param_set_bool_enable_only(const char *val, + const struct kernel_param *kp) +-- +1.8.0.1 + + +From eaa24912bea0dc76a5522da7a2bc2ae9c6b2359f Mon Sep 17 00:00:00 2001 +From: Josh Boyer +Date: Fri, 26 Oct 2012 14:02:09 -0400 +Subject: [PATCH 18/18] hibernate: Disable in a Secure Boot environment + +There is currently no way to verify the resume image when returning +from hibernate. This might compromise the secure boot trust model, +so until we can work with signed hibernate images we disable it in +a Secure Boot environment. + +Signed-off-by: Josh Boyer +--- + kernel/power/hibernate.c | 14 +++++++++++++- + kernel/power/main.c | 4 +++- + kernel/power/user.c | 3 +++ + 3 files changed, 19 insertions(+), 2 deletions(-) + +diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c +index b26f5f1..f04343b 100644 +--- a/kernel/power/hibernate.c ++++ b/kernel/power/hibernate.c +@@ -632,6 +632,10 @@ int hibernate(void) + { + int error; + ++ if (!capable(CAP_COMPROMISE_KERNEL)) { ++ return -EPERM; ++ } ++ + lock_system_sleep(); + /* The snapshot device should not be opened while we're running */ + if (!atomic_add_unless(&snapshot_device_available, -1, 0)) { +@@ -723,7 +727,7 @@ static int software_resume(void) + /* + * If the user said "noresume".. bail out early. + */ +- if (noresume) ++ if (noresume || !capable(CAP_COMPROMISE_KERNEL)) + return 0; + + /* +@@ -889,6 +893,11 @@ static ssize_t disk_show(struct kobject *kobj, struct kobj_attribute *attr, + int i; + char *start = buf; + ++ if (!capable(CAP_COMPROMISE_KERNEL)) { ++ buf += sprintf(buf, "[%s]\n", "disabled"); ++ return buf-start; ++ } ++ + for (i = HIBERNATION_FIRST; i <= HIBERNATION_MAX; i++) { + if (!hibernation_modes[i]) + continue; +@@ -923,6 +932,9 @@ static ssize_t disk_store(struct kobject *kobj, struct kobj_attribute *attr, + char *p; + int mode = HIBERNATION_INVALID; + ++ if (!capable(CAP_COMPROMISE_KERNEL)) ++ return -EPERM; ++ + p = memchr(buf, '\n', n); + len = p ? p - buf : n; + +diff --git a/kernel/power/main.c b/kernel/power/main.c +index 1c16f91..82eed15 100644 +--- a/kernel/power/main.c ++++ b/kernel/power/main.c +@@ -301,7 +301,9 @@ static ssize_t state_show(struct kobject *kobj, struct kobj_attribute *attr, + } + #endif + #ifdef CONFIG_HIBERNATION +- s += sprintf(s, "%s\n", "disk"); ++ if (capable(CAP_COMPROMISE_KERNEL)) { ++ s += sprintf(s, "%s\n", "disk"); ++ } + #else + if (s != buf) + /* convert the last space to a newline */ +diff --git a/kernel/power/user.c b/kernel/power/user.c +index 4ed81e7..b11a0f4 100644 +--- a/kernel/power/user.c ++++ b/kernel/power/user.c +@@ -48,6 +48,9 @@ static int snapshot_open(struct inode *inode, struct file *filp) + struct snapshot_data *data; + int error; + ++ if (!capable(CAP_COMPROMISE_KERNEL)) ++ return -EPERM; ++ + lock_system_sleep(); + + if (!atomic_add_unless(&snapshot_device_available, -1, 0)) { +-- +1.8.0.1 + diff --git a/sources b/sources index 580ae0b..7b1c33c 100644 --- a/sources +++ b/sources @@ -1 +1,3 @@ 21223369d682bcf44bcdfe1521095983 linux-3.7.tar.xz +bf527ba474ebb9a8a0cd2432ac0ac2b8 patch-3.8-rc2.xz +3ae68b09402b6b775b5174508138b0b7 patch-3.8-rc2-git1.xz