From 0822685323171c28c5cf1c9d6a7dc608c5c8e17a Mon Sep 17 00:00:00 2001 From: Joonyoung Shim Date: Tue, 17 May 2016 13:58:08 +0900 Subject: [PATCH 01/16] ARM: mali400: fix building out of tree s/$(src)/$(srctree)\/$(src)/ $(srctree) has absolute path of kernel root directory, so with this commit, building problem by relative path will be gone from outside of kernel tree. Change-Id: Ib6e4a23a5858b029c75b7e760082846a2247f21a Signed-off-by: Joonyoung Shim --- drivers/gpu/arm/mali400/r4p0_rel0/Kbuild | 24 ++++++++++++------------ drivers/gpu/arm/mali400/r5p0_rel0/Kbuild | 24 ++++++++++++------------ drivers/gpu/arm/mali400/r5p2_rel0/Kbuild | 24 ++++++++++++------------ 3 files changed, 36 insertions(+), 36 deletions(-) diff --git a/drivers/gpu/arm/mali400/r4p0_rel0/Kbuild b/drivers/gpu/arm/mali400/r4p0_rel0/Kbuild index 184e444..98d8874 100755 --- a/drivers/gpu/arm/mali400/r4p0_rel0/Kbuild +++ b/drivers/gpu/arm/mali400/r4p0_rel0/Kbuild @@ -31,7 +31,7 @@ DFS_ONE_STEP_SCALE_DOWN ?= 1 MATCH_DFS_TO_LOWER_FREQ ?= 1 # The GPL product will only include the license/gpl directory -ccflags-y += -I$(src)/linux/license/gpl +ccflags-y += -I$(srctree)/$(src)/linux/license/gpl ifeq ($(CONFIG_MALI400),y) MALI_ENABLE_GPU_CONTROL_IN_PARAM = 0 @@ -115,7 +115,7 @@ mali-$(CONFIG_MALI400_PROFILING) += linux/mali_ukk_profiling.o mali-$(CONFIG_MALI400_PROFILING) += linux/mali_osk_profiling.o mali-$(CONFIG_MALI400_INTERNAL_PROFILING) += linux/mali_profiling_internal.o timestamp-$(TIMESTAMP)/mali_timestamp.o -ccflags-$(CONFIG_MALI400_INTERNAL_PROFILING) += -I$(src)/timestamp-$(TIMESTAMP) +ccflags-$(CONFIG_MALI400_INTERNAL_PROFILING) += -I$(srctree)/$(src)/timestamp-$(TIMESTAMP) mali-$(CONFIG_DMA_SHARED_BUFFER) += linux/mali_memory_dma_buf.o mali-$(CONFIG_SYNC) += linux/mali_sync.o @@ -155,16 +155,16 @@ ifeq ($(MALI_UPPER_HALF_SCHEDULING),1) ccflags-y += -DMALI_UPPER_HALF_SCHEDULING endif -ccflags-$(CONFIG_MALI400_UMP) += -I$(src)/../ump/include/ump +ccflags-$(CONFIG_MALI400_UMP) += -I$(srctree)/$(src)/../ump/include/ump ccflags-$(CONFIG_MALI400_DEBUG) += -DDEBUG # Use our defines when compiling -ccflags-y += -I$(src) -I$(src)/include -I$(src)/common -I$(src)/linux -I$(src)/platform -I$(src)/platform/$(MALI_PLATFORM) +ccflags-y += -I$(srctree)/$(src) -I$(srctree)/$(src)/include -I$(srctree)/$(src)/common -I$(srctree)/$(src)/linux -I$(srctree)/$(src)/platform -I$(srctree)/$(src)/platform/$(MALI_PLATFORM) # Get subversion revision number, fall back to only ${MALI_RELEASE_NAME} if no svn info is available -MALI_RELEASE_NAME=$(shell cat $(src)/.version 2> /dev/null) +MALI_RELEASE_NAME=$(shell cat $(srctree)/$(src)/.version 2> /dev/null) -#SVN_INFO = (cd $(src); svn info 2>/dev/null) +#SVN_INFO = (cd $(srctree)/$(src); svn info 2>/dev/null) ifneq ($(shell $(SVN_INFO) 2>/dev/null),) # SVN detected @@ -175,13 +175,13 @@ CHANGED_REVISION := $(shell $(SVN_INFO) | grep '^Last Changed Rev: ' | cut -d: - REPO_URL := $(shell $(SVN_INFO) | grep '^URL: ' | cut -d: -f2- | cut -b2-) else # SVN -#GIT_REV := $(shell cd $(src); git describe --always 2>/dev/null) +#GIT_REV := $(shell cd $(srctree)/$(src); git describe --always 2>/dev/null) ifneq ($(GIT_REV),) # Git detected DRIVER_REV := $(MALI_RELEASE_NAME)-$(GIT_REV) -CHANGE_DATE := $(shell cd $(src); git log -1 --format="%ci") +CHANGE_DATE := $(shell cd $(srctree)/$(src); git log -1 --format="%ci") CHANGED_REVISION := $(GIT_REV) -REPO_URL := $(shell cd $(src); git describe --all --always 2>/dev/null) +REPO_URL := $(shell cd $(srctree)/$(src); git describe --all --always 2>/dev/null) else # Git # No Git or SVN detected @@ -194,7 +194,7 @@ endif ccflags-y += -DSVN_REV_STRING=\"$(DRIVER_REV)\" VERSION_STRINGS := -VERSION_STRINGS += API_VERSION=$(shell cd $(src); grep "\#define _MALI_API_VERSION" $(FILES_PREFIX)include/linux/mali/mali_utgard_uk_types.h | cut -d' ' -f 3 ) +VERSION_STRINGS += API_VERSION=$(shell cd $(srctree)/$(src); grep "\#define _MALI_API_VERSION" $(FILES_PREFIX)include/linux/mali/mali_utgard_uk_types.h | cut -d' ' -f 3 ) VERSION_STRINGS += REPO_URL=$(REPO_URL) VERSION_STRINGS += REVISION=$(DRIVER_REV) VERSION_STRINGS += CHANGED_REVISION=$(CHANGED_REVISION) @@ -217,5 +217,5 @@ VERSION_STRINGS += USING_POWER_PERFORMANCE_POLICY=$(CONFIG_POWER_PERFORMANCE_POL VERSION_STRINGS += MALI_UPPER_HALF_SCHEDULING=$(MALI_UPPER_HALF_SCHEDULING) # Create file with Mali driver configuration -$(src)/__malidrv_build_info.c: - @echo 'const char *__malidrv_build_info(void) { return "malidrv: $(VERSION_STRINGS)";}' > $(src)/__malidrv_build_info.c +$(srctree)/$(src)/__malidrv_build_info.c: + @echo 'const char *__malidrv_build_info(void) { return "malidrv: $(VERSION_STRINGS)";}' > $(srctree)/$(src)/__malidrv_build_info.c diff --git a/drivers/gpu/arm/mali400/r5p0_rel0/Kbuild b/drivers/gpu/arm/mali400/r5p0_rel0/Kbuild index 34f6974..ae86206 100644 --- a/drivers/gpu/arm/mali400/r5p0_rel0/Kbuild +++ b/drivers/gpu/arm/mali400/r5p0_rel0/Kbuild @@ -28,7 +28,7 @@ MATCH_DFS_TO_LOWER_FREQ ?= 1 GLES_MEM_PROFILE ?= 1 # The GPL product will only include the license/gpl directory -ccflags-y += -I$(src)/linux/license/gpl +ccflags-y += -I$(srctree)/$(src)/linux/license/gpl ifeq ($(USING_GPU_UTILIZATION), 1) ifeq ($(USING_DVFS), 1) @@ -111,7 +111,7 @@ mali-$(CONFIG_MALI400_PROFILING) += linux/mali_ukk_profiling.o mali-$(CONFIG_MALI400_PROFILING) += linux/mali_osk_profiling.o mali-$(CONFIG_MALI400_INTERNAL_PROFILING) += linux/mali_profiling_internal.o timestamp-$(TIMESTAMP)/mali_timestamp.o -ccflags-$(CONFIG_MALI400_INTERNAL_PROFILING) += -I$(src)/timestamp-$(TIMESTAMP) +ccflags-$(CONFIG_MALI400_INTERNAL_PROFILING) += -I$(srctree)/$(src)/timestamp-$(TIMESTAMP) mali-$(CONFIG_DMA_SHARED_BUFFER) += linux/mali_memory_dma_buf.o mali-$(CONFIG_SYNC) += linux/mali_sync.o @@ -146,16 +146,16 @@ ifeq ($(MALI_UPPER_HALF_SCHEDULING),1) ccflags-y += -DMALI_UPPER_HALF_SCHEDULING endif -ccflags-$(CONFIG_MALI400_UMP) += -I$(src)/../ump/include/ump +ccflags-$(CONFIG_MALI400_UMP) += -I$(srctree)/$(src)/../ump/include/ump ccflags-$(CONFIG_MALI400_DEBUG) += -DDEBUG # Use our defines when compiling -ccflags-y += -I$(src) -I$(src)/include -I$(src)/common -I$(src)/linux -I$(src)/platform -I$(src)/platform/$(MALI_PLATFORM) +ccflags-y += -I$(srctree)/$(src) -I$(srctree)/$(src)/include -I$(srctree)/$(src)/common -I$(srctree)/$(src)/linux -I$(srctree)/$(src)/platform -I$(srctree)/$(src)/platform/$(MALI_PLATFORM) # Get subversion revision number, fall back to only ${MALI_RELEASE_NAME} if no svn info is available -MALI_RELEASE_NAME=$(shell cat $(src)/.version 2> /dev/null) +MALI_RELEASE_NAME=$(shell cat $(srctree)/$(src)/.version 2> /dev/null) -#SVN_INFO = (cd $(src); svn info 2>/dev/null) +#SVN_INFO = (cd $(srctree)/$(src); svn info 2>/dev/null) ifneq ($(shell $(SVN_INFO) 2>/dev/null),) # SVN detected @@ -166,13 +166,13 @@ CHANGED_REVISION := $(shell $(SVN_INFO) | grep '^Last Changed Rev: ' | cut -d: - REPO_URL := $(shell $(SVN_INFO) | grep '^URL: ' | cut -d: -f2- | cut -b2-) else # SVN -#GIT_REV := $(shell cd $(src); git describe --always 2>/dev/null) +#GIT_REV := $(shell cd $(srctree)/$(src); git describe --always 2>/dev/null) ifneq ($(GIT_REV),) # Git detected DRIVER_REV := $(MALI_RELEASE_NAME)-$(GIT_REV) -CHANGE_DATE := $(shell cd $(src); git log -1 --format="%ci") +CHANGE_DATE := $(shell cd $(srctree)/$(src); git log -1 --format="%ci") CHANGED_REVISION := $(GIT_REV) -REPO_URL := $(shell cd $(src); git describe --all --always 2>/dev/null) +REPO_URL := $(shell cd $(srctree)/$(src); git describe --all --always 2>/dev/null) else # Git # No Git or SVN detected @@ -186,7 +186,7 @@ ccflags-y += -DSVN_REV_STRING=\"$(DRIVER_REV)\" ccflags-y += -fno-PIC VERSION_STRINGS := -VERSION_STRINGS += API_VERSION=$(shell cd $(src); grep "\#define _MALI_API_VERSION" $(FILES_PREFIX)include/linux/mali/mali_utgard_uk_types.h | cut -d' ' -f 3 ) +VERSION_STRINGS += API_VERSION=$(shell cd $(srctree)/$(src); grep "\#define _MALI_API_VERSION" $(FILES_PREFIX)include/linux/mali/mali_utgard_uk_types.h | cut -d' ' -f 3 ) VERSION_STRINGS += REPO_URL=$(REPO_URL) VERSION_STRINGS += REVISION=$(DRIVER_REV) VERSION_STRINGS += CHANGED_REVISION=$(CHANGED_REVISION) @@ -209,5 +209,5 @@ VERSION_STRINGS += USING_DVFS=$(CONFIG_MALI_DVFS) VERSION_STRINGS += MALI_UPPER_HALF_SCHEDULING=$(MALI_UPPER_HALF_SCHEDULING) # Create file with Mali driver configuration -$(src)/__malidrv_build_info.c: - @echo 'const char *__malidrv_build_info(void) { return "malidrv: $(VERSION_STRINGS)";}' > $(src)/__malidrv_build_info.c +$(srctree)/$(src)/__malidrv_build_info.c: + @echo 'const char *__malidrv_build_info(void) { return "malidrv: $(VERSION_STRINGS)";}' > $(srctree)/$(src)/__malidrv_build_info.c diff --git a/drivers/gpu/arm/mali400/r5p2_rel0/Kbuild b/drivers/gpu/arm/mali400/r5p2_rel0/Kbuild index 8bd7891..42babbd 100644 --- a/drivers/gpu/arm/mali400/r5p2_rel0/Kbuild +++ b/drivers/gpu/arm/mali400/r5p2_rel0/Kbuild @@ -28,7 +28,7 @@ MATCH_DFS_TO_LOWER_FREQ ?= 1 GLES_MEM_PROFILE ?= 1 # The GPL product will only include the license/gpl directory -ccflags-y += -I$(src)/linux/license/gpl +ccflags-y += -I$(srctree)/$(src)/linux/license/gpl ifeq ($(USING_GPU_UTILIZATION), 1) ifeq ($(USING_DVFS), 1) @@ -116,7 +116,7 @@ mali-$(CONFIG_MALI400_PROFILING) += linux/mali_ukk_profiling.o mali-$(CONFIG_MALI400_PROFILING) += linux/mali_osk_profiling.o mali-$(CONFIG_MALI400_INTERNAL_PROFILING) += linux/mali_profiling_internal.o timestamp-$(TIMESTAMP)/mali_timestamp.o -ccflags-$(CONFIG_MALI400_INTERNAL_PROFILING) += -I$(src)/timestamp-$(TIMESTAMP) +ccflags-$(CONFIG_MALI400_INTERNAL_PROFILING) += -I$(srctree)/$(src)/timestamp-$(TIMESTAMP) mali-$(CONFIG_DMA_SHARED_BUFFER) += linux/mali_memory_dma_buf.o mali-$(CONFIG_SYNC) += linux/mali_sync.o @@ -150,16 +150,16 @@ ifeq ($(MALI_UPPER_HALF_SCHEDULING),1) ccflags-y += -DMALI_UPPER_HALF_SCHEDULING endif -ccflags-$(CONFIG_MALI400_UMP) += -I$(src)/../ump/include/ump +ccflags-$(CONFIG_MALI400_UMP) += -I$(srctree)/$(src)/../ump/include/ump ccflags-$(CONFIG_MALI400_DEBUG) += -DDEBUG # Use our defines when compiling -ccflags-y += -I$(src) -I$(src)/include -I$(src)/common -I$(src)/linux -I$(src)/platform -I$(src)/platform/$(MALI_PLATFORM) +ccflags-y += -I$(srctree)/$(src) -I$(srctree)/$(src)/include -I$(srctree)/$(src)/common -I$(srctree)/$(src)/linux -I$(srctree)/$(src)/platform -I$(srctree)/$(src)/platform/$(MALI_PLATFORM) # Get subversion revision number, fall back to only ${MALI_RELEASE_NAME} if no svn info is available -MALI_RELEASE_NAME=$(shell cat $(src)/.version 2> /dev/null) +MALI_RELEASE_NAME=$(shell cat $(srctree)/$(src)/.version 2> /dev/null) -#SVN_INFO = (cd $(src); svn info 2>/dev/null) +#SVN_INFO = (cd $(srctree)/$(src); svn info 2>/dev/null) ifneq ($(shell $(SVN_INFO) 2>/dev/null),) # SVN detected @@ -170,13 +170,13 @@ CHANGED_REVISION := $(shell $(SVN_INFO) | grep '^Last Changed Rev: ' | cut -d: - REPO_URL := $(shell $(SVN_INFO) | grep '^URL: ' | cut -d: -f2- | cut -b2-) else # SVN -#GIT_REV := $(shell cd $(src); git describe --always 2>/dev/null) +#GIT_REV := $(shell cd $(srctree)/$(src); git describe --always 2>/dev/null) ifneq ($(GIT_REV),) # Git detected DRIVER_REV := $(MALI_RELEASE_NAME)-$(GIT_REV) -CHANGE_DATE := $(shell cd $(src); git log -1 --format="%ci") +CHANGE_DATE := $(shell cd $(srctree)/$(src); git log -1 --format="%ci") CHANGED_REVISION := $(GIT_REV) -REPO_URL := $(shell cd $(src); git describe --all --always 2>/dev/null) +REPO_URL := $(shell cd $(srctree)/$(src); git describe --all --always 2>/dev/null) else # Git # No Git or SVN detected @@ -190,7 +190,7 @@ ccflags-y += -DSVN_REV_STRING=\"$(DRIVER_REV)\" ccflags-y += -fno-PIC VERSION_STRINGS := -VERSION_STRINGS += API_VERSION=$(shell cd $(src); grep "\#define _MALI_API_VERSION" $(FILES_PREFIX)include/linux/mali/mali_utgard_uk_types.h | cut -d' ' -f 3 ) +VERSION_STRINGS += API_VERSION=$(shell cd $(srctree)/$(src); grep "\#define _MALI_API_VERSION" $(FILES_PREFIX)include/linux/mali/mali_utgard_uk_types.h | cut -d' ' -f 3 ) VERSION_STRINGS += REPO_URL=$(REPO_URL) VERSION_STRINGS += REVISION=$(DRIVER_REV) VERSION_STRINGS += CHANGED_REVISION=$(CHANGED_REVISION) @@ -213,5 +213,5 @@ VERSION_STRINGS += USING_DVFS=$(CONFIG_MALI_DVFS) VERSION_STRINGS += MALI_UPPER_HALF_SCHEDULING=$(MALI_UPPER_HALF_SCHEDULING) # Create file with Mali driver configuration -$(src)/__malidrv_build_info.c: - @echo 'const char *__malidrv_build_info(void) { return "malidrv: $(VERSION_STRINGS)";}' > $(src)/__malidrv_build_info.c +$(srctree)/$(src)/__malidrv_build_info.c: + @echo 'const char *__malidrv_build_info(void) { return "malidrv: $(VERSION_STRINGS)";}' > $(srctree)/$(src)/__malidrv_build_info.c -- 2.7.4 From c9f5ffa1a62f400e6b426b7d33dc30643f67d1f5 Mon Sep 17 00:00:00 2001 From: Joonyoung Shim Date: Mon, 23 May 2016 15:35:41 +0900 Subject: [PATCH 02/16] ARM: mali400: r5p2_rel0: fix build error MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Include pm_runtime.h to fix below build error when CONFIG_PM_RUNTIME is disabled. drivers/gpu/arm/mali400/r5p2_rel0/linux/mali_kernel_linux.c: In function ‘mali_driver_suspend_scheduler’: drivers/gpu/arm/mali400/r5p2_rel0/linux/mali_kernel_linux.c:595:2: error: implicit declaration of function ‘pm_runtime_active’ [-Werror=implicit-function-declaration] if (pm_runtime_active(dev)) ^ Change-Id: Ic613dd9785a9d563e50361328944bd23d33fd70c Signed-off-by: Joonyoung Shim --- drivers/gpu/arm/mali400/r5p2_rel0/linux/mali_kernel_linux.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/gpu/arm/mali400/r5p2_rel0/linux/mali_kernel_linux.c b/drivers/gpu/arm/mali400/r5p2_rel0/linux/mali_kernel_linux.c index 2493266..3035f08 100644 --- a/drivers/gpu/arm/mali400/r5p2_rel0/linux/mali_kernel_linux.c +++ b/drivers/gpu/arm/mali400/r5p2_rel0/linux/mali_kernel_linux.c @@ -24,9 +24,7 @@ #include #include #include -#ifdef CONFIG_PM_RUNTIME #include -#endif #include #include "mali_kernel_common.h" #include "mali_session.h" -- 2.7.4 From 3e64e276ca6f653f066aed31dfc13b0c520a592a Mon Sep 17 00:00:00 2001 From: Seung-Woo Kim Date: Mon, 23 May 2016 17:23:22 +0900 Subject: [PATCH 03/16] ARM: mali400: r5p2_rel0: replace CONFIG_PM_RUNTIME to CONFIG_PM After commit 464ed18ebdb6 ("PM: Eliminate CONFIG_PM_RUNTIME") which is applied kernel version 3.19, PM_RUNTIME is eliminated. So this patch replaces CONFIG_PM_RUNTIME to CONFIG_PM for kernel version larger than 3.19. Signed-off-by: Seung-Woo Kim [jy0922.shim: apply to mali400 r5p2_rel0 with some modification] Signed-off-by: Joonyoung Shim Change-Id: Iab2e17c07b397fe164623e1ecec58c54296c83a7 --- drivers/gpu/arm/mali400/r5p2_rel0/common/mali_pm.c | 5 ++++- .../gpu/arm/mali400/r5p2_rel0/linux/mali_kernel_linux.c | 9 ++++++--- drivers/gpu/arm/mali400/r5p2_rel0/linux/mali_osk_pm.c | 14 ++++++++------ drivers/gpu/arm/mali400/r5p2_rel0/platform/arm/arm.c | 8 ++++---- 4 files changed, 22 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/arm/mali400/r5p2_rel0/common/mali_pm.c b/drivers/gpu/arm/mali400/r5p2_rel0/common/mali_pm.c index 85cdde0..9c6505c 100644 --- a/drivers/gpu/arm/mali400/r5p2_rel0/common/mali_pm.c +++ b/drivers/gpu/arm/mali400/r5p2_rel0/common/mali_pm.c @@ -8,6 +8,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +#include + #include "mali_pm.h" #include "mali_kernel_common.h" #include "mali_osk.h" @@ -70,7 +72,8 @@ static int mali_pm_domain_power_cost_result[MALI_MAX_NUMBER_OF_PHYSICAL_PP_GROUP * Keep track of runtime PM state, so that we know * how to resume during OS resume. */ -#ifdef CONFIG_PM_RUNTIME +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,19,0) && defined(CONFIG_PM_RUNTIME))\ + || defined(CONFIG_PM) static mali_bool mali_pm_runtime_active = MALI_FALSE; #else /* when kernel don't enable PM_RUNTIME, set the flag always true, diff --git a/drivers/gpu/arm/mali400/r5p2_rel0/linux/mali_kernel_linux.c b/drivers/gpu/arm/mali400/r5p2_rel0/linux/mali_kernel_linux.c index 3035f08..5ec81ed 100644 --- a/drivers/gpu/arm/mali400/r5p2_rel0/linux/mali_kernel_linux.c +++ b/drivers/gpu/arm/mali400/r5p2_rel0/linux/mali_kernel_linux.c @@ -179,7 +179,8 @@ static int mali_remove(struct platform_device *pdev); static int mali_driver_suspend_scheduler(struct device *dev); static int mali_driver_resume_scheduler(struct device *dev); -#ifdef CONFIG_PM_RUNTIME +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,19,0) && defined(CONFIG_PM_RUNTIME))\ + || defined(CONFIG_PM) static int mali_driver_runtime_suspend(struct device *dev); static int mali_driver_runtime_resume(struct device *dev); static int mali_driver_runtime_idle(struct device *dev); @@ -210,7 +211,8 @@ struct pm_ext_ops mali_dev_ext_pm_ops = { }; #else static const struct dev_pm_ops mali_dev_pm_ops = { -#ifdef CONFIG_PM_RUNTIME +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,19,0) && defined(CONFIG_PM_RUNTIME))\ + || defined(CONFIG_PM) .runtime_suspend = mali_driver_runtime_suspend, .runtime_resume = mali_driver_runtime_resume, .runtime_idle = mali_driver_runtime_idle, @@ -627,7 +629,8 @@ static int mali_driver_resume_scheduler(struct device *dev) return 0; } -#ifdef CONFIG_PM_RUNTIME +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,19,0) && defined(CONFIG_PM_RUNTIME))\ + || defined(CONFIG_PM) static int mali_driver_runtime_suspend(struct device *dev) { if (MALI_TRUE == mali_pm_runtime_suspend()) { diff --git a/drivers/gpu/arm/mali400/r5p2_rel0/linux/mali_osk_pm.c b/drivers/gpu/arm/mali400/r5p2_rel0/linux/mali_osk_pm.c index 21180d3..9253e54 100644 --- a/drivers/gpu/arm/mali400/r5p2_rel0/linux/mali_osk_pm.c +++ b/drivers/gpu/arm/mali400/r5p2_rel0/linux/mali_osk_pm.c @@ -15,9 +15,7 @@ #include -#ifdef CONFIG_PM_RUNTIME #include -#endif /* CONFIG_PM_RUNTIME */ #include #include #include "mali_osk.h" @@ -27,7 +25,8 @@ /* Can NOT run in atomic context */ _mali_osk_errcode_t _mali_osk_pm_dev_ref_get_sync(void) { -#ifdef CONFIG_PM_RUNTIME +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,19,0) && defined(CONFIG_PM_RUNTIME))\ + || defined(CONFIG_PM) int err; MALI_DEBUG_ASSERT_POINTER(mali_platform_device); err = pm_runtime_get_sync(&(mali_platform_device->dev)); @@ -45,7 +44,8 @@ _mali_osk_errcode_t _mali_osk_pm_dev_ref_get_sync(void) /* Can run in atomic context */ _mali_osk_errcode_t _mali_osk_pm_dev_ref_get_async(void) { -#ifdef CONFIG_PM_RUNTIME +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,19,0) && defined(CONFIG_PM_RUNTIME))\ + || defined(CONFIG_PM) int err; MALI_DEBUG_ASSERT_POINTER(mali_platform_device); err = pm_runtime_get(&(mali_platform_device->dev)); @@ -64,7 +64,8 @@ _mali_osk_errcode_t _mali_osk_pm_dev_ref_get_async(void) /* Can run in atomic context */ void _mali_osk_pm_dev_ref_put(void) { -#ifdef CONFIG_PM_RUNTIME +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,19,0) && defined(CONFIG_PM_RUNTIME))\ + || defined(CONFIG_PM) MALI_DEBUG_ASSERT_POINTER(mali_platform_device); #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) pm_runtime_mark_last_busy(&(mali_platform_device->dev)); @@ -77,7 +78,8 @@ void _mali_osk_pm_dev_ref_put(void) void _mali_osk_pm_dev_barrier(void) { -#ifdef CONFIG_PM_RUNTIME +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,19,0) && defined(CONFIG_PM_RUNTIME))\ + || defined(CONFIG_PM) pm_runtime_barrier(&(mali_platform_device->dev)); #endif } diff --git a/drivers/gpu/arm/mali400/r5p2_rel0/platform/arm/arm.c b/drivers/gpu/arm/mali400/r5p2_rel0/platform/arm/arm.c index 9eaf07e..4853944 100644 --- a/drivers/gpu/arm/mali400/r5p2_rel0/platform/arm/arm.c +++ b/drivers/gpu/arm/mali400/r5p2_rel0/platform/arm/arm.c @@ -17,9 +17,7 @@ #include #include #include -#ifdef CONFIG_PM_RUNTIME #include -#endif #include #include #include "mali_kernel_common.h" @@ -192,7 +190,8 @@ int mali_platform_device_register(void) /* Register the platform device */ err = platform_device_register(&mali_gpu_device); if (0 == err) { -#ifdef CONFIG_PM_RUNTIME +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,19,0) && defined(CONFIG_PM_RUNTIME))\ + || defined(CONFIG_PM) #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) pm_runtime_set_autosuspend_delay(&(mali_gpu_device.dev), 1000); pm_runtime_use_autosuspend(&(mali_gpu_device.dev)); @@ -280,7 +279,8 @@ int mali_platform_device_init(struct platform_device *device) err = platform_device_add_data(device, &mali_gpu_data, sizeof(mali_gpu_data)); if (0 == err) { -#ifdef CONFIG_PM_RUNTIME +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,19,0) && defined(CONFIG_PM_RUNTIME))\ + || defined(CONFIG_PM) #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) pm_runtime_set_autosuspend_delay(&(device->dev), 1000); pm_runtime_use_autosuspend(&(device->dev)); -- 2.7.4 From aea2a5eebeb8e44b8e64c070f67520e5a1c80b7f Mon Sep 17 00:00:00 2001 From: Joonyoung Shim Date: Tue, 10 May 2016 15:27:25 +0900 Subject: [PATCH 04/16] ARM: tizen_tm1_defconfig: Enable mali400 r5p2_rel0 Enable mali400 r5p2_rel0 instead of r5p0_rel0. Change-Id: I4f7f01788d91b6d4e9c102029cbfa5a1b5c3f300 Signed-off-by: Joonyoung Shim --- arch/arm/configs/tizen_tm1_defconfig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/arm/configs/tizen_tm1_defconfig b/arch/arm/configs/tizen_tm1_defconfig index 5007420..b597df9 100755 --- a/arch/arm/configs/tizen_tm1_defconfig +++ b/arch/arm/configs/tizen_tm1_defconfig @@ -2113,11 +2113,12 @@ CONFIG_MALI400=y CONFIG_MALI_DMA_BUF_MAP_ON_ATTACH=y CONFIG_MALI_SHARED_INTERRUPTS=y # CONFIG_MALI_PMU_PARALLEL_POWER_UP is not set -CONFIG_MALI_VER_R5P0_REL0=y +# CONFIG_MALI_VER_R5P0_REL0 is not set # CONFIG_MALI450 is not set # CONFIG_MALI_DVFS is not set CONFIG_MALI_DT=y # CONFIG_MALI_QUIET is not set +CONFIG_MALI_VER_R5P2_REL0=y # CONFIG_VGASTATE is not set # CONFIG_VIDEO_OUTPUT_CONTROL is not set CONFIG_HDMI=y -- 2.7.4 From 6e9479c7c433aa0e00faa9ab750535ed9d77cc1e Mon Sep 17 00:00:00 2001 From: Joonyoung Shim Date: Mon, 20 Jun 2016 18:42:18 +0900 Subject: [PATCH 05/16] input: touchkey: add resume function Now, there is only suspend function then it will cause a problem that touchkey is not working after sleep, so add resume function. It's enough only that resume function calls tc300k_input_open() because suspend function calls just tc300k_input_close(). Change-Id: I2b96fe797a94fbd20cd3082c9460130dd6b848eb Signed-off-by: Joonyoung Shim --- drivers/input/keyboard/coreriver/tc350-touchkey.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/input/keyboard/coreriver/tc350-touchkey.c b/drivers/input/keyboard/coreriver/tc350-touchkey.c index 4d54fec..0d980a7 100644 --- a/drivers/input/keyboard/coreriver/tc350-touchkey.c +++ b/drivers/input/keyboard/coreriver/tc350-touchkey.c @@ -2373,6 +2373,14 @@ static int tc300k_suspend(struct device *dev) return 0; } + +static int tc300k_resume(struct device *dev) +{ + struct tc300k_data *data = dev_get_drvdata(dev); + struct input_dev *input_dev = data->input_dev; + + return tc300k_input_open(input_dev); +} #endif MODULE_DEVICE_TABLE(i2c, tc300k_id); @@ -2380,6 +2388,7 @@ MODULE_DEVICE_TABLE(i2c, tc300k_id); #ifndef CONFIG_HAS_EARLYSUSPEND const struct dev_pm_ops tc300k_pm_ops = { .suspend = tc300k_suspend, + .resume = tc300k_resume, }; #endif -- 2.7.4 From 773a1cd3ccf9b1fa8e7d492255c6f1ad0f307c95 Mon Sep 17 00:00:00 2001 From: Seung-Woo Kim Date: Wed, 6 Jul 2016 19:59:19 +0900 Subject: [PATCH 06/16] sensors/ims1911: use deffered probe for i2c fail case from probe This patch fixes to use deffered probe error for i2c read fail from probe. Change-Id: Ic4bc12fef0c9dee69d98bbdfb1ed1d5f2c2f62de Signed-off-by: Seung-Woo Kim --- drivers/sensors/ims1911.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/sensors/ims1911.c b/drivers/sensors/ims1911.c index 8a32f78..0b078fe 100644 --- a/drivers/sensors/ims1911.c +++ b/drivers/sensors/ims1911.c @@ -761,7 +761,7 @@ static int ims1911_detect(struct ims1911_data *data) if(i2c_read_byte(data, IMS1911_OPERATION_MODE_SEL, &val) == I2C_FAIL) { dev_err(&data->client->dev, "ims1911 i2c fail : not found\n"); - return -1; + return -EPROBE_DEFER; } #if 0 if(val != 0) { -- 2.7.4 From d3717461f4cba8dc7c5b91a9f872e2bab0a4e7f4 Mon Sep 17 00:00:00 2001 From: jooseong lee Date: Wed, 20 Jul 2016 10:07:11 +0900 Subject: [PATCH 07/16] Smack: Assign smack_known_web label for kernel thread's socket in the sk_alloc_security hook Creating struct sock by sk_alloc function in various kernel subsystems like bluetooth dosen't call smack_socket_post_create(). In such case, received sock label is the floor('_') label and makes access deny. Refers to: http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=7412301b76bd53ee53b860f611fc3b5b1c2245b5 Change-Id: I614c5f0e6d59be5ca6b49f0581edfef79fc334cf Signed-off-by: jooseong lee --- security/smack/smack_lsm.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index f0cea06..7e800c6 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -2145,8 +2145,16 @@ static int smack_sk_alloc_security(struct sock *sk, int family, gfp_t gfp_flags) if (ssp == NULL) return -ENOMEM; - ssp->smk_in = skp; - ssp->smk_out = skp; + /* + * Sockets created by kernel threads receive web label. + */ + if (unlikely(current->flags & PF_KTHREAD)) { + ssp->smk_in = &smack_known_web; + ssp->smk_out = &smack_known_web; + } else { + ssp->smk_in = skp; + ssp->smk_out = skp; + } ssp->smk_packet = NULL; sk->sk_security = ssp; -- 2.7.4 From 22ba78a338328de86f001c1c52b74b73331eb515 Mon Sep 17 00:00:00 2001 From: Michal Bloch Date: Thu, 21 Jul 2016 13:41:02 +0200 Subject: [PATCH 08/16] kmsg: allow binary characters * do not touch unprintable characters. This is so that logs can have formatting such as newlines, tabulation, or colours. * the textual part is now delimited by \0. This is because \n which used to be the delimiter is now available for logs. Signed-off-by: Michal Bloch Change-Id: I030a4eab791f4468897d3dcdc5bb04549f30b2f7 Signed-off-by: Kichan Kwon --- kernel/printk_kmsg.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/kernel/printk_kmsg.c b/kernel/printk_kmsg.c index ceb15f6..7a209f4 100644 --- a/kernel/printk_kmsg.c +++ b/kernel/printk_kmsg.c @@ -1061,15 +1061,19 @@ static ssize_t kmsg_read(struct log_buffer *log_b, struct file *file, user->seq, ts_usec, cont); user->prev = msg->flags; - /* escape non-printable characters */ for (i = 0; i < msg->text_len; i++) { unsigned char c = log_text(msg)[i]; - if (c < ' ' || c >= 127 || c == '\\') - p += scnprintf(p, e - p, "\\x%02x", c); - else - append_char(&p, e, c); + append_char(&p, e, c); } + + /* + * The \0 is delimits the text part, while the newline is for formatting + * when catting the device directly. We cannot use \n for delimiting due + * to security: else one could forge dictionary tags through the message + * such as "text\n _PID=123" + */ + append_char(&p, e, '\0'); append_char(&p, e, '\n'); if (msg->dict_len) { @@ -1089,11 +1093,6 @@ static ssize_t kmsg_read(struct log_buffer *log_b, struct file *file, continue; } - if (c < ' ' || c >= 127 || c == '\\') { - p += scnprintf(p, e - p, "\\x%02x", c); - continue; - } - append_char(&p, e, c); } append_char(&p, e, '\n'); -- 2.7.4 From fe8173a61d6c5dd06e63281051a4ab184299fe03 Mon Sep 17 00:00:00 2001 From: Filipe Manana Date: Sun, 9 Nov 2014 08:38:39 +0000 Subject: [PATCH 09/16] Btrfs: make xattr replace operations atomic commit 5f5bc6b1e2d5a6f827bc860ef2dc5b6f365d1339 upstream. Replacing a xattr consists of doing a lookup for its existing value, delete the current value from the respective leaf, release the search path and then finally insert the new value. This leaves a time window where readers (getxattr, listxattrs) won't see any value for the xattr. Xattrs are used to store ACLs, so this has security implications. This change also fixes 2 other existing issues which were: *) Deleting the old xattr value without verifying first if the new xattr will fit in the existing leaf item (in case multiple xattrs are packed in the same item due to name hash collision); *) Returning -EEXIST when the flag XATTR_CREATE is given and the xattr doesn't exist but we have have an existing item that packs muliple xattrs with the same name hash as the input xattr. In this case we should return ENOSPC. A test case for xfstests follows soon. Thanks to Alexandre Oliva for reporting the non-atomicity of the xattr replace implementation. Change-Id: I286d47858be086bb974cb4fa8eee5d32e8bee61d Reported-by: Alexandre Oliva Signed-off-by: Filipe Manana Signed-off-by: Chris Mason [shengyong: backport to 3.10 - FIX: CVE-2014-9710 - adjust context - ASSERT() was added v3.12, so we do check with if statement - set the first parameter of btrfs_item_nr() as NULL, because it is not used, and is removed in v3.13 ] Signed-off-by: Sheng Yong Signed-off-by: Greg Kroah-Hartman Signed-off-by: Junghoon Kim --- fs/btrfs/ctree.c | 2 +- fs/btrfs/ctree.h | 5 ++ fs/btrfs/dir-item.c | 10 +--- fs/btrfs/xattr.c | 159 +++++++++++++++++++++++++++++++++------------------- 4 files changed, 111 insertions(+), 65 deletions(-) diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index 7fb054b..82f14a1 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c @@ -2769,7 +2769,7 @@ done: */ if (!p->leave_spinning) btrfs_set_path_blocking(p); - if (ret < 0) + if (ret < 0 && !p->skip_release_on_error) btrfs_release_path(p); return ret; } diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index d6dd49b..c19444e 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -586,6 +586,7 @@ struct btrfs_path { unsigned int skip_locking:1; unsigned int leave_spinning:1; unsigned int search_commit_root:1; + unsigned int skip_release_on_error:1; }; /* @@ -3406,6 +3407,10 @@ struct btrfs_dir_item *btrfs_lookup_xattr(struct btrfs_trans_handle *trans, int verify_dir_item(struct btrfs_root *root, struct extent_buffer *leaf, struct btrfs_dir_item *dir_item); +struct btrfs_dir_item *btrfs_match_dir_item_name(struct btrfs_root *root, + struct btrfs_path *path, + const char *name, + int name_len); /* orphan.c */ int btrfs_insert_orphan_item(struct btrfs_trans_handle *trans, diff --git a/fs/btrfs/dir-item.c b/fs/btrfs/dir-item.c index 79e594e..6f61b9b 100644 --- a/fs/btrfs/dir-item.c +++ b/fs/btrfs/dir-item.c @@ -21,10 +21,6 @@ #include "hash.h" #include "transaction.h" -static struct btrfs_dir_item *btrfs_match_dir_item_name(struct btrfs_root *root, - struct btrfs_path *path, - const char *name, int name_len); - /* * insert a name into a directory, doing overflow properly if there is a hash * collision. data_size indicates how big the item inserted should be. On @@ -383,9 +379,9 @@ struct btrfs_dir_item *btrfs_lookup_xattr(struct btrfs_trans_handle *trans, * this walks through all the entries in a dir item and finds one * for a specific name. */ -static struct btrfs_dir_item *btrfs_match_dir_item_name(struct btrfs_root *root, - struct btrfs_path *path, - const char *name, int name_len) +struct btrfs_dir_item *btrfs_match_dir_item_name(struct btrfs_root *root, + struct btrfs_path *path, + const char *name, int name_len) { struct btrfs_dir_item *dir_item; unsigned long name_ptr; diff --git a/fs/btrfs/xattr.c b/fs/btrfs/xattr.c index 05740b9..9cf20d6 100644 --- a/fs/btrfs/xattr.c +++ b/fs/btrfs/xattr.c @@ -27,6 +27,7 @@ #include "transaction.h" #include "xattr.h" #include "disk-io.h" +#include "locking.h" ssize_t __btrfs_getxattr(struct inode *inode, const char *name, @@ -89,7 +90,7 @@ static int do_setxattr(struct btrfs_trans_handle *trans, struct inode *inode, const char *name, const void *value, size_t size, int flags) { - struct btrfs_dir_item *di; + struct btrfs_dir_item *di = NULL; struct btrfs_root *root = BTRFS_I(inode)->root; struct btrfs_path *path; size_t name_len = strlen(name); @@ -101,84 +102,128 @@ static int do_setxattr(struct btrfs_trans_handle *trans, path = btrfs_alloc_path(); if (!path) return -ENOMEM; + path->skip_release_on_error = 1; + + if (!value) { + di = btrfs_lookup_xattr(trans, root, path, btrfs_ino(inode), + name, name_len, -1); + if (!di && (flags & XATTR_REPLACE)) + ret = -ENODATA; + else if (di) + ret = btrfs_delete_one_dir_name(trans, root, path, di); + goto out; + } + /* + * For a replace we can't just do the insert blindly. + * Do a lookup first (read-only btrfs_search_slot), and return if xattr + * doesn't exist. If it exists, fall down below to the insert/replace + * path - we can't race with a concurrent xattr delete, because the VFS + * locks the inode's i_mutex before calling setxattr or removexattr. + */ if (flags & XATTR_REPLACE) { - di = btrfs_lookup_xattr(trans, root, path, btrfs_ino(inode), name, - name_len, -1); - if (IS_ERR(di)) { - ret = PTR_ERR(di); - goto out; - } else if (!di) { + if(!mutex_is_locked(&inode->i_mutex)) { + pr_err("BTRFS: assertion failed: %s, file: %s, line: %d", + "mutex_is_locked(&inode->i_mutex)", __FILE__, + __LINE__); + BUG(); + } + di = btrfs_lookup_xattr(NULL, root, path, btrfs_ino(inode), + name, name_len, 0); + if (!di) { ret = -ENODATA; goto out; } - ret = btrfs_delete_one_dir_name(trans, root, path, di); - if (ret) - goto out; btrfs_release_path(path); + di = NULL; + } + ret = btrfs_insert_xattr_item(trans, root, path, btrfs_ino(inode), + name, name_len, value, size); + if (ret == -EOVERFLOW) { /* - * remove the attribute + * We have an existing item in a leaf, split_leaf couldn't + * expand it. That item might have or not a dir_item that + * matches our target xattr, so lets check. */ - if (!value) - goto out; - } else { - di = btrfs_lookup_xattr(NULL, root, path, btrfs_ino(inode), - name, name_len, 0); - if (IS_ERR(di)) { - ret = PTR_ERR(di); + ret = 0; + btrfs_assert_tree_locked(path->nodes[0]); + di = btrfs_match_dir_item_name(root, path, name, name_len); + if (!di && !(flags & XATTR_REPLACE)) { + ret = -ENOSPC; goto out; } - if (!di && !value) - goto out; - btrfs_release_path(path); + } else if (ret == -EEXIST) { + ret = 0; + di = btrfs_match_dir_item_name(root, path, name, name_len); + if(!di) { /* logic error */ + pr_err("BTRFS: assertion failed: %s, file: %s, line: %d", + "di", __FILE__, __LINE__); + BUG(); + } + } else if (ret) { + goto out; } -again: - ret = btrfs_insert_xattr_item(trans, root, path, btrfs_ino(inode), - name, name_len, value, size); - /* - * If we're setting an xattr to a new value but the new value is say - * exactly BTRFS_MAX_XATTR_SIZE, we could end up with EOVERFLOW getting - * back from split_leaf. This is because it thinks we'll be extending - * the existing item size, but we're asking for enough space to add the - * item itself. So if we get EOVERFLOW just set ret to EEXIST and let - * the rest of the function figure it out. - */ - if (ret == -EOVERFLOW) + if (di && (flags & XATTR_CREATE)) { ret = -EEXIST; + goto out; + } - if (ret == -EEXIST) { - if (flags & XATTR_CREATE) - goto out; + if (di) { /* - * We can't use the path we already have since we won't have the - * proper locking for a delete, so release the path and - * re-lookup to delete the thing. + * We're doing a replace, and it must be atomic, that is, at + * any point in time we have either the old or the new xattr + * value in the tree. We don't want readers (getxattr and + * listxattrs) to miss a value, this is specially important + * for ACLs. */ - btrfs_release_path(path); - di = btrfs_lookup_xattr(trans, root, path, btrfs_ino(inode), - name, name_len, -1); - if (IS_ERR(di)) { - ret = PTR_ERR(di); - goto out; - } else if (!di) { - /* Shouldn't happen but just in case... */ - btrfs_release_path(path); - goto again; + const int slot = path->slots[0]; + struct extent_buffer *leaf = path->nodes[0]; + const u16 old_data_len = btrfs_dir_data_len(leaf, di); + const u32 item_size = btrfs_item_size_nr(leaf, slot); + const u32 data_size = sizeof(*di) + name_len + size; + struct btrfs_item *item; + unsigned long data_ptr; + char *ptr; + + if (size > old_data_len) { + if (btrfs_leaf_free_space(root, leaf) < + (size - old_data_len)) { + ret = -ENOSPC; + goto out; + } } - ret = btrfs_delete_one_dir_name(trans, root, path, di); - if (ret) - goto out; + if (old_data_len + name_len + sizeof(*di) == item_size) { + /* No other xattrs packed in the same leaf item. */ + if (size > old_data_len) + btrfs_extend_item(root, path, + size - old_data_len); + else if (size < old_data_len) + btrfs_truncate_item(root, path, data_size, 1); + } else { + /* There are other xattrs packed in the same item. */ + ret = btrfs_delete_one_dir_name(trans, root, path, di); + if (ret) + goto out; + btrfs_extend_item(root, path, data_size); + } + item = btrfs_item_nr(NULL, slot); + ptr = btrfs_item_ptr(leaf, slot, char); + ptr += btrfs_item_size(leaf, item) - data_size; + di = (struct btrfs_dir_item *)ptr; + btrfs_set_dir_data_len(leaf, di, size); + data_ptr = ((unsigned long)(di + 1)) + name_len; + write_extent_buffer(leaf, value, data_ptr, size); + btrfs_mark_buffer_dirty(leaf); + } else { /* - * We have a value to set, so go back and try to insert it now. + * Insert, and we had space for the xattr, so path->slots[0] is + * where our xattr dir_item is and btrfs_insert_xattr_item() + * filled it. */ - if (value) { - btrfs_release_path(path); - goto again; - } } out: btrfs_free_path(path); -- 2.7.4 From 9c9b400993e03d745b704ad68d517be9e4d30544 Mon Sep 17 00:00:00 2001 From: David Howells Date: Fri, 18 Dec 2015 01:34:26 +0000 Subject: [PATCH 10/16] KEYS: Fix race between read and revoke commit b4a1b4f5047e4f54e194681125c74c0aa64d637d upstream. This fixes CVE-2015-7550. There's a race between keyctl_read() and keyctl_revoke(). If the revoke happens between keyctl_read() checking the validity of a key and the key's semaphore being taken, then the key type read method will see a revoked key. This causes a problem for the user-defined key type because it assumes in its read method that there will always be a payload in a non-revoked key and doesn't check for a NULL pointer. Fix this by making keyctl_read() check the validity of a key after taking semaphore instead of before. I think the bug was introduced with the original keyrings code. This was discovered by a multithreaded test program generated by syzkaller (http://github.com/google/syzkaller). Here's a cleaned up version: #include #include #include void *thr0(void *arg) { key_serial_t key = (unsigned long)arg; keyctl_revoke(key); return 0; } void *thr1(void *arg) { key_serial_t key = (unsigned long)arg; char buffer[16]; keyctl_read(key, buffer, 16); return 0; } int main() { key_serial_t key = add_key("user", "%", "foo", 3, KEY_SPEC_USER_KEYRING); pthread_t th[5]; pthread_create(&th[0], 0, thr0, (void *)(unsigned long)key); pthread_create(&th[1], 0, thr1, (void *)(unsigned long)key); pthread_create(&th[2], 0, thr0, (void *)(unsigned long)key); pthread_create(&th[3], 0, thr1, (void *)(unsigned long)key); pthread_join(th[0], 0); pthread_join(th[1], 0); pthread_join(th[2], 0); pthread_join(th[3], 0); return 0; } Build as: cc -o keyctl-race keyctl-race.c -lkeyutils -lpthread Run as: while keyctl-race; do :; done as it may need several iterations to crash the kernel. The crash can be summarised as: BUG: unable to handle kernel NULL pointer dereference at 0000000000000010 IP: [] user_read+0x56/0xa3 ... Call Trace: [] keyctl_read_key+0xb6/0xd7 [] SyS_keyctl+0x83/0xe0 [] entry_SYSCALL_64_fastpath+0x12/0x6f Reported-by: Dmitry Vyukov Signed-off-by: David Howells Tested-by: Dmitry Vyukov Signed-off-by: James Morris Signed-off-by: Greg Kroah-Hartman Change-Id: Ie59035bed50d4e1aa2248a0bd5128a0f997ab29a Signed-off-by: Junghoon Kim --- security/keys/keyctl.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c index 33cfd27..3242195 100644 --- a/security/keys/keyctl.c +++ b/security/keys/keyctl.c @@ -744,16 +744,16 @@ long keyctl_read_key(key_serial_t keyid, char __user *buffer, size_t buflen) /* the key is probably readable - now try to read it */ can_read_key: - ret = key_validate(key); - if (ret == 0) { - ret = -EOPNOTSUPP; - if (key->type->read) { - /* read the data with the semaphore held (since we - * might sleep) */ - down_read(&key->sem); + ret = -EOPNOTSUPP; + if (key->type->read) { + /* Read the data with the semaphore held (since we might sleep) + * to protect against the key being updated or revoked. + */ + down_read(&key->sem); + ret = key_validate(key); + if (ret == 0) ret = key->type->read(key, buffer, buflen); - up_read(&key->sem); - } + up_read(&key->sem); } error2: -- 2.7.4 From c673f883daef4c7f8d8a7adfeb834e87af6b06ac Mon Sep 17 00:00:00 2001 From: Sasha Levin Date: Mon, 29 Dec 2014 09:39:01 -0500 Subject: [PATCH 11/16] KEYS: close race between key lookup and freeing commit a3a8784454692dd72e5d5d34dcdab17b4420e74c upstream. When a key is being garbage collected, it's key->user would get put before the ->destroy() callback is called, where the key is removed from it's respective tracking structures. This leaves a key hanging in a semi-invalid state which leaves a window open for a different task to try an access key->user. An example is find_keyring_by_name() which would dereference key->user for a key that is in the process of being garbage collected (where key->user was freed but ->destroy() wasn't called yet - so it's still present in the linked list). This would cause either a panic, or corrupt memory. Fixes CVE-2014-9529. Signed-off-by: Sasha Levin Signed-off-by: David Howells Signed-off-by: Greg Kroah-Hartman Change-Id: Iab7bb60ba1db5931cd8911ed04452cdb55358eda Signed-off-by: Junghoon Kim --- security/keys/gc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/security/keys/gc.c b/security/keys/gc.c index d67c97b..7978186 100644 --- a/security/keys/gc.c +++ b/security/keys/gc.c @@ -201,12 +201,12 @@ static noinline void key_gc_unused_keys(struct list_head *keys) if (test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) atomic_dec(&key->user->nikeys); - key_user_put(key->user); - /* now throw away the key memory */ if (key->type->destroy) key->type->destroy(key); + key_user_put(key->user); + kfree(key->description); #ifdef KEY_DEBUGGING -- 2.7.4 From a5559d92337b4832fb01ecead46abc6c4cee8781 Mon Sep 17 00:00:00 2001 From: Hannes Frederic Sowa Date: Mon, 14 Dec 2015 22:03:39 +0100 Subject: [PATCH 12/16] net: add validation for the socket syscall protocol argument MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit [ Upstream commit 79462ad02e861803b3840cc782248c7359451cd9 ] 郭永刚 reported that one could simply crash the kernel as root by using a simple program: int socket_fd; struct sockaddr_in addr; addr.sin_port = 0; addr.sin_addr.s_addr = INADDR_ANY; addr.sin_family = 10; socket_fd = socket(10,3,0x40000000); connect(socket_fd , &addr,16); AF_INET, AF_INET6 sockets actually only support 8-bit protocol identifiers. inet_sock's skc_protocol field thus is sized accordingly, thus larger protocol identifiers simply cut off the higher bits and store a zero in the protocol fields. This could lead to e.g. NULL function pointer because as a result of the cut off inet_num is zero and we call down to inet_autobind, which is NULL for raw sockets. kernel: Call Trace: kernel: [] ? inet_autobind+0x2e/0x70 kernel: [] inet_dgram_connect+0x54/0x80 kernel: [] SYSC_connect+0xd9/0x110 kernel: [] ? ptrace_notify+0x5b/0x80 kernel: [] ? syscall_trace_enter_phase2+0x108/0x200 kernel: [] SyS_connect+0xe/0x10 kernel: [] tracesys_phase2+0x84/0x89 I found no particular commit which introduced this problem. Change-Id: I30cd09ffb9705304bcda7247fe28ac14c8bb20a9 CVE: CVE-2015-8543 Cc: Cong Wang Reported-by: 郭永刚 Signed-off-by: Hannes Frederic Sowa Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman Signed-off-by: Junghoon Kim --- include/net/sock.h | 1 + net/ax25/af_ax25.c | 3 +++ net/decnet/af_decnet.c | 3 +++ net/ipv4/af_inet.c | 3 +++ net/ipv6/af_inet6.c | 3 +++ net/irda/af_irda.c | 3 +++ 6 files changed, 16 insertions(+) diff --git a/include/net/sock.h b/include/net/sock.h index d512f27..6d2ec72 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -353,6 +353,7 @@ struct sock { sk_no_check : 2, sk_userlocks : 4, sk_protocol : 8, +#define SK_PROTOCOL_MAX U8_MAX sk_type : 16; kmemcheck_bitfield_end(flags); int sk_wmem_queued; diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c index ba6db78..69940a7 100644 --- a/net/ax25/af_ax25.c +++ b/net/ax25/af_ax25.c @@ -806,6 +806,9 @@ static int ax25_create(struct net *net, struct socket *sock, int protocol, struct sock *sk; ax25_cb *ax25; + if (protocol < 0 || protocol > SK_PROTOCOL_MAX) + return -EINVAL; + if (!net_eq(net, &init_net)) return -EAFNOSUPPORT; diff --git a/net/decnet/af_decnet.c b/net/decnet/af_decnet.c index c21f200..ca61065 100644 --- a/net/decnet/af_decnet.c +++ b/net/decnet/af_decnet.c @@ -677,6 +677,9 @@ static int dn_create(struct net *net, struct socket *sock, int protocol, { struct sock *sk; + if (protocol < 0 || protocol > SK_PROTOCOL_MAX) + return -EINVAL; + if (!net_eq(net, &init_net)) return -EAFNOSUPPORT; diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index f022e0e..14ad21e 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c @@ -304,6 +304,9 @@ static int inet_create(struct net *net, struct socket *sock, int protocol, if (sock->type != SOCK_RAW && sock->type != SOCK_DGRAM) build_ehash_secret(); + if (protocol < 0 || protocol >= IPPROTO_MAX) + return -EINVAL; + sock->state = SS_UNCONNECTED; /* Look for the requested type/protocol pair. */ diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index d29ae19..72aa1a1 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c @@ -131,6 +131,9 @@ static int inet6_create(struct net *net, struct socket *sock, int protocol, !inet_ehash_secret) build_ehash_secret(); + if (protocol < 0 || protocol >= IPPROTO_MAX) + return -EINVAL; + /* Look for the requested type/protocol pair. */ lookup_protocol: err = -ESOCKTNOSUPPORT; diff --git a/net/irda/af_irda.c b/net/irda/af_irda.c index a5e62ef..f8133ff 100644 --- a/net/irda/af_irda.c +++ b/net/irda/af_irda.c @@ -1105,6 +1105,9 @@ static int irda_create(struct net *net, struct socket *sock, int protocol, IRDA_DEBUG(2, "%s()\n", __func__); + if (protocol < 0 || protocol > SK_PROTOCOL_MAX) + return -EINVAL; + if (net != &init_net) return -EAFNOSUPPORT; -- 2.7.4 From cea8626c062dd526184b75a9d23b6b92287f8ada Mon Sep 17 00:00:00 2001 From: Florian Westphal Date: Fri, 26 Sep 2014 11:35:42 +0200 Subject: [PATCH 13/16] netfilter: conntrack: disable generic tracking for known protocols commit db29a9508a9246e77087c5531e45b2c88ec6988b upstream. Given following iptables ruleset: -P FORWARD DROP -A FORWARD -m sctp --dport 9 -j ACCEPT -A FORWARD -p tcp --dport 80 -j ACCEPT -A FORWARD -p tcp -m conntrack -m state ESTABLISHED,RELATED -j ACCEPT One would assume that this allows SCTP on port 9 and TCP on port 80. Unfortunately, if the SCTP conntrack module is not loaded, this allows *all* SCTP communication, to pass though, i.e. -p sctp -j ACCEPT, which we think is a security issue. This is because on the first SCTP packet on port 9, we create a dummy "generic l4" conntrack entry without any port information (since conntrack doesn't know how to extract this information). All subsequent packets that are unknown will then be in established state since they will fallback to proto_generic and will match the 'generic' entry. Our originally proposed version [1] completely disabled generic protocol tracking, but Jozsef suggests to not track protocols for which a more suitable helper is available, hence we now mitigate the issue for in tree known ct protocol helpers only, so that at least NAT and direction information will still be preserved for others. [1] http://www.spinics.net/lists/netfilter-devel/msg33430.html Joint work with Daniel Borkmann. Fixes CVE-2014-8160. Change-Id: I8dbb1b870c0724acba5f20d353c856f16ec00ae0 Signed-off-by: Florian Westphal Signed-off-by: Daniel Borkmann Acked-by: Jozsef Kadlecsik Signed-off-by: Pablo Neira Ayuso Signed-off-by: Zhiqiang Zhang Signed-off-by: Greg Kroah-Hartman Signed-off-by: Junghoon Kim --- net/netfilter/nf_conntrack_proto_generic.c | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/net/netfilter/nf_conntrack_proto_generic.c b/net/netfilter/nf_conntrack_proto_generic.c index d25f293..957c1db 100644 --- a/net/netfilter/nf_conntrack_proto_generic.c +++ b/net/netfilter/nf_conntrack_proto_generic.c @@ -14,6 +14,30 @@ static unsigned int nf_ct_generic_timeout __read_mostly = 600*HZ; +static bool nf_generic_should_process(u8 proto) +{ + switch (proto) { +#ifdef CONFIG_NF_CT_PROTO_SCTP_MODULE + case IPPROTO_SCTP: + return false; +#endif +#ifdef CONFIG_NF_CT_PROTO_DCCP_MODULE + case IPPROTO_DCCP: + return false; +#endif +#ifdef CONFIG_NF_CT_PROTO_GRE_MODULE + case IPPROTO_GRE: + return false; +#endif +#ifdef CONFIG_NF_CT_PROTO_UDPLITE_MODULE + case IPPROTO_UDPLITE: + return false; +#endif + default: + return true; + } +} + static inline struct nf_generic_net *generic_pernet(struct net *net) { return &net->ct.nf_ct_proto.generic; @@ -67,7 +91,7 @@ static int generic_packet(struct nf_conn *ct, static bool generic_new(struct nf_conn *ct, const struct sk_buff *skb, unsigned int dataoff, unsigned int *timeouts) { - return true; + return nf_generic_should_process(nf_ct_protonum(ct)); } #if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT) -- 2.7.4 From f93b5806246ec965d2118a8cd9d27919c3efa658 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Tue, 16 Jun 2015 22:11:06 +0100 Subject: [PATCH 14/16] pipe: iovec: Fix memory corruption when retrying atomic copy as non-atomic pipe_iov_copy_{from,to}_user() may be tried twice with the same iovec, the first time atomically and the second time not. The second attempt needs to continue from the iovec position, pipe buffer offset and remaining length where the first attempt failed, but currently the pipe buffer offset and remaining length are reset. This will corrupt the piped data (possibly also leading to an information leak between processes) and may also corrupt kernel memory. This was fixed upstream by commits f0d1bec9d58d ("new helper: copy_page_from_iter()") and 637b58c2887e ("switch pipe_read() to copy_page_to_iter()"), but those aren't suitable for stable. This fix for older kernel versions was made by Seth Jennings for RHEL and I have extracted it from their update. CVE-2015-1805 Change-Id: Iedade4714500e63ad26599fe7aaa91d886df84a9 References: https://bugzilla.redhat.com/show_bug.cgi?id=1202855 Signed-off-by: Ben Hutchings Signed-off-by: Greg Kroah-Hartman Signed-off-by: Junghoon Kim --- fs/pipe.c | 55 ++++++++++++++++++++++++++++++++----------------------- 1 file changed, 32 insertions(+), 23 deletions(-) diff --git a/fs/pipe.c b/fs/pipe.c index dd07912..96c3084 100644 --- a/fs/pipe.c +++ b/fs/pipe.c @@ -117,25 +117,27 @@ void pipe_wait(struct pipe_inode_info *pipe) } static int -pipe_iov_copy_from_user(void *to, struct iovec *iov, unsigned long len, - int atomic) +pipe_iov_copy_from_user(void *addr, int *offset, struct iovec *iov, + size_t *remaining, int atomic) { unsigned long copy; - while (len > 0) { + while (*remaining > 0) { while (!iov->iov_len) iov++; - copy = min_t(unsigned long, len, iov->iov_len); + copy = min_t(unsigned long, *remaining, iov->iov_len); if (atomic) { - if (__copy_from_user_inatomic(to, iov->iov_base, copy)) + if (__copy_from_user_inatomic(addr + *offset, + iov->iov_base, copy)) return -EFAULT; } else { - if (copy_from_user(to, iov->iov_base, copy)) + if (copy_from_user(addr + *offset, + iov->iov_base, copy)) return -EFAULT; } - to += copy; - len -= copy; + *offset += copy; + *remaining -= copy; iov->iov_base += copy; iov->iov_len -= copy; } @@ -143,25 +145,27 @@ pipe_iov_copy_from_user(void *to, struct iovec *iov, unsigned long len, } static int -pipe_iov_copy_to_user(struct iovec *iov, const void *from, unsigned long len, - int atomic) +pipe_iov_copy_to_user(struct iovec *iov, void *addr, int *offset, + size_t *remaining, int atomic) { unsigned long copy; - while (len > 0) { + while (*remaining > 0) { while (!iov->iov_len) iov++; - copy = min_t(unsigned long, len, iov->iov_len); + copy = min_t(unsigned long, *remaining, iov->iov_len); if (atomic) { - if (__copy_to_user_inatomic(iov->iov_base, from, copy)) + if (__copy_to_user_inatomic(iov->iov_base, + addr + *offset, copy)) return -EFAULT; } else { - if (copy_to_user(iov->iov_base, from, copy)) + if (copy_to_user(iov->iov_base, + addr + *offset, copy)) return -EFAULT; } - from += copy; - len -= copy; + *offset += copy; + *remaining -= copy; iov->iov_base += copy; iov->iov_len -= copy; } @@ -395,7 +399,7 @@ pipe_read(struct kiocb *iocb, const struct iovec *_iov, struct pipe_buffer *buf = pipe->bufs + curbuf; const struct pipe_buf_operations *ops = buf->ops; void *addr; - size_t chars = buf->len; + size_t chars = buf->len, remaining; int error, atomic; if (chars > total_len) @@ -409,9 +413,11 @@ pipe_read(struct kiocb *iocb, const struct iovec *_iov, } atomic = !iov_fault_in_pages_write(iov, chars); + remaining = chars; redo: addr = ops->map(pipe, buf, atomic); - error = pipe_iov_copy_to_user(iov, addr + buf->offset, chars, atomic); + error = pipe_iov_copy_to_user(iov, addr, &buf->offset, + &remaining, atomic); ops->unmap(pipe, buf, addr); if (unlikely(error)) { /* @@ -426,7 +432,6 @@ redo: break; } ret += chars; - buf->offset += chars; buf->len -= chars; /* Was it a packet buffer? Clean up and exit */ @@ -531,6 +536,7 @@ pipe_write(struct kiocb *iocb, const struct iovec *_iov, if (ops->can_merge && offset + chars <= PAGE_SIZE) { int error, atomic = 1; void *addr; + size_t remaining = chars; error = ops->confirm(pipe, buf); if (error) @@ -539,8 +545,8 @@ pipe_write(struct kiocb *iocb, const struct iovec *_iov, iov_fault_in_pages_read(iov, chars); redo1: addr = ops->map(pipe, buf, atomic); - error = pipe_iov_copy_from_user(offset + addr, iov, - chars, atomic); + error = pipe_iov_copy_from_user(addr, &offset, iov, + &remaining, atomic); ops->unmap(pipe, buf, addr); ret = error; do_wakeup = 1; @@ -575,6 +581,8 @@ redo1: struct page *page = pipe->tmp_page; char *src; int error, atomic = 1; + int offset = 0; + size_t remaining; if (!page) { #ifndef CONFIG_SPRD_PAGERECORDER @@ -599,14 +607,15 @@ redo1: chars = total_len; iov_fault_in_pages_read(iov, chars); + remaining = chars; redo2: if (atomic) src = kmap_atomic(page); else src = kmap(page); - error = pipe_iov_copy_from_user(src, iov, chars, - atomic); + error = pipe_iov_copy_from_user(src, &offset, iov, + &remaining, atomic); if (atomic) kunmap_atomic(src); else -- 2.7.4 From 2331bbf3776b5294e93b7a646c6591ed8d08b70e Mon Sep 17 00:00:00 2001 From: Quentin Casasnovas Date: Tue, 24 Nov 2015 17:13:21 -0500 Subject: [PATCH 15/16] RDS: fix race condition when sending a message on unbound socket Sasha's found a NULL pointer dereference in the RDS connection code when sending a message to an apparently unbound socket. The problem is caused by the code checking if the socket is bound in rds_sendmsg(), which checks the rs_bound_addr field without taking a lock on the socket. This opens a race where rs_bound_addr is temporarily set but where the transport is not in rds_bind(), leading to a NULL pointer dereference when trying to dereference 'trans' in __rds_conn_create(). Vegard wrote a reproducer for this issue, so kindly ask him to share if you're interested. I cannot reproduce the NULL pointer dereference using Vegard's reproducer with this patch, whereas I could without. Complete earlier incomplete fix to CVE-2015-6937: 74e98eb08588 ("RDS: verify the underlying transport exists before creating a connection") Cc: David S. Miller Cc: stable@vger.kernel.org Change-Id: I697622374cf9a4b8d805fb5a58987cfe8646afed Reviewed-by: Vegard Nossum Reviewed-by: Sasha Levin Acked-by: Santosh Shilimkar Signed-off-by: Quentin Casasnovas Signed-off-by: David S. Miller Signed-off-by: Junghoon Kim --- net/rds/send.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/net/rds/send.c b/net/rds/send.c index 88eace5..31c9fa4 100644 --- a/net/rds/send.c +++ b/net/rds/send.c @@ -955,11 +955,13 @@ int rds_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, release_sock(sk); } - /* racing with another thread binding seems ok here */ + lock_sock(sk); if (daddr == 0 || rs->rs_bound_addr == 0) { + release_sock(sk); ret = -ENOTCONN; /* XXX not a great errno */ goto out; } + release_sock(sk); /* size of rm including all sgs */ ret = rds_rm_size(msg, payload_len); -- 2.7.4 From 7ec1da918e216faeb0e807abd1f9596101a727eb Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Thu, 29 Jan 2015 02:50:33 +0000 Subject: [PATCH 16/16] splice: Apply generic position and size checks to each write commit 894c6350eaad7e613ae267504014a456e00a3e2a from the 3.2-stable branch. We need to check the position and size of file writes against various limits, using generic_write_check(). This was not being done for the splice write path. It was fixed upstream by commit 8d0207652cbe ("->splice_write() via ->write_iter()") but we can't apply that. CVE-2014-7822 Signed-off-by: Ben Hutchings [Ben fixed it in 3.2 stable, i ported it to 3.10 stable] Signed-off-by: Zhang Zhen Signed-off-by: Greg Kroah-Hartman Change-Id: I10f6cd44e0223d515d905ee5f3043b5d22c31057 Signed-off-by: Junghoon Kim --- fs/ocfs2/file.c | 8 +++++--- fs/splice.c | 8 ++++++-- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index 46387e4..e0b1c88 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c @@ -2453,12 +2453,14 @@ static ssize_t ocfs2_file_splice_write(struct pipe_inode_info *pipe, struct address_space *mapping = out->f_mapping; struct inode *inode = mapping->host; struct splice_desc sd = { - .total_len = len, .flags = flags, - .pos = *ppos, .u.file = out, }; - + ret = generic_write_checks(out, ppos, &len, 0); + if(ret) + return ret; + sd.total_len = len; + sd.pos = *ppos; trace_ocfs2_file_splice_write(inode, out, out->f_path.dentry, (unsigned long long)OCFS2_I(inode)->ip_blkno, diff --git a/fs/splice.c b/fs/splice.c index 4b5a5fa..f183f13 100644 --- a/fs/splice.c +++ b/fs/splice.c @@ -1012,13 +1012,17 @@ generic_file_splice_write(struct pipe_inode_info *pipe, struct file *out, struct address_space *mapping = out->f_mapping; struct inode *inode = mapping->host; struct splice_desc sd = { - .total_len = len, .flags = flags, - .pos = *ppos, .u.file = out, }; ssize_t ret; + ret = generic_write_checks(out, ppos, &len, S_ISBLK(inode->i_mode)); + if (ret) + return ret; + sd.total_len = len; + sd.pos = *ppos; + pipe_lock(pipe); splice_from_pipe_begin(&sd); -- 2.7.4