summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Shi <alex.shi@linaro.org>2016-06-02 17:59:02 +0800
committerAlex Shi <alex.shi@linaro.org>2016-06-02 17:59:02 +0800
commitcf5ba83bb248452b5b320d8f2ee48bd90e5cf3f6 (patch)
tree502638c84cddb697ca38c300b2f8b8d681ad0f29
parent58189909e6da3df54f13394e842635c3c4c8d68f (diff)
parent63a2b92307eb8fff4451ae58ca937dd6aa899469 (diff)
Merge branch 'lsk-v4.4-android' of git://android.git.linaro.org/kernel/linaro-android into linux-linaro-lsk-v4.4-android
-rw-r--r--android/configs/android-base.cfg3
-rw-r--r--android/configs/android-recommended.cfg1
-rw-r--r--arch/arm/include/asm/mach/mmc.h28
-rw-r--r--drivers/Kconfig2
-rw-r--r--drivers/Makefile1
-rw-r--r--drivers/base/power/main.c45
-rw-r--r--drivers/cpufreq/cpufreq_interactive.c27
-rw-r--r--drivers/hid/hid-multitouch.c10
-rw-r--r--drivers/hid/hid-steelseries.c5
-rw-r--r--drivers/misc/Kconfig4
-rw-r--r--drivers/misc/Makefile1
-rw-r--r--drivers/misc/uid_stat.c153
-rw-r--r--drivers/net/wireless/ti/wlcore/init.c5
-rw-r--r--drivers/staging/android/fiq_debugger/Kconfig9
-rw-r--r--drivers/staging/android/fiq_debugger/fiq_debugger.c36
-rw-r--r--drivers/switch/Kconfig15
-rw-r--r--drivers/switch/Makefile4
-rw-r--r--drivers/switch/switch_class.c174
-rw-r--r--drivers/switch/switch_gpio.c172
-rw-r--r--fs/fuse/dev.c5
-rw-r--r--fs/fuse/dir.c45
-rw-r--r--fs/fuse/fuse_i.h3
-rw-r--r--fs/notify/inotify/inotify_user.c2
-rw-r--r--fs/proc/base.c42
-rw-r--r--fs/sdcardfs/dentry.c6
-rw-r--r--include/linux/amba/mmci.h3
-rw-r--r--include/linux/dcache.h2
-rw-r--r--include/linux/switch.h53
-rw-r--r--include/linux/uid_stat.h29
-rw-r--r--include/linux/usb/class-dual-role.h9
-rw-r--r--include/net/activity_stats.h25
-rw-r--r--include/net/tcp.h2
-rw-r--r--include/uapi/linux/fuse.h1
-rw-r--r--include/uapi/linux/sockios.h1
-rw-r--r--mm/vmscan.c43
-rw-r--r--net/Kconfig8
-rw-r--r--net/Makefile1
-rw-r--r--net/activity_stats.c118
-rw-r--r--net/ipv4/af_inet.c1
-rw-r--r--net/ipv4/devinet.c8
-rw-r--r--net/ipv4/tcp.c133
-rw-r--r--net/ipv6/af_inet6.c17
-rw-r--r--net/mac80211/mesh_hwmp.c2
-rw-r--r--net/netfilter/xt_qtaguid.c4
-rw-r--r--security/selinux/hooks.c41
-rw-r--r--security/selinux/include/classmap.h2
46 files changed, 198 insertions, 1103 deletions
diff --git a/android/configs/android-base.cfg b/android/configs/android-base.cfg
index fa53af0c37ad..304f1d4fd7c4 100644
--- a/android/configs/android-base.cfg
+++ b/android/configs/android-base.cfg
@@ -57,6 +57,7 @@ CONFIG_IP_NF_MANGLE=y
CONFIG_IP_NF_MATCH_AH=y
CONFIG_IP_NF_MATCH_ECN=y
CONFIG_IP_NF_MATCH_TTL=y
+CONFIG_IP_NF_NAT=y
CONFIG_IP_NF_RAW=y
CONFIG_IP_NF_SECURITY=y
CONFIG_IP_NF_TARGET_MASQUERADE=y
@@ -138,6 +139,7 @@ CONFIG_PPP_BSDCOMP=y
CONFIG_PPP_DEFLATE=y
CONFIG_PPP_MPPE=y
CONFIG_PREEMPT=y
+CONFIG_QUOTA=y
CONFIG_RESOURCE_COUNTERS=y
CONFIG_RTC_CLASS=y
CONFIG_RT_GROUP_SCHED=y
@@ -146,7 +148,6 @@ CONFIG_SECURITY_NETWORK=y
CONFIG_SECURITY_SELINUX=y
CONFIG_SETEND_EMULATION=y
CONFIG_STAGING=y
-CONFIG_SWITCH=y
CONFIG_SWP_EMULATION=y
CONFIG_SYNC=y
CONFIG_TUN=y
diff --git a/android/configs/android-recommended.cfg b/android/configs/android-recommended.cfg
index e4c8aaade197..35936afdcae4 100644
--- a/android/configs/android-recommended.cfg
+++ b/android/configs/android-recommended.cfg
@@ -119,7 +119,6 @@ CONFIG_TIMER_STATS=y
CONFIG_TMPFS=y
CONFIG_TMPFS_POSIX_ACL=y
CONFIG_UHID=y
-CONFIG_UID_STAT=y
CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_HIDDEV=y
diff --git a/arch/arm/include/asm/mach/mmc.h b/arch/arm/include/asm/mach/mmc.h
deleted file mode 100644
index bca864ac945f..000000000000
--- a/arch/arm/include/asm/mach/mmc.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * arch/arm/include/asm/mach/mmc.h
- */
-#ifndef ASMARM_MACH_MMC_H
-#define ASMARM_MACH_MMC_H
-
-#include <linux/mmc/host.h>
-#include <linux/mmc/card.h>
-#include <linux/mmc/sdio_func.h>
-
-struct embedded_sdio_data {
- struct sdio_cis cis;
- struct sdio_cccr cccr;
- struct sdio_embedded_func *funcs;
- int num_funcs;
-};
-
-struct mmc_platform_data {
- unsigned int ocr_mask; /* available voltages */
- int built_in; /* built-in device flag */
- int card_present; /* card detect state */
- u32 (*translate_vdd)(struct device *, unsigned int);
- unsigned int (*status)(struct device *);
- struct embedded_sdio_data *embedded_sdio;
- int (*register_status_notify)(void (*callback)(int card_present, void *dev_id), void *dev_id);
-};
-
-#endif
diff --git a/drivers/Kconfig b/drivers/Kconfig
index 3c363e559864..d2ac339de85f 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -104,8 +104,6 @@ source "drivers/memstick/Kconfig"
source "drivers/leds/Kconfig"
-source "drivers/switch/Kconfig"
-
source "drivers/accessibility/Kconfig"
source "drivers/infiniband/Kconfig"
diff --git a/drivers/Makefile b/drivers/Makefile
index 8acfb530993d..795d0ca714bf 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -122,7 +122,6 @@ obj-$(CONFIG_CPU_IDLE) += cpuidle/
obj-y += mmc/
obj-$(CONFIG_MEMSTICK) += memstick/
obj-y += leds/
-obj-$(CONFIG_SWITCH) += switch/
obj-$(CONFIG_INFINIBAND) += infiniband/
obj-$(CONFIG_SGI_SN) += sn/
obj-y += firmware/
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index 6ed8b9326629..5ea529165362 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -35,8 +35,6 @@
#include <linux/timer.h>
#include <linux/wakeup_reason.h>
-#include <asm/current.h>
-
#include "../base.h"
#include "power.h"
@@ -62,12 +60,6 @@ struct suspend_stats suspend_stats;
static DEFINE_MUTEX(dpm_list_mtx);
static pm_message_t pm_transition;
-static void dpm_drv_timeout(unsigned long data);
-struct dpm_drv_wd_data {
- struct device *dev;
- struct task_struct *tsk;
-};
-
static int async_error;
static char *pm_verb(int event)
@@ -839,30 +831,6 @@ static void async_resume(void *data, async_cookie_t cookie)
}
/**
- * dpm_drv_timeout - Driver suspend / resume watchdog handler
- * @data: struct device which timed out
- *
- * Called when a driver has timed out suspending or resuming.
- * There's not much we can do here to recover so
- * BUG() out for a crash-dump
- *
- */
-static void dpm_drv_timeout(unsigned long data)
-{
- struct dpm_drv_wd_data *wd_data = (void *)data;
- struct device *dev = wd_data->dev;
- struct task_struct *tsk = wd_data->tsk;
-
- printk(KERN_EMERG "**** DPM device timeout: %s (%s)\n", dev_name(dev),
- (dev->driver ? dev->driver->name : "no driver"));
-
- printk(KERN_EMERG "dpm suspend stack:\n");
- show_stack(tsk, NULL);
-
- BUG();
-}
-
-/**
* dpm_resume - Execute "resume" callbacks for non-sysdev devices.
* @state: PM transition of the system being carried out.
*
@@ -1380,8 +1348,6 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async)
pm_callback_t callback = NULL;
char *info = NULL;
int error = 0;
- struct timer_list timer;
- struct dpm_drv_wd_data data;
char suspend_abort[MAX_SUSPEND_ABORT_LEN];
DECLARE_DPM_WATCHDOG_ON_STACK(wd);
@@ -1412,14 +1378,6 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async)
if (dev->power.syscore)
goto Complete;
-
- data.dev = dev;
- data.tsk = current;
- init_timer_on_stack(&timer);
- timer.expires = jiffies + HZ * 12;
- timer.function = dpm_drv_timeout;
- timer.data = (unsigned long)&data;
- add_timer(&timer);
if (dev->power.direct_complete) {
if (pm_runtime_status_suspended(dev)) {
@@ -1500,9 +1458,6 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async)
device_unlock(dev);
dpm_watchdog_clear(&wd);
- del_timer_sync(&timer);
- destroy_timer_on_stack(&timer);
-
Complete:
complete_all(&dev->power.completion);
if (error)
diff --git a/drivers/cpufreq/cpufreq_interactive.c b/drivers/cpufreq/cpufreq_interactive.c
index bd83be39f17b..f2929e628820 100644
--- a/drivers/cpufreq/cpufreq_interactive.c
+++ b/drivers/cpufreq/cpufreq_interactive.c
@@ -116,28 +116,6 @@ struct cpufreq_interactive_tunables {
bool io_is_busy;
};
-/*
- * HACK: FIXME: Bring back cpufreq_{get,put}_global_kobject()
- * definition removed by upstream commit 8eec1020f0c0 "cpufreq:
- * create cpu/cpufreq at boot time" to fix build failures.
- */
-static int cpufreq_global_kobject_usage;
-
-int cpufreq_get_global_kobject(void)
-{
- if (!cpufreq_global_kobject_usage++)
- return kobject_add(cpufreq_global_kobject,
- &cpu_subsys.dev_root->kobj, "%s", "cpufreq");
-
- return 0;
-}
-
-void cpufreq_put_global_kobject(void)
-{
- if (!--cpufreq_global_kobject_usage)
- kobject_del(cpufreq_global_kobject);
-}
-
/* For cases where we have single governor instance for system */
static struct cpufreq_interactive_tunables *common_tunables;
@@ -1206,7 +1184,6 @@ static int cpufreq_governor_interactive(struct cpufreq_policy *policy,
policy->governor_data = tunables;
if (!have_governor_per_policy()) {
common_tunables = tunables;
- WARN_ON(cpufreq_get_global_kobject());
}
rc = sysfs_create_group(get_governor_parent_kobj(policy),
@@ -1216,7 +1193,6 @@ static int cpufreq_governor_interactive(struct cpufreq_policy *policy,
policy->governor_data = NULL;
if (!have_governor_per_policy()) {
common_tunables = NULL;
- cpufreq_put_global_kobject();
}
return rc;
}
@@ -1240,9 +1216,6 @@ static int cpufreq_governor_interactive(struct cpufreq_policy *policy,
sysfs_remove_group(get_governor_parent_kobj(policy),
get_sysfs_attr());
- if (!have_governor_per_policy())
- cpufreq_put_global_kobject();
-
kfree(tunables);
common_tunables = NULL;
}
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
index 7ecd96bdf834..c5ec4f915594 100644
--- a/drivers/hid/hid-multitouch.c
+++ b/drivers/hid/hid-multitouch.c
@@ -450,16 +450,6 @@ static int mt_touch_input_mapping(struct hid_device *hdev, struct hid_input *hi,
if ((usage->hid & HID_USAGE_PAGE) == HID_UP_BUTTON)
td->buttons_count++;
- /* Only map fields from TouchScreen or TouchPad collections.
- * We need to ignore fields that belong to other collections
- * such as Mouse that might have the same GenericDesktop usages. */
- if (field->application == HID_DG_TOUCHSCREEN)
- set_bit(INPUT_PROP_DIRECT, hi->input->propbit);
- else if (field->application == HID_DG_TOUCHPAD)
- set_bit(INPUT_PROP_POINTER, hi->input->propbit);
- else
- return 0;
-
if (usage->usage_index)
prev_usage = &field->usage[usage->usage_index - 1];
diff --git a/drivers/hid/hid-steelseries.c b/drivers/hid/hid-steelseries.c
index 93ddc1c65b4c..3edd4ac36494 100644
--- a/drivers/hid/hid-steelseries.c
+++ b/drivers/hid/hid-steelseries.c
@@ -253,11 +253,6 @@ static int steelseries_srws1_probe(struct hid_device *hdev,
goto err_free;
}
- if (!hid_validate_values(hdev, HID_OUTPUT_REPORT, 0, 0, 16)) {
- ret = -ENODEV;
- goto err_free;
- }
-
ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
if (ret) {
hid_err(hdev, "hw start failed\n");
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 2dcafd0ba17f..ca7463544c72 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -412,10 +412,6 @@ config TI_DAC7512
This driver can also be built as a module. If so, the module
will be called ti_dac7512.
-config UID_STAT
- bool "UID based statistics tracking exported to /proc/uid_stat"
- default n
-
config VMWARE_BALLOON
tristate "VMware Balloon Driver"
depends on VMWARE_VMCI && X86 && HYPERVISOR_GUEST
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 24483a6caa6b..e5142b836aee 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -35,7 +35,6 @@ obj-$(CONFIG_ISL29020) += isl29020.o
obj-$(CONFIG_SENSORS_TSL2550) += tsl2550.o
obj-$(CONFIG_DS1682) += ds1682.o
obj-$(CONFIG_TI_DAC7512) += ti_dac7512.o
-obj-$(CONFIG_UID_STAT) += uid_stat.o
obj-$(CONFIG_C2PORT) += c2port/
obj-$(CONFIG_HMC6352) += hmc6352.o
obj-y += eeprom/
diff --git a/drivers/misc/uid_stat.c b/drivers/misc/uid_stat.c
deleted file mode 100644
index 185c69c9738a..000000000000
--- a/drivers/misc/uid_stat.c
+++ /dev/null
@@ -1,153 +0,0 @@
-/* drivers/misc/uid_stat.c
- *
- * Copyright (C) 2008 - 2009 Google, Inc.
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- */
-
-#include <linux/atomic.h>
-
-#include <linux/err.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/stat.h>
-#include <linux/uid_stat.h>
-#include <net/activity_stats.h>
-
-static DEFINE_SPINLOCK(uid_lock);
-static LIST_HEAD(uid_list);
-static struct proc_dir_entry *parent;
-
-struct uid_stat {
- struct list_head link;
- uid_t uid;
- atomic_t tcp_rcv;
- atomic_t tcp_snd;
-};
-
-static struct uid_stat *find_uid_stat(uid_t uid) {
- struct uid_stat *entry;
-
- list_for_each_entry(entry, &uid_list, link) {
- if (entry->uid == uid) {
- return entry;
- }
- }
- return NULL;
-}
-
-static int uid_stat_atomic_int_show(struct seq_file *m, void *v)
-{
- unsigned int bytes;
- atomic_t *counter = m->private;
-
- bytes = (unsigned int) (atomic_read(counter) + INT_MIN);
- seq_printf(m, "%u\n", bytes);
- return seq_has_overflowed(m) ? -ENOSPC : 0;
-}
-
-static int uid_stat_read_atomic_int_open(struct inode *inode, struct file *file)
-{
- return single_open(file, uid_stat_atomic_int_show, PDE_DATA(inode));
-}
-
-static const struct file_operations uid_stat_read_atomic_int_fops = {
- .open = uid_stat_read_atomic_int_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = seq_release,
-};
-
-/* Create a new entry for tracking the specified uid. */
-static struct uid_stat *create_stat(uid_t uid) {
- struct uid_stat *new_uid;
- /* Create the uid stat struct and append it to the list. */
- new_uid = kmalloc(sizeof(struct uid_stat), GFP_ATOMIC);
- if (!new_uid)
- return NULL;
-
- new_uid->uid = uid;
- /* Counters start at INT_MIN, so we can track 4GB of network traffic. */
- atomic_set(&new_uid->tcp_rcv, INT_MIN);
- atomic_set(&new_uid->tcp_snd, INT_MIN);
-
- list_add_tail(&new_uid->link, &uid_list);
- return new_uid;
-}
-
-static void create_stat_proc(struct uid_stat *new_uid)
-{
- char uid_s[32];
- struct proc_dir_entry *entry;
- sprintf(uid_s, "%d", new_uid->uid);
- entry = proc_mkdir(uid_s, parent);
-
- /* Keep reference to uid_stat so we know what uid to read stats from. */
- proc_create_data("tcp_snd", S_IRUGO, entry,
- &uid_stat_read_atomic_int_fops, &new_uid->tcp_snd);
-
- proc_create_data("tcp_rcv", S_IRUGO, entry,
- &uid_stat_read_atomic_int_fops, &new_uid->tcp_rcv);
-}
-
-static struct uid_stat *find_or_create_uid_stat(uid_t uid)
-{
- struct uid_stat *entry;
- unsigned long flags;
- spin_lock_irqsave(&uid_lock, flags);
- entry = find_uid_stat(uid);
- if (entry) {
- spin_unlock_irqrestore(&uid_lock, flags);
- return entry;
- }
- entry = create_stat(uid);
- spin_unlock_irqrestore(&uid_lock, flags);
- if (entry)
- create_stat_proc(entry);
- return entry;
-}
-
-int uid_stat_tcp_snd(uid_t uid, int size) {
- struct uid_stat *entry;
- activity_stats_update();
- entry = find_or_create_uid_stat(uid);
- if (!entry)
- return -1;
- atomic_add(size, &entry->tcp_snd);
- return 0;
-}
-
-int uid_stat_tcp_rcv(uid_t uid, int size) {
- struct uid_stat *entry;
- activity_stats_update();
- entry = find_or_create_uid_stat(uid);
- if (!entry)
- return -1;
- atomic_add(size, &entry->tcp_rcv);
- return 0;
-}
-
-static int __init uid_stat_init(void)
-{
- parent = proc_mkdir("uid_stat", NULL);
- if (!parent) {
- pr_err("uid_stat: failed to create proc entry\n");
- return -1;
- }
- return 0;
-}
-
-__initcall(uid_stat_init);
diff --git a/drivers/net/wireless/ti/wlcore/init.c b/drivers/net/wireless/ti/wlcore/init.c
index e92f2639af2c..9fd3c6af0a61 100644
--- a/drivers/net/wireless/ti/wlcore/init.c
+++ b/drivers/net/wireless/ti/wlcore/init.c
@@ -549,6 +549,11 @@ static int wl12xx_init_ap_role(struct wl1271 *wl, struct wl12xx_vif *wlvif)
{
int ret;
+ /* Disable filtering */
+ ret = wl1271_acx_group_address_tbl(wl, wlvif, false, NULL, 0);
+ if (ret < 0)
+ return ret;
+
ret = wl1271_acx_ap_max_tx_retry(wl, wlvif);
if (ret < 0)
return ret;
diff --git a/drivers/staging/android/fiq_debugger/Kconfig b/drivers/staging/android/fiq_debugger/Kconfig
index 56f7f999377e..60fc224d4efc 100644
--- a/drivers/staging/android/fiq_debugger/Kconfig
+++ b/drivers/staging/android/fiq_debugger/Kconfig
@@ -42,6 +42,15 @@ config FIQ_DEBUGGER_CONSOLE_DEFAULT_ENABLE
If enabled, this puts the fiq debugger into console mode by default.
Otherwise, the fiq debugger will start out in debug mode.
+config FIQ_DEBUGGER_UART_OVERLAY
+ bool "Install uart DT overlay"
+ depends on FIQ_DEBUGGER
+ select OF_OVERLAY
+ default n
+ help
+ If enabled, fiq debugger is calling fiq_debugger_uart_overlay()
+ that will apply overlay uart_overlay@0 to disable proper uart.
+
config FIQ_WATCHDOG
bool
select FIQ_DEBUGGER
diff --git a/drivers/staging/android/fiq_debugger/fiq_debugger.c b/drivers/staging/android/fiq_debugger/fiq_debugger.c
index 7f056831dbff..b132cff14f01 100644
--- a/drivers/staging/android/fiq_debugger/fiq_debugger.c
+++ b/drivers/staging/android/fiq_debugger/fiq_debugger.c
@@ -39,6 +39,10 @@
#include <asm/fiq_glue.h>
#endif
+#ifdef CONFIG_FIQ_DEBUGGER_UART_OVERLAY
+#include <linux/of.h>
+#endif
+
#include <linux/uaccess.h>
#include "fiq_debugger.h"
@@ -119,11 +123,13 @@ static bool initial_console_enable;
#endif
static bool fiq_kgdb_enable;
+static bool fiq_debugger_disable;
module_param_named(no_sleep, initial_no_sleep, bool, 0644);
module_param_named(debug_enable, initial_debug_enable, bool, 0644);
module_param_named(console_enable, initial_console_enable, bool, 0644);
module_param_named(kgdb_enable, fiq_kgdb_enable, bool, 0644);
+module_param_named(disable, fiq_debugger_disable, bool, 0644);
#ifdef CONFIG_FIQ_DEBUGGER_WAKEUP_IRQ_ALWAYS_ON
static inline
@@ -1201,11 +1207,41 @@ static struct platform_driver fiq_debugger_driver = {
},
};
+#if defined(CONFIG_FIQ_DEBUGGER_UART_OVERLAY)
+int fiq_debugger_uart_overlay(void)
+{
+ struct device_node *onp = of_find_node_by_path("/uart_overlay@0");
+ int ret;
+
+ if (!onp) {
+ pr_err("serial_debugger: uart overlay not found\n");
+ return -ENODEV;
+ }
+
+ ret = of_overlay_create(onp);
+ if (ret < 0) {
+ pr_err("serial_debugger: fail to create overlay: %d\n", ret);
+ of_node_put(onp);
+ return ret;
+ }
+
+ pr_info("serial_debugger: uart overlay applied\n");
+ return 0;
+}
+#endif
+
static int __init fiq_debugger_init(void)
{
+ if (fiq_debugger_disable) {
+ pr_err("serial_debugger: disabled\n");
+ return -ENODEV;
+ }
#if defined(CONFIG_FIQ_DEBUGGER_CONSOLE)
fiq_debugger_tty_init();
#endif
+#if defined(CONFIG_FIQ_DEBUGGER_UART_OVERLAY)
+ fiq_debugger_uart_overlay();
+#endif
return platform_driver_register(&fiq_debugger_driver);
}
diff --git a/drivers/switch/Kconfig b/drivers/switch/Kconfig
deleted file mode 100644
index 19404b6f7778..000000000000
--- a/drivers/switch/Kconfig
+++ /dev/null
@@ -1,15 +0,0 @@
-menuconfig SWITCH
- tristate "Switch class support"
- help
- Say Y here to enable switch class support. This allows
- monitoring switches by userspace via sysfs and uevent.
-
-if SWITCH
-
-config SWITCH_GPIO
- tristate "GPIO Swith support"
- depends on GPIOLIB
- help
- Say Y here to enable GPIO based switch support.
-
-endif # SWITCH
diff --git a/drivers/switch/Makefile b/drivers/switch/Makefile
deleted file mode 100644
index f7606ed4a719..000000000000
--- a/drivers/switch/Makefile
+++ /dev/null
@@ -1,4 +0,0 @@
-# Switch Class Driver
-obj-$(CONFIG_SWITCH) += switch_class.o
-obj-$(CONFIG_SWITCH_GPIO) += switch_gpio.o
-
diff --git a/drivers/switch/switch_class.c b/drivers/switch/switch_class.c
deleted file mode 100644
index e373b625806e..000000000000
--- a/drivers/switch/switch_class.c
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * drivers/switch/switch_class.c
- *
- * Copyright (C) 2008 Google, Inc.
- * Author: Mike Lockwood <lockwood@android.com>
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
-*/
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/device.h>
-#include <linux/fs.h>
-#include <linux/err.h>
-#include <linux/switch.h>
-
-struct class *switch_class;
-static atomic_t device_count;
-
-static ssize_t state_show(struct device *dev, struct device_attribute *attr,
- char *buf)
-{
- struct switch_dev *sdev = (struct switch_dev *)
- dev_get_drvdata(dev);
-
- if (sdev->print_state) {
- int ret = sdev->print_state(sdev, buf);
- if (ret >= 0)
- return ret;
- }
- return sprintf(buf, "%d\n", sdev->state);
-}
-
-static ssize_t name_show(struct device *dev, struct device_attribute *attr,
- char *buf)
-{
- struct switch_dev *sdev = (struct switch_dev *)
- dev_get_drvdata(dev);
-
- if (sdev->print_name) {
- int ret = sdev->print_name(sdev, buf);
- if (ret >= 0)
- return ret;
- }
- return sprintf(buf, "%s\n", sdev->name);
-}
-
-static DEVICE_ATTR(state, S_IRUGO, state_show, NULL);
-static DEVICE_ATTR(name, S_IRUGO, name_show, NULL);
-
-void switch_set_state(struct switch_dev *sdev, int state)
-{
- char name_buf[120];
- char state_buf[120];
- char *prop_buf;
- char *envp[3];
- int env_offset = 0;
- int length;
-
- if (sdev->state != state) {
- sdev->state = state;
-
- prop_buf = (char *)get_zeroed_page(GFP_KERNEL);
- if (prop_buf) {
- length = name_show(sdev->dev, NULL, prop_buf);
- if (length > 0) {
- if (prop_buf[length - 1] == '\n')
- prop_buf[length - 1] = 0;
- snprintf(name_buf, sizeof(name_buf),
- "SWITCH_NAME=%s", prop_buf);
- envp[env_offset++] = name_buf;
- }
- length = state_show(sdev->dev, NULL, prop_buf);
- if (length > 0) {
- if (prop_buf[length - 1] == '\n')
- prop_buf[length - 1] = 0;
- snprintf(state_buf, sizeof(state_buf),
- "SWITCH_STATE=%s", prop_buf);
- envp[env_offset++] = state_buf;
- }
- envp[env_offset] = NULL;
- kobject_uevent_env(&sdev->dev->kobj, KOBJ_CHANGE, envp);
- free_page((unsigned long)prop_buf);
- } else {
- printk(KERN_ERR "out of memory in switch_set_state\n");
- kobject_uevent(&sdev->dev->kobj, KOBJ_CHANGE);
- }
- }
-}
-EXPORT_SYMBOL_GPL(switch_set_state);
-
-static int create_switch_class(void)
-{
- if (!switch_class) {
- switch_class = class_create(THIS_MODULE, "switch");
- if (IS_ERR(switch_class))
- return PTR_ERR(switch_class);
- atomic_set(&device_count, 0);
- }
-
- return 0;
-}
-
-int switch_dev_register(struct switch_dev *sdev)
-{
- int ret;
-
- if (!switch_class) {
- ret = create_switch_class();
- if (ret < 0)
- return ret;
- }
-
- sdev->index = atomic_inc_return(&device_count);
- sdev->dev = device_create(switch_class, NULL,
- MKDEV(0, sdev->index), NULL, sdev->name);
- if (IS_ERR(sdev->dev))
- return PTR_ERR(sdev->dev);
-
- ret = device_create_file(sdev->dev, &dev_attr_state);
- if (ret < 0)
- goto err_create_file_1;
- ret = device_create_file(sdev->dev, &dev_attr_name);
- if (ret < 0)
- goto err_create_file_2;
-
- dev_set_drvdata(sdev->dev, sdev);
- sdev->state = 0;
- return 0;
-
-err_create_file_2:
- device_remove_file(sdev->dev, &dev_attr_state);
-err_create_file_1:
- device_destroy(switch_class, MKDEV(0, sdev->index));
- printk(KERN_ERR "switch: Failed to register driver %s\n", sdev->name);
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(switch_dev_register);
-
-void switch_dev_unregister(struct switch_dev *sdev)
-{
- device_remove_file(sdev->dev, &dev_attr_name);
- device_remove_file(sdev->dev, &dev_attr_state);
- device_destroy(switch_class, MKDEV(0, sdev->index));
- dev_set_drvdata(sdev->dev, NULL);
-}
-EXPORT_SYMBOL_GPL(switch_dev_unregister);
-
-static int __init switch_class_init(void)
-{
- return create_switch_class();
-}
-
-static void __exit switch_class_exit(void)
-{
- class_destroy(switch_class);
-}
-
-module_init(switch_class_init);
-module_exit(switch_class_exit);
-
-MODULE_AUTHOR("Mike Lockwood <lockwood@android.com>");
-MODULE_DESCRIPTION("Switch class driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/switch/switch_gpio.c b/drivers/switch/switch_gpio.c
deleted file mode 100644
index 621d62d20c99..000000000000
--- a/drivers/switch/switch_gpio.c
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * drivers/switch/switch_gpio.c
- *
- * Copyright (C) 2008 Google, Inc.
- * Author: Mike Lockwood <lockwood@android.com>
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
-*/
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <linux/switch.h>
-#include <linux/workqueue.h>
-#include <linux/gpio.h>
-
-struct gpio_switch_data {
- struct switch_dev sdev;
- unsigned gpio;
- const char *name_on;
- const char *name_off;
- const char *state_on;
- const char *state_off;
- int irq;
- struct work_struct work;
-};
-
-static void gpio_switch_work(struct work_struct *work)
-{
- int state;
- struct gpio_switch_data *data =
- container_of(work, struct gpio_switch_data, work);
-
- state = gpio_get_value(data->gpio);
- switch_set_state(&data->sdev, state);
-}
-
-static irqreturn_t gpio_irq_handler(int irq, void *dev_id)
-{
- struct gpio_switch_data *switch_data =
- (struct gpio_switch_data *)dev_id;
-
- schedule_work(&switch_data->work);
- return IRQ_HANDLED;
-}
-
-static ssize_t switch_gpio_print_state(struct switch_dev *sdev, char *buf)
-{
- struct gpio_switch_data *switch_data =
- container_of(sdev, struct gpio_switch_data, sdev);
- const char *state;
- if (switch_get_state(sdev))
- state = switch_data->state_on;
- else
- state = switch_data->state_off;
-
- if (state)
- return sprintf(buf, "%s\n", state);
- return -1;
-}
-
-static int gpio_switch_probe(struct platform_device *pdev)
-{
- struct gpio_switch_platform_data *pdata = pdev->dev.platform_data;
- struct gpio_switch_data *switch_data;
- int ret = 0;
-
- if (!pdata)
- return -EBUSY;
-
- switch_data = kzalloc(sizeof(struct gpio_switch_data), GFP_KERNEL);
- if (!switch_data)
- return -ENOMEM;
-
- switch_data->sdev.name = pdata->name;
- switch_data->gpio = pdata->gpio;
- switch_data->name_on = pdata->name_on;
- switch_data->name_off = pdata->name_off;
- switch_data->state_on = pdata->state_on;
- switch_data->state_off = pdata->state_off;
- switch_data->sdev.print_state = switch_gpio_print_state;
-
- ret = switch_dev_register(&switch_data->sdev);
- if (ret < 0)
- goto err_switch_dev_register;
-
- ret = gpio_request(switch_data->gpio, pdev->name);
- if (ret < 0)
- goto err_request_gpio;
-
- ret = gpio_direction_input(switch_data->gpio);
- if (ret < 0)
- goto err_set_gpio_input;
-
- INIT_WORK(&switch_data->work, gpio_switch_work);
-
- switch_data->irq = gpio_to_irq(switch_data->gpio);
- if (switch_data->irq < 0) {
- ret = switch_data->irq;
- goto err_detect_irq_num_failed;
- }
-
- ret = request_irq(switch_data->irq, gpio_irq_handler,
- IRQF_TRIGGER_LOW, pdev->name, switch_data);
- if (ret < 0)
- goto err_request_irq;
-
- /* Perform initial detection */
- gpio_switch_work(&switch_data->work);
-
- return 0;
-
-err_request_irq:
-err_detect_irq_num_failed:
-err_set_gpio_input:
- gpio_free(switch_data->gpio);
-err_request_gpio:
- switch_dev_unregister(&switch_data->sdev);
-err_switch_dev_register:
- kfree(switch_data);
-
- return ret;
-}
-
-static int gpio_switch_remove(struct platform_device *pdev)
-{
- struct gpio_switch_data *switch_data = platform_get_drvdata(pdev);
-
- cancel_work_sync(&switch_data->work);
- gpio_free(switch_data->gpio);
- switch_dev_unregister(&switch_data->sdev);
- kfree(switch_data);
-
- return 0;
-}
-
-static struct platform_driver gpio_switch_driver = {
- .probe = gpio_switch_probe,
- .remove = gpio_switch_remove,
- .driver = {
- .name = "switch-gpio",
- .owner = THIS_MODULE,
- },
-};
-
-static int __init gpio_switch_init(void)
-{
- return platform_driver_register(&gpio_switch_driver);
-}
-
-static void __exit gpio_switch_exit(void)
-{
- platform_driver_unregister(&gpio_switch_driver);
-}
-
-module_init(gpio_switch_init);
-module_exit(gpio_switch_exit);
-
-MODULE_AUTHOR("Mike Lockwood <lockwood@android.com>");
-MODULE_DESCRIPTION("GPIO Switch driver");
-MODULE_LICENSE("GPL");
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
index 175fcdeabe4c..8932c06e40c1 100644
--- a/fs/fuse/dev.c
+++ b/fs/fuse/dev.c
@@ -13,6 +13,7 @@
#include <linux/poll.h>
#include <linux/uio.h>
#include <linux/miscdevice.h>
+#include <linux/namei.h>
#include <linux/pagemap.h>
#include <linux/file.h>
#include <linux/slab.h>
@@ -1935,6 +1936,10 @@ static ssize_t fuse_dev_do_write(struct fuse_dev *fud,
cs->move_pages = 0;
err = copy_out_args(cs, &req->out, nbytes);
+ if (req->in.h.opcode == FUSE_CANONICAL_PATH) {
+ req->out.h.error = kern_path((char *)req->out.args[0].value, 0,
+ req->canonical_path);
+ }
fuse_copy_finish(cs);
spin_lock(&fpq->lock);
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index 5e2e08712d3b..24df0a5df675 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -267,6 +267,50 @@ invalid:
goto out;
}
+/*
+ * Get the canonical path. Since we must translate to a path, this must be done
+ * in the context of the userspace daemon, however, the userspace daemon cannot
+ * look up paths on its own. Instead, we handle the lookup as a special case
+ * inside of the write request.
+ */
+static void fuse_dentry_canonical_path(const struct path *path, struct path *canonical_path) {
+ struct inode *inode = path->dentry->d_inode;
+ struct fuse_conn *fc = get_fuse_conn(inode);
+ struct fuse_req *req;
+ int err;
+ char *path_name;
+
+ req = fuse_get_req(fc, 1);
+ err = PTR_ERR(req);
+ if (IS_ERR(req))
+ goto default_path;
+
+ path_name = (char*)__get_free_page(GFP_KERNEL);
+ if (!path_name) {
+ fuse_put_request(fc, req);
+ goto default_path;
+ }
+
+ req->in.h.opcode = FUSE_CANONICAL_PATH;
+ req->in.h.nodeid = get_node_id(inode);
+ req->in.numargs = 0;
+ req->out.numargs = 1;
+ req->out.args[0].size = PATH_MAX;
+ req->out.args[0].value = path_name;
+ req->canonical_path = canonical_path;
+ req->out.argvar = 1;
+ fuse_request_send(fc, req);
+ err = req->out.h.error;
+ fuse_put_request(fc, req);
+ free_page((unsigned long)path_name);
+ if (!err)
+ return;
+default_path:
+ canonical_path->dentry = path->dentry;
+ canonical_path->mnt = path->mnt;
+ path_get(canonical_path);
+}
+
static int invalid_nodeid(u64 nodeid)
{
return !nodeid || nodeid == FUSE_ROOT_ID;
@@ -274,6 +318,7 @@ static int invalid_nodeid(u64 nodeid)
const struct dentry_operations fuse_dentry_operations = {
.d_revalidate = fuse_dentry_revalidate,
+ .d_canonical_path = fuse_dentry_canonical_path,
};
int fuse_valid_type(int m)
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
index 604cd42dafef..644687ae04bd 100644
--- a/fs/fuse/fuse_i.h
+++ b/fs/fuse/fuse_i.h
@@ -372,6 +372,9 @@ struct fuse_req {
/** Inode used in the request or NULL */
struct inode *inode;
+ /** Path used for completing d_canonical_path */
+ struct path *canonical_path;
+
/** AIO control block */
struct fuse_io_priv *io;
diff --git a/fs/notify/inotify/inotify_user.c b/fs/notify/inotify/inotify_user.c
index f72f3b25b3f2..e2893f17dde2 100644
--- a/fs/notify/inotify/inotify_user.c
+++ b/fs/notify/inotify/inotify_user.c
@@ -746,7 +746,7 @@ SYSCALL_DEFINE3(inotify_add_watch, int, fd, const char __user *, pathname,
/* support stacked filesystems */
if(path.dentry && path.dentry->d_op) {
if (path.dentry->d_op->d_canonical_path) {
- path.dentry->d_op->d_canonical_path(path.dentry, &alteredpath);
+ path.dentry->d_op->d_canonical_path(&path, &alteredpath);
canonical_path = &alteredpath;
path_put(&path);
}
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 23d60b1995fb..2df808a81035 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -3079,6 +3079,44 @@ int proc_pid_readdir(struct file *file, struct dir_context *ctx)
}
/*
+ * proc_tid_comm_permission is a special permission function exclusively
+ * used for the node /proc/<pid>/task/<tid>/comm.
+ * It bypasses generic permission checks in the case where a task of the same
+ * task group attempts to access the node.
+ * The rational behind this is that glibc and bionic access this node for
+ * cross thread naming (pthread_set/getname_np(!self)). However, if
+ * PR_SET_DUMPABLE gets set to 0 this node among others becomes uid=0 gid=0,
+ * which locks out the cross thread naming implementation.
+ * This function makes sure that the node is always accessible for members of
+ * same thread group.
+ */
+static int proc_tid_comm_permission(struct inode *inode, int mask)
+{
+ bool is_same_tgroup;
+ struct task_struct *task;
+
+ task = get_proc_task(inode);
+ if (!task)
+ return -ESRCH;
+ is_same_tgroup = same_thread_group(current, task);
+ put_task_struct(task);
+
+ if (likely(is_same_tgroup && !(mask & MAY_EXEC))) {
+ /* This file (/proc/<pid>/task/<tid>/comm) can always be
+ * read or written by the members of the corresponding
+ * thread group.
+ */
+ return 0;
+ }
+
+ return generic_permission(inode, mask);
+}
+
+static const struct inode_operations proc_tid_comm_inode_operations = {
+ .permission = proc_tid_comm_permission,
+};
+
+/*
* Tasks
*/
static const struct pid_entry tid_base_stuff[] = {
@@ -3096,7 +3134,9 @@ static const struct pid_entry tid_base_stuff[] = {
#ifdef CONFIG_SCHED_DEBUG
REG("sched", S_IRUGO|S_IWUSR, proc_pid_sched_operations),
#endif
- REG("comm", S_IRUGO|S_IWUSR, proc_pid_set_comm_operations),
+ NOD("comm", S_IFREG|S_IRUGO|S_IWUSR,
+ &proc_tid_comm_inode_operations,
+ &proc_pid_set_comm_operations, {}),
#ifdef CONFIG_HAVE_ARCH_TRACEHOOK
ONE("syscall", S_IRUSR, proc_pid_syscall),
#endif
diff --git a/fs/sdcardfs/dentry.c b/fs/sdcardfs/dentry.c
index ba165ef11e27..971928ab6c21 100644
--- a/fs/sdcardfs/dentry.c
+++ b/fs/sdcardfs/dentry.c
@@ -172,11 +172,15 @@ static int sdcardfs_cmp_ci(const struct dentry *parent,
return 1;
}
+static void sdcardfs_canonical_path(const struct path *path, struct path *actual_path) {
+ sdcardfs_get_real_lower(path->dentry, actual_path);
+}
+
const struct dentry_operations sdcardfs_ci_dops = {
.d_revalidate = sdcardfs_d_revalidate,
.d_release = sdcardfs_d_release,
.d_hash = sdcardfs_hash_ci,
.d_compare = sdcardfs_cmp_ci,
- .d_canonical_path = sdcardfs_get_real_lower,
+ .d_canonical_path = sdcardfs_canonical_path,
};
diff --git a/include/linux/amba/mmci.h b/include/linux/amba/mmci.h
index 8bfd21c13d59..eff56cb0016a 100644
--- a/include/linux/amba/mmci.h
+++ b/include/linux/amba/mmci.h
@@ -40,10 +40,7 @@ struct mmci_platform_data {
int gpio_wp;
int gpio_cd;
bool cd_invert;
- unsigned int status_irq;
struct embedded_sdio_data *embedded_sdio;
- int (*register_status_notify)(void (*callback)(int card_present, void *dev_id), void *dev_id);
-
};
#endif
diff --git a/include/linux/dcache.h b/include/linux/dcache.h
index d184e283cf81..71ff59b66dc4 100644
--- a/include/linux/dcache.h
+++ b/include/linux/dcache.h
@@ -161,7 +161,7 @@ struct dentry_operations {
struct vfsmount *(*d_automount)(struct path *);
int (*d_manage)(struct dentry *, bool);
struct inode *(*d_select_inode)(struct dentry *, unsigned);
- void (*d_canonical_path)(const struct dentry *, struct path *);
+ void (*d_canonical_path)(const struct path *, struct path *);
struct dentry *(*d_real)(struct dentry *, struct inode *);
} ____cacheline_aligned;
diff --git a/include/linux/switch.h b/include/linux/switch.h
deleted file mode 100644
index 3e4c748e343a..000000000000
--- a/include/linux/switch.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Switch class driver
- *
- * Copyright (C) 2008 Google, Inc.
- * Author: Mike Lockwood <lockwood@android.com>
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
-*/
-
-#ifndef __LINUX_SWITCH_H__
-#define __LINUX_SWITCH_H__
-
-struct switch_dev {
- const char *name;
- struct device *dev;
- int index;
- int state;
-
- ssize_t (*print_name)(struct switch_dev *sdev, char *buf);
- ssize_t (*print_state)(struct switch_dev *sdev, char *buf);
-};
-
-struct gpio_switch_platform_data {
- const char *name;
- unsigned gpio;
-
- /* if NULL, switch_dev.name will be printed */
- const char *name_on;
- const char *name_off;
- /* if NULL, "0" or "1" will be printed */
- const char *state_on;
- const char *state_off;
-};
-
-extern int switch_dev_register(struct switch_dev *sdev);
-extern void switch_dev_unregister(struct switch_dev *sdev);
-
-static inline int switch_get_state(struct switch_dev *sdev)
-{
- return sdev->state;
-}
-
-extern void switch_set_state(struct switch_dev *sdev, int state);
-
-#endif /* __LINUX_SWITCH_H__ */
diff --git a/include/linux/uid_stat.h b/include/linux/uid_stat.h
deleted file mode 100644
index 6bd6c4e52d17..000000000000
--- a/include/linux/uid_stat.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/* include/linux/uid_stat.h
- *
- * Copyright (C) 2008-2009 Google, Inc.
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- */
-
-#ifndef __uid_stat_h
-#define __uid_stat_h
-
-/* Contains definitions for resource tracking per uid. */
-
-#ifdef CONFIG_UID_STAT
-int uid_stat_tcp_snd(uid_t uid, int size);
-int uid_stat_tcp_rcv(uid_t uid, int size);
-#else
-#define uid_stat_tcp_snd(uid, size) do {} while (0);
-#define uid_stat_tcp_rcv(uid, size) do {} while (0);
-#endif
-
-#endif /* _LINUX_UID_STAT_H */
diff --git a/include/linux/usb/class-dual-role.h b/include/linux/usb/class-dual-role.h
index af42ed34944a..c6df2238012e 100644
--- a/include/linux/usb/class-dual-role.h
+++ b/include/linux/usb/class-dual-role.h
@@ -109,18 +109,19 @@ extern int dual_role_property_is_writeable(struct dual_role_phy_instance
enum dual_role_property prop);
extern void *dual_role_get_drvdata(struct dual_role_phy_instance *dual_role);
#else /* CONFIG_DUAL_ROLE_USB_INTF */
-static void dual_role_instance_changed(struct dual_role_phy_instance
+static inline void dual_role_instance_changed(struct dual_role_phy_instance
*dual_role){}
-static struct dual_role_phy_instance *__must_check
+static inline struct dual_role_phy_instance *__must_check
devm_dual_role_instance_register(struct device *parent,
const struct dual_role_phy_desc *desc)
{
return ERR_PTR(-ENOSYS);
}
-static void devm_dual_role_instance_unregister(struct device *dev,
+static inline void devm_dual_role_instance_unregister(struct device *dev,
struct dual_role_phy_instance
*dual_role){}
-static void *dual_role_get_drvdata(struct dual_role_phy_instance *dual_role)
+static inline void *dual_role_get_drvdata(struct dual_role_phy_instance
+ *dual_role)
{
return ERR_PTR(-ENOSYS);
}
diff --git a/include/net/activity_stats.h b/include/net/activity_stats.h
deleted file mode 100644
index 10e4c1506eeb..000000000000
--- a/include/net/activity_stats.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2010 Google, Inc.
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * Author: Mike Chan (mike@android.com)
- */
-
-#ifndef __activity_stats_h
-#define __activity_stats_h
-
-#ifdef CONFIG_NET_ACTIVITY_STATS
-void activity_stats_update(void);
-#else
-#define activity_stats_update(void) {}
-#endif
-
-#endif /* _NET_ACTIVITY_STATS_H */
diff --git a/include/net/tcp.h b/include/net/tcp.h
index 5f4d135a00cc..b36cebad6b2f 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -1681,8 +1681,6 @@ static inline bool tcp_stream_memory_free(const struct sock *sk)
return notsent_bytes < tcp_notsent_lowat(tp);
}
-extern int tcp_nuke_addr(struct net *net, struct sockaddr *addr);
-
#ifdef CONFIG_PROC_FS
int tcp4_proc_init(void);
void tcp4_proc_exit(void);
diff --git a/include/uapi/linux/fuse.h b/include/uapi/linux/fuse.h
index c9aca042e61d..8485dd4300b8 100644
--- a/include/uapi/linux/fuse.h
+++ b/include/uapi/linux/fuse.h
@@ -358,6 +358,7 @@ enum fuse_opcode {
FUSE_FALLOCATE = 43,
FUSE_READDIRPLUS = 44,
FUSE_RENAME2 = 45,
+ FUSE_CANONICAL_PATH= 2016,
/* CUSE specific operations */
CUSE_INIT = 4096,
diff --git a/include/uapi/linux/sockios.h b/include/uapi/linux/sockios.h
index 623e9aab645e..e888b1aed69f 100644
--- a/include/uapi/linux/sockios.h
+++ b/include/uapi/linux/sockios.h
@@ -65,7 +65,6 @@
#define SIOCDIFADDR 0x8936 /* delete PA address */
#define SIOCSIFHWBROADCAST 0x8937 /* set hardware broadcast addr */
#define SIOCGIFCOUNT 0x8938 /* get number of devices */
-#define SIOCKILLADDR 0x8939 /* kill sockets with this local addr */
#define SIOCGIFBR 0x8940 /* Bridging support */
#define SIOCSIFBR 0x8941 /* Set bridging options */
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 2e6547ec1b09..0c114e2b01d3 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -46,7 +46,6 @@
#include <linux/oom.h>
#include <linux/prefetch.h>
#include <linux/printk.h>
-#include <linux/debugfs.h>
#include <asm/tlbflush.h>
#include <asm/div64.h>
@@ -221,39 +220,6 @@ static unsigned long get_lru_size(struct lruvec *lruvec, enum lru_list lru)
return zone_page_state(lruvec_zone(lruvec), NR_LRU_BASE + lru);
}
-struct dentry *debug_file;
-
-static int debug_shrinker_show(struct seq_file *s, void *unused)
-{
- struct shrinker *shrinker;
- struct shrink_control sc;
-
- sc.gfp_mask = -1;
- sc.nr_to_scan = 0;
-
- down_read(&shrinker_rwsem);
- list_for_each_entry(shrinker, &shrinker_list, list) {
- int num_objs;
-
- num_objs = shrinker->count_objects(shrinker, &sc);
- seq_printf(s, "%pf %d\n", shrinker->scan_objects, num_objs);
- }
- up_read(&shrinker_rwsem);
- return 0;
-}
-
-static int debug_shrinker_open(struct inode *inode, struct file *file)
-{
- return single_open(file, debug_shrinker_show, inode->i_private);
-}
-
-static const struct file_operations debug_shrinker_fops = {
- .open = debug_shrinker_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
-
/*
* Add a shrinker callback to be called from the vm.
*/
@@ -283,15 +249,6 @@ int register_shrinker(struct shrinker *shrinker)
}
EXPORT_SYMBOL(register_shrinker);
-static int __init add_shrinker_debug(void)
-{
- debugfs_create_file("shrinker", 0644, NULL, NULL,
- &debug_shrinker_fops);
- return 0;
-}
-
-late_initcall(add_shrinker_debug);
-
/*
* Remove one
*/
diff --git a/net/Kconfig b/net/Kconfig
index 043fe1dc0860..ce9585cf343a 100644
--- a/net/Kconfig
+++ b/net/Kconfig
@@ -92,14 +92,6 @@ config ANDROID_PARANOID_NETWORK
help
none
-config NET_ACTIVITY_STATS
- bool "Network activity statistics tracking"
- default y
- help
- Network activity statistics are useful for tracking wireless
- modem activity on 2G, 3G, 4G wireless networks. Counts number of
- transmissions and groups them in specified time buckets.
-
config NETWORK_SECMARK
bool "Security Marking"
help
diff --git a/net/Makefile b/net/Makefile
index eeb9d5db454f..a5d04098dfce 100644
--- a/net/Makefile
+++ b/net/Makefile
@@ -77,4 +77,3 @@ endif
ifneq ($(CONFIG_NET_L3_MASTER_DEV),)
obj-y += l3mdev/
endif
-obj-$(CONFIG_NET_ACTIVITY_STATS) += activity_stats.o
diff --git a/net/activity_stats.c b/net/activity_stats.c
deleted file mode 100644
index 3bf92d80b8b9..000000000000
--- a/net/activity_stats.c
+++ /dev/null
@@ -1,118 +0,0 @@
-/* net/activity_stats.c
- *
- * Copyright (C) 2010 Google, Inc.
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * Author: Mike Chan (mike@android.com)
- */
-
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
-#include <linux/suspend.h>
-#include <net/net_namespace.h>
-
-/*
- * Track transmission rates in buckets (power of 2).
- * 1,2,4,8...512 seconds.
- *
- * Buckets represent the count of network transmissions at least
- * N seconds apart, where N is 1 << bucket index.
- */
-#define BUCKET_MAX 10
-
-/* Track network activity frequency */
-static unsigned long activity_stats[BUCKET_MAX];
-static ktime_t last_transmit;
-static ktime_t suspend_time;
-static DEFINE_SPINLOCK(activity_lock);
-
-void activity_stats_update(void)
-{
- int i;
- unsigned long flags;
- ktime_t now;
- s64 delta;
-
- spin_lock_irqsave(&activity_lock, flags);
- now = ktime_get();
- delta = ktime_to_ns(ktime_sub(now, last_transmit));
-
- for (i = BUCKET_MAX - 1; i >= 0; i--) {
- /*
- * Check if the time delta between network activity is within the
- * minimum bucket range.
- */
- if (delta < (1000000000ULL << i))
- continue;
-
- activity_stats[i]++;
- last_transmit = now;
- break;
- }
- spin_unlock_irqrestore(&activity_lock, flags);
-}
-
-static int activity_stats_show(struct seq_file *m, void *v)
-{
- int i;
-
- seq_printf(m, "Min Bucket(sec) Count\n");
-
- for (i = 0; i < BUCKET_MAX; i++) {
- seq_printf(m, "%15d %lu\n", 1 << i, activity_stats[i]);
- if (seq_has_overflowed(m))
- return -ENOSPC;
- }
-
- return 0;
-}
-
-static int activity_stats_notifier(struct notifier_block *nb,
- unsigned long event, void *dummy)
-{
- switch (event) {
- case PM_SUSPEND_PREPARE:
- suspend_time = ktime_get_real();
- break;
-
- case PM_POST_SUSPEND:
- suspend_time = ktime_sub(ktime_get_real(), suspend_time);
- last_transmit = ktime_sub(last_transmit, suspend_time);
- }
-
- return 0;
-}
-
-static int activity_stats_open(struct inode *inode, struct file *file)
-{
- return single_open(file, activity_stats_show, PDE_DATA(inode));
-}
-
-static const struct file_operations activity_stats_fops = {
- .open = activity_stats_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = seq_release,
-};
-
-static struct notifier_block activity_stats_notifier_block = {
- .notifier_call = activity_stats_notifier,
-};
-
-static int __init activity_stats_init(void)
-{
- proc_create("activity", S_IRUGO,
- init_net.proc_net_stat, &activity_stats_fops);
- return register_pm_notifier(&activity_stats_notifier_block);
-}
-
-subsys_initcall(activity_stats_init);
-
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index 671eb0092915..eb12bd0ff9d3 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -886,7 +886,6 @@ int inet_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
case SIOCSIFPFLAGS:
case SIOCGIFPFLAGS:
case SIOCSIFFLAGS:
- case SIOCKILLADDR:
err = devinet_ioctl(net, cmd, (void __user *)arg);
break;
default:
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index 926169c94a0b..0212591b0077 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -59,7 +59,6 @@
#include <net/arp.h>
#include <net/ip.h>
-#include <net/tcp.h>
#include <net/route.h>
#include <net/ip_fib.h>
#include <net/rtnetlink.h>
@@ -969,7 +968,6 @@ int devinet_ioctl(struct net *net, unsigned int cmd, void __user *arg)
case SIOCSIFBRDADDR: /* Set the broadcast address */
case SIOCSIFDSTADDR: /* Set the destination address */
case SIOCSIFNETMASK: /* Set the netmask for the interface */
- case SIOCKILLADDR: /* Nuke all sockets on this address */
ret = -EPERM;
if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
goto out;
@@ -1021,8 +1019,7 @@ int devinet_ioctl(struct net *net, unsigned int cmd, void __user *arg)
}
ret = -EADDRNOTAVAIL;
- if (!ifa && cmd != SIOCSIFADDR && cmd != SIOCSIFFLAGS
- && cmd != SIOCKILLADDR)
+ if (!ifa && cmd != SIOCSIFADDR && cmd != SIOCSIFFLAGS)
goto done;
switch (cmd) {
@@ -1149,9 +1146,6 @@ int devinet_ioctl(struct net *net, unsigned int cmd, void __user *arg)
inet_insert_ifa(ifa);
}
break;
- case SIOCKILLADDR: /* Nuke all connections on this address */
- ret = tcp_nuke_addr(net, (struct sockaddr *) sin);
- break;
}
done:
rtnl_unlock();
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 7c0465202cc5..6ecfc9de599c 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -269,16 +269,12 @@
#include <linux/crypto.h>
#include <linux/time.h>
#include <linux/slab.h>
-#include <linux/uid_stat.h>
#include <net/icmp.h>
#include <net/inet_common.h>
#include <net/tcp.h>
#include <net/xfrm.h>
#include <net/ip.h>
-#include <net/ip6_route.h>
-#include <net/ipv6.h>
-#include <net/transp_v6.h>
#include <net/sock.h>
#include <asm/uaccess.h>
@@ -1288,10 +1284,6 @@ out:
tcp_push(sk, flags, mss_now, tp->nonagle, size_goal);
out_nopush:
release_sock(sk);
-
- if (copied + copied_syn)
- uid_stat_tcp_snd(from_kuid(&init_user_ns, current_uid()),
- copied + copied_syn);
return copied + copied_syn;
do_fault:
@@ -1566,8 +1558,6 @@ int tcp_read_sock(struct sock *sk, read_descriptor_t *desc,
if (copied > 0) {
tcp_recv_skb(sk, seq, &offset);
tcp_cleanup_rbuf(sk, copied);
- uid_stat_tcp_rcv(from_kuid(&init_user_ns, current_uid()),
- copied);
}
return copied;
}
@@ -1901,10 +1891,6 @@ skip_copy:
tcp_cleanup_rbuf(sk, copied);
release_sock(sk);
-
- if (copied > 0)
- uid_stat_tcp_rcv(from_kuid(&init_user_ns, current_uid()),
- copied);
return copied;
out:
@@ -1913,9 +1899,6 @@ out:
recv_urg:
err = tcp_recv_urg(sk, msg, len, flags);
- if (err > 0)
- uid_stat_tcp_rcv(from_kuid(&init_user_ns, current_uid()),
- err);
goto out;
recv_sndq:
@@ -3254,119 +3237,3 @@ void __init tcp_init(void)
BUG_ON(tcp_register_congestion_control(&tcp_reno) != 0);
tcp_tasklet_init();
}
-
-static int tcp_is_local(struct net *net, __be32 addr) {
- struct rtable *rt;
- struct flowi4 fl4 = { .daddr = addr };
- rt = ip_route_output_key(net, &fl4);
- if (IS_ERR_OR_NULL(rt))
- return 0;
- return rt->dst.dev && (rt->dst.dev->flags & IFF_LOOPBACK);
-}
-
-#if defined(CONFIG_IPV6)
-static int tcp_is_local6(struct net *net, struct in6_addr *addr) {
- struct rt6_info *rt6 = rt6_lookup(net, addr, addr, 0, 0);
- return rt6 && rt6->dst.dev && (rt6->dst.dev->flags & IFF_LOOPBACK);
-}
-#endif
-
-/*
- * tcp_nuke_addr - destroy all sockets on the given local address
- * if local address is the unspecified address (0.0.0.0 or ::), destroy all
- * sockets with local addresses that are not configured.
- */
-int tcp_nuke_addr(struct net *net, struct sockaddr *addr)
-{
- int family = addr->sa_family;
- unsigned int bucket;
-
- struct in_addr *in;
-#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
- struct in6_addr *in6 = NULL;
-#endif
- if (family == AF_INET) {
- in = &((struct sockaddr_in *)addr)->sin_addr;
-#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
- } else if (family == AF_INET6) {
- in6 = &((struct sockaddr_in6 *)addr)->sin6_addr;
-#endif
- } else {
- return -EAFNOSUPPORT;
- }
-
- for (bucket = 0; bucket <= tcp_hashinfo.ehash_mask; bucket++) {
- struct hlist_nulls_node *node;
- struct sock *sk;
- spinlock_t *lock = inet_ehash_lockp(&tcp_hashinfo, bucket);
-
-restart:
- spin_lock_bh(lock);
- sk_nulls_for_each(sk, node, &tcp_hashinfo.ehash[bucket].chain) {
- struct inet_sock *inet = inet_sk(sk);
-
- if (sk->sk_state == TCP_TIME_WAIT) {
- /*
- * Sockets that are in TIME_WAIT state are
- * instances of lightweight inet_timewait_sock,
- * we should simply skip them (or we'll try to
- * access non-existing fields and crash).
- */
- continue;
- }
-
- if (sysctl_ip_dynaddr && sk->sk_state == TCP_SYN_SENT)
- continue;
-
- if (sock_flag(sk, SOCK_DEAD))
- continue;
-
- if (family == AF_INET) {
- __be32 s4 = inet->inet_rcv_saddr;
- if (s4 == LOOPBACK4_IPV6)
- continue;
-
- if (in->s_addr != s4 &&
- !(in->s_addr == INADDR_ANY &&
- !tcp_is_local(net, s4)))
- continue;
- }
-
-#if defined(CONFIG_IPV6)
- if (family == AF_INET6) {
- struct in6_addr *s6;
- if (!inet->pinet6)
- continue;
-
- s6 = &sk->sk_v6_rcv_saddr;
- if (ipv6_addr_type(s6) == IPV6_ADDR_MAPPED)
- continue;
-
- if (!ipv6_addr_equal(in6, s6) &&
- !(ipv6_addr_equal(in6, &in6addr_any) &&
- !tcp_is_local6(net, s6)))
- continue;
- }
-#endif
-
- sock_hold(sk);
- spin_unlock_bh(lock);
-
- local_bh_disable();
- bh_lock_sock(sk);
- sk->sk_err = ETIMEDOUT;
- sk->sk_error_report(sk);
-
- tcp_done(sk);
- bh_unlock_sock(sk);
- local_bh_enable();
- sock_put(sk);
-
- goto restart;
- }
- spin_unlock_bh(lock);
- }
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(tcp_nuke_addr);
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index 99fccad391e0..d9b25bd17bf1 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -495,21 +495,6 @@ int inet6_getname(struct socket *sock, struct sockaddr *uaddr,
}
EXPORT_SYMBOL(inet6_getname);
-int inet6_killaddr_ioctl(struct net *net, void __user *arg) {
- struct in6_ifreq ireq;
- struct sockaddr_in6 sin6;
-
- if (!capable(CAP_NET_ADMIN))
- return -EACCES;
-
- if (copy_from_user(&ireq, arg, sizeof(struct in6_ifreq)))
- return -EFAULT;
-
- sin6.sin6_family = AF_INET6;
- sin6.sin6_addr = ireq.ifr6_addr;
- return tcp_nuke_addr(net, (struct sockaddr *) &sin6);
-}
-
int inet6_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
{
struct sock *sk = sock->sk;
@@ -533,8 +518,6 @@ int inet6_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
return addrconf_del_ifaddr(net, (void __user *) arg);
case SIOCSIFDSTADDR:
return addrconf_set_dstaddr(net, (void __user *) arg);
- case SIOCKILLADDR:
- return inet6_killaddr_ioctl(net, (void __user *) arg);
default:
if (!sk->sk_prot->ioctl)
return -ENOIOCTLCMD;
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c
index c6be0b4f4058..b6dc2d7cd650 100644
--- a/net/mac80211/mesh_hwmp.c
+++ b/net/mac80211/mesh_hwmp.c
@@ -530,7 +530,7 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata,
const u8 *target_addr, *orig_addr;
const u8 *da;
u8 target_flags, ttl, flags;
- u32 orig_sn, target_sn, lifetime, target_metric;
+ u32 orig_sn, target_sn, lifetime, target_metric = 0;
bool reply = false;
bool forward = true;
bool root_is_gate;
diff --git a/net/netfilter/xt_qtaguid.c b/net/netfilter/xt_qtaguid.c
index e1442bfb668d..e2e7d54f9bb1 100644
--- a/net/netfilter/xt_qtaguid.c
+++ b/net/netfilter/xt_qtaguid.c
@@ -1606,7 +1606,7 @@ static struct sock *qtaguid_find_sk(const struct sk_buff *skb,
* When in TCP_TIME_WAIT the sk is not a "struct sock" but
* "struct inet_timewait_sock" which is missing fields.
*/
- if (sk->sk_state == TCP_TIME_WAIT) {
+ if (!sk_fullsock(sk) || sk->sk_state == TCP_TIME_WAIT) {
sock_gen_put(sk);
sk = NULL;
}
@@ -1689,7 +1689,7 @@ static bool qtaguid_mt(const struct sk_buff *skb, struct xt_action_param *par)
/* default: Fall through and do UID releated work */
}
- sk = skb->sk;
+ sk = skb_to_full_sk(skb);
/*
* When in TCP_TIME_WAIT the sk is not a "struct sock" but
* "struct inet_timewait_sock" which is missing fields.
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 7c22a15c7e4b..94a0bfc748d1 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -420,6 +420,7 @@ static int selinux_is_sblabel_mnt(struct super_block *sb)
!strcmp(sb->s_type->name, "sysfs") ||
!strcmp(sb->s_type->name, "pstore") ||
!strcmp(sb->s_type->name, "debugfs") ||
+ !strcmp(sb->s_type->name, "tracefs") ||
!strcmp(sb->s_type->name, "rootfs");
}
@@ -464,13 +465,6 @@ static int sb_finish_set_opts(struct super_block *sb)
if (selinux_is_sblabel_mnt(sb))
sbsec->flags |= SBLABEL_MNT;
- /*
- * Special handling for rootfs. Is genfs but supports
- * setting SELinux context on in-core inodes.
- */
- if (strncmp(sb->s_type->name, "rootfs", sizeof("rootfs")) == 0)
- sbsec->flags |= SBLABEL_MNT;
-
/* Initialize the root inode. */
rc = inode_doinit_with_dentry(root_inode, root);
@@ -3660,6 +3654,38 @@ static int selinux_kernel_module_request(char *kmod_name)
SYSTEM__MODULE_REQUEST, &ad);
}
+static int selinux_kernel_module_from_file(struct file *file)
+{
+ struct common_audit_data ad;
+ struct inode_security_struct *isec;
+ struct file_security_struct *fsec;
+ struct inode *inode;
+ u32 sid = current_sid();
+ int rc;
+
+ /* init_module */
+ if (file == NULL)
+ return avc_has_perm(sid, sid, SECCLASS_SYSTEM,
+ SYSTEM__MODULE_LOAD, NULL);
+
+ /* finit_module */
+ ad.type = LSM_AUDIT_DATA_PATH;
+ ad.u.path = file->f_path;
+
+ inode = file_inode(file);
+ isec = inode->i_security;
+ fsec = file->f_security;
+
+ if (sid != fsec->sid) {
+ rc = avc_has_perm(sid, fsec->sid, SECCLASS_FD, FD__USE, &ad);
+ if (rc)
+ return rc;
+ }
+
+ return avc_has_perm(sid, isec->sid, SECCLASS_SYSTEM,
+ SYSTEM__MODULE_LOAD, &ad);
+}
+
static int selinux_task_setpgid(struct task_struct *p, pid_t pgid)
{
return current_has_perm(p, PROCESS__SETPGID);
@@ -5950,6 +5976,7 @@ static struct security_hook_list selinux_hooks[] = {
LSM_HOOK_INIT(kernel_act_as, selinux_kernel_act_as),
LSM_HOOK_INIT(kernel_create_files_as, selinux_kernel_create_files_as),
LSM_HOOK_INIT(kernel_module_request, selinux_kernel_module_request),
+ LSM_HOOK_INIT(kernel_module_from_file, selinux_kernel_module_from_file),
LSM_HOOK_INIT(task_setpgid, selinux_task_setpgid),
LSM_HOOK_INIT(task_getpgid, selinux_task_getpgid),
LSM_HOOK_INIT(task_getsid, selinux_task_getsid),
diff --git a/security/selinux/include/classmap.h b/security/selinux/include/classmap.h
index 5a4eef59aeff..b393d29ae857 100644
--- a/security/selinux/include/classmap.h
+++ b/security/selinux/include/classmap.h
@@ -32,7 +32,7 @@ struct security_class_mapping secclass_map[] = {
"setsockcreate", NULL } },
{ "system",
{ "ipc_info", "syslog_read", "syslog_mod",
- "syslog_console", "module_request", NULL } },
+ "syslog_console", "module_request", "module_load", NULL } },
{ "capability",
{ "chown", "dac_override", "dac_read_search",
"fowner", "fsetid", "kill", "setgid", "setuid", "setpcap",