From b8a5593858bb3d7100b3d94483299bff54e6efbe Mon Sep 17 00:00:00 2001 From: Rom Lemarchand Date: Thu, 7 Apr 2016 07:19:34 -0700 Subject: [PATCH 01/43] android: base-cfg: enable CONFIG_QUOTA Bug: 28032718 Change-Id: I7cb6b641f72085e69b90dca11d2ea68adcd02390 (cherry picked from commit e1b53a388e9cfcf870520a6899a37456cf1ae2c6) --- android/configs/android-base.cfg | 1 + 1 file changed, 1 insertion(+) diff --git a/android/configs/android-base.cfg b/android/configs/android-base.cfg index fa53af0c37ad..3f82e9339dad 100644 --- a/android/configs/android-base.cfg +++ b/android/configs/android-base.cfg @@ -138,6 +138,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 From c2e10e5cb24622a42dba65c52e1a4793c9287966 Mon Sep 17 00:00:00 2001 From: Jeff Vander Stoep Date: Tue, 5 Apr 2016 13:06:27 -0700 Subject: [PATCH 02/43] BACKPORT: selinux: restrict kernel module loading Backport notes: Backport uses kernel_module_from_file not kernel_read_file hook. kernel_read_file replaced kernel_module_from_file in the 4.6 kernel. There are no inode_security_() helper functions (also introduced in 4.6) so the inode lookup is done using the file_inode() helper which is standard for kernel version < 4.6. (Cherry picked from commit 61d612ea731e57dc510472fb746b55cdc017f371) Utilize existing kernel_read_file hook on kernel module load. Add module_load permission to the system class. Enforces restrictions on kernel module origin when calling the finit_module syscall. The hook checks that source type has permission module_load for the target type. Example for finit_module: allow foo bar_file:system module_load; Similarly restrictions are enforced on kernel module loading when calling the init_module syscall. The hook checks that source type has permission module_load with itself as the target object because the kernel module is sourced from the calling process. Example for init_module: allow foo foo:system module_load; Bug: 27824855 Change-Id: I64bf3bd1ab2dc735321160642dc6bbfa996f8068 Signed-off-by: Jeff Vander Stoep Signed-off-by: Paul Moore --- security/selinux/hooks.c | 33 +++++++++++++++++++++++++++++ security/selinux/include/classmap.h | 2 +- 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 7c22a15c7e4b..78d06ff4eeb7 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -3660,6 +3660,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 +5982,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", From 56fc8bbed1d9d612b146b81a18582ad09c3b1cab Mon Sep 17 00:00:00 2001 From: Amit Pundir Date: Tue, 12 Apr 2016 01:19:24 +0530 Subject: [PATCH 03/43] ANDROID: base-cfg: enable CONFIG_IP_NF_NAT IP_NF_TARGET_{MASQUERADE,NETMAP,REDIRECT} configs, already enabled in android-base.cfg for tethering, are of no use if CONFIG_IP_NF_NAT is not enabled. Don't rely on platform config for that and enable CONFIG_IP_NF_NAT in android-base.cfg as well. Change-Id: Ic72bcebbd925b142b09539466bf963188c83108a Signed-off-by: Amit Pundir --- android/configs/android-base.cfg | 1 + 1 file changed, 1 insertion(+) diff --git a/android/configs/android-base.cfg b/android/configs/android-base.cfg index 3f82e9339dad..a8b529cae6eb 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 From d18fffdddbf0a395440cd8e8e2578d322c8f0dbd Mon Sep 17 00:00:00 2001 From: Dmitry Shmidt Date: Tue, 19 Apr 2016 12:37:31 -0700 Subject: [PATCH 04/43] Revert "drivers: switch: remove S_IWUSR from dev_attr" This reverts commit dc66dee02dcd6ea774e3ed4ae32e88b0f3b4bee7. --- drivers/switch/switch_class.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/switch/switch_class.c b/drivers/switch/switch_class.c index e373b625806e..e05fc2591147 100644 --- a/drivers/switch/switch_class.c +++ b/drivers/switch/switch_class.c @@ -54,8 +54,8 @@ static ssize_t name_show(struct device *dev, struct device_attribute *attr, 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); +static DEVICE_ATTR(state, S_IRUGO | S_IWUSR, state_show, NULL); +static DEVICE_ATTR(name, S_IRUGO | S_IWUSR, name_show, NULL); void switch_set_state(struct switch_dev *sdev, int state) { From c631c9800f20373ddafff77ce19844e78d2d2d9d Mon Sep 17 00:00:00 2001 From: Dmitry Shmidt Date: Tue, 19 Apr 2016 12:37:47 -0700 Subject: [PATCH 05/43] Revert "switch: switch class and GPIO drivers." Drivers should use extcon moving forward. Documentation/extcon/porting-android-switch-class describes how to port existing switch class drivers to extcon. This reverts commit e4b8e66e0ae2e78e913d7b86f2507fdb0aa731b4. Change-Id: I5b622c7ab4c0cb9670f8903f259a99888f503c1a --- drivers/Kconfig | 2 - drivers/Makefile | 1 - drivers/switch/Kconfig | 15 --- drivers/switch/Makefile | 4 - drivers/switch/switch_class.c | 174 ---------------------------------- drivers/switch/switch_gpio.c | 172 --------------------------------- include/linux/switch.h | 53 ----------- 7 files changed, 421 deletions(-) delete mode 100644 drivers/switch/Kconfig delete mode 100644 drivers/switch/Makefile delete mode 100644 drivers/switch/switch_class.c delete mode 100644 drivers/switch/switch_gpio.c delete mode 100644 include/linux/switch.h 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/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 e05fc2591147..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 - * - * 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 -#include -#include -#include -#include -#include -#include - -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 | S_IWUSR, state_show, NULL); -static DEVICE_ATTR(name, S_IRUGO | S_IWUSR, 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 "); -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 - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include - -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 "); -MODULE_DESCRIPTION("GPIO Switch driver"); -MODULE_LICENSE("GPL"); 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 - * - * 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__ */ From e193d9de7c58bd7a1fdc102fe06b0e5c802ac57b Mon Sep 17 00:00:00 2001 From: Dmitry Shmidt Date: Tue, 19 Apr 2016 12:44:42 -0700 Subject: [PATCH 06/43] android: base-cfg: remove CONFIG_SWITCH Change-Id: I3fd1aa7a54fe3a8d3ad5537cbc61386e52f41ea0 Signed-off-by: Dmitry Shmidt --- android/configs/android-base.cfg | 1 - 1 file changed, 1 deletion(-) diff --git a/android/configs/android-base.cfg b/android/configs/android-base.cfg index a8b529cae6eb..304f1d4fd7c4 100644 --- a/android/configs/android-base.cfg +++ b/android/configs/android-base.cfg @@ -148,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 From 7f3c0b7b8a48d16707bc9d332b2dda175312ce50 Mon Sep 17 00:00:00 2001 From: Dmitry Shmidt Date: Thu, 21 Apr 2016 15:43:29 -0700 Subject: [PATCH 07/43] Revert "tcp: Fix IPV6 module build errors" This reverts commit 3823c8136f2170b3ac5e6a5f8b857746a786e845. --- net/ipv4/tcp.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 7c0465202cc5..e23f2c529eca 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -3264,7 +3264,7 @@ static int tcp_is_local(struct net *net, __be32 addr) { return rt->dst.dev && (rt->dst.dev->flags & IFF_LOOPBACK); } -#if defined(CONFIG_IPV6) +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 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); @@ -3332,7 +3332,7 @@ int tcp_nuke_addr(struct net *net, struct sockaddr *addr) continue; } -#if defined(CONFIG_IPV6) +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) if (family == AF_INET6) { struct in6_addr *s6; if (!inet->pinet6) @@ -3369,4 +3369,3 @@ int tcp_nuke_addr(struct net *net, struct sockaddr *addr) return 0; } -EXPORT_SYMBOL_GPL(tcp_nuke_addr); From 99bbdddee077677da9acc8dd340ab206781f8614 Mon Sep 17 00:00:00 2001 From: Dmitry Shmidt Date: Thu, 21 Apr 2016 15:43:58 -0700 Subject: [PATCH 08/43] Revert "Don't kill IPv4 sockets when killing IPv6 sockets was requested." This reverts commit 8bf4413b4f54e24120b90ecbfee426beeddc3ff0. --- net/ipv4/tcp.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index e23f2c529eca..edd1312ba73d 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -3335,8 +3335,6 @@ int tcp_nuke_addr(struct net *net, struct sockaddr *addr) #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 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) From cf84d75f72ae87d15b959967c9a0e1b74f686a6f Mon Sep 17 00:00:00 2001 From: Dmitry Shmidt Date: Thu, 21 Apr 2016 15:44:11 -0700 Subject: [PATCH 09/43] Revert "net: fix crash in tcp_nuke_addr()" This reverts commit 08f7c4280cd5efe9e274240c42177f459431bac2. --- net/ipv4/tcp.c | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index edd1312ba73d..6c8a77eb6e57 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -3305,19 +3305,8 @@ int tcp_nuke_addr(struct net *net, struct sockaddr *addr) 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; From d8c5b6f8507d171050d318f3126cf2c43cee1dd5 Mon Sep 17 00:00:00 2001 From: Dmitry Shmidt Date: Thu, 21 Apr 2016 15:44:25 -0700 Subject: [PATCH 10/43] Revert "net: fix iterating over hashtable in tcp_nuke_addr()" This reverts commit 4747299b2c8e8778927b3df0501023d76fe4f2d5. --- net/ipv4/tcp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 6c8a77eb6e57..0d01284271b4 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -3295,7 +3295,7 @@ int tcp_nuke_addr(struct net *net, struct sockaddr *addr) return -EAFNOSUPPORT; } - for (bucket = 0; bucket <= tcp_hashinfo.ehash_mask; bucket++) { + 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); From 3094efd84ca7c548cdba67fa6d995c3bc52238e7 Mon Sep 17 00:00:00 2001 From: Dmitry Shmidt Date: Thu, 21 Apr 2016 15:47:01 -0700 Subject: [PATCH 11/43] Revert "net: socket ioctl to reset connections matching local address" Use SOCK_DESTROY from now instead of SIOCKILLADDR This reverts commit 38f0ec724f5306c81130ca9343c856aa37a76d54. Change-Id: I2dcd833b66c88a48de8978dce9d72ab78f9af549 --- include/net/tcp.h | 2 - include/uapi/linux/sockios.h | 1 - net/ipv4/af_inet.c | 1 - net/ipv4/devinet.c | 8 +-- net/ipv4/tcp.c | 105 ----------------------------------- net/ipv6/af_inet6.c | 17 ------ 6 files changed, 1 insertion(+), 133 deletions(-) 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/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/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 #include -#include #include #include #include @@ -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 0d01284271b4..cf2e13db0619 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -276,9 +276,6 @@ #include #include #include -#include -#include -#include #include #include @@ -3254,105 +3251,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) || defined(CONFIG_IPV6_MODULE) -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 (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) || defined(CONFIG_IPV6_MODULE) - if (family == AF_INET6) { - struct in6_addr *s6; - - 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; -} 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; From 985a3401366362eb0a76b2818e5df205c16da2ee Mon Sep 17 00:00:00 2001 From: Amit Pundir Date: Mon, 25 Apr 2016 16:58:20 +0530 Subject: [PATCH 12/43] Revert "misc: uid_stat: Include linux/atomic.h instead of asm/atomic.h" This reverts commit 8d3a6c1538fb021448c4f6381f6191061f947ba1. This series of patches revert AOSP UID_STAT and NET_ACTIVITY_STATS drivers. I could not find any meaningful usage of these interfaces in AOSP master. UID_STAT driver expose "/proc/uid_stat/*" interfaces but it is only used in AOSP master as in what appears be an out of date bandwidth test in frameworks/base and in somewhat recent battery utils test in external/chromium-trace project. NET_ACTIVITY_STATS driver expose "/proc/net/stat/activity" interface but I can not track its usage anywhere in AOSP at all. Signed-off-by: Amit Pundir --- drivers/misc/uid_stat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/misc/uid_stat.c b/drivers/misc/uid_stat.c index 185c69c9738a..8b8c9a22360b 100644 --- a/drivers/misc/uid_stat.c +++ b/drivers/misc/uid_stat.c @@ -13,7 +13,7 @@ * */ -#include +#include #include #include From 5cbf5fb1475adfe150d662f203a5e7d06aaaae63 Mon Sep 17 00:00:00 2001 From: Amit Pundir Date: Mon, 25 Apr 2016 17:00:08 +0530 Subject: [PATCH 13/43] Revert "misc seq_printf fixes for 4.4" This reverts commit 5c7566a29bff14166d952f2ea525d5231546f821. This patch revert some changes in net/netfilter/xt_qtaguid.c as well. I'll submit another patch to restore those changes. Signed-off-by: Amit Pundir --- drivers/misc/uid_stat.c | 3 +-- net/activity_stats.c | 7 ++++--- net/netfilter/xt_qtaguid.c | 5 +++-- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/misc/uid_stat.c b/drivers/misc/uid_stat.c index 8b8c9a22360b..4766c1f83b94 100644 --- a/drivers/misc/uid_stat.c +++ b/drivers/misc/uid_stat.c @@ -55,8 +55,7 @@ static int uid_stat_atomic_int_show(struct seq_file *m, void *v) 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; + return seq_printf(m, "%u\n", bytes); } static int uid_stat_read_atomic_int_open(struct inode *inode, struct file *file) diff --git a/net/activity_stats.c b/net/activity_stats.c index 3bf92d80b8b9..4609ce2043eb 100644 --- a/net/activity_stats.c +++ b/net/activity_stats.c @@ -63,13 +63,14 @@ void activity_stats_update(void) static int activity_stats_show(struct seq_file *m, void *v) { int i; + int ret; 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; + ret = seq_printf(m, "%15d %lu\n", 1 << i, activity_stats[i]); + if (ret) + return ret; } return 0; diff --git a/net/netfilter/xt_qtaguid.c b/net/netfilter/xt_qtaguid.c index e1442bfb668d..04bb081adde8 100644 --- a/net/netfilter/xt_qtaguid.c +++ b/net/netfilter/xt_qtaguid.c @@ -2543,6 +2543,7 @@ static void pp_stats_header(struct seq_file *m) static int pp_stats_line(struct seq_file *m, struct tag_stat *ts_entry, int cnt_set) { + int ret; struct data_counters *cnts; tag_t tag = ts_entry->tn.tag; uid_t stat_uid = get_uid_from_tag(tag); @@ -2561,7 +2562,7 @@ static int pp_stats_line(struct seq_file *m, struct tag_stat *ts_entry, } ppi->item_index++; cnts = &ts_entry->counters; - seq_printf(m, "%d %s 0x%llx %u %u " + ret = seq_printf(m, "%d %s 0x%llx %u %u " "%llu %llu " "%llu %llu " "%llu %llu " @@ -2591,7 +2592,7 @@ static int pp_stats_line(struct seq_file *m, struct tag_stat *ts_entry, cnts->bpc[cnt_set][IFS_TX][IFS_UDP].packets, cnts->bpc[cnt_set][IFS_TX][IFS_PROTO_OTHER].bytes, cnts->bpc[cnt_set][IFS_TX][IFS_PROTO_OTHER].packets); - return seq_has_overflowed(m) ? -ENOSPC : 1; + return ret ?: 1; } static bool pp_sets(struct seq_file *m, struct tag_stat *ts_entry) From d9e6431c6c494ffb4b61c1a9f447f952127d02fd Mon Sep 17 00:00:00 2001 From: Amit Pundir Date: Mon, 25 Apr 2016 17:00:31 +0530 Subject: [PATCH 14/43] Revert "misc: uidstat: Remove use of obsolete create_proc_read_entry api" This reverts commit fccab646d33381af63e4f4c0d4f309a1d2b4b0c3. Signed-off-by: Amit Pundir --- drivers/misc/uid_stat.c | 50 ++++++++++++++++++++++++++--------------- 1 file changed, 32 insertions(+), 18 deletions(-) diff --git a/drivers/misc/uid_stat.c b/drivers/misc/uid_stat.c index 4766c1f83b94..509822c81e97 100644 --- a/drivers/misc/uid_stat.c +++ b/drivers/misc/uid_stat.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include #include @@ -49,26 +48,41 @@ static struct uid_stat *find_uid_stat(uid_t uid) { return NULL; } -static int uid_stat_atomic_int_show(struct seq_file *m, void *v) +static int tcp_snd_read_proc(char *page, char **start, off_t off, + int count, int *eof, void *data) { + int len; unsigned int bytes; - atomic_t *counter = m->private; + char *p = page; + struct uid_stat *uid_entry = (struct uid_stat *) data; + if (!data) + return 0; - bytes = (unsigned int) (atomic_read(counter) + INT_MIN); - return seq_printf(m, "%u\n", bytes); + bytes = (unsigned int) (atomic_read(&uid_entry->tcp_snd) + INT_MIN); + p += sprintf(p, "%u\n", bytes); + len = (p - page) - off; + *eof = (len <= count) ? 1 : 0; + *start = page + off; + return len; } -static int uid_stat_read_atomic_int_open(struct inode *inode, struct file *file) +static int tcp_rcv_read_proc(char *page, char **start, off_t off, + int count, int *eof, void *data) { - return single_open(file, uid_stat_atomic_int_show, PDE_DATA(inode)); -} + int len; + unsigned int bytes; + char *p = page; + struct uid_stat *uid_entry = (struct uid_stat *) data; + if (!data) + return 0; -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, -}; + bytes = (unsigned int) (atomic_read(&uid_entry->tcp_rcv) + INT_MIN); + p += sprintf(p, "%u\n", bytes); + len = (p - page) - off; + *eof = (len <= count) ? 1 : 0; + *start = page + off; + return len; +} /* Create a new entry for tracking the specified uid. */ static struct uid_stat *create_stat(uid_t uid) { @@ -95,11 +109,11 @@ static void create_stat_proc(struct uid_stat *new_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); + create_proc_read_entry("tcp_snd", S_IRUGO, entry , tcp_snd_read_proc, + (void *) new_uid); - proc_create_data("tcp_rcv", S_IRUGO, entry, - &uid_stat_read_atomic_int_fops, &new_uid->tcp_rcv); + create_proc_read_entry("tcp_rcv", S_IRUGO, entry, tcp_rcv_read_proc, + (void *) new_uid); } static struct uid_stat *find_or_create_uid_stat(uid_t uid) From e9edcb004651ba55399b3c019b9f08aecb476e0d Mon Sep 17 00:00:00 2001 From: Amit Pundir Date: Mon, 25 Apr 2016 17:00:43 +0530 Subject: [PATCH 15/43] Revert "misc: uidstat: avoid create_stat() race and blockage." This reverts commit f7a812174033fe620509e6e8ca7022abd924b1c4. Signed-off-by: Amit Pundir --- drivers/misc/uid_stat.c | 52 +++++++++++++++++------------------------ 1 file changed, 21 insertions(+), 31 deletions(-) diff --git a/drivers/misc/uid_stat.c b/drivers/misc/uid_stat.c index 509822c81e97..2141124a6c12 100644 --- a/drivers/misc/uid_stat.c +++ b/drivers/misc/uid_stat.c @@ -38,13 +38,17 @@ struct uid_stat { }; static struct uid_stat *find_uid_stat(uid_t uid) { + unsigned long flags; struct uid_stat *entry; + spin_lock_irqsave(&uid_lock, flags); list_for_each_entry(entry, &uid_list, link) { if (entry->uid == uid) { + spin_unlock_irqrestore(&uid_lock, flags); return entry; } } + spin_unlock_irqrestore(&uid_lock, flags); return NULL; } @@ -86,10 +90,13 @@ static int tcp_rcv_read_proc(char *page, char **start, off_t off, /* Create a new entry for tracking the specified uid. */ static struct uid_stat *create_stat(uid_t uid) { + unsigned long flags; + char uid_s[32]; struct uid_stat *new_uid; + struct proc_dir_entry *entry; + /* Create the uid stat struct and append it to the list. */ - new_uid = kmalloc(sizeof(struct uid_stat), GFP_ATOMIC); - if (!new_uid) + if ((new_uid = kmalloc(sizeof(struct uid_stat), GFP_KERNEL)) == NULL) return NULL; new_uid->uid = uid; @@ -97,15 +104,11 @@ static struct uid_stat *create_stat(uid_t uid) { atomic_set(&new_uid->tcp_rcv, INT_MIN); atomic_set(&new_uid->tcp_snd, INT_MIN); + spin_lock_irqsave(&uid_lock, flags); list_add_tail(&new_uid->link, &uid_list); - return new_uid; -} + spin_unlock_irqrestore(&uid_lock, flags); -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); + sprintf(uid_s, "%d", uid); entry = proc_mkdir(uid_s, parent); /* Keep reference to uid_stat so we know what uid to read stats from. */ @@ -114,31 +117,17 @@ static void create_stat_proc(struct uid_stat *new_uid) create_proc_read_entry("tcp_rcv", S_IRUGO, entry, tcp_rcv_read_proc, (void *) new_uid); -} -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; + return new_uid; } 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; + if ((entry = find_uid_stat(uid)) == NULL && + ((entry = create_stat(uid)) == NULL)) { + return -1; + } atomic_add(size, &entry->tcp_snd); return 0; } @@ -146,9 +135,10 @@ int uid_stat_tcp_snd(uid_t uid, int size) { 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; + if ((entry = find_uid_stat(uid)) == NULL && + ((entry = create_stat(uid)) == NULL)) { + return -1; + } atomic_add(size, &entry->tcp_rcv); return 0; } From 87b4d82801832426d42df4982e7af11473c5e1f2 Mon Sep 17 00:00:00 2001 From: Amit Pundir Date: Mon, 25 Apr 2016 17:00:57 +0530 Subject: [PATCH 16/43] Revert "net: activity_stats: Stop using obsolete create_proc_read_entry api" This reverts commit 7c121720fa14889d59e933aad0a8b9ce948a39ae. Signed-off-by: Amit Pundir --- net/activity_stats.c | 40 ++++++++++++++++++---------------------- 1 file changed, 18 insertions(+), 22 deletions(-) diff --git a/net/activity_stats.c b/net/activity_stats.c index 4609ce2043eb..8a3e93470069 100644 --- a/net/activity_stats.c +++ b/net/activity_stats.c @@ -15,7 +15,6 @@ */ #include -#include #include #include @@ -60,20 +59,29 @@ void activity_stats_update(void) spin_unlock_irqrestore(&activity_lock, flags); } -static int activity_stats_show(struct seq_file *m, void *v) +static int activity_stats_read_proc(char *page, char **start, off_t off, + int count, int *eof, void *data) { int i; - int ret; + int len; + char *p = page; - seq_printf(m, "Min Bucket(sec) Count\n"); + /* Only print if offset is 0, or we have enough buffer space */ + if (off || count < (30 * BUCKET_MAX + 22)) + return -ENOMEM; + + len = snprintf(p, count, "Min Bucket(sec) Count\n"); + count -= len; + p += len; for (i = 0; i < BUCKET_MAX; i++) { - ret = seq_printf(m, "%15d %lu\n", 1 << i, activity_stats[i]); - if (ret) - return ret; + len = snprintf(p, count, "%15d %lu\n", 1 << i, activity_stats[i]); + count -= len; + p += len; } + *eof = 1; - return 0; + return p - page; } static int activity_stats_notifier(struct notifier_block *nb, @@ -92,26 +100,14 @@ static int activity_stats_notifier(struct notifier_block *nb, 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); + create_proc_read_entry("activity", S_IRUGO, + init_net.proc_net_stat, activity_stats_read_proc, NULL); return register_pm_notifier(&activity_stats_notifier_block); } From 358ebabf995e4a9bddfcd8eb6d888f1ba2b1c227 Mon Sep 17 00:00:00 2001 From: Amit Pundir Date: Mon, 25 Apr 2016 17:01:08 +0530 Subject: [PATCH 17/43] Revert "net: activity_stats: Add statistics for network transmission activity" This reverts commit afedd7beba14385fd797166751fde39e0f52cf72. Signed-off-by: Amit Pundir --- drivers/misc/uid_stat.c | 3 - include/net/activity_stats.h | 25 -------- net/Kconfig | 8 --- net/Makefile | 1 - net/activity_stats.c | 115 ----------------------------------- 5 files changed, 152 deletions(-) delete mode 100644 include/net/activity_stats.h delete mode 100644 net/activity_stats.c diff --git a/drivers/misc/uid_stat.c b/drivers/misc/uid_stat.c index 2141124a6c12..e6760b56083c 100644 --- a/drivers/misc/uid_stat.c +++ b/drivers/misc/uid_stat.c @@ -24,7 +24,6 @@ #include #include #include -#include static DEFINE_SPINLOCK(uid_lock); static LIST_HEAD(uid_list); @@ -123,7 +122,6 @@ static struct uid_stat *create_stat(uid_t uid) { int uid_stat_tcp_snd(uid_t uid, int size) { struct uid_stat *entry; - activity_stats_update(); if ((entry = find_uid_stat(uid)) == NULL && ((entry = create_stat(uid)) == NULL)) { return -1; @@ -134,7 +132,6 @@ int uid_stat_tcp_snd(uid_t uid, int size) { int uid_stat_tcp_rcv(uid_t uid, int size) { struct uid_stat *entry; - activity_stats_update(); if ((entry = find_uid_stat(uid)) == NULL && ((entry = create_stat(uid)) == NULL)) { return -1; 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/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 8a3e93470069..000000000000 --- a/net/activity_stats.c +++ /dev/null @@ -1,115 +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 -#include -#include - -/* - * 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_read_proc(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - int i; - int len; - char *p = page; - - /* Only print if offset is 0, or we have enough buffer space */ - if (off || count < (30 * BUCKET_MAX + 22)) - return -ENOMEM; - - len = snprintf(p, count, "Min Bucket(sec) Count\n"); - count -= len; - p += len; - - for (i = 0; i < BUCKET_MAX; i++) { - len = snprintf(p, count, "%15d %lu\n", 1 << i, activity_stats[i]); - count -= len; - p += len; - } - *eof = 1; - - return p - page; -} - -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 struct notifier_block activity_stats_notifier_block = { - .notifier_call = activity_stats_notifier, -}; - -static int __init activity_stats_init(void) -{ - create_proc_read_entry("activity", S_IRUGO, - init_net.proc_net_stat, activity_stats_read_proc, NULL); - return register_pm_notifier(&activity_stats_notifier_block); -} - -subsys_initcall(activity_stats_init); - From 58025a0a1b0a001af20ea3f601fb9978e9a4e57e Mon Sep 17 00:00:00 2001 From: Amit Pundir Date: Mon, 25 Apr 2016 17:08:15 +0530 Subject: [PATCH 18/43] Revert "misc: uidstat: Adding uid stat driver to collect network statistics." This reverts commit 6b6d5fbf9ae567aefb58099a30bbb6d25fa8925b. Signed-off-by: Amit Pundir --- drivers/misc/Kconfig | 4 - drivers/misc/Makefile | 1 - drivers/misc/uid_stat.c | 153 --------------------------------------- include/linux/uid_stat.h | 29 -------- net/ipv4/tcp.c | 14 ---- 5 files changed, 201 deletions(-) delete mode 100644 drivers/misc/uid_stat.c delete mode 100644 include/linux/uid_stat.h 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 e6760b56083c..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 - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -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) { - unsigned long flags; - struct uid_stat *entry; - - spin_lock_irqsave(&uid_lock, flags); - list_for_each_entry(entry, &uid_list, link) { - if (entry->uid == uid) { - spin_unlock_irqrestore(&uid_lock, flags); - return entry; - } - } - spin_unlock_irqrestore(&uid_lock, flags); - return NULL; -} - -static int tcp_snd_read_proc(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - int len; - unsigned int bytes; - char *p = page; - struct uid_stat *uid_entry = (struct uid_stat *) data; - if (!data) - return 0; - - bytes = (unsigned int) (atomic_read(&uid_entry->tcp_snd) + INT_MIN); - p += sprintf(p, "%u\n", bytes); - len = (p - page) - off; - *eof = (len <= count) ? 1 : 0; - *start = page + off; - return len; -} - -static int tcp_rcv_read_proc(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - int len; - unsigned int bytes; - char *p = page; - struct uid_stat *uid_entry = (struct uid_stat *) data; - if (!data) - return 0; - - bytes = (unsigned int) (atomic_read(&uid_entry->tcp_rcv) + INT_MIN); - p += sprintf(p, "%u\n", bytes); - len = (p - page) - off; - *eof = (len <= count) ? 1 : 0; - *start = page + off; - return len; -} - -/* Create a new entry for tracking the specified uid. */ -static struct uid_stat *create_stat(uid_t uid) { - unsigned long flags; - char uid_s[32]; - struct uid_stat *new_uid; - struct proc_dir_entry *entry; - - /* Create the uid stat struct and append it to the list. */ - if ((new_uid = kmalloc(sizeof(struct uid_stat), GFP_KERNEL)) == NULL) - 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); - - spin_lock_irqsave(&uid_lock, flags); - list_add_tail(&new_uid->link, &uid_list); - spin_unlock_irqrestore(&uid_lock, flags); - - sprintf(uid_s, "%d", uid); - entry = proc_mkdir(uid_s, parent); - - /* Keep reference to uid_stat so we know what uid to read stats from. */ - create_proc_read_entry("tcp_snd", S_IRUGO, entry , tcp_snd_read_proc, - (void *) new_uid); - - create_proc_read_entry("tcp_rcv", S_IRUGO, entry, tcp_rcv_read_proc, - (void *) new_uid); - - return new_uid; -} - -int uid_stat_tcp_snd(uid_t uid, int size) { - struct uid_stat *entry; - if ((entry = find_uid_stat(uid)) == NULL && - ((entry = create_stat(uid)) == NULL)) { - return -1; - } - atomic_add(size, &entry->tcp_snd); - return 0; -} - -int uid_stat_tcp_rcv(uid_t uid, int size) { - struct uid_stat *entry; - if ((entry = find_uid_stat(uid)) == NULL && - ((entry = create_stat(uid)) == NULL)) { - 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/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/net/ipv4/tcp.c b/net/ipv4/tcp.c index cf2e13db0619..6ecfc9de599c 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -269,7 +269,6 @@ #include #include #include -#include #include #include @@ -1285,10 +1284,6 @@ int tcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t size) 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: @@ -1563,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; } @@ -1898,10 +1891,6 @@ int tcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int nonblock, 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: @@ -1910,9 +1899,6 @@ int tcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int nonblock, 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: From 6fb5902fa958c09ad440cadcdaa4915c650c3803 Mon Sep 17 00:00:00 2001 From: Amit Pundir Date: Thu, 1 Oct 2015 10:44:36 +0530 Subject: [PATCH 19/43] netfilter: xt_qtaguid: seq_printf fixes Update seq_printf() usage in xt_qtaguid to align with changes from mainline commit 6798a8caaf64 "fs/seq_file: convert int seq_vprint/seq_printf/etc... returns to void". Signed-off-by: Amit Pundir --- net/netfilter/xt_qtaguid.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/net/netfilter/xt_qtaguid.c b/net/netfilter/xt_qtaguid.c index 04bb081adde8..e1442bfb668d 100644 --- a/net/netfilter/xt_qtaguid.c +++ b/net/netfilter/xt_qtaguid.c @@ -2543,7 +2543,6 @@ static void pp_stats_header(struct seq_file *m) static int pp_stats_line(struct seq_file *m, struct tag_stat *ts_entry, int cnt_set) { - int ret; struct data_counters *cnts; tag_t tag = ts_entry->tn.tag; uid_t stat_uid = get_uid_from_tag(tag); @@ -2562,7 +2561,7 @@ static int pp_stats_line(struct seq_file *m, struct tag_stat *ts_entry, } ppi->item_index++; cnts = &ts_entry->counters; - ret = seq_printf(m, "%d %s 0x%llx %u %u " + seq_printf(m, "%d %s 0x%llx %u %u " "%llu %llu " "%llu %llu " "%llu %llu " @@ -2592,7 +2591,7 @@ static int pp_stats_line(struct seq_file *m, struct tag_stat *ts_entry, cnts->bpc[cnt_set][IFS_TX][IFS_UDP].packets, cnts->bpc[cnt_set][IFS_TX][IFS_PROTO_OTHER].bytes, cnts->bpc[cnt_set][IFS_TX][IFS_PROTO_OTHER].packets); - return ret ?: 1; + return seq_has_overflowed(m) ? -ENOSPC : 1; } static bool pp_sets(struct seq_file *m, struct tag_stat *ts_entry) From aaed164e81bcc055eee6e18a4450310bfa620fba Mon Sep 17 00:00:00 2001 From: Amit Pundir Date: Mon, 25 Apr 2016 23:55:44 +0530 Subject: [PATCH 20/43] android: recommended.cfg: remove CONFIG_UID_STAT Remove UID Stat driver. Change-Id: Ifc9d2c6fe27900f30e6407398f5b24222518bffc Signed-off-by: Amit Pundir --- android/configs/android-recommended.cfg | 1 - 1 file changed, 1 deletion(-) 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 From 6fa18ffc7122663277db9311c4e679f632d2b78d Mon Sep 17 00:00:00 2001 From: Daniel Rosenberg Date: Fri, 22 Apr 2016 00:00:14 -0700 Subject: [PATCH 21/43] vfs: change d_canonical_path to take two paths bug: 23904372 Change-Id: I4a686d64b6de37decf60019be1718e1d820193e6 Signed-off-by: Daniel Rosenberg --- fs/notify/inotify/inotify_user.c | 2 +- fs/sdcardfs/dentry.c | 6 +++++- include/linux/dcache.h | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) 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/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/dcache.h b/include/linux/dcache.h index e4221f7c5b53..bdbb2d490d2d 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; From 28813390bf99b818801105328fbc2da466a9974d Mon Sep 17 00:00:00 2001 From: Daniel Rosenberg Date: Fri, 22 Apr 2016 00:00:48 -0700 Subject: [PATCH 22/43] fuse: Add support for d_canonical_path Allows FUSE to report to inotify that it is acting as a layered filesystem. The userspace component returns a string representing the location of the underlying file. If the string cannot be resolved into a path, the top level path is returned instead. bug: 23904372 Change-Id: Iabdca0bbedfbff59e9c820c58636a68ef9683d9f Signed-off-by: Daniel Rosenberg --- fs/fuse/dev.c | 5 +++++ fs/fuse/dir.c | 45 +++++++++++++++++++++++++++++++++++++++ fs/fuse/fuse_i.h | 3 +++ include/uapi/linux/fuse.h | 1 + 4 files changed, 54 insertions(+) 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 #include #include +#include #include #include #include @@ -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 @@ static int fuse_dentry_revalidate(struct dentry *entry, unsigned int flags) 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/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, From e7d7e51782dc6837d958d730848f5c5dceaee71d Mon Sep 17 00:00:00 2001 From: Amit Pundir Date: Tue, 26 Apr 2016 15:51:06 +0530 Subject: [PATCH 23/43] Revert "SELinux: build fix for 4.1" This reverts commit 43e1b4f528e1654fadd1097f7cc5c50be6e45b77. This patch is part of code which is already upstreamed in v4.4. Commits 5c73fceb8c70 (SELinux: Enable setting security contexts on rootfs inodes.), 12f348b9dcf6 (SELinux: rename SE_SBLABELSUPP to SBLABEL_MNT), and b43e725d8d38 (SELinux: use a helper function to determine seclabel). for reference. Signed-off-by: Amit Pundir --- security/selinux/hooks.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 78d06ff4eeb7..d4d12949de09 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -469,7 +469,7 @@ static int sb_finish_set_opts(struct super_block *sb) * setting SELinux context on in-core inodes. */ if (strncmp(sb->s_type->name, "rootfs", sizeof("rootfs")) == 0) - sbsec->flags |= SBLABEL_MNT; + sbsec->flags |= SE_SBLABELSUPP; /* Initialize the root inode. */ rc = inode_doinit_with_dentry(root_inode, root); From ab378c0ed26df68765c2930fd9ab3f3935424b53 Mon Sep 17 00:00:00 2001 From: Amit Pundir Date: Tue, 26 Apr 2016 15:51:20 +0530 Subject: [PATCH 24/43] Revert "SELinux: Enable setting security contexts on rootfs inodes." This reverts commit 78d36d2111cd4ca722a602846f7db8f54a0b074c. Drop this duplicate patch. This patch is already upstreamed in v4.4. Commits 5c73fceb8c70 (SELinux: Enable setting security contexts on rootfs inodes.), 12f348b9dcf6 (SELinux: rename SE_SBLABELSUPP to SBLABEL_MNT), and b43e725d8d38 (SELinux: use a helper function to determine seclabel), for reference. Signed-off-by: Amit Pundir --- security/selinux/hooks.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index d4d12949de09..9b0586d0f3c4 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -464,13 +464,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 |= SE_SBLABELSUPP; - /* Initialize the root inode. */ rc = inode_doinit_with_dentry(root_inode, root); From 52a20402ae1d5d81ddccd2be2a9f62283cc256e7 Mon Sep 17 00:00:00 2001 From: Dmitry Shmidt Date: Mon, 25 Apr 2016 14:28:30 -0700 Subject: [PATCH 25/43] Revert "mm: vmscan: Add a debug file for shrinkers" Kernel panic when type "cat /sys/kernel/debug/shrinker" Unable to handle kernel paging request at virtual address 0af37d40 pgd = d4dec000 [0af37d40] *pgd=00000000 Internal error: Oops: 5 [#1] PREEMPT SMP ARM [] (_raw_spin_lock) from [] (list_lru_count_one+0x14/0x28) [] (list_lru_count_one) from [] (super_cache_count+0x40/0xa0) [] (super_cache_count) from [] (debug_shrinker_show+0x50/0x90) [] (debug_shrinker_show) from [] (seq_read+0x1ec/0x48c) [] (seq_read) from [] (__vfs_read+0x20/0xd0) [] (__vfs_read) from [] (vfs_read+0x7c/0x104) [] (vfs_read) from [] (SyS_read+0x44/0x9c) [] (SyS_read) from [] (ret_fast_syscall+0x0/0x3c) Code: e1a04000 e3a00001 ebd66b39 f594f000 (e1943f9f) ---[ end trace 60c74014a63a9688 ]--- Kernel panic - not syncing: Fatal exception shrink_control.nid is used but not initialzed, same for shrink_control.memcg. This reverts commit b0e7a582b2264cdf75874dcd8df915b6b4427755. Change-Id: I108de88fa4baaef99a53c4e4c6a1d8c4b4804157 Reported-by: Xiaowen Liu Signed-off-by: Dmitry Shmidt --- mm/vmscan.c | 43 ------------------------------------------- 1 file changed, 43 deletions(-) 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 #include #include -#include #include #include @@ -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 */ From 202d12a1f733a252ee76f4cc497c9ce86270ebb2 Mon Sep 17 00:00:00 2001 From: John Stultz Date: Fri, 22 Apr 2016 17:12:57 -0700 Subject: [PATCH 26/43] xt_qtaguid: Fix panic caused by synack processing In upstream commit ca6fb06518836ef9b65dc0aac02ff97704d52a05 (tcp: attach SYNACK messages to request sockets instead of listener) http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=ca6fb0651883 The building of synack messages was changed, which made it so the skb->sk points to a casted request_sock. This is problematic, as there is no sk_socket in a request_sock. So when the qtaguid_mt function tries to access the sk->sk_socket, it accesses uninitialized memory. After looking at how other netfilter implementations handle this, I realized there was a skb_to_full_sk() helper added, which the xt_qtaguid code isn't yet using. This patch adds its use, and resovles panics seen when accessing uninitialzed memory when processing synack packets. Reported-by: YongQin Liu Signed-off-by: John Stultz --- net/netfilter/xt_qtaguid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/netfilter/xt_qtaguid.c b/net/netfilter/xt_qtaguid.c index e1442bfb668d..822dc3c3bce1 100644 --- a/net/netfilter/xt_qtaguid.c +++ b/net/netfilter/xt_qtaguid.c @@ -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. From 11f34dc252b9dc8f899b0624ef2f192a9f05d254 Mon Sep 17 00:00:00 2001 From: Amit Pundir Date: Tue, 26 Apr 2016 15:14:35 +0530 Subject: [PATCH 27/43] Revert "HID: steelseries: validate output report details" This reverts commit 90037b2720acffa6da2269a10ecf24ec2dace89b. Remove duplicate code. This patch is already upstreamed in v4.4, commit 41df7f6d4372 (HID: steelseries: validate output report details). Signed-off-by: Amit Pundir --- drivers/hid/hid-steelseries.c | 5 ----- 1 file changed, 5 deletions(-) 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"); From f3126efd240499b6313ad3cd9ed6ed25ee97eb89 Mon Sep 17 00:00:00 2001 From: Amit Pundir Date: Tue, 26 Apr 2016 14:47:53 +0530 Subject: [PATCH 28/43] Revert "hid-multitouch: Filter collections by application usage." This reverts commit 0840b80cb9626906b57df54e7229db60f9aea4f2. This patch is already upstreamed in v4.4, commit 658d4aed59b3 (HID: hid-multitouch: Filter collections by application usage.), and further fixed/cleaned up afterwards in commits c2ef8f21ea8f (HID: multitouch: add support for trackpads), 76f5902aebda (HID: hid-multitouch: Simplify setup and frame synchronization) et al. By having this duplicate patch in AOSP we are doing redundant checks for Touchscreen and Touchpad devices. Signed-off-by: Amit Pundir --- drivers/hid/hid-multitouch.c | 10 ---------- 1 file changed, 10 deletions(-) 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]; From 284430f2784e49c5c6d59f8b58c47220602069f8 Mon Sep 17 00:00:00 2001 From: Yongqin Liu Date: Thu, 28 Apr 2016 13:53:36 +0800 Subject: [PATCH 29/43] quick selinux support for tracefs Here is just the quick fix for tracefs with selinux. just add tracefs to the list of whitelisted filesystem types in selinux_is_sblabel_mnt(), but the right fix would be to generalize this logic as described in the last item on the todo list, https://bitbucket.org/seandroid/wiki/wiki/ToDo Change-Id: I2aa803ccffbcd2802a7287514da7648e6b364157 Signed-off-by: Yongqin Liu --- security/selinux/hooks.c | 1 + 1 file changed, 1 insertion(+) diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 9b0586d0f3c4..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"); } From dab07c53da6e724035684eb63a27d478e49c58c5 Mon Sep 17 00:00:00 2001 From: Amit Pundir Date: Mon, 2 May 2016 15:32:15 +0530 Subject: [PATCH 30/43] Revert "mmc: Add status IRQ and status callback function to mmc platform data" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 91fa97e1e5c001d52f6c993d37be08d1e84f47b7. This patch is no longer valid. There are no users for this status irq and callback in android-4.x. The Qcom platform (mach-msm/qsd8x50, HTC Dream..) and SDCC controller (msm_sdcc) using this status IRQ and callback are dropped from mainline sometime back. 27842bb18b00 (mmc: Remove msm_sdcc driver) c0c89fafa289 (ARM: Remove mach-msm and associated ARM architecture code) Change-Id: Ia38e42a06dc184395f79c1ec1d306bf9775704d5 Signed-off-by: Amit Pundir --- include/linux/amba/mmci.h | 3 --- 1 file changed, 3 deletions(-) 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 From d4c7c8eafe99e465e06b81a9ee0458bff5f65b1d Mon Sep 17 00:00:00 2001 From: Jack Pham Date: Wed, 23 Mar 2016 13:18:03 -0700 Subject: [PATCH 31/43] usb: dual-role: make stub functions inline MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If CONFIG_DUAL_ROLE_USB_INTF is disabled but the exported functions are referenced, the build will result in warnings such as: In file included from include/linux/usb/class-dual-role.h:112:13: warning: ‘dual_role_instance_changed’ defined but not used [-Wunused-function] These stub functions should be static inline. Change-Id: I5a9ef58dca32306fac5a4c7f28cdaa36fa8ae078 Signed-off-by: Jack Pham (cherry picked from commit 2d152dbb0743526b21d6bbefe097f874c027f860) (cherry picked from commit 8ad66cafaa10e6ba94ff79a8dbc2cc437c6bfe93) --- include/linux/usb/class-dual-role.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) 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); } From 761edb8bf7a03a72ae12adbf1ab64bde92f2cb8c Mon Sep 17 00:00:00 2001 From: Amit Pundir Date: Wed, 4 May 2016 11:05:15 +0530 Subject: [PATCH 32/43] Revert "ARM: Add 'card_present' state to mmc_platfrom_data" This reverts commit 541632275e983573b8250fcd4402f772d7bd1e6f. mmc_platform_data (or arch/arm/include/asm/mach/mmc.h in general) has no active user in android-4.x kernels. Also all the necessary bits are already moved to include/linux/amba/mmci.h. 6ef297f86b62 (ARM: 5720/1: Move MMCI header to amba include dir) Change-Id: Iff384eb527327bf88543408e0257241c1fd99a43 Signed-off-by: Amit Pundir --- arch/arm/include/asm/mach/mmc.h | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm/include/asm/mach/mmc.h b/arch/arm/include/asm/mach/mmc.h index bca864ac945f..f8d391ad9203 100644 --- a/arch/arm/include/asm/mach/mmc.h +++ b/arch/arm/include/asm/mach/mmc.h @@ -18,7 +18,6 @@ struct embedded_sdio_data { 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; From 96515037c151b35a09a10544bd82099fcab8af9d Mon Sep 17 00:00:00 2001 From: Amit Pundir Date: Wed, 4 May 2016 11:14:16 +0530 Subject: [PATCH 33/43] Revert "Recreate asm/mach/mmc.h include file" This reverts commit 5b42ae3edab6c39c1337d36881d29350bb36dcff. This recereated arch/arm/include/asm/mach/mmc.h include file has no active user in android-4.x kernels. Also all the necessary bits are already moved to include/linux/amba/mmci.h. 6ef297f86b62 (ARM: 5720/1: Move MMCI header to amba include dir) Change-Id: Ibf258b355d17f54f49b777a8f6e0089e9b59a3a5 Signed-off-by: Amit Pundir --- arch/arm/include/asm/mach/mmc.h | 27 --------------------------- 1 file changed, 27 deletions(-) delete mode 100644 arch/arm/include/asm/mach/mmc.h diff --git a/arch/arm/include/asm/mach/mmc.h b/arch/arm/include/asm/mach/mmc.h deleted file mode 100644 index f8d391ad9203..000000000000 --- a/arch/arm/include/asm/mach/mmc.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * arch/arm/include/asm/mach/mmc.h - */ -#ifndef ASMARM_MACH_MMC_H -#define ASMARM_MACH_MMC_H - -#include -#include -#include - -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 */ - 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 From ad8a69c91954d48d3eaa0784f2f3bc9204dc10b3 Mon Sep 17 00:00:00 2001 From: Dmitry Shmidt Date: Wed, 4 May 2016 13:51:38 -0700 Subject: [PATCH 34/43] fiq_debugger: Add option to apply uart overlay by FIQ_DEBUGGER_UART_OVERLAY fiq_debugger is taking over uart, so it is necessary to disable original uart in DT file. It can be done manually or by overlay. Change-Id: I9f50ec15b0e22e602d73b9f745fc8666f8925d09 Signed-off-by: Dmitry Shmidt --- drivers/staging/android/fiq_debugger/Kconfig | 9 ++++++ .../android/fiq_debugger/fiq_debugger.c | 30 +++++++++++++++++++ 2 files changed, 39 insertions(+) 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..0c558331a3d2 100644 --- a/drivers/staging/android/fiq_debugger/fiq_debugger.c +++ b/drivers/staging/android/fiq_debugger/fiq_debugger.c @@ -39,6 +39,10 @@ #include #endif +#ifdef CONFIG_FIQ_DEBUGGER_UART_OVERLAY +#include +#endif + #include #include "fiq_debugger.h" @@ -1201,10 +1205,36 @@ 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 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); } From e40360e32afc3f3efb62bd249e5f3d36b01e85e3 Mon Sep 17 00:00:00 2001 From: Lianwei Wang Date: Fri, 6 May 2016 00:17:57 -0700 Subject: [PATCH 35/43] Revert "drivers: power: Add watchdog timer to catch drivers which lockup during suspend." This reverts commit ad86cc8ad63229eeeba0628e99f2f59df55a25fd. Commit 70fea60d888d ("PM / Sleep: Detect device suspend/resume lockup...") added a suspend/resume watchdog timer to catch the lockup. Let's revert the duplicate one. Change-Id: Ic72a87432e27844155467817600adc6cf0c2209c Signed-off-by: Lianwei Wang Signed-off-by: Amit Pundir --- drivers/base/power/main.c | 43 --------------------------------------- 1 file changed, 43 deletions(-) diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index 6ed8b9326629..2f7a6e1b568c 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c @@ -62,12 +62,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) @@ -838,30 +832,6 @@ static void async_resume(void *data, async_cookie_t cookie) put_device(dev); } -/** - * 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 +1350,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 +1380,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 +1460,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) From be1bb4a76a5a55d354823fa7c6aeae63ac69e245 Mon Sep 17 00:00:00 2001 From: Jimmy Perchet Date: Mon, 9 May 2016 10:32:04 -0700 Subject: [PATCH 36/43] FROMLIST: wlcore: Disable filtering in AP role When you configure (set it up) a STA interface, the driver install a multicast filter. This is normal behavior, when one application subscribe to multicast address the filter is updated. When Access Point interface is configured, there is no filter installation and the "filter update" path is disabled in the driver. The problem happens when you switch an interface from STA type to AP type. The filter is installed but there are no means to update it. Change-Id: Ied22323af831575303abd548574918baa9852dd0 Signed-off-by: Dmitry Shmidt --- drivers/net/wireless/ti/wlcore/init.c | 5 +++++ 1 file changed, 5 insertions(+) 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; From 1a6976beade0acd4f56514dac72891cb23bafec3 Mon Sep 17 00:00:00 2001 From: Janis Danisevskis Date: Thu, 14 Apr 2016 13:57:03 +0100 Subject: [PATCH 37/43] UPSTREAM: procfs: fixes pthread cross-thread naming if !PR_DUMPABLE The PR_DUMPABLE flag causes the pid related paths of the proc file system to be owned by ROOT. The implementation of pthread_set/getname_np however needs access to /proc//task//comm. If PR_DUMPABLE is false this implementation is locked out. This patch installs a special permission function for the file "comm" that grants read and write access to all threads of the same group regardless of the ownership of the inode. For all other threads the function falls back to the generic inode permission check. Signed-off-by: Janis Danisevskis --- fs/proc/base.c | 42 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) 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 @@ -3078,6 +3078,44 @@ int proc_pid_readdir(struct file *file, struct dir_context *ctx) return 0; } +/* + * proc_tid_comm_permission is a special permission function exclusively + * used for the node /proc//task//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//task//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 */ @@ -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 From f73ca028a0a4cc307597efc6ef2c910dc2d20639 Mon Sep 17 00:00:00 2001 From: Dmitry Shmidt Date: Wed, 11 May 2016 11:01:02 -0700 Subject: [PATCH 38/43] fiq_debugger: Add fiq_debugger.disable option This change allows to use same kernel image with different console options for uart and fiq_debugger. If fiq_debugger.disable will be set to 1/y/Y, fiq_debugger will not be initialized. Change-Id: I71fda54f5f863d13b1437b1f909e52dd375d002d Signed-off-by: Dmitry Shmidt --- drivers/staging/android/fiq_debugger/fiq_debugger.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/staging/android/fiq_debugger/fiq_debugger.c b/drivers/staging/android/fiq_debugger/fiq_debugger.c index 0c558331a3d2..b132cff14f01 100644 --- a/drivers/staging/android/fiq_debugger/fiq_debugger.c +++ b/drivers/staging/android/fiq_debugger/fiq_debugger.c @@ -123,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 @@ -1230,6 +1232,10 @@ int fiq_debugger_uart_overlay(void) 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 From 4158b3431f473aad101da1100a9b241ff8b3cc74 Mon Sep 17 00:00:00 2001 From: John Stultz Date: Thu, 12 May 2016 11:17:52 -0700 Subject: [PATCH 39/43] xt_qtaguid: Fix panic caused by processing non-full socket. In an issue very similar to 4e461c777e3 (xt_qtaguid: Fix panic caused by synack processing), we were seeing panics on occasion in testing. In this case, it was the same issue, but caused by a different call path, as the sk being returned from qtaguid_find_sk() was not a full socket. Resulting in the sk->sk_socket deref to fail. This patch adds an extra check to ensure the sk being retuned is a full socket, and if not it returns NULL. Reported-by: Milosz Wasilewski Signed-off-by: John Stultz --- net/netfilter/xt_qtaguid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/netfilter/xt_qtaguid.c b/net/netfilter/xt_qtaguid.c index 822dc3c3bce1..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; } From b42fb9a7101001d14f996fe2e671f3e7eddded3b Mon Sep 17 00:00:00 2001 From: Amit Pundir Date: Mon, 16 May 2016 13:17:28 +0530 Subject: [PATCH 40/43] Revert "cpufreq: interactive: build fixes for 4.4" This reverts commit bc68f6c4efbd4ddbb15817203f18b7941d9ffd52. This build fix broke the Interactive Gov at runtime with duplicate sysfs entry warnings at boot time. We no longer need to this create/destroy cpufreq sysfs entry at run time on need basis thanks to upstream commit 8eec1020f0c0 (cpufreq: create cpu/cpufreq at boot time) which creates it at boot time. Hence drop this build fix. Signed-off-by: Amit Pundir --- drivers/cpufreq/cpufreq_interactive.c | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/drivers/cpufreq/cpufreq_interactive.c b/drivers/cpufreq/cpufreq_interactive.c index bd83be39f17b..7f846b06e024 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; From de5723c8a64e7f7a69662b75d4a789a6e5307dd4 Mon Sep 17 00:00:00 2001 From: Amit Pundir Date: Mon, 16 May 2016 13:25:35 +0530 Subject: [PATCH 41/43] cpufreq: interactive: drop cpufreq_{get,put}_global_kobject func calls Upstream commit 8eec1020f0c0 (cpufreq: create cpu/cpufreq at boot time) make sure that cpufreq sysfs entry get created at boot time, and there is no need to create/destroy it on need basis anymore. So drop deprecated cpufreq_{get,put}_global_kobject function calls which otherwise result in following compilation errors: drivers/cpufreq/cpufreq_interactive.c: In function 'cpufreq_governor_interactive': drivers/cpufreq/cpufreq_interactive.c:1187:4: error: implicit declaration of function 'cpufreq_get_global_kobject' [-Werror=implicit-function-declaration] WARN_ON(cpufreq_get_global_kobject()); ^ drivers/cpufreq/cpufreq_interactive.c:1197:5: error: implicit declaration of function 'cpufreq_put_global_kobject'[-Werror=implicit-function-declaration] cpufreq_put_global_kobject(); ^ Signed-off-by: Amit Pundir --- drivers/cpufreq/cpufreq_interactive.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/cpufreq/cpufreq_interactive.c b/drivers/cpufreq/cpufreq_interactive.c index 7f846b06e024..f2929e628820 100644 --- a/drivers/cpufreq/cpufreq_interactive.c +++ b/drivers/cpufreq/cpufreq_interactive.c @@ -1184,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), @@ -1194,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; } @@ -1218,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; } From aacf3ae2a6caae8dfc7d4a41a9f537674613831c Mon Sep 17 00:00:00 2001 From: Amit Pundir Date: Tue, 17 May 2016 16:06:17 +0530 Subject: [PATCH 42/43] Revert "drivers: power: use 'current' instead of 'get_current()'" This reverts commit e1b5d103894d097fb630aebc3c1fdaf257f7c9bb. This patch fixed the aosp commit ad86cc8ad632 (drivers: power: Add watchdog timer to catch drivers which lockup during suspend.), which we dropped in Change Id Ic72a87432e27844155467817600adc6cf0c2209c, so we no longer need this fix. A part of this patch is already reverted in above mentioned Change Id. Signed-off-by: Amit Pundir --- drivers/base/power/main.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index 2f7a6e1b568c..5ea529165362 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c @@ -35,8 +35,6 @@ #include #include -#include - #include "../base.h" #include "power.h" From 63a2b92307eb8fff4451ae58ca937dd6aa899469 Mon Sep 17 00:00:00 2001 From: Jeff Mahoney Date: Mon, 4 Apr 2016 14:15:23 -0400 Subject: [PATCH 43/43] =?UTF-8?q?UPSTREAM:=20mac80211:=20fix=20"warning:?= =?UTF-8?q?=20=E2=80=98target=5Fmetric=E2=80=99=20may=20be=20used=20uninit?= =?UTF-8?q?ialized"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (This cherry-picks b4201cc4fc6e1c57d6d306b1f787865043d60129 upstream) This fixes: net/mac80211/mesh_hwmp.c:603:26: warning: ‘target_metric’ may be used uninitialized in this function target_metric is only consumed when reply = true so no bug exists here, but not all versions of gcc realize it. Initialize to 0 to remove the warning. Change-Id: I13923fda9d314f48196c29e4354133dfe01f5abd Signed-off-by: Jeff Mahoney Signed-off-by: Johannes Berg [jstultz: Cherry-picked to android-4.4] Signed-off-by: John Stultz --- net/mac80211/mesh_hwmp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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;