diff options
author | Alex Shi <alex.shi@linaro.org> | 2016-06-02 17:59:02 +0800 |
---|---|---|
committer | Alex Shi <alex.shi@linaro.org> | 2016-06-02 17:59:02 +0800 |
commit | cf5ba83bb248452b5b320d8f2ee48bd90e5cf3f6 (patch) | |
tree | 502638c84cddb697ca38c300b2f8b8d681ad0f29 | |
parent | 58189909e6da3df54f13394e842635c3c4c8d68f (diff) | |
parent | 63a2b92307eb8fff4451ae58ca937dd6aa899469 (diff) |
Merge branch 'lsk-v4.4-android' of git://android.git.linaro.org/kernel/linaro-android into linux-linaro-lsk-v4.4-android
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", |