mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-03 09:41:54 +09:00
Merge tag 'v3.10.45' of git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable into odroidc-3.10.y
This is the 3.10.45 stable release
This commit is contained in:
2
Makefile
2
Makefile
@@ -1,6 +1,6 @@
|
||||
VERSION = 3
|
||||
PATCHLEVEL = 10
|
||||
SUBLEVEL = 44
|
||||
SUBLEVEL = 45
|
||||
EXTRAVERSION =
|
||||
NAME = TOSSUG Baby Fish
|
||||
|
||||
|
||||
@@ -25,24 +25,28 @@
|
||||
|
||||
#include "generic.h"
|
||||
|
||||
#define AT91_RTC_IDR 0x24 /* Interrupt Disable Register */
|
||||
#define AT91_RTC_IMR 0x28 /* Interrupt Mask Register */
|
||||
#define AT91_RTC_IDR 0x24 /* Interrupt Disable Register */
|
||||
#define AT91_RTC_IMR 0x28 /* Interrupt Mask Register */
|
||||
#define AT91_RTC_IRQ_MASK 0x1f /* Available IRQs mask */
|
||||
|
||||
void __init at91_sysirq_mask_rtc(u32 rtc_base)
|
||||
{
|
||||
void __iomem *base;
|
||||
u32 mask;
|
||||
|
||||
base = ioremap(rtc_base, 64);
|
||||
if (!base)
|
||||
return;
|
||||
|
||||
mask = readl_relaxed(base + AT91_RTC_IMR);
|
||||
if (mask) {
|
||||
pr_info("AT91: Disabling rtc irq\n");
|
||||
writel_relaxed(mask, base + AT91_RTC_IDR);
|
||||
(void)readl_relaxed(base + AT91_RTC_IMR); /* flush */
|
||||
}
|
||||
/*
|
||||
* sam9x5 SoCs have the following errata:
|
||||
* "RTC: Interrupt Mask Register cannot be used
|
||||
* Interrupt Mask Register read always returns 0."
|
||||
*
|
||||
* Hence we're not relying on IMR values to disable
|
||||
* interrupts.
|
||||
*/
|
||||
writel_relaxed(AT91_RTC_IRQ_MASK, base + AT91_RTC_IDR);
|
||||
(void)readl_relaxed(base + AT91_RTC_IMR); /* flush */
|
||||
|
||||
iounmap(base);
|
||||
}
|
||||
|
||||
@@ -299,7 +299,7 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, unsigned int id)
|
||||
if (cpu_has_veic || cpu_has_vint) {
|
||||
size = 0x200 + VECTORSPACING * 64;
|
||||
} else {
|
||||
size = 0x200;
|
||||
size = 0x4000;
|
||||
}
|
||||
|
||||
/* Save Linux EBASE */
|
||||
|
||||
@@ -83,9 +83,9 @@ static void bpf_flush_icache(void *start_, void *end_)
|
||||
#define BNE (F2(0, 2) | CONDNE)
|
||||
|
||||
#ifdef CONFIG_SPARC64
|
||||
#define BNE_PTR (F2(0, 1) | CONDNE | (2 << 20))
|
||||
#define BE_PTR (F2(0, 1) | CONDE | (2 << 20))
|
||||
#else
|
||||
#define BNE_PTR BNE
|
||||
#define BE_PTR BE
|
||||
#endif
|
||||
|
||||
#define SETHI(K, REG) \
|
||||
@@ -600,7 +600,7 @@ void bpf_jit_compile(struct sk_filter *fp)
|
||||
case BPF_S_ANC_IFINDEX:
|
||||
emit_skb_loadptr(dev, r_A);
|
||||
emit_cmpi(r_A, 0);
|
||||
emit_branch(BNE_PTR, cleanup_addr + 4);
|
||||
emit_branch(BE_PTR, cleanup_addr + 4);
|
||||
emit_nop();
|
||||
emit_load32(r_A, struct net_device, ifindex, r_A);
|
||||
break;
|
||||
@@ -613,7 +613,7 @@ void bpf_jit_compile(struct sk_filter *fp)
|
||||
case BPF_S_ANC_HATYPE:
|
||||
emit_skb_loadptr(dev, r_A);
|
||||
emit_cmpi(r_A, 0);
|
||||
emit_branch(BNE_PTR, cleanup_addr + 4);
|
||||
emit_branch(BE_PTR, cleanup_addr + 4);
|
||||
emit_nop();
|
||||
emit_load16(r_A, struct net_device, type, r_A);
|
||||
break;
|
||||
|
||||
@@ -370,6 +370,8 @@ static inline void apic_clear_irr(int vec, struct kvm_lapic *apic)
|
||||
|
||||
static inline void apic_set_isr(int vec, struct kvm_lapic *apic)
|
||||
{
|
||||
/* Note that we never get here with APIC virtualization enabled. */
|
||||
|
||||
if (!__apic_test_and_set_vector(vec, apic->regs + APIC_ISR))
|
||||
++apic->isr_count;
|
||||
BUG_ON(apic->isr_count > MAX_APIC_VECTOR);
|
||||
@@ -381,12 +383,48 @@ static inline void apic_set_isr(int vec, struct kvm_lapic *apic)
|
||||
apic->highest_isr_cache = vec;
|
||||
}
|
||||
|
||||
static inline int apic_find_highest_isr(struct kvm_lapic *apic)
|
||||
{
|
||||
int result;
|
||||
|
||||
/*
|
||||
* Note that isr_count is always 1, and highest_isr_cache
|
||||
* is always -1, with APIC virtualization enabled.
|
||||
*/
|
||||
if (!apic->isr_count)
|
||||
return -1;
|
||||
if (likely(apic->highest_isr_cache != -1))
|
||||
return apic->highest_isr_cache;
|
||||
|
||||
result = find_highest_vector(apic->regs + APIC_ISR);
|
||||
ASSERT(result == -1 || result >= 16);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline void apic_clear_isr(int vec, struct kvm_lapic *apic)
|
||||
{
|
||||
if (__apic_test_and_clear_vector(vec, apic->regs + APIC_ISR))
|
||||
struct kvm_vcpu *vcpu;
|
||||
if (!__apic_test_and_clear_vector(vec, apic->regs + APIC_ISR))
|
||||
return;
|
||||
|
||||
vcpu = apic->vcpu;
|
||||
|
||||
/*
|
||||
* We do get here for APIC virtualization enabled if the guest
|
||||
* uses the Hyper-V APIC enlightenment. In this case we may need
|
||||
* to trigger a new interrupt delivery by writing the SVI field;
|
||||
* on the other hand isr_count and highest_isr_cache are unused
|
||||
* and must be left alone.
|
||||
*/
|
||||
if (unlikely(kvm_apic_vid_enabled(vcpu->kvm)))
|
||||
kvm_x86_ops->hwapic_isr_update(vcpu->kvm,
|
||||
apic_find_highest_isr(apic));
|
||||
else {
|
||||
--apic->isr_count;
|
||||
BUG_ON(apic->isr_count < 0);
|
||||
apic->highest_isr_cache = -1;
|
||||
BUG_ON(apic->isr_count < 0);
|
||||
apic->highest_isr_cache = -1;
|
||||
}
|
||||
}
|
||||
|
||||
int kvm_lapic_find_highest_irr(struct kvm_vcpu *vcpu)
|
||||
@@ -466,22 +504,6 @@ static void pv_eoi_clr_pending(struct kvm_vcpu *vcpu)
|
||||
__clear_bit(KVM_APIC_PV_EOI_PENDING, &vcpu->arch.apic_attention);
|
||||
}
|
||||
|
||||
static inline int apic_find_highest_isr(struct kvm_lapic *apic)
|
||||
{
|
||||
int result;
|
||||
|
||||
/* Note that isr_count is always 1 with vid enabled */
|
||||
if (!apic->isr_count)
|
||||
return -1;
|
||||
if (likely(apic->highest_isr_cache != -1))
|
||||
return apic->highest_isr_cache;
|
||||
|
||||
result = find_highest_vector(apic->regs + APIC_ISR);
|
||||
ASSERT(result == -1 || result >= 16);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void kvm_apic_update_tmr(struct kvm_vcpu *vcpu, u32 *tmr)
|
||||
{
|
||||
struct kvm_lapic *apic = vcpu->arch.apic;
|
||||
@@ -1619,6 +1641,8 @@ int kvm_get_apic_interrupt(struct kvm_vcpu *vcpu)
|
||||
int vector = kvm_apic_has_interrupt(vcpu);
|
||||
struct kvm_lapic *apic = vcpu->arch.apic;
|
||||
|
||||
/* Note that we never get here with APIC virtualization enabled. */
|
||||
|
||||
if (vector == -1)
|
||||
return -1;
|
||||
|
||||
|
||||
@@ -466,7 +466,7 @@ static int crypto_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
|
||||
type -= CRYPTO_MSG_BASE;
|
||||
link = &crypto_dispatch[type];
|
||||
|
||||
if (!capable(CAP_NET_ADMIN))
|
||||
if (!netlink_capable(skb, CAP_NET_ADMIN))
|
||||
return -EPERM;
|
||||
|
||||
if ((type == (CRYPTO_MSG_GETALG - CRYPTO_MSG_BASE) &&
|
||||
|
||||
@@ -369,7 +369,7 @@ static void cn_proc_mcast_ctl(struct cn_msg *msg,
|
||||
return;
|
||||
|
||||
/* Can only change if privileged. */
|
||||
if (!capable(CAP_NET_ADMIN)) {
|
||||
if (!__netlink_ns_capable(nsp, &init_user_ns, CAP_NET_ADMIN)) {
|
||||
err = EPERM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/mman.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/init.h>
|
||||
@@ -459,6 +460,11 @@ static bool do_hot_add;
|
||||
*/
|
||||
static uint pressure_report_delay = 45;
|
||||
|
||||
/*
|
||||
* The last time we posted a pressure report to host.
|
||||
*/
|
||||
static unsigned long last_post_time;
|
||||
|
||||
module_param(hot_add, bool, (S_IRUGO | S_IWUSR));
|
||||
MODULE_PARM_DESC(hot_add, "If set attempt memory hot_add");
|
||||
|
||||
@@ -542,6 +548,7 @@ struct hv_dynmem_device {
|
||||
|
||||
static struct hv_dynmem_device dm_device;
|
||||
|
||||
static void post_status(struct hv_dynmem_device *dm);
|
||||
#ifdef CONFIG_MEMORY_HOTPLUG
|
||||
|
||||
static void hv_bring_pgs_online(unsigned long start_pfn, unsigned long size)
|
||||
@@ -612,7 +619,7 @@ static void hv_mem_hot_add(unsigned long start, unsigned long size,
|
||||
* have not been "onlined" within the allowed time.
|
||||
*/
|
||||
wait_for_completion_timeout(&dm_device.ol_waitevent, 5*HZ);
|
||||
|
||||
post_status(&dm_device);
|
||||
}
|
||||
|
||||
return;
|
||||
@@ -951,11 +958,17 @@ static void post_status(struct hv_dynmem_device *dm)
|
||||
{
|
||||
struct dm_status status;
|
||||
struct sysinfo val;
|
||||
unsigned long now = jiffies;
|
||||
unsigned long last_post = last_post_time;
|
||||
|
||||
if (pressure_report_delay > 0) {
|
||||
--pressure_report_delay;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!time_after(now, (last_post_time + HZ)))
|
||||
return;
|
||||
|
||||
si_meminfo(&val);
|
||||
memset(&status, 0, sizeof(struct dm_status));
|
||||
status.hdr.type = DM_STATUS_REPORT;
|
||||
@@ -983,6 +996,14 @@ static void post_status(struct hv_dynmem_device *dm)
|
||||
if (status.hdr.trans_id != atomic_read(&trans_id))
|
||||
return;
|
||||
|
||||
/*
|
||||
* If the last post time that we sampled has changed,
|
||||
* we have raced, don't post the status.
|
||||
*/
|
||||
if (last_post != last_post_time)
|
||||
return;
|
||||
|
||||
last_post_time = jiffies;
|
||||
vmbus_sendpacket(dm->dev->channel, &status,
|
||||
sizeof(struct dm_status),
|
||||
(unsigned long)NULL,
|
||||
@@ -1117,7 +1138,7 @@ static void balloon_up(struct work_struct *dummy)
|
||||
|
||||
if (ret == -EAGAIN)
|
||||
msleep(20);
|
||||
|
||||
post_status(&dm_device);
|
||||
} while (ret == -EAGAIN);
|
||||
|
||||
if (ret) {
|
||||
@@ -1144,8 +1165,10 @@ static void balloon_down(struct hv_dynmem_device *dm,
|
||||
struct dm_unballoon_response resp;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < range_count; i++)
|
||||
for (i = 0; i < range_count; i++) {
|
||||
free_balloon_pages(dm, &range_array[i]);
|
||||
post_status(&dm_device);
|
||||
}
|
||||
|
||||
if (req->more_pages == 1)
|
||||
return;
|
||||
|
||||
@@ -161,12 +161,11 @@ static int at91_adc_channel_init(struct iio_dev *idev)
|
||||
return idev->num_channels;
|
||||
}
|
||||
|
||||
static u8 at91_adc_get_trigger_value_by_name(struct iio_dev *idev,
|
||||
static int at91_adc_get_trigger_value_by_name(struct iio_dev *idev,
|
||||
struct at91_adc_trigger *triggers,
|
||||
const char *trigger_name)
|
||||
{
|
||||
struct at91_adc_state *st = iio_priv(idev);
|
||||
u8 value = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < st->trigger_number; i++) {
|
||||
@@ -179,15 +178,16 @@ static u8 at91_adc_get_trigger_value_by_name(struct iio_dev *idev,
|
||||
return -ENOMEM;
|
||||
|
||||
if (strcmp(trigger_name, name) == 0) {
|
||||
value = triggers[i].value;
|
||||
kfree(name);
|
||||
break;
|
||||
if (triggers[i].value == 0)
|
||||
return -EINVAL;
|
||||
return triggers[i].value;
|
||||
}
|
||||
|
||||
kfree(name);
|
||||
}
|
||||
|
||||
return value;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int at91_adc_configure_trigger(struct iio_trigger *trig, bool state)
|
||||
@@ -197,14 +197,14 @@ static int at91_adc_configure_trigger(struct iio_trigger *trig, bool state)
|
||||
struct iio_buffer *buffer = idev->buffer;
|
||||
struct at91_adc_reg_desc *reg = st->registers;
|
||||
u32 status = at91_adc_readl(st, reg->trigger_register);
|
||||
u8 value;
|
||||
int value;
|
||||
u8 bit;
|
||||
|
||||
value = at91_adc_get_trigger_value_by_name(idev,
|
||||
st->trigger_list,
|
||||
idev->trig->name);
|
||||
if (value == 0)
|
||||
return -EINVAL;
|
||||
if (value < 0)
|
||||
return value;
|
||||
|
||||
if (state) {
|
||||
st->buffer = kmalloc(idev->scan_bytes, GFP_KERNEL);
|
||||
|
||||
@@ -1214,8 +1214,8 @@ static const struct max1363_chip_info max1363_chip_info_tbl[] = {
|
||||
.num_modes = ARRAY_SIZE(max1238_mode_list),
|
||||
.default_mode = s0to11,
|
||||
.info = &max1238_info,
|
||||
.channels = max1238_channels,
|
||||
.num_channels = ARRAY_SIZE(max1238_channels),
|
||||
.channels = max1038_channels,
|
||||
.num_channels = ARRAY_SIZE(max1038_channels),
|
||||
},
|
||||
[max11605] = {
|
||||
.bits = 8,
|
||||
@@ -1224,8 +1224,8 @@ static const struct max1363_chip_info max1363_chip_info_tbl[] = {
|
||||
.num_modes = ARRAY_SIZE(max1238_mode_list),
|
||||
.default_mode = s0to11,
|
||||
.info = &max1238_info,
|
||||
.channels = max1238_channels,
|
||||
.num_channels = ARRAY_SIZE(max1238_channels),
|
||||
.channels = max1038_channels,
|
||||
.num_channels = ARRAY_SIZE(max1038_channels),
|
||||
},
|
||||
[max11606] = {
|
||||
.bits = 10,
|
||||
@@ -1274,8 +1274,8 @@ static const struct max1363_chip_info max1363_chip_info_tbl[] = {
|
||||
.num_modes = ARRAY_SIZE(max1238_mode_list),
|
||||
.default_mode = s0to11,
|
||||
.info = &max1238_info,
|
||||
.channels = max1238_channels,
|
||||
.num_channels = ARRAY_SIZE(max1238_channels),
|
||||
.channels = max1138_channels,
|
||||
.num_channels = ARRAY_SIZE(max1138_channels),
|
||||
},
|
||||
[max11611] = {
|
||||
.bits = 10,
|
||||
@@ -1284,8 +1284,8 @@ static const struct max1363_chip_info max1363_chip_info_tbl[] = {
|
||||
.num_modes = ARRAY_SIZE(max1238_mode_list),
|
||||
.default_mode = s0to11,
|
||||
.info = &max1238_info,
|
||||
.channels = max1238_channels,
|
||||
.num_channels = ARRAY_SIZE(max1238_channels),
|
||||
.channels = max1138_channels,
|
||||
.num_channels = ARRAY_SIZE(max1138_channels),
|
||||
},
|
||||
[max11612] = {
|
||||
.bits = 12,
|
||||
|
||||
@@ -276,8 +276,6 @@ static int ak8975_read_axis(struct iio_dev *indio_dev, int index, int *val)
|
||||
{
|
||||
struct ak8975_data *data = iio_priv(indio_dev);
|
||||
struct i2c_client *client = data->client;
|
||||
u16 meas_reg;
|
||||
s16 raw;
|
||||
int ret;
|
||||
|
||||
mutex_lock(&data->lock);
|
||||
@@ -322,16 +320,11 @@ static int ak8975_read_axis(struct iio_dev *indio_dev, int index, int *val)
|
||||
dev_err(&client->dev, "Read axis data fails\n");
|
||||
goto exit;
|
||||
}
|
||||
meas_reg = ret;
|
||||
|
||||
mutex_unlock(&data->lock);
|
||||
|
||||
/* Endian conversion of the measured values. */
|
||||
raw = (s16) (le16_to_cpu(meas_reg));
|
||||
|
||||
/* Clamp to valid range. */
|
||||
raw = clamp_t(s16, raw, -4096, 4095);
|
||||
*val = raw;
|
||||
*val = clamp_t(s16, ret, -4096, 4095);
|
||||
return IIO_VAL_INT;
|
||||
|
||||
exit:
|
||||
|
||||
@@ -2129,13 +2129,8 @@ static int __mlx4_init_one(struct pci_dev *pdev, int pci_dev_data)
|
||||
/* Allow large DMA segments, up to the firmware limit of 1 GB */
|
||||
dma_set_max_seg_size(&pdev->dev, 1024 * 1024 * 1024);
|
||||
|
||||
priv = kzalloc(sizeof(*priv), GFP_KERNEL);
|
||||
if (!priv) {
|
||||
err = -ENOMEM;
|
||||
goto err_release_regions;
|
||||
}
|
||||
|
||||
dev = &priv->dev;
|
||||
dev = pci_get_drvdata(pdev);
|
||||
priv = mlx4_priv(dev);
|
||||
dev->pdev = pdev;
|
||||
INIT_LIST_HEAD(&priv->ctx_list);
|
||||
spin_lock_init(&priv->ctx_lock);
|
||||
@@ -2300,8 +2295,7 @@ slave_start:
|
||||
mlx4_sense_init(dev);
|
||||
mlx4_start_sense(dev);
|
||||
|
||||
priv->pci_dev_data = pci_dev_data;
|
||||
pci_set_drvdata(pdev, dev);
|
||||
priv->removed = 0;
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -2367,84 +2361,110 @@ err_disable_pdev:
|
||||
|
||||
static int mlx4_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
{
|
||||
struct mlx4_priv *priv;
|
||||
struct mlx4_dev *dev;
|
||||
|
||||
printk_once(KERN_INFO "%s", mlx4_version);
|
||||
|
||||
priv = kzalloc(sizeof(*priv), GFP_KERNEL);
|
||||
if (!priv)
|
||||
return -ENOMEM;
|
||||
|
||||
dev = &priv->dev;
|
||||
pci_set_drvdata(pdev, dev);
|
||||
priv->pci_dev_data = id->driver_data;
|
||||
|
||||
return __mlx4_init_one(pdev, id->driver_data);
|
||||
}
|
||||
|
||||
static void __mlx4_remove_one(struct pci_dev *pdev)
|
||||
{
|
||||
struct mlx4_dev *dev = pci_get_drvdata(pdev);
|
||||
struct mlx4_priv *priv = mlx4_priv(dev);
|
||||
int pci_dev_data;
|
||||
int p;
|
||||
|
||||
if (priv->removed)
|
||||
return;
|
||||
|
||||
pci_dev_data = priv->pci_dev_data;
|
||||
|
||||
/* in SRIOV it is not allowed to unload the pf's
|
||||
* driver while there are alive vf's */
|
||||
if (mlx4_is_master(dev)) {
|
||||
if (mlx4_how_many_lives_vf(dev))
|
||||
printk(KERN_ERR "Removing PF when there are assigned VF's !!!\n");
|
||||
}
|
||||
mlx4_stop_sense(dev);
|
||||
mlx4_unregister_device(dev);
|
||||
|
||||
for (p = 1; p <= dev->caps.num_ports; p++) {
|
||||
mlx4_cleanup_port_info(&priv->port[p]);
|
||||
mlx4_CLOSE_PORT(dev, p);
|
||||
}
|
||||
|
||||
if (mlx4_is_master(dev))
|
||||
mlx4_free_resource_tracker(dev,
|
||||
RES_TR_FREE_SLAVES_ONLY);
|
||||
|
||||
mlx4_cleanup_counters_table(dev);
|
||||
mlx4_cleanup_qp_table(dev);
|
||||
mlx4_cleanup_srq_table(dev);
|
||||
mlx4_cleanup_cq_table(dev);
|
||||
mlx4_cmd_use_polling(dev);
|
||||
mlx4_cleanup_eq_table(dev);
|
||||
mlx4_cleanup_mcg_table(dev);
|
||||
mlx4_cleanup_mr_table(dev);
|
||||
mlx4_cleanup_xrcd_table(dev);
|
||||
mlx4_cleanup_pd_table(dev);
|
||||
|
||||
if (mlx4_is_master(dev))
|
||||
mlx4_free_resource_tracker(dev,
|
||||
RES_TR_FREE_STRUCTS_ONLY);
|
||||
|
||||
iounmap(priv->kar);
|
||||
mlx4_uar_free(dev, &priv->driver_uar);
|
||||
mlx4_cleanup_uar_table(dev);
|
||||
if (!mlx4_is_slave(dev))
|
||||
mlx4_clear_steering(dev);
|
||||
mlx4_free_eq_table(dev);
|
||||
if (mlx4_is_master(dev))
|
||||
mlx4_multi_func_cleanup(dev);
|
||||
mlx4_close_hca(dev);
|
||||
if (mlx4_is_slave(dev))
|
||||
mlx4_multi_func_cleanup(dev);
|
||||
mlx4_cmd_cleanup(dev);
|
||||
|
||||
if (dev->flags & MLX4_FLAG_MSI_X)
|
||||
pci_disable_msix(pdev);
|
||||
if (dev->flags & MLX4_FLAG_SRIOV) {
|
||||
mlx4_warn(dev, "Disabling SR-IOV\n");
|
||||
pci_disable_sriov(pdev);
|
||||
}
|
||||
|
||||
if (!mlx4_is_slave(dev))
|
||||
mlx4_free_ownership(dev);
|
||||
|
||||
kfree(dev->caps.qp0_tunnel);
|
||||
kfree(dev->caps.qp0_proxy);
|
||||
kfree(dev->caps.qp1_tunnel);
|
||||
kfree(dev->caps.qp1_proxy);
|
||||
|
||||
pci_release_regions(pdev);
|
||||
pci_disable_device(pdev);
|
||||
memset(priv, 0, sizeof(*priv));
|
||||
priv->pci_dev_data = pci_dev_data;
|
||||
priv->removed = 1;
|
||||
}
|
||||
|
||||
static void mlx4_remove_one(struct pci_dev *pdev)
|
||||
{
|
||||
struct mlx4_dev *dev = pci_get_drvdata(pdev);
|
||||
struct mlx4_priv *priv = mlx4_priv(dev);
|
||||
int p;
|
||||
|
||||
if (dev) {
|
||||
/* in SRIOV it is not allowed to unload the pf's
|
||||
* driver while there are alive vf's */
|
||||
if (mlx4_is_master(dev)) {
|
||||
if (mlx4_how_many_lives_vf(dev))
|
||||
printk(KERN_ERR "Removing PF when there are assigned VF's !!!\n");
|
||||
}
|
||||
mlx4_stop_sense(dev);
|
||||
mlx4_unregister_device(dev);
|
||||
|
||||
for (p = 1; p <= dev->caps.num_ports; p++) {
|
||||
mlx4_cleanup_port_info(&priv->port[p]);
|
||||
mlx4_CLOSE_PORT(dev, p);
|
||||
}
|
||||
|
||||
if (mlx4_is_master(dev))
|
||||
mlx4_free_resource_tracker(dev,
|
||||
RES_TR_FREE_SLAVES_ONLY);
|
||||
|
||||
mlx4_cleanup_counters_table(dev);
|
||||
mlx4_cleanup_mcg_table(dev);
|
||||
mlx4_cleanup_qp_table(dev);
|
||||
mlx4_cleanup_srq_table(dev);
|
||||
mlx4_cleanup_cq_table(dev);
|
||||
mlx4_cmd_use_polling(dev);
|
||||
mlx4_cleanup_eq_table(dev);
|
||||
mlx4_cleanup_mr_table(dev);
|
||||
mlx4_cleanup_xrcd_table(dev);
|
||||
mlx4_cleanup_pd_table(dev);
|
||||
|
||||
if (mlx4_is_master(dev))
|
||||
mlx4_free_resource_tracker(dev,
|
||||
RES_TR_FREE_STRUCTS_ONLY);
|
||||
|
||||
iounmap(priv->kar);
|
||||
mlx4_uar_free(dev, &priv->driver_uar);
|
||||
mlx4_cleanup_uar_table(dev);
|
||||
if (!mlx4_is_slave(dev))
|
||||
mlx4_clear_steering(dev);
|
||||
mlx4_free_eq_table(dev);
|
||||
if (mlx4_is_master(dev))
|
||||
mlx4_multi_func_cleanup(dev);
|
||||
mlx4_close_hca(dev);
|
||||
if (mlx4_is_slave(dev))
|
||||
mlx4_multi_func_cleanup(dev);
|
||||
mlx4_cmd_cleanup(dev);
|
||||
|
||||
if (dev->flags & MLX4_FLAG_MSI_X)
|
||||
pci_disable_msix(pdev);
|
||||
if (dev->flags & MLX4_FLAG_SRIOV) {
|
||||
mlx4_warn(dev, "Disabling SR-IOV\n");
|
||||
pci_disable_sriov(pdev);
|
||||
}
|
||||
|
||||
if (!mlx4_is_slave(dev))
|
||||
mlx4_free_ownership(dev);
|
||||
|
||||
kfree(dev->caps.qp0_tunnel);
|
||||
kfree(dev->caps.qp0_proxy);
|
||||
kfree(dev->caps.qp1_tunnel);
|
||||
kfree(dev->caps.qp1_proxy);
|
||||
|
||||
kfree(priv);
|
||||
pci_release_regions(pdev);
|
||||
pci_disable_device(pdev);
|
||||
pci_set_drvdata(pdev, NULL);
|
||||
}
|
||||
__mlx4_remove_one(pdev);
|
||||
kfree(priv);
|
||||
pci_set_drvdata(pdev, NULL);
|
||||
}
|
||||
|
||||
int mlx4_restart_one(struct pci_dev *pdev)
|
||||
@@ -2454,7 +2474,7 @@ int mlx4_restart_one(struct pci_dev *pdev)
|
||||
int pci_dev_data;
|
||||
|
||||
pci_dev_data = priv->pci_dev_data;
|
||||
mlx4_remove_one(pdev);
|
||||
__mlx4_remove_one(pdev);
|
||||
return __mlx4_init_one(pdev, pci_dev_data);
|
||||
}
|
||||
|
||||
@@ -2509,7 +2529,7 @@ MODULE_DEVICE_TABLE(pci, mlx4_pci_table);
|
||||
static pci_ers_result_t mlx4_pci_err_detected(struct pci_dev *pdev,
|
||||
pci_channel_state_t state)
|
||||
{
|
||||
mlx4_remove_one(pdev);
|
||||
__mlx4_remove_one(pdev);
|
||||
|
||||
return state == pci_channel_io_perm_failure ?
|
||||
PCI_ERS_RESULT_DISCONNECT : PCI_ERS_RESULT_NEED_RESET;
|
||||
@@ -2517,7 +2537,11 @@ static pci_ers_result_t mlx4_pci_err_detected(struct pci_dev *pdev,
|
||||
|
||||
static pci_ers_result_t mlx4_pci_slot_reset(struct pci_dev *pdev)
|
||||
{
|
||||
int ret = __mlx4_init_one(pdev, 0);
|
||||
struct mlx4_dev *dev = pci_get_drvdata(pdev);
|
||||
struct mlx4_priv *priv = mlx4_priv(dev);
|
||||
int ret;
|
||||
|
||||
ret = __mlx4_init_one(pdev, priv->pci_dev_data);
|
||||
|
||||
return ret ? PCI_ERS_RESULT_DISCONNECT : PCI_ERS_RESULT_RECOVERED;
|
||||
}
|
||||
|
||||
@@ -743,6 +743,7 @@ struct mlx4_priv {
|
||||
spinlock_t ctx_lock;
|
||||
|
||||
int pci_dev_data;
|
||||
int removed;
|
||||
|
||||
struct list_head pgdir_list;
|
||||
struct mutex pgdir_mutex;
|
||||
|
||||
@@ -961,7 +961,6 @@ static int macvlan_device_event(struct notifier_block *unused,
|
||||
list_for_each_entry_safe(vlan, next, &port->vlans, list)
|
||||
vlan->dev->rtnl_link_ops->dellink(vlan->dev, &list_kill);
|
||||
unregister_netdevice_many(&list_kill);
|
||||
list_del(&list_kill);
|
||||
break;
|
||||
case NETDEV_PRE_TYPE_CHANGE:
|
||||
/* Forbid underlaying device to change its type. */
|
||||
|
||||
@@ -1542,6 +1542,7 @@ static int team_change_mtu(struct net_device *dev, int new_mtu)
|
||||
* to traverse list in reverse under rcu_read_lock
|
||||
*/
|
||||
mutex_lock(&team->lock);
|
||||
team->port_mtu_change_allowed = true;
|
||||
list_for_each_entry(port, &team->port_list, list) {
|
||||
err = dev_set_mtu(port->dev, new_mtu);
|
||||
if (err) {
|
||||
@@ -1550,6 +1551,7 @@ static int team_change_mtu(struct net_device *dev, int new_mtu)
|
||||
goto unwind;
|
||||
}
|
||||
}
|
||||
team->port_mtu_change_allowed = false;
|
||||
mutex_unlock(&team->lock);
|
||||
|
||||
dev->mtu = new_mtu;
|
||||
@@ -1559,6 +1561,7 @@ static int team_change_mtu(struct net_device *dev, int new_mtu)
|
||||
unwind:
|
||||
list_for_each_entry_continue_reverse(port, &team->port_list, list)
|
||||
dev_set_mtu(port->dev, dev->mtu);
|
||||
team->port_mtu_change_allowed = false;
|
||||
mutex_unlock(&team->lock);
|
||||
|
||||
return err;
|
||||
@@ -2678,7 +2681,9 @@ static int team_device_event(struct notifier_block *unused,
|
||||
break;
|
||||
case NETDEV_CHANGEMTU:
|
||||
/* Forbid to change mtu of underlaying device */
|
||||
return NOTIFY_BAD;
|
||||
if (!port->team->port_mtu_change_allowed)
|
||||
return NOTIFY_BAD;
|
||||
break;
|
||||
case NETDEV_PRE_TYPE_CHANGE:
|
||||
/* Forbid to change type of underlaying device */
|
||||
return NOTIFY_BAD;
|
||||
|
||||
@@ -739,7 +739,12 @@ static const struct usb_device_id products[] = {
|
||||
{QMI_FIXED_INTF(0x2357, 0x9000, 4)}, /* TP-LINK MA260 */
|
||||
{QMI_FIXED_INTF(0x1bc7, 0x1200, 5)}, /* Telit LE920 */
|
||||
{QMI_FIXED_INTF(0x1bc7, 0x1201, 2)}, /* Telit LE920 */
|
||||
{QMI_FIXED_INTF(0x0b3c, 0xc005, 6)}, /* Olivetti Olicard 200 */
|
||||
{QMI_FIXED_INTF(0x0b3c, 0xc000, 4)}, /* Olivetti Olicard 100 */
|
||||
{QMI_FIXED_INTF(0x0b3c, 0xc001, 4)}, /* Olivetti Olicard 120 */
|
||||
{QMI_FIXED_INTF(0x0b3c, 0xc002, 4)}, /* Olivetti Olicard 140 */
|
||||
{QMI_FIXED_INTF(0x0b3c, 0xc004, 6)}, /* Olivetti Olicard 155 */
|
||||
{QMI_FIXED_INTF(0x0b3c, 0xc005, 6)}, /* Olivetti Olicard 200 */
|
||||
{QMI_FIXED_INTF(0x0b3c, 0xc00a, 6)}, /* Olivetti Olicard 160 */
|
||||
{QMI_FIXED_INTF(0x0b3c, 0xc00b, 4)}, /* Olivetti Olicard 500 */
|
||||
{QMI_FIXED_INTF(0x1e2d, 0x0060, 4)}, /* Cinterion PLxx */
|
||||
{QMI_FIXED_INTF(0x1e2d, 0x0053, 4)}, /* Cinterion PHxx,PXxx */
|
||||
|
||||
@@ -1314,7 +1314,7 @@ static void vxlan_setup(struct net_device *dev)
|
||||
|
||||
eth_hw_addr_random(dev);
|
||||
ether_setup(dev);
|
||||
dev->hard_header_len = ETH_HLEN + VXLAN_HEADROOM;
|
||||
dev->needed_headroom = ETH_HLEN + VXLAN_HEADROOM;
|
||||
|
||||
dev->netdev_ops = &vxlan_netdev_ops;
|
||||
dev->destructor = vxlan_free;
|
||||
@@ -1454,7 +1454,7 @@ static int vxlan_newlink(struct net *net, struct net_device *dev,
|
||||
dev->mtu = lowerdev->mtu - VXLAN_HEADROOM;
|
||||
|
||||
/* update header length based on lower device */
|
||||
dev->hard_header_len = lowerdev->hard_header_len +
|
||||
dev->needed_headroom = lowerdev->hard_header_len +
|
||||
VXLAN_HEADROOM;
|
||||
}
|
||||
|
||||
|
||||
@@ -49,6 +49,7 @@ struct at91_rtc_config {
|
||||
|
||||
static const struct at91_rtc_config *at91_rtc_config;
|
||||
static DECLARE_COMPLETION(at91_rtc_updated);
|
||||
static DECLARE_COMPLETION(at91_rtc_upd_rdy);
|
||||
static unsigned int at91_alarm_year = AT91_RTC_EPOCH;
|
||||
static void __iomem *at91_rtc_regs;
|
||||
static int irq;
|
||||
@@ -162,6 +163,8 @@ static int at91_rtc_settime(struct device *dev, struct rtc_time *tm)
|
||||
1900 + tm->tm_year, tm->tm_mon, tm->tm_mday,
|
||||
tm->tm_hour, tm->tm_min, tm->tm_sec);
|
||||
|
||||
wait_for_completion(&at91_rtc_upd_rdy);
|
||||
|
||||
/* Stop Time/Calendar from counting */
|
||||
cr = at91_rtc_read(AT91_RTC_CR);
|
||||
at91_rtc_write(AT91_RTC_CR, cr | AT91_RTC_UPDCAL | AT91_RTC_UPDTIM);
|
||||
@@ -184,7 +187,9 @@ static int at91_rtc_settime(struct device *dev, struct rtc_time *tm)
|
||||
|
||||
/* Restart Time/Calendar */
|
||||
cr = at91_rtc_read(AT91_RTC_CR);
|
||||
at91_rtc_write(AT91_RTC_SCCR, AT91_RTC_SECEV);
|
||||
at91_rtc_write(AT91_RTC_CR, cr & ~(AT91_RTC_UPDCAL | AT91_RTC_UPDTIM));
|
||||
at91_rtc_write_ier(AT91_RTC_SECEV);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -291,8 +296,10 @@ static irqreturn_t at91_rtc_interrupt(int irq, void *dev_id)
|
||||
if (rtsr) { /* this interrupt is shared! Is it ours? */
|
||||
if (rtsr & AT91_RTC_ALARM)
|
||||
events |= (RTC_AF | RTC_IRQF);
|
||||
if (rtsr & AT91_RTC_SECEV)
|
||||
events |= (RTC_UF | RTC_IRQF);
|
||||
if (rtsr & AT91_RTC_SECEV) {
|
||||
complete(&at91_rtc_upd_rdy);
|
||||
at91_rtc_write_idr(AT91_RTC_SECEV);
|
||||
}
|
||||
if (rtsr & AT91_RTC_ACKUPD)
|
||||
complete(&at91_rtc_updated);
|
||||
|
||||
@@ -415,6 +422,11 @@ static int __init at91_rtc_probe(struct platform_device *pdev)
|
||||
}
|
||||
platform_set_drvdata(pdev, rtc);
|
||||
|
||||
/* enable SECEV interrupt in order to initialize at91_rtc_upd_rdy
|
||||
* completion.
|
||||
*/
|
||||
at91_rtc_write_ier(AT91_RTC_SECEV);
|
||||
|
||||
dev_info(&pdev->dev, "AT91 Real Time Clock driver.\n");
|
||||
return 0;
|
||||
|
||||
|
||||
@@ -77,7 +77,7 @@ scsi_nl_rcv_msg(struct sk_buff *skb)
|
||||
goto next_msg;
|
||||
}
|
||||
|
||||
if (!capable(CAP_SYS_ADMIN)) {
|
||||
if (!netlink_capable(skb, CAP_SYS_ADMIN)) {
|
||||
err = -EPERM;
|
||||
goto next_msg;
|
||||
}
|
||||
|
||||
@@ -672,9 +672,13 @@ static int tsl2x7x_chip_on(struct iio_dev *indio_dev)
|
||||
chip->tsl2x7x_config[TSL2X7X_PRX_COUNT] =
|
||||
chip->tsl2x7x_settings.prox_pulse_count;
|
||||
chip->tsl2x7x_config[TSL2X7X_PRX_MINTHRESHLO] =
|
||||
chip->tsl2x7x_settings.prox_thres_low;
|
||||
(chip->tsl2x7x_settings.prox_thres_low) & 0xFF;
|
||||
chip->tsl2x7x_config[TSL2X7X_PRX_MINTHRESHHI] =
|
||||
(chip->tsl2x7x_settings.prox_thres_low >> 8) & 0xFF;
|
||||
chip->tsl2x7x_config[TSL2X7X_PRX_MAXTHRESHLO] =
|
||||
chip->tsl2x7x_settings.prox_thres_high;
|
||||
(chip->tsl2x7x_settings.prox_thres_high) & 0xFF;
|
||||
chip->tsl2x7x_config[TSL2X7X_PRX_MAXTHRESHHI] =
|
||||
(chip->tsl2x7x_settings.prox_thres_high >> 8) & 0xFF;
|
||||
|
||||
/* and make sure we're not already on */
|
||||
if (chip->tsl2x7x_chip_status == TSL2X7X_CHIP_WORKING) {
|
||||
|
||||
@@ -315,6 +315,16 @@ static int chap_server_compute_md5(
|
||||
pr_err("Unable to convert incoming challenge\n");
|
||||
goto out;
|
||||
}
|
||||
/*
|
||||
* During mutual authentication, the CHAP_C generated by the
|
||||
* initiator must not match the original CHAP_C generated by
|
||||
* the target.
|
||||
*/
|
||||
if (!memcmp(challenge_binhex, chap->challenge, CHAP_CHALLENGE_LENGTH)) {
|
||||
pr_err("initiator CHAP_C matches target CHAP_C, failing"
|
||||
" login attempt\n");
|
||||
goto out;
|
||||
}
|
||||
/*
|
||||
* Generate CHAP_N and CHAP_R for mutual authentication.
|
||||
*/
|
||||
|
||||
@@ -122,13 +122,23 @@ static void acm_release_minor(struct acm *acm)
|
||||
static int acm_ctrl_msg(struct acm *acm, int request, int value,
|
||||
void *buf, int len)
|
||||
{
|
||||
int retval = usb_control_msg(acm->dev, usb_sndctrlpipe(acm->dev, 0),
|
||||
int retval;
|
||||
|
||||
retval = usb_autopm_get_interface(acm->control);
|
||||
if (retval)
|
||||
return retval;
|
||||
|
||||
retval = usb_control_msg(acm->dev, usb_sndctrlpipe(acm->dev, 0),
|
||||
request, USB_RT_ACM, value,
|
||||
acm->control->altsetting[0].desc.bInterfaceNumber,
|
||||
buf, len, 5000);
|
||||
|
||||
dev_dbg(&acm->control->dev,
|
||||
"%s - rq 0x%02x, val %#x, len %#x, result %d\n",
|
||||
__func__, request, value, len, retval);
|
||||
|
||||
usb_autopm_put_interface(acm->control);
|
||||
|
||||
return retval < 0 ? retval : 0;
|
||||
}
|
||||
|
||||
@@ -233,12 +243,9 @@ static int acm_write_start(struct acm *acm, int wbn)
|
||||
acm->susp_count);
|
||||
usb_autopm_get_interface_async(acm->control);
|
||||
if (acm->susp_count) {
|
||||
if (!acm->delayed_wb)
|
||||
acm->delayed_wb = wb;
|
||||
else
|
||||
usb_autopm_put_interface_async(acm->control);
|
||||
usb_anchor_urb(wb->urb, &acm->delayed);
|
||||
spin_unlock_irqrestore(&acm->write_lock, flags);
|
||||
return 0; /* A white lie */
|
||||
return 0;
|
||||
}
|
||||
usb_mark_last_busy(acm->dev);
|
||||
|
||||
@@ -516,6 +523,7 @@ static int acm_port_activate(struct tty_port *port, struct tty_struct *tty)
|
||||
{
|
||||
struct acm *acm = container_of(port, struct acm, port);
|
||||
int retval = -ENODEV;
|
||||
int i;
|
||||
|
||||
dev_dbg(&acm->control->dev, "%s\n", __func__);
|
||||
|
||||
@@ -564,6 +572,8 @@ static int acm_port_activate(struct tty_port *port, struct tty_struct *tty)
|
||||
return 0;
|
||||
|
||||
error_submit_read_urbs:
|
||||
for (i = 0; i < acm->rx_buflimit; i++)
|
||||
usb_kill_urb(acm->read_urbs[i]);
|
||||
acm->ctrlout = 0;
|
||||
acm_set_control(acm, acm->ctrlout);
|
||||
error_set_control:
|
||||
@@ -591,21 +601,35 @@ static void acm_port_destruct(struct tty_port *port)
|
||||
static void acm_port_shutdown(struct tty_port *port)
|
||||
{
|
||||
struct acm *acm = container_of(port, struct acm, port);
|
||||
struct urb *urb;
|
||||
struct acm_wb *wb;
|
||||
int i;
|
||||
int pm_err;
|
||||
|
||||
dev_dbg(&acm->control->dev, "%s\n", __func__);
|
||||
|
||||
mutex_lock(&acm->mutex);
|
||||
if (!acm->disconnected) {
|
||||
usb_autopm_get_interface(acm->control);
|
||||
pm_err = usb_autopm_get_interface(acm->control);
|
||||
acm_set_control(acm, acm->ctrlout = 0);
|
||||
|
||||
for (;;) {
|
||||
urb = usb_get_from_anchor(&acm->delayed);
|
||||
if (!urb)
|
||||
break;
|
||||
wb = urb->context;
|
||||
wb->use = 0;
|
||||
usb_autopm_put_interface_async(acm->control);
|
||||
}
|
||||
|
||||
usb_kill_urb(acm->ctrlurb);
|
||||
for (i = 0; i < ACM_NW; i++)
|
||||
usb_kill_urb(acm->wb[i].urb);
|
||||
for (i = 0; i < acm->rx_buflimit; i++)
|
||||
usb_kill_urb(acm->read_urbs[i]);
|
||||
acm->control->needs_remote_wakeup = 0;
|
||||
usb_autopm_put_interface(acm->control);
|
||||
if (!pm_err)
|
||||
usb_autopm_put_interface(acm->control);
|
||||
}
|
||||
mutex_unlock(&acm->mutex);
|
||||
}
|
||||
@@ -1190,6 +1214,7 @@ made_compressed_probe:
|
||||
acm->bInterval = epread->bInterval;
|
||||
tty_port_init(&acm->port);
|
||||
acm->port.ops = &acm_port_ops;
|
||||
init_usb_anchor(&acm->delayed);
|
||||
|
||||
buf = usb_alloc_coherent(usb_dev, ctrlsize, GFP_KERNEL, &acm->ctrl_dma);
|
||||
if (!buf) {
|
||||
@@ -1434,18 +1459,15 @@ static int acm_suspend(struct usb_interface *intf, pm_message_t message)
|
||||
struct acm *acm = usb_get_intfdata(intf);
|
||||
int cnt;
|
||||
|
||||
if (PMSG_IS_AUTO(message)) {
|
||||
int b;
|
||||
|
||||
spin_lock_irq(&acm->write_lock);
|
||||
b = acm->transmitting;
|
||||
spin_unlock_irq(&acm->write_lock);
|
||||
if (b)
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
spin_lock_irq(&acm->read_lock);
|
||||
spin_lock(&acm->write_lock);
|
||||
if (PMSG_IS_AUTO(message)) {
|
||||
if (acm->transmitting) {
|
||||
spin_unlock(&acm->write_lock);
|
||||
spin_unlock_irq(&acm->read_lock);
|
||||
return -EBUSY;
|
||||
}
|
||||
}
|
||||
cnt = acm->susp_count++;
|
||||
spin_unlock(&acm->write_lock);
|
||||
spin_unlock_irq(&acm->read_lock);
|
||||
@@ -1453,8 +1475,7 @@ static int acm_suspend(struct usb_interface *intf, pm_message_t message)
|
||||
if (cnt)
|
||||
return 0;
|
||||
|
||||
if (test_bit(ASYNCB_INITIALIZED, &acm->port.flags))
|
||||
stop_data_traffic(acm);
|
||||
stop_data_traffic(acm);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1462,29 +1483,24 @@ static int acm_suspend(struct usb_interface *intf, pm_message_t message)
|
||||
static int acm_resume(struct usb_interface *intf)
|
||||
{
|
||||
struct acm *acm = usb_get_intfdata(intf);
|
||||
struct acm_wb *wb;
|
||||
struct urb *urb;
|
||||
int rv = 0;
|
||||
int cnt;
|
||||
|
||||
spin_lock_irq(&acm->read_lock);
|
||||
acm->susp_count -= 1;
|
||||
cnt = acm->susp_count;
|
||||
spin_unlock_irq(&acm->read_lock);
|
||||
spin_lock(&acm->write_lock);
|
||||
|
||||
if (cnt)
|
||||
return 0;
|
||||
if (--acm->susp_count)
|
||||
goto out;
|
||||
|
||||
if (test_bit(ASYNCB_INITIALIZED, &acm->port.flags)) {
|
||||
rv = usb_submit_urb(acm->ctrlurb, GFP_NOIO);
|
||||
rv = usb_submit_urb(acm->ctrlurb, GFP_ATOMIC);
|
||||
|
||||
spin_lock_irq(&acm->write_lock);
|
||||
if (acm->delayed_wb) {
|
||||
wb = acm->delayed_wb;
|
||||
acm->delayed_wb = NULL;
|
||||
spin_unlock_irq(&acm->write_lock);
|
||||
acm_start_wb(acm, wb);
|
||||
} else {
|
||||
spin_unlock_irq(&acm->write_lock);
|
||||
for (;;) {
|
||||
urb = usb_get_from_anchor(&acm->delayed);
|
||||
if (!urb)
|
||||
break;
|
||||
|
||||
acm_start_wb(acm, urb->context);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1492,12 +1508,14 @@ static int acm_resume(struct usb_interface *intf)
|
||||
* do the write path at all cost
|
||||
*/
|
||||
if (rv < 0)
|
||||
goto err_out;
|
||||
goto out;
|
||||
|
||||
rv = acm_submit_read_urbs(acm, GFP_NOIO);
|
||||
rv = acm_submit_read_urbs(acm, GFP_ATOMIC);
|
||||
}
|
||||
out:
|
||||
spin_unlock(&acm->write_lock);
|
||||
spin_unlock_irq(&acm->read_lock);
|
||||
|
||||
err_out:
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
@@ -117,7 +117,7 @@ struct acm {
|
||||
unsigned int throttled:1; /* actually throttled */
|
||||
unsigned int throttle_req:1; /* throttle requested */
|
||||
u8 bInterval;
|
||||
struct acm_wb *delayed_wb; /* write queued for a device about to be woken */
|
||||
struct usb_anchor delayed; /* writes queued for a device about to be woken */
|
||||
};
|
||||
|
||||
#define CDC_DATA_INTERFACE_TYPE 0x0a
|
||||
|
||||
@@ -193,6 +193,7 @@ struct team {
|
||||
bool user_carrier_enabled;
|
||||
bool queue_override_enabled;
|
||||
struct list_head *qom_lists; /* array of queue override mapping lists */
|
||||
bool port_mtu_change_allowed;
|
||||
long mode_priv[TEAM_MODE_PRIV_LONGS];
|
||||
};
|
||||
|
||||
|
||||
@@ -16,9 +16,10 @@ static inline struct nlmsghdr *nlmsg_hdr(const struct sk_buff *skb)
|
||||
}
|
||||
|
||||
enum netlink_skb_flags {
|
||||
NETLINK_SKB_MMAPED = 0x1, /* Packet data is mmaped */
|
||||
NETLINK_SKB_TX = 0x2, /* Packet was sent by userspace */
|
||||
NETLINK_SKB_DELIVERED = 0x4, /* Packet was delivered */
|
||||
NETLINK_SKB_MMAPED = 0x1, /* Packet data is mmaped */
|
||||
NETLINK_SKB_TX = 0x2, /* Packet was sent by userspace */
|
||||
NETLINK_SKB_DELIVERED = 0x4, /* Packet was delivered */
|
||||
NETLINK_SKB_DST = 0x8, /* Dst set in sendto or sendmsg */
|
||||
};
|
||||
|
||||
struct netlink_skb_parms {
|
||||
@@ -144,4 +145,11 @@ static inline int netlink_dump_start(struct sock *ssk, struct sk_buff *skb,
|
||||
return __netlink_dump_start(ssk, skb, nlh, control);
|
||||
}
|
||||
|
||||
bool __netlink_ns_capable(const struct netlink_skb_parms *nsp,
|
||||
struct user_namespace *ns, int cap);
|
||||
bool netlink_ns_capable(const struct sk_buff *skb,
|
||||
struct user_namespace *ns, int cap);
|
||||
bool netlink_capable(const struct sk_buff *skb, int cap);
|
||||
bool netlink_net_capable(const struct sk_buff *skb, int cap);
|
||||
|
||||
#endif /* __LINUX_NETLINK_H */
|
||||
|
||||
@@ -23,7 +23,7 @@ int sock_diag_check_cookie(void *sk, __u32 *cookie);
|
||||
void sock_diag_save_cookie(void *sk, __u32 *cookie);
|
||||
|
||||
int sock_diag_put_meminfo(struct sock *sk, struct sk_buff *skb, int attr);
|
||||
int sock_diag_put_filterinfo(struct sock *sk,
|
||||
int sock_diag_put_filterinfo(bool may_report_filterinfo, struct sock *sk,
|
||||
struct sk_buff *skb, int attrtype);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -178,16 +178,9 @@ static inline void inet_peer_refcheck(const struct inet_peer *p)
|
||||
/* can be called with or without local BH being disabled */
|
||||
static inline int inet_getid(struct inet_peer *p, int more)
|
||||
{
|
||||
int old, new;
|
||||
more++;
|
||||
inet_peer_refcheck(p);
|
||||
do {
|
||||
old = atomic_read(&p->ip_id_count);
|
||||
new = old + more;
|
||||
if (!new)
|
||||
new = 1;
|
||||
} while (atomic_cmpxchg(&p->ip_id_count, old, new) != old);
|
||||
return new;
|
||||
return atomic_add_return(more, &p->ip_id_count) - more;
|
||||
}
|
||||
|
||||
#endif /* _NET_INETPEER_H */
|
||||
|
||||
@@ -2248,6 +2248,11 @@ extern void sock_enable_timestamp(struct sock *sk, int flag);
|
||||
extern int sock_get_timestamp(struct sock *, struct timeval __user *);
|
||||
extern int sock_get_timestampns(struct sock *, struct timespec __user *);
|
||||
|
||||
bool sk_ns_capable(const struct sock *sk,
|
||||
struct user_namespace *user_ns, int cap);
|
||||
bool sk_capable(const struct sock *sk, int cap);
|
||||
bool sk_net_capable(const struct sock *sk, int cap);
|
||||
|
||||
/*
|
||||
* Enable debug/info messages
|
||||
*/
|
||||
|
||||
@@ -120,6 +120,8 @@ struct snd_card {
|
||||
int user_ctl_count; /* count of all user controls */
|
||||
struct list_head controls; /* all controls for this card */
|
||||
struct list_head ctl_files; /* active control files */
|
||||
struct mutex user_ctl_lock; /* protects user controls against
|
||||
concurrent access */
|
||||
|
||||
struct snd_info_entry *proc_root; /* root for soundcard specific files */
|
||||
struct snd_info_entry *proc_id; /* the card id */
|
||||
|
||||
@@ -80,7 +80,7 @@ struct snd_compr_tstamp {
|
||||
struct snd_compr_avail {
|
||||
__u64 avail;
|
||||
struct snd_compr_tstamp tstamp;
|
||||
};
|
||||
} __attribute__((packed));
|
||||
|
||||
enum snd_compr_direction {
|
||||
SND_COMPRESS_PLAYBACK = 0,
|
||||
|
||||
@@ -593,13 +593,13 @@ static int audit_netlink_ok(struct sk_buff *skb, u16 msg_type)
|
||||
case AUDIT_TTY_SET:
|
||||
case AUDIT_TRIM:
|
||||
case AUDIT_MAKE_EQUIV:
|
||||
if (!capable(CAP_AUDIT_CONTROL))
|
||||
if (!netlink_capable(skb, CAP_AUDIT_CONTROL))
|
||||
err = -EPERM;
|
||||
break;
|
||||
case AUDIT_USER:
|
||||
case AUDIT_FIRST_USER_MSG ... AUDIT_LAST_USER_MSG:
|
||||
case AUDIT_FIRST_USER_MSG2 ... AUDIT_LAST_USER_MSG2:
|
||||
if (!capable(CAP_AUDIT_WRITE))
|
||||
if (!netlink_capable(skb, CAP_AUDIT_WRITE))
|
||||
err = -EPERM;
|
||||
break;
|
||||
default: /* bad msg */
|
||||
|
||||
@@ -720,8 +720,10 @@ static bool can_stop_idle_tick(int cpu, struct tick_sched *ts)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (unlikely(ts->nohz_mode == NOHZ_MODE_INACTIVE))
|
||||
if (unlikely(ts->nohz_mode == NOHZ_MODE_INACTIVE)) {
|
||||
ts->sleep_length = (ktime_t) { .tv64 = NSEC_PER_SEC/HZ };
|
||||
return false;
|
||||
}
|
||||
|
||||
if (need_resched())
|
||||
return false;
|
||||
|
||||
@@ -19,11 +19,31 @@
|
||||
#include <linux/lzo.h>
|
||||
#include "lzodefs.h"
|
||||
|
||||
#define HAVE_IP(x) ((size_t)(ip_end - ip) >= (size_t)(x))
|
||||
#define HAVE_OP(x) ((size_t)(op_end - op) >= (size_t)(x))
|
||||
#define NEED_IP(x) if (!HAVE_IP(x)) goto input_overrun
|
||||
#define NEED_OP(x) if (!HAVE_OP(x)) goto output_overrun
|
||||
#define TEST_LB(m_pos) if ((m_pos) < out) goto lookbehind_overrun
|
||||
#define HAVE_IP(t, x) \
|
||||
(((size_t)(ip_end - ip) >= (size_t)(t + x)) && \
|
||||
(((t + x) >= t) && ((t + x) >= x)))
|
||||
|
||||
#define HAVE_OP(t, x) \
|
||||
(((size_t)(op_end - op) >= (size_t)(t + x)) && \
|
||||
(((t + x) >= t) && ((t + x) >= x)))
|
||||
|
||||
#define NEED_IP(t, x) \
|
||||
do { \
|
||||
if (!HAVE_IP(t, x)) \
|
||||
goto input_overrun; \
|
||||
} while (0)
|
||||
|
||||
#define NEED_OP(t, x) \
|
||||
do { \
|
||||
if (!HAVE_OP(t, x)) \
|
||||
goto output_overrun; \
|
||||
} while (0)
|
||||
|
||||
#define TEST_LB(m_pos) \
|
||||
do { \
|
||||
if ((m_pos) < out) \
|
||||
goto lookbehind_overrun; \
|
||||
} while (0)
|
||||
|
||||
int lzo1x_decompress_safe(const unsigned char *in, size_t in_len,
|
||||
unsigned char *out, size_t *out_len)
|
||||
@@ -58,14 +78,14 @@ int lzo1x_decompress_safe(const unsigned char *in, size_t in_len,
|
||||
while (unlikely(*ip == 0)) {
|
||||
t += 255;
|
||||
ip++;
|
||||
NEED_IP(1);
|
||||
NEED_IP(1, 0);
|
||||
}
|
||||
t += 15 + *ip++;
|
||||
}
|
||||
t += 3;
|
||||
copy_literal_run:
|
||||
#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
|
||||
if (likely(HAVE_IP(t + 15) && HAVE_OP(t + 15))) {
|
||||
if (likely(HAVE_IP(t, 15) && HAVE_OP(t, 15))) {
|
||||
const unsigned char *ie = ip + t;
|
||||
unsigned char *oe = op + t;
|
||||
do {
|
||||
@@ -81,8 +101,8 @@ copy_literal_run:
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
NEED_OP(t);
|
||||
NEED_IP(t + 3);
|
||||
NEED_OP(t, 0);
|
||||
NEED_IP(t, 3);
|
||||
do {
|
||||
*op++ = *ip++;
|
||||
} while (--t > 0);
|
||||
@@ -95,7 +115,7 @@ copy_literal_run:
|
||||
m_pos -= t >> 2;
|
||||
m_pos -= *ip++ << 2;
|
||||
TEST_LB(m_pos);
|
||||
NEED_OP(2);
|
||||
NEED_OP(2, 0);
|
||||
op[0] = m_pos[0];
|
||||
op[1] = m_pos[1];
|
||||
op += 2;
|
||||
@@ -119,10 +139,10 @@ copy_literal_run:
|
||||
while (unlikely(*ip == 0)) {
|
||||
t += 255;
|
||||
ip++;
|
||||
NEED_IP(1);
|
||||
NEED_IP(1, 0);
|
||||
}
|
||||
t += 31 + *ip++;
|
||||
NEED_IP(2);
|
||||
NEED_IP(2, 0);
|
||||
}
|
||||
m_pos = op - 1;
|
||||
next = get_unaligned_le16(ip);
|
||||
@@ -137,10 +157,10 @@ copy_literal_run:
|
||||
while (unlikely(*ip == 0)) {
|
||||
t += 255;
|
||||
ip++;
|
||||
NEED_IP(1);
|
||||
NEED_IP(1, 0);
|
||||
}
|
||||
t += 7 + *ip++;
|
||||
NEED_IP(2);
|
||||
NEED_IP(2, 0);
|
||||
}
|
||||
next = get_unaligned_le16(ip);
|
||||
ip += 2;
|
||||
@@ -154,7 +174,7 @@ copy_literal_run:
|
||||
#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
|
||||
if (op - m_pos >= 8) {
|
||||
unsigned char *oe = op + t;
|
||||
if (likely(HAVE_OP(t + 15))) {
|
||||
if (likely(HAVE_OP(t, 15))) {
|
||||
do {
|
||||
COPY8(op, m_pos);
|
||||
op += 8;
|
||||
@@ -164,7 +184,7 @@ copy_literal_run:
|
||||
m_pos += 8;
|
||||
} while (op < oe);
|
||||
op = oe;
|
||||
if (HAVE_IP(6)) {
|
||||
if (HAVE_IP(6, 0)) {
|
||||
state = next;
|
||||
COPY4(op, ip);
|
||||
op += next;
|
||||
@@ -172,7 +192,7 @@ copy_literal_run:
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
NEED_OP(t);
|
||||
NEED_OP(t, 0);
|
||||
do {
|
||||
*op++ = *m_pos++;
|
||||
} while (op < oe);
|
||||
@@ -181,7 +201,7 @@ copy_literal_run:
|
||||
#endif
|
||||
{
|
||||
unsigned char *oe = op + t;
|
||||
NEED_OP(t);
|
||||
NEED_OP(t, 0);
|
||||
op[0] = m_pos[0];
|
||||
op[1] = m_pos[1];
|
||||
op += 2;
|
||||
@@ -194,15 +214,15 @@ match_next:
|
||||
state = next;
|
||||
t = next;
|
||||
#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
|
||||
if (likely(HAVE_IP(6) && HAVE_OP(4))) {
|
||||
if (likely(HAVE_IP(6, 0) && HAVE_OP(4, 0))) {
|
||||
COPY4(op, ip);
|
||||
op += t;
|
||||
ip += t;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
NEED_IP(t + 3);
|
||||
NEED_OP(t);
|
||||
NEED_IP(t, 3);
|
||||
NEED_OP(t, 0);
|
||||
while (t > 0) {
|
||||
*op++ = *ip++;
|
||||
t--;
|
||||
|
||||
@@ -201,8 +201,8 @@ int nla_parse(struct nlattr **tb, int maxtype, const struct nlattr *head,
|
||||
}
|
||||
|
||||
if (unlikely(rem > 0))
|
||||
printk(KERN_WARNING "netlink: %d bytes leftover after parsing "
|
||||
"attributes.\n", rem);
|
||||
pr_warn_ratelimited("netlink: %d bytes leftover after parsing attributes in process `%s'.\n",
|
||||
rem, current->comm);
|
||||
|
||||
err = 0;
|
||||
errout:
|
||||
|
||||
@@ -784,7 +784,7 @@ static int cgw_create_job(struct sk_buff *skb, struct nlmsghdr *nlh)
|
||||
struct cgw_job *gwj;
|
||||
int err = 0;
|
||||
|
||||
if (!capable(CAP_NET_ADMIN))
|
||||
if (!netlink_capable(skb, CAP_NET_ADMIN))
|
||||
return -EPERM;
|
||||
|
||||
if (nlmsg_len(nlh) < sizeof(*r))
|
||||
@@ -876,7 +876,7 @@ static int cgw_remove_job(struct sk_buff *skb, struct nlmsghdr *nlh)
|
||||
struct can_can_gw ccgw;
|
||||
int err = 0;
|
||||
|
||||
if (!capable(CAP_NET_ADMIN))
|
||||
if (!netlink_capable(skb, CAP_NET_ADMIN))
|
||||
return -EPERM;
|
||||
|
||||
if (nlmsg_len(nlh) < sizeof(*r))
|
||||
|
||||
@@ -5827,6 +5827,9 @@ EXPORT_SYMBOL(unregister_netdevice_queue);
|
||||
/**
|
||||
* unregister_netdevice_many - unregister many devices
|
||||
* @head: list of devices
|
||||
*
|
||||
* Note: As most callers use a stack allocated list_head,
|
||||
* we force a list_del() to make sure stack wont be corrupted later.
|
||||
*/
|
||||
void unregister_netdevice_many(struct list_head *head)
|
||||
{
|
||||
@@ -5836,6 +5839,7 @@ void unregister_netdevice_many(struct list_head *head)
|
||||
rollback_registered_many(head);
|
||||
list_for_each_entry(dev, head, unreg_list)
|
||||
net_set_todo(dev);
|
||||
list_del(head);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(unregister_netdevice_many);
|
||||
@@ -6252,7 +6256,6 @@ static void __net_exit default_device_exit_batch(struct list_head *net_list)
|
||||
}
|
||||
}
|
||||
unregister_netdevice_many(&dev_kill_list);
|
||||
list_del(&dev_kill_list);
|
||||
rtnl_unlock();
|
||||
}
|
||||
|
||||
|
||||
@@ -1044,6 +1044,7 @@ static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
|
||||
struct nlattr *tb[IFLA_MAX+1];
|
||||
u32 ext_filter_mask = 0;
|
||||
int err;
|
||||
int hdrlen;
|
||||
|
||||
s_h = cb->args[0];
|
||||
s_idx = cb->args[1];
|
||||
@@ -1051,8 +1052,17 @@ static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
|
||||
rcu_read_lock();
|
||||
cb->seq = net->dev_base_seq;
|
||||
|
||||
if (nlmsg_parse(cb->nlh, sizeof(struct ifinfomsg), tb, IFLA_MAX,
|
||||
ifla_policy) >= 0) {
|
||||
/* A hack to preserve kernel<->userspace interface.
|
||||
* The correct header is ifinfomsg. It is consistent with rtnl_getlink.
|
||||
* However, before Linux v3.9 the code here assumed rtgenmsg and that's
|
||||
* what iproute2 < v3.9.0 used.
|
||||
* We can detect the old iproute2. Even including the IFLA_EXT_MASK
|
||||
* attribute, its netlink message is shorter than struct ifinfomsg.
|
||||
*/
|
||||
hdrlen = nlmsg_len(cb->nlh) < sizeof(struct ifinfomsg) ?
|
||||
sizeof(struct rtgenmsg) : sizeof(struct ifinfomsg);
|
||||
|
||||
if (nlmsg_parse(cb->nlh, hdrlen, tb, IFLA_MAX, ifla_policy) >= 0) {
|
||||
|
||||
if (tb[IFLA_EXT_MASK])
|
||||
ext_filter_mask = nla_get_u32(tb[IFLA_EXT_MASK]);
|
||||
@@ -1294,7 +1304,8 @@ static int do_set_master(struct net_device *dev, int ifindex)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm,
|
||||
static int do_setlink(const struct sk_buff *skb,
|
||||
struct net_device *dev, struct ifinfomsg *ifm,
|
||||
struct nlattr **tb, char *ifname, int modified)
|
||||
{
|
||||
const struct net_device_ops *ops = dev->netdev_ops;
|
||||
@@ -1306,7 +1317,7 @@ static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm,
|
||||
err = PTR_ERR(net);
|
||||
goto errout;
|
||||
}
|
||||
if (!ns_capable(net->user_ns, CAP_NET_ADMIN)) {
|
||||
if (!netlink_ns_capable(skb, net->user_ns, CAP_NET_ADMIN)) {
|
||||
err = -EPERM;
|
||||
goto errout;
|
||||
}
|
||||
@@ -1560,7 +1571,7 @@ static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh)
|
||||
if (err < 0)
|
||||
goto errout;
|
||||
|
||||
err = do_setlink(dev, ifm, tb, ifname, 0);
|
||||
err = do_setlink(skb, dev, ifm, tb, ifname, 0);
|
||||
errout:
|
||||
return err;
|
||||
}
|
||||
@@ -1600,7 +1611,6 @@ static int rtnl_dellink(struct sk_buff *skb, struct nlmsghdr *nlh)
|
||||
|
||||
ops->dellink(dev, &list_kill);
|
||||
unregister_netdevice_many(&list_kill);
|
||||
list_del(&list_kill);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1678,7 +1688,8 @@ err:
|
||||
}
|
||||
EXPORT_SYMBOL(rtnl_create_link);
|
||||
|
||||
static int rtnl_group_changelink(struct net *net, int group,
|
||||
static int rtnl_group_changelink(const struct sk_buff *skb,
|
||||
struct net *net, int group,
|
||||
struct ifinfomsg *ifm,
|
||||
struct nlattr **tb)
|
||||
{
|
||||
@@ -1687,7 +1698,7 @@ static int rtnl_group_changelink(struct net *net, int group,
|
||||
|
||||
for_each_netdev(net, dev) {
|
||||
if (dev->group == group) {
|
||||
err = do_setlink(dev, ifm, tb, NULL, 0);
|
||||
err = do_setlink(skb, dev, ifm, tb, NULL, 0);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
@@ -1789,12 +1800,12 @@ replay:
|
||||
modified = 1;
|
||||
}
|
||||
|
||||
return do_setlink(dev, ifm, tb, ifname, modified);
|
||||
return do_setlink(skb, dev, ifm, tb, ifname, modified);
|
||||
}
|
||||
|
||||
if (!(nlh->nlmsg_flags & NLM_F_CREATE)) {
|
||||
if (ifm->ifi_index == 0 && tb[IFLA_GROUP])
|
||||
return rtnl_group_changelink(net,
|
||||
return rtnl_group_changelink(skb, net,
|
||||
nla_get_u32(tb[IFLA_GROUP]),
|
||||
ifm, tb);
|
||||
return -ENODEV;
|
||||
@@ -1906,9 +1917,13 @@ static u16 rtnl_calcit(struct sk_buff *skb, struct nlmsghdr *nlh)
|
||||
struct nlattr *tb[IFLA_MAX+1];
|
||||
u32 ext_filter_mask = 0;
|
||||
u16 min_ifinfo_dump_size = 0;
|
||||
int hdrlen;
|
||||
|
||||
if (nlmsg_parse(nlh, sizeof(struct ifinfomsg), tb, IFLA_MAX,
|
||||
ifla_policy) >= 0) {
|
||||
/* Same kernel<->userspace interface hack as in rtnl_dump_ifinfo. */
|
||||
hdrlen = nlmsg_len(nlh) < sizeof(struct ifinfomsg) ?
|
||||
sizeof(struct rtgenmsg) : sizeof(struct ifinfomsg);
|
||||
|
||||
if (nlmsg_parse(nlh, hdrlen, tb, IFLA_MAX, ifla_policy) >= 0) {
|
||||
if (tb[IFLA_EXT_MASK])
|
||||
ext_filter_mask = nla_get_u32(tb[IFLA_EXT_MASK]);
|
||||
}
|
||||
@@ -2179,7 +2194,7 @@ static int rtnl_fdb_del(struct sk_buff *skb, struct nlmsghdr *nlh)
|
||||
int err = -EINVAL;
|
||||
__u8 *addr;
|
||||
|
||||
if (!capable(CAP_NET_ADMIN))
|
||||
if (!netlink_capable(skb, CAP_NET_ADMIN))
|
||||
return -EPERM;
|
||||
|
||||
err = nlmsg_parse(nlh, sizeof(*ndm), tb, NDA_MAX, NULL);
|
||||
@@ -2635,7 +2650,7 @@ static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
|
||||
sz_idx = type>>2;
|
||||
kind = type&3;
|
||||
|
||||
if (kind != 2 && !ns_capable(net->user_ns, CAP_NET_ADMIN))
|
||||
if (kind != 2 && !netlink_net_capable(skb, CAP_NET_ADMIN))
|
||||
return -EPERM;
|
||||
|
||||
if (kind == 2 && nlh->nlmsg_flags&NLM_F_DUMP) {
|
||||
|
||||
@@ -142,6 +142,55 @@
|
||||
static DEFINE_MUTEX(proto_list_mutex);
|
||||
static LIST_HEAD(proto_list);
|
||||
|
||||
/**
|
||||
* sk_ns_capable - General socket capability test
|
||||
* @sk: Socket to use a capability on or through
|
||||
* @user_ns: The user namespace of the capability to use
|
||||
* @cap: The capability to use
|
||||
*
|
||||
* Test to see if the opener of the socket had when the socket was
|
||||
* created and the current process has the capability @cap in the user
|
||||
* namespace @user_ns.
|
||||
*/
|
||||
bool sk_ns_capable(const struct sock *sk,
|
||||
struct user_namespace *user_ns, int cap)
|
||||
{
|
||||
return file_ns_capable(sk->sk_socket->file, user_ns, cap) &&
|
||||
ns_capable(user_ns, cap);
|
||||
}
|
||||
EXPORT_SYMBOL(sk_ns_capable);
|
||||
|
||||
/**
|
||||
* sk_capable - Socket global capability test
|
||||
* @sk: Socket to use a capability on or through
|
||||
* @cap: The global capbility to use
|
||||
*
|
||||
* Test to see if the opener of the socket had when the socket was
|
||||
* created and the current process has the capability @cap in all user
|
||||
* namespaces.
|
||||
*/
|
||||
bool sk_capable(const struct sock *sk, int cap)
|
||||
{
|
||||
return sk_ns_capable(sk, &init_user_ns, cap);
|
||||
}
|
||||
EXPORT_SYMBOL(sk_capable);
|
||||
|
||||
/**
|
||||
* sk_net_capable - Network namespace socket capability test
|
||||
* @sk: Socket to use a capability on or through
|
||||
* @cap: The capability to use
|
||||
*
|
||||
* Test to see if the opener of the socket had when the socke was created
|
||||
* and the current process has the capability @cap over the network namespace
|
||||
* the socket is a member of.
|
||||
*/
|
||||
bool sk_net_capable(const struct sock *sk, int cap)
|
||||
{
|
||||
return sk_ns_capable(sk, sock_net(sk)->user_ns, cap);
|
||||
}
|
||||
EXPORT_SYMBOL(sk_net_capable);
|
||||
|
||||
|
||||
#ifdef CONFIG_MEMCG_KMEM
|
||||
int mem_cgroup_sockets_init(struct mem_cgroup *memcg, struct cgroup_subsys *ss)
|
||||
{
|
||||
|
||||
@@ -49,7 +49,7 @@ int sock_diag_put_meminfo(struct sock *sk, struct sk_buff *skb, int attrtype)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(sock_diag_put_meminfo);
|
||||
|
||||
int sock_diag_put_filterinfo(struct sock *sk,
|
||||
int sock_diag_put_filterinfo(bool may_report_filterinfo, struct sock *sk,
|
||||
struct sk_buff *skb, int attrtype)
|
||||
{
|
||||
struct nlattr *attr;
|
||||
@@ -57,7 +57,7 @@ int sock_diag_put_filterinfo(struct sock *sk,
|
||||
unsigned int len;
|
||||
int err = 0;
|
||||
|
||||
if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN)) {
|
||||
if (!may_report_filterinfo) {
|
||||
nla_reserve(skb, attrtype, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1670,7 +1670,7 @@ static int dcb_doit(struct sk_buff *skb, struct nlmsghdr *nlh)
|
||||
struct nlmsghdr *reply_nlh = NULL;
|
||||
const struct reply_func *fn;
|
||||
|
||||
if ((nlh->nlmsg_type == RTM_SETDCB) && !capable(CAP_NET_ADMIN))
|
||||
if ((nlh->nlmsg_type == RTM_SETDCB) && !netlink_capable(skb, CAP_NET_ADMIN))
|
||||
return -EPERM;
|
||||
|
||||
ret = nlmsg_parse(nlh, sizeof(*dcb), tb, DCB_ATTR_MAX,
|
||||
|
||||
@@ -573,7 +573,7 @@ static int dn_nl_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh)
|
||||
struct dn_ifaddr __rcu **ifap;
|
||||
int err = -EINVAL;
|
||||
|
||||
if (!capable(CAP_NET_ADMIN))
|
||||
if (!netlink_capable(skb, CAP_NET_ADMIN))
|
||||
return -EPERM;
|
||||
|
||||
if (!net_eq(net, &init_net))
|
||||
@@ -617,7 +617,7 @@ static int dn_nl_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh)
|
||||
struct dn_ifaddr *ifa;
|
||||
int err;
|
||||
|
||||
if (!capable(CAP_NET_ADMIN))
|
||||
if (!netlink_capable(skb, CAP_NET_ADMIN))
|
||||
return -EPERM;
|
||||
|
||||
if (!net_eq(net, &init_net))
|
||||
|
||||
@@ -505,7 +505,7 @@ static int dn_fib_rtm_delroute(struct sk_buff *skb, struct nlmsghdr *nlh)
|
||||
struct nlattr *attrs[RTA_MAX+1];
|
||||
int err;
|
||||
|
||||
if (!capable(CAP_NET_ADMIN))
|
||||
if (!netlink_capable(skb, CAP_NET_ADMIN))
|
||||
return -EPERM;
|
||||
|
||||
if (!net_eq(net, &init_net))
|
||||
@@ -530,7 +530,7 @@ static int dn_fib_rtm_newroute(struct sk_buff *skb, struct nlmsghdr *nlh)
|
||||
struct nlattr *attrs[RTA_MAX+1];
|
||||
int err;
|
||||
|
||||
if (!capable(CAP_NET_ADMIN))
|
||||
if (!netlink_capable(skb, CAP_NET_ADMIN))
|
||||
return -EPERM;
|
||||
|
||||
if (!net_eq(net, &init_net))
|
||||
|
||||
@@ -107,7 +107,7 @@ static inline void dnrmg_receive_user_skb(struct sk_buff *skb)
|
||||
if (nlh->nlmsg_len < sizeof(*nlh) || skb->len < nlh->nlmsg_len)
|
||||
return;
|
||||
|
||||
if (!capable(CAP_NET_ADMIN))
|
||||
if (!netlink_capable(skb, CAP_NET_ADMIN))
|
||||
RCV_SKB_FAIL(-EPERM);
|
||||
|
||||
/* Eventually we might send routing messages too */
|
||||
|
||||
@@ -86,18 +86,26 @@ out:
|
||||
}
|
||||
EXPORT_SYMBOL(ip4_datagram_connect);
|
||||
|
||||
/* Because UDP xmit path can manipulate sk_dst_cache without holding
|
||||
* socket lock, we need to use sk_dst_set() here,
|
||||
* even if we own the socket lock.
|
||||
*/
|
||||
void ip4_datagram_release_cb(struct sock *sk)
|
||||
{
|
||||
const struct inet_sock *inet = inet_sk(sk);
|
||||
const struct ip_options_rcu *inet_opt;
|
||||
__be32 daddr = inet->inet_daddr;
|
||||
struct dst_entry *dst;
|
||||
struct flowi4 fl4;
|
||||
struct rtable *rt;
|
||||
|
||||
if (! __sk_dst_get(sk) || __sk_dst_check(sk, 0))
|
||||
return;
|
||||
|
||||
rcu_read_lock();
|
||||
|
||||
dst = __sk_dst_get(sk);
|
||||
if (!dst || !dst->obsolete || dst->ops->check(dst, 0)) {
|
||||
rcu_read_unlock();
|
||||
return;
|
||||
}
|
||||
inet_opt = rcu_dereference(inet->inet_opt);
|
||||
if (inet_opt && inet_opt->opt.srr)
|
||||
daddr = inet_opt->opt.faddr;
|
||||
@@ -105,8 +113,10 @@ void ip4_datagram_release_cb(struct sock *sk)
|
||||
inet->inet_saddr, inet->inet_dport,
|
||||
inet->inet_sport, sk->sk_protocol,
|
||||
RT_CONN_FLAGS(sk), sk->sk_bound_dev_if);
|
||||
if (!IS_ERR(rt))
|
||||
__sk_dst_set(sk, &rt->dst);
|
||||
|
||||
dst = !IS_ERR(rt) ? &rt->dst : NULL;
|
||||
sk_dst_set(sk, dst);
|
||||
|
||||
rcu_read_unlock();
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ip4_datagram_release_cb);
|
||||
|
||||
@@ -149,13 +149,13 @@ static int ipip_err(struct sk_buff *skb, u32 info)
|
||||
|
||||
if (type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED) {
|
||||
ipv4_update_pmtu(skb, dev_net(skb->dev), info,
|
||||
t->dev->ifindex, 0, IPPROTO_IPIP, 0);
|
||||
t->parms.link, 0, IPPROTO_IPIP, 0);
|
||||
err = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (type == ICMP_REDIRECT) {
|
||||
ipv4_redirect(skb, dev_net(skb->dev), t->dev->ifindex, 0,
|
||||
ipv4_redirect(skb, dev_net(skb->dev), t->parms.link, 0,
|
||||
IPPROTO_IPIP, 0);
|
||||
err = 0;
|
||||
goto out;
|
||||
@@ -483,4 +483,5 @@ static void __exit ipip_fini(void)
|
||||
module_init(ipip_init);
|
||||
module_exit(ipip_fini);
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS_RTNL_LINK("ipip");
|
||||
MODULE_ALIAS_NETDEV("tunl0");
|
||||
|
||||
@@ -2720,13 +2720,12 @@ static void tcp_process_loss(struct sock *sk, int flag, bool is_dupack)
|
||||
bool recovered = !before(tp->snd_una, tp->high_seq);
|
||||
|
||||
if (tp->frto) { /* F-RTO RFC5682 sec 3.1 (sack enhanced version). */
|
||||
if (flag & FLAG_ORIG_SACK_ACKED) {
|
||||
/* Step 3.b. A timeout is spurious if not all data are
|
||||
* lost, i.e., never-retransmitted data are (s)acked.
|
||||
*/
|
||||
tcp_try_undo_loss(sk, true);
|
||||
/* Step 3.b. A timeout is spurious if not all data are
|
||||
* lost, i.e., never-retransmitted data are (s)acked.
|
||||
*/
|
||||
if (tcp_try_undo_loss(sk, flag & FLAG_ORIG_SACK_ACKED))
|
||||
return;
|
||||
}
|
||||
|
||||
if (after(tp->snd_nxt, tp->high_seq) &&
|
||||
(flag & FLAG_DATA_SACKED || is_dupack)) {
|
||||
tp->frto = 0; /* Loss was real: 2nd part of step 3.a */
|
||||
|
||||
@@ -61,6 +61,7 @@
|
||||
MODULE_AUTHOR("Ville Nuorvala");
|
||||
MODULE_DESCRIPTION("IPv6 tunneling device");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS_RTNL_LINK("ip6tnl");
|
||||
MODULE_ALIAS_NETDEV("ip6tnl0");
|
||||
|
||||
#ifdef IP6_TNL_DEBUG
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
void ipv6_select_ident(struct frag_hdr *fhdr, struct rt6_info *rt)
|
||||
{
|
||||
static atomic_t ipv6_fragmentation_id;
|
||||
int old, new;
|
||||
int ident;
|
||||
|
||||
#if IS_ENABLED(CONFIG_IPV6)
|
||||
if (rt && !(rt->dst.flags & DST_NOPEER)) {
|
||||
@@ -25,13 +25,8 @@ void ipv6_select_ident(struct frag_hdr *fhdr, struct rt6_info *rt)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
do {
|
||||
old = atomic_read(&ipv6_fragmentation_id);
|
||||
new = old + 1;
|
||||
if (!new)
|
||||
new = 1;
|
||||
} while (atomic_cmpxchg(&ipv6_fragmentation_id, old, new) != old);
|
||||
fhdr->identification = htonl(new);
|
||||
ident = atomic_inc_return(&ipv6_fragmentation_id);
|
||||
fhdr->identification = htonl(ident);
|
||||
}
|
||||
EXPORT_SYMBOL(ipv6_select_ident);
|
||||
|
||||
|
||||
@@ -530,12 +530,12 @@ static int ipip6_err(struct sk_buff *skb, u32 info)
|
||||
|
||||
if (type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED) {
|
||||
ipv4_update_pmtu(skb, dev_net(skb->dev), info,
|
||||
t->dev->ifindex, 0, IPPROTO_IPV6, 0);
|
||||
t->parms.link, 0, IPPROTO_IPV6, 0);
|
||||
err = 0;
|
||||
goto out;
|
||||
}
|
||||
if (type == ICMP_REDIRECT) {
|
||||
ipv4_redirect(skb, dev_net(skb->dev), t->dev->ifindex, 0,
|
||||
ipv4_redirect(skb, dev_net(skb->dev), t->parms.link, 0,
|
||||
IPPROTO_IPV6, 0);
|
||||
err = 0;
|
||||
goto out;
|
||||
@@ -1654,4 +1654,5 @@ xfrm_tunnel_failed:
|
||||
module_init(sit_init);
|
||||
module_exit(sit_cleanup);
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS_RTNL_LINK("sit");
|
||||
MODULE_ALIAS_NETDEV("sit0");
|
||||
|
||||
@@ -1746,7 +1746,6 @@ void ieee80211_remove_interfaces(struct ieee80211_local *local)
|
||||
}
|
||||
mutex_unlock(&local->iflist_mtx);
|
||||
unregister_netdevice_many(&unreg_list);
|
||||
list_del(&unreg_list);
|
||||
|
||||
list_for_each_entry_safe(sdata, tmp, &wdev_list, list) {
|
||||
list_del(&sdata->list);
|
||||
|
||||
@@ -147,7 +147,7 @@ static int nfnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
|
||||
const struct nfnetlink_subsystem *ss;
|
||||
int type, err;
|
||||
|
||||
if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
|
||||
if (!netlink_net_capable(skb, CAP_NET_ADMIN))
|
||||
return -EPERM;
|
||||
|
||||
/* All the messages must at least contain nfgenmsg */
|
||||
|
||||
@@ -1219,7 +1219,74 @@ retry:
|
||||
return err;
|
||||
}
|
||||
|
||||
static inline int netlink_capable(const struct socket *sock, unsigned int flag)
|
||||
/**
|
||||
* __netlink_ns_capable - General netlink message capability test
|
||||
* @nsp: NETLINK_CB of the socket buffer holding a netlink command from userspace.
|
||||
* @user_ns: The user namespace of the capability to use
|
||||
* @cap: The capability to use
|
||||
*
|
||||
* Test to see if the opener of the socket we received the message
|
||||
* from had when the netlink socket was created and the sender of the
|
||||
* message has has the capability @cap in the user namespace @user_ns.
|
||||
*/
|
||||
bool __netlink_ns_capable(const struct netlink_skb_parms *nsp,
|
||||
struct user_namespace *user_ns, int cap)
|
||||
{
|
||||
return ((nsp->flags & NETLINK_SKB_DST) ||
|
||||
file_ns_capable(nsp->sk->sk_socket->file, user_ns, cap)) &&
|
||||
ns_capable(user_ns, cap);
|
||||
}
|
||||
EXPORT_SYMBOL(__netlink_ns_capable);
|
||||
|
||||
/**
|
||||
* netlink_ns_capable - General netlink message capability test
|
||||
* @skb: socket buffer holding a netlink command from userspace
|
||||
* @user_ns: The user namespace of the capability to use
|
||||
* @cap: The capability to use
|
||||
*
|
||||
* Test to see if the opener of the socket we received the message
|
||||
* from had when the netlink socket was created and the sender of the
|
||||
* message has has the capability @cap in the user namespace @user_ns.
|
||||
*/
|
||||
bool netlink_ns_capable(const struct sk_buff *skb,
|
||||
struct user_namespace *user_ns, int cap)
|
||||
{
|
||||
return __netlink_ns_capable(&NETLINK_CB(skb), user_ns, cap);
|
||||
}
|
||||
EXPORT_SYMBOL(netlink_ns_capable);
|
||||
|
||||
/**
|
||||
* netlink_capable - Netlink global message capability test
|
||||
* @skb: socket buffer holding a netlink command from userspace
|
||||
* @cap: The capability to use
|
||||
*
|
||||
* Test to see if the opener of the socket we received the message
|
||||
* from had when the netlink socket was created and the sender of the
|
||||
* message has has the capability @cap in all user namespaces.
|
||||
*/
|
||||
bool netlink_capable(const struct sk_buff *skb, int cap)
|
||||
{
|
||||
return netlink_ns_capable(skb, &init_user_ns, cap);
|
||||
}
|
||||
EXPORT_SYMBOL(netlink_capable);
|
||||
|
||||
/**
|
||||
* netlink_net_capable - Netlink network namespace message capability test
|
||||
* @skb: socket buffer holding a netlink command from userspace
|
||||
* @cap: The capability to use
|
||||
*
|
||||
* Test to see if the opener of the socket we received the message
|
||||
* from had when the netlink socket was created and the sender of the
|
||||
* message has has the capability @cap over the network namespace of
|
||||
* the socket we received the message from.
|
||||
*/
|
||||
bool netlink_net_capable(const struct sk_buff *skb, int cap)
|
||||
{
|
||||
return netlink_ns_capable(skb, sock_net(skb->sk)->user_ns, cap);
|
||||
}
|
||||
EXPORT_SYMBOL(netlink_net_capable);
|
||||
|
||||
static inline int netlink_allowed(const struct socket *sock, unsigned int flag)
|
||||
{
|
||||
return (nl_table[sock->sk->sk_protocol].flags & flag) ||
|
||||
ns_capable(sock_net(sock->sk)->user_ns, CAP_NET_ADMIN);
|
||||
@@ -1287,7 +1354,7 @@ static int netlink_bind(struct socket *sock, struct sockaddr *addr,
|
||||
|
||||
/* Only superuser is allowed to listen multicasts */
|
||||
if (nladdr->nl_groups) {
|
||||
if (!netlink_capable(sock, NL_CFG_F_NONROOT_RECV))
|
||||
if (!netlink_allowed(sock, NL_CFG_F_NONROOT_RECV))
|
||||
return -EPERM;
|
||||
err = netlink_realloc_groups(sk);
|
||||
if (err)
|
||||
@@ -1349,7 +1416,7 @@ static int netlink_connect(struct socket *sock, struct sockaddr *addr,
|
||||
return -EINVAL;
|
||||
|
||||
/* Only superuser is allowed to send multicasts */
|
||||
if (nladdr->nl_groups && !netlink_capable(sock, NL_CFG_F_NONROOT_SEND))
|
||||
if (nladdr->nl_groups && !netlink_allowed(sock, NL_CFG_F_NONROOT_SEND))
|
||||
return -EPERM;
|
||||
|
||||
if (!nlk->portid)
|
||||
@@ -1921,7 +1988,7 @@ static int netlink_setsockopt(struct socket *sock, int level, int optname,
|
||||
break;
|
||||
case NETLINK_ADD_MEMBERSHIP:
|
||||
case NETLINK_DROP_MEMBERSHIP: {
|
||||
if (!netlink_capable(sock, NL_CFG_F_NONROOT_RECV))
|
||||
if (!netlink_allowed(sock, NL_CFG_F_NONROOT_RECV))
|
||||
return -EPERM;
|
||||
err = netlink_realloc_groups(sk);
|
||||
if (err)
|
||||
@@ -2053,6 +2120,7 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock,
|
||||
struct sk_buff *skb;
|
||||
int err;
|
||||
struct scm_cookie scm;
|
||||
u32 netlink_skb_flags = 0;
|
||||
|
||||
if (msg->msg_flags&MSG_OOB)
|
||||
return -EOPNOTSUPP;
|
||||
@@ -2072,8 +2140,9 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock,
|
||||
dst_group = ffs(addr->nl_groups);
|
||||
err = -EPERM;
|
||||
if ((dst_group || dst_portid) &&
|
||||
!netlink_capable(sock, NL_CFG_F_NONROOT_SEND))
|
||||
!netlink_allowed(sock, NL_CFG_F_NONROOT_SEND))
|
||||
goto out;
|
||||
netlink_skb_flags |= NETLINK_SKB_DST;
|
||||
} else {
|
||||
dst_portid = nlk->dst_portid;
|
||||
dst_group = nlk->dst_group;
|
||||
@@ -2103,6 +2172,7 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock,
|
||||
NETLINK_CB(skb).portid = nlk->portid;
|
||||
NETLINK_CB(skb).dst_group = dst_group;
|
||||
NETLINK_CB(skb).creds = siocb->scm->creds;
|
||||
NETLINK_CB(skb).flags = netlink_skb_flags;
|
||||
|
||||
err = -EFAULT;
|
||||
if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) {
|
||||
|
||||
@@ -592,7 +592,7 @@ static int genl_family_rcv_msg(struct genl_family *family,
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if ((ops->flags & GENL_ADMIN_PERM) &&
|
||||
!capable(CAP_NET_ADMIN))
|
||||
!netlink_capable(skb, CAP_NET_ADMIN))
|
||||
return -EPERM;
|
||||
|
||||
if (nlh->nlmsg_flags & NLM_F_DUMP) {
|
||||
|
||||
@@ -127,6 +127,7 @@ static int pdiag_put_fanout(struct packet_sock *po, struct sk_buff *nlskb)
|
||||
|
||||
static int sk_diag_fill(struct sock *sk, struct sk_buff *skb,
|
||||
struct packet_diag_req *req,
|
||||
bool may_report_filterinfo,
|
||||
struct user_namespace *user_ns,
|
||||
u32 portid, u32 seq, u32 flags, int sk_ino)
|
||||
{
|
||||
@@ -171,7 +172,8 @@ static int sk_diag_fill(struct sock *sk, struct sk_buff *skb,
|
||||
goto out_nlmsg_trim;
|
||||
|
||||
if ((req->pdiag_show & PACKET_SHOW_FILTER) &&
|
||||
sock_diag_put_filterinfo(sk, skb, PACKET_DIAG_FILTER))
|
||||
sock_diag_put_filterinfo(may_report_filterinfo, sk, skb,
|
||||
PACKET_DIAG_FILTER))
|
||||
goto out_nlmsg_trim;
|
||||
|
||||
return nlmsg_end(skb, nlh);
|
||||
@@ -187,9 +189,11 @@ static int packet_diag_dump(struct sk_buff *skb, struct netlink_callback *cb)
|
||||
struct packet_diag_req *req;
|
||||
struct net *net;
|
||||
struct sock *sk;
|
||||
bool may_report_filterinfo;
|
||||
|
||||
net = sock_net(skb->sk);
|
||||
req = nlmsg_data(cb->nlh);
|
||||
may_report_filterinfo = netlink_net_capable(cb->skb, CAP_NET_ADMIN);
|
||||
|
||||
mutex_lock(&net->packet.sklist_lock);
|
||||
sk_for_each(sk, &net->packet.sklist) {
|
||||
@@ -199,6 +203,7 @@ static int packet_diag_dump(struct sk_buff *skb, struct netlink_callback *cb)
|
||||
goto next;
|
||||
|
||||
if (sk_diag_fill(sk, skb, req,
|
||||
may_report_filterinfo,
|
||||
sk_user_ns(NETLINK_CB(cb->skb).sk),
|
||||
NETLINK_CB(cb->skb).portid,
|
||||
cb->nlh->nlmsg_seq, NLM_F_MULTI,
|
||||
|
||||
@@ -70,10 +70,10 @@ static int addr_doit(struct sk_buff *skb, struct nlmsghdr *nlh)
|
||||
int err;
|
||||
u8 pnaddr;
|
||||
|
||||
if (!capable(CAP_NET_ADMIN))
|
||||
if (!netlink_capable(skb, CAP_NET_ADMIN))
|
||||
return -EPERM;
|
||||
|
||||
if (!capable(CAP_SYS_ADMIN))
|
||||
if (!netlink_capable(skb, CAP_SYS_ADMIN))
|
||||
return -EPERM;
|
||||
|
||||
ASSERT_RTNL();
|
||||
@@ -233,10 +233,10 @@ static int route_doit(struct sk_buff *skb, struct nlmsghdr *nlh)
|
||||
int err;
|
||||
u8 dst;
|
||||
|
||||
if (!capable(CAP_NET_ADMIN))
|
||||
if (!netlink_capable(skb, CAP_NET_ADMIN))
|
||||
return -EPERM;
|
||||
|
||||
if (!capable(CAP_SYS_ADMIN))
|
||||
if (!netlink_capable(skb, CAP_SYS_ADMIN))
|
||||
return -EPERM;
|
||||
|
||||
ASSERT_RTNL();
|
||||
|
||||
@@ -989,7 +989,7 @@ static int tc_ctl_action(struct sk_buff *skb, struct nlmsghdr *n)
|
||||
u32 portid = skb ? NETLINK_CB(skb).portid : 0;
|
||||
int ret = 0, ovr = 0;
|
||||
|
||||
if ((n->nlmsg_type != RTM_GETACTION) && !capable(CAP_NET_ADMIN))
|
||||
if ((n->nlmsg_type != RTM_GETACTION) && !netlink_capable(skb, CAP_NET_ADMIN))
|
||||
return -EPERM;
|
||||
|
||||
ret = nlmsg_parse(n, sizeof(struct tcamsg), tca, TCA_ACT_MAX, NULL);
|
||||
|
||||
@@ -138,7 +138,7 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n)
|
||||
int err;
|
||||
int tp_created = 0;
|
||||
|
||||
if ((n->nlmsg_type != RTM_GETTFILTER) && !capable(CAP_NET_ADMIN))
|
||||
if ((n->nlmsg_type != RTM_GETTFILTER) && !netlink_capable(skb, CAP_NET_ADMIN))
|
||||
return -EPERM;
|
||||
|
||||
replay:
|
||||
|
||||
@@ -1024,7 +1024,7 @@ static int tc_get_qdisc(struct sk_buff *skb, struct nlmsghdr *n)
|
||||
struct Qdisc *p = NULL;
|
||||
int err;
|
||||
|
||||
if ((n->nlmsg_type != RTM_GETQDISC) && !capable(CAP_NET_ADMIN))
|
||||
if ((n->nlmsg_type != RTM_GETQDISC) && !netlink_capable(skb, CAP_NET_ADMIN))
|
||||
return -EPERM;
|
||||
|
||||
err = nlmsg_parse(n, sizeof(*tcm), tca, TCA_MAX, NULL);
|
||||
@@ -1091,7 +1091,7 @@ static int tc_modify_qdisc(struct sk_buff *skb, struct nlmsghdr *n)
|
||||
struct Qdisc *q, *p;
|
||||
int err;
|
||||
|
||||
if (!capable(CAP_NET_ADMIN))
|
||||
if (!netlink_capable(skb, CAP_NET_ADMIN))
|
||||
return -EPERM;
|
||||
|
||||
replay:
|
||||
@@ -1431,7 +1431,7 @@ static int tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n)
|
||||
u32 qid;
|
||||
int err;
|
||||
|
||||
if ((n->nlmsg_type != RTM_GETTCLASS) && !capable(CAP_NET_ADMIN))
|
||||
if ((n->nlmsg_type != RTM_GETTCLASS) && !netlink_capable(skb, CAP_NET_ADMIN))
|
||||
return -EPERM;
|
||||
|
||||
err = nlmsg_parse(n, sizeof(*tcm), tca, TCA_MAX, NULL);
|
||||
|
||||
@@ -387,7 +387,7 @@ void sctp_association_free(struct sctp_association *asoc)
|
||||
/* Only real associations count against the endpoint, so
|
||||
* don't bother for if this is a temporary association.
|
||||
*/
|
||||
if (!asoc->temp) {
|
||||
if (!list_empty(&asoc->asocs)) {
|
||||
list_del(&asoc->asocs);
|
||||
|
||||
/* Decrement the backlog value for a TCP-style listening
|
||||
|
||||
@@ -47,7 +47,7 @@ static int handle_cmd(struct sk_buff *skb, struct genl_info *info)
|
||||
int hdr_space = nlmsg_total_size(GENL_HDRLEN + TIPC_GENL_HDRLEN);
|
||||
u16 cmd;
|
||||
|
||||
if ((req_userhdr->cmd & 0xC000) && (!capable(CAP_NET_ADMIN)))
|
||||
if ((req_userhdr->cmd & 0xC000) && (!netlink_capable(skb, CAP_NET_ADMIN)))
|
||||
cmd = TIPC_CMD_NOT_NET_ADMIN;
|
||||
else
|
||||
cmd = req_userhdr->cmd;
|
||||
|
||||
@@ -2362,7 +2362,7 @@ static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
|
||||
link = &xfrm_dispatch[type];
|
||||
|
||||
/* All operations require privileges, even GET */
|
||||
if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
|
||||
if (!netlink_net_capable(skb, CAP_NET_ADMIN))
|
||||
return -EPERM;
|
||||
|
||||
if ((type == (XFRM_MSG_GETSA - XFRM_MSG_BASE) ||
|
||||
|
||||
@@ -275,12 +275,20 @@ static int evm_protect_xattr(struct dentry *dentry, const char *xattr_name,
|
||||
* @xattr_value: pointer to the new extended attribute value
|
||||
* @xattr_value_len: pointer to the new extended attribute value length
|
||||
*
|
||||
* Updating 'security.evm' requires CAP_SYS_ADMIN privileges and that
|
||||
* the current value is valid.
|
||||
* Before allowing the 'security.evm' protected xattr to be updated,
|
||||
* verify the existing value is valid. As only the kernel should have
|
||||
* access to the EVM encrypted key needed to calculate the HMAC, prevent
|
||||
* userspace from writing HMAC value. Writing 'security.evm' requires
|
||||
* requires CAP_SYS_ADMIN privileges.
|
||||
*/
|
||||
int evm_inode_setxattr(struct dentry *dentry, const char *xattr_name,
|
||||
const void *xattr_value, size_t xattr_value_len)
|
||||
{
|
||||
const struct evm_ima_xattr_data *xattr_data = xattr_value;
|
||||
|
||||
if ((strcmp(xattr_name, XATTR_NAME_EVM) == 0)
|
||||
&& (xattr_data->type == EVM_XATTR_HMAC))
|
||||
return -EPERM;
|
||||
return evm_protect_xattr(dentry, xattr_name, xattr_value,
|
||||
xattr_value_len);
|
||||
}
|
||||
|
||||
@@ -24,6 +24,36 @@
|
||||
|
||||
static struct crypto_shash *ima_shash_tfm;
|
||||
|
||||
/**
|
||||
* ima_kernel_read - read file content
|
||||
*
|
||||
* This is a function for reading file content instead of kernel_read().
|
||||
* It does not perform locking checks to ensure it cannot be blocked.
|
||||
* It does not perform security checks because it is irrelevant for IMA.
|
||||
*
|
||||
*/
|
||||
static int ima_kernel_read(struct file *file, loff_t offset,
|
||||
char *addr, unsigned long count)
|
||||
{
|
||||
mm_segment_t old_fs;
|
||||
char __user *buf = addr;
|
||||
ssize_t ret;
|
||||
|
||||
if (!(file->f_mode & FMODE_READ))
|
||||
return -EBADF;
|
||||
if (!file->f_op->read && !file->f_op->aio_read)
|
||||
return -EINVAL;
|
||||
|
||||
old_fs = get_fs();
|
||||
set_fs(get_ds());
|
||||
if (file->f_op->read)
|
||||
ret = file->f_op->read(file, buf, count, &offset);
|
||||
else
|
||||
ret = do_sync_read(file, buf, count, &offset);
|
||||
set_fs(old_fs);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ima_init_crypto(void)
|
||||
{
|
||||
long rc;
|
||||
@@ -70,7 +100,7 @@ int ima_calc_file_hash(struct file *file, char *digest)
|
||||
while (offset < i_size) {
|
||||
int rbuf_len;
|
||||
|
||||
rbuf_len = kernel_read(file, offset, rbuf, PAGE_SIZE);
|
||||
rbuf_len = ima_kernel_read(file, offset, rbuf, PAGE_SIZE);
|
||||
if (rbuf_len < 0) {
|
||||
rc = rbuf_len;
|
||||
break;
|
||||
|
||||
@@ -289,6 +289,10 @@ static bool snd_ctl_remove_numid_conflict(struct snd_card *card,
|
||||
{
|
||||
struct snd_kcontrol *kctl;
|
||||
|
||||
/* Make sure that the ids assigned to the control do not wrap around */
|
||||
if (card->last_numid >= UINT_MAX - count)
|
||||
card->last_numid = 0;
|
||||
|
||||
list_for_each_entry(kctl, &card->controls, list) {
|
||||
if (kctl->id.numid < card->last_numid + 1 + count &&
|
||||
kctl->id.numid + kctl->count > card->last_numid + 1) {
|
||||
@@ -331,6 +335,7 @@ int snd_ctl_add(struct snd_card *card, struct snd_kcontrol *kcontrol)
|
||||
{
|
||||
struct snd_ctl_elem_id id;
|
||||
unsigned int idx;
|
||||
unsigned int count;
|
||||
int err = -EINVAL;
|
||||
|
||||
if (! kcontrol)
|
||||
@@ -338,6 +343,9 @@ int snd_ctl_add(struct snd_card *card, struct snd_kcontrol *kcontrol)
|
||||
if (snd_BUG_ON(!card || !kcontrol->info))
|
||||
goto error;
|
||||
id = kcontrol->id;
|
||||
if (id.index > UINT_MAX - kcontrol->count)
|
||||
goto error;
|
||||
|
||||
down_write(&card->controls_rwsem);
|
||||
if (snd_ctl_find_id(card, &id)) {
|
||||
up_write(&card->controls_rwsem);
|
||||
@@ -359,8 +367,9 @@ int snd_ctl_add(struct snd_card *card, struct snd_kcontrol *kcontrol)
|
||||
card->controls_count += kcontrol->count;
|
||||
kcontrol->id.numid = card->last_numid + 1;
|
||||
card->last_numid += kcontrol->count;
|
||||
count = kcontrol->count;
|
||||
up_write(&card->controls_rwsem);
|
||||
for (idx = 0; idx < kcontrol->count; idx++, id.index++, id.numid++)
|
||||
for (idx = 0; idx < count; idx++, id.index++, id.numid++)
|
||||
snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_ADD, &id);
|
||||
return 0;
|
||||
|
||||
@@ -389,6 +398,7 @@ int snd_ctl_replace(struct snd_card *card, struct snd_kcontrol *kcontrol,
|
||||
bool add_on_replace)
|
||||
{
|
||||
struct snd_ctl_elem_id id;
|
||||
unsigned int count;
|
||||
unsigned int idx;
|
||||
struct snd_kcontrol *old;
|
||||
int ret;
|
||||
@@ -424,8 +434,9 @@ add:
|
||||
card->controls_count += kcontrol->count;
|
||||
kcontrol->id.numid = card->last_numid + 1;
|
||||
card->last_numid += kcontrol->count;
|
||||
count = kcontrol->count;
|
||||
up_write(&card->controls_rwsem);
|
||||
for (idx = 0; idx < kcontrol->count; idx++, id.index++, id.numid++)
|
||||
for (idx = 0; idx < count; idx++, id.index++, id.numid++)
|
||||
snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_ADD, &id);
|
||||
return 0;
|
||||
|
||||
@@ -898,9 +909,9 @@ static int snd_ctl_elem_write(struct snd_card *card, struct snd_ctl_file *file,
|
||||
result = kctl->put(kctl, control);
|
||||
}
|
||||
if (result > 0) {
|
||||
struct snd_ctl_elem_id id = control->id;
|
||||
up_read(&card->controls_rwsem);
|
||||
snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE,
|
||||
&control->id);
|
||||
snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, &id);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -992,6 +1003,7 @@ static int snd_ctl_elem_unlock(struct snd_ctl_file *file,
|
||||
|
||||
struct user_element {
|
||||
struct snd_ctl_elem_info info;
|
||||
struct snd_card *card;
|
||||
void *elem_data; /* element data */
|
||||
unsigned long elem_data_size; /* size of element data in bytes */
|
||||
void *tlv_data; /* TLV data */
|
||||
@@ -1035,7 +1047,9 @@ static int snd_ctl_elem_user_get(struct snd_kcontrol *kcontrol,
|
||||
{
|
||||
struct user_element *ue = kcontrol->private_data;
|
||||
|
||||
mutex_lock(&ue->card->user_ctl_lock);
|
||||
memcpy(&ucontrol->value, ue->elem_data, ue->elem_data_size);
|
||||
mutex_unlock(&ue->card->user_ctl_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1044,10 +1058,12 @@ static int snd_ctl_elem_user_put(struct snd_kcontrol *kcontrol,
|
||||
{
|
||||
int change;
|
||||
struct user_element *ue = kcontrol->private_data;
|
||||
|
||||
|
||||
mutex_lock(&ue->card->user_ctl_lock);
|
||||
change = memcmp(&ucontrol->value, ue->elem_data, ue->elem_data_size) != 0;
|
||||
if (change)
|
||||
memcpy(ue->elem_data, &ucontrol->value, ue->elem_data_size);
|
||||
mutex_unlock(&ue->card->user_ctl_lock);
|
||||
return change;
|
||||
}
|
||||
|
||||
@@ -1067,19 +1083,32 @@ static int snd_ctl_elem_user_tlv(struct snd_kcontrol *kcontrol,
|
||||
new_data = memdup_user(tlv, size);
|
||||
if (IS_ERR(new_data))
|
||||
return PTR_ERR(new_data);
|
||||
mutex_lock(&ue->card->user_ctl_lock);
|
||||
change = ue->tlv_data_size != size;
|
||||
if (!change)
|
||||
change = memcmp(ue->tlv_data, new_data, size);
|
||||
kfree(ue->tlv_data);
|
||||
ue->tlv_data = new_data;
|
||||
ue->tlv_data_size = size;
|
||||
mutex_unlock(&ue->card->user_ctl_lock);
|
||||
} else {
|
||||
if (! ue->tlv_data_size || ! ue->tlv_data)
|
||||
return -ENXIO;
|
||||
if (size < ue->tlv_data_size)
|
||||
return -ENOSPC;
|
||||
int ret = 0;
|
||||
|
||||
mutex_lock(&ue->card->user_ctl_lock);
|
||||
if (!ue->tlv_data_size || !ue->tlv_data) {
|
||||
ret = -ENXIO;
|
||||
goto err_unlock;
|
||||
}
|
||||
if (size < ue->tlv_data_size) {
|
||||
ret = -ENOSPC;
|
||||
goto err_unlock;
|
||||
}
|
||||
if (copy_to_user(tlv, ue->tlv_data, ue->tlv_data_size))
|
||||
return -EFAULT;
|
||||
ret = -EFAULT;
|
||||
err_unlock:
|
||||
mutex_unlock(&ue->card->user_ctl_lock);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
return change;
|
||||
}
|
||||
@@ -1137,8 +1166,6 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file,
|
||||
struct user_element *ue;
|
||||
int idx, err;
|
||||
|
||||
if (!replace && card->user_ctl_count >= MAX_USER_CONTROLS)
|
||||
return -ENOMEM;
|
||||
if (info->count < 1)
|
||||
return -EINVAL;
|
||||
access = info->access == 0 ? SNDRV_CTL_ELEM_ACCESS_READWRITE :
|
||||
@@ -1147,21 +1174,16 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file,
|
||||
SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE));
|
||||
info->id.numid = 0;
|
||||
memset(&kctl, 0, sizeof(kctl));
|
||||
down_write(&card->controls_rwsem);
|
||||
_kctl = snd_ctl_find_id(card, &info->id);
|
||||
err = 0;
|
||||
if (_kctl) {
|
||||
if (replace)
|
||||
err = snd_ctl_remove(card, _kctl);
|
||||
else
|
||||
err = -EBUSY;
|
||||
} else {
|
||||
if (replace)
|
||||
err = -ENOENT;
|
||||
|
||||
if (replace) {
|
||||
err = snd_ctl_remove_user_ctl(file, &info->id);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
up_write(&card->controls_rwsem);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
if (card->user_ctl_count >= MAX_USER_CONTROLS)
|
||||
return -ENOMEM;
|
||||
|
||||
memcpy(&kctl.id, &info->id, sizeof(info->id));
|
||||
kctl.count = info->owner ? info->owner : 1;
|
||||
access |= SNDRV_CTL_ELEM_ACCESS_USER;
|
||||
@@ -1211,6 +1233,7 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file,
|
||||
ue = kzalloc(sizeof(struct user_element) + private_size, GFP_KERNEL);
|
||||
if (ue == NULL)
|
||||
return -ENOMEM;
|
||||
ue->card = card;
|
||||
ue->info = *info;
|
||||
ue->info.access = 0;
|
||||
ue->elem_data = (char *)ue + sizeof(*ue);
|
||||
@@ -1322,8 +1345,9 @@ static int snd_ctl_tlv_ioctl(struct snd_ctl_file *file,
|
||||
}
|
||||
err = kctl->tlv.c(kctl, op_flag, tlv.length, _tlv->tlv);
|
||||
if (err > 0) {
|
||||
struct snd_ctl_elem_id id = kctl->id;
|
||||
up_read(&card->controls_rwsem);
|
||||
snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_TLV, &kctl->id);
|
||||
snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_TLV, &id);
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -208,6 +208,7 @@ int snd_card_create(int idx, const char *xid,
|
||||
INIT_LIST_HEAD(&card->devices);
|
||||
init_rwsem(&card->controls_rwsem);
|
||||
rwlock_init(&card->ctl_files_rwlock);
|
||||
mutex_init(&card->user_ctl_lock);
|
||||
INIT_LIST_HEAD(&card->controls);
|
||||
INIT_LIST_HEAD(&card->ctl_files);
|
||||
spin_lock_init(&card->files_lock);
|
||||
|
||||
@@ -3356,6 +3356,7 @@ enum {
|
||||
ALC269_FIXUP_STEREO_DMIC,
|
||||
ALC269_FIXUP_QUANTA_MUTE,
|
||||
ALC269_FIXUP_LIFEBOOK,
|
||||
ALC269_FIXUP_LIFEBOOK_EXTMIC,
|
||||
ALC269_FIXUP_AMIC,
|
||||
ALC269_FIXUP_DMIC,
|
||||
ALC269VB_FIXUP_AMIC,
|
||||
@@ -3463,6 +3464,13 @@ static const struct hda_fixup alc269_fixups[] = {
|
||||
.chained = true,
|
||||
.chain_id = ALC269_FIXUP_QUANTA_MUTE
|
||||
},
|
||||
[ALC269_FIXUP_LIFEBOOK_EXTMIC] = {
|
||||
.type = HDA_FIXUP_PINS,
|
||||
.v.pins = (const struct hda_pintbl[]) {
|
||||
{ 0x19, 0x01a1903c }, /* headset mic, with jack detect */
|
||||
{ }
|
||||
},
|
||||
},
|
||||
[ALC269_FIXUP_AMIC] = {
|
||||
.type = HDA_FIXUP_PINS,
|
||||
.v.pins = (const struct hda_pintbl[]) {
|
||||
@@ -3713,6 +3721,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
|
||||
SND_PCI_QUIRK(0x1025, 0x0742, "Acer AO756", ALC271_FIXUP_HP_GATE_MIC_JACK),
|
||||
SND_PCI_QUIRK_VENDOR(0x1025, "Acer Aspire", ALC271_FIXUP_DMIC),
|
||||
SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook", ALC269_FIXUP_LIFEBOOK),
|
||||
SND_PCI_QUIRK(0x10cf, 0x1845, "Lifebook U904", ALC269_FIXUP_LIFEBOOK_EXTMIC),
|
||||
SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE),
|
||||
SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE),
|
||||
SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE),
|
||||
@@ -4664,6 +4673,7 @@ static const struct hda_codec_preset snd_hda_preset_realtek[] = {
|
||||
{ .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 },
|
||||
{ .id = 0x10ec0671, .name = "ALC671", .patch = patch_alc662 },
|
||||
{ .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 },
|
||||
{ .id = 0x10ec0867, .name = "ALC891", .patch = patch_alc882 },
|
||||
{ .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
|
||||
{ .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
|
||||
{ .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 },
|
||||
|
||||
@@ -255,6 +255,7 @@ static struct reg_default max98090_reg[] = {
|
||||
static bool max98090_volatile_register(struct device *dev, unsigned int reg)
|
||||
{
|
||||
switch (reg) {
|
||||
case M98090_REG_SOFTWARE_RESET:
|
||||
case M98090_REG_DEVICE_STATUS:
|
||||
case M98090_REG_JACK_STATUS:
|
||||
case M98090_REG_REVISION_ID:
|
||||
@@ -2343,6 +2344,8 @@ static int max98090_runtime_resume(struct device *dev)
|
||||
|
||||
regcache_cache_only(max98090->regmap, false);
|
||||
|
||||
max98090_reset(max98090);
|
||||
|
||||
regcache_sync(max98090->regmap);
|
||||
|
||||
return 0;
|
||||
|
||||
Reference in New Issue
Block a user