diff options
| -rw-r--r-- | drivers/dma/Kconfig | 11 | ||||
| -rw-r--r-- | drivers/dma/dw_dmac_regs.h | 18 | ||||
| -rw-r--r-- | drivers/rtc/rtc-imxdi.c | 2 | ||||
| -rw-r--r-- | drivers/video/backlight/Kconfig | 3 | ||||
| -rw-r--r-- | fs/compat_ioctl.c | 2 | ||||
| -rw-r--r-- | include/linux/rbtree_augmented.h | 1 | ||||
| -rw-r--r-- | kernel/pid_namespace.c | 12 | ||||
| -rw-r--r-- | lib/genalloc.c | 2 | ||||
| -rw-r--r-- | mm/mmu_notifier.c | 26 | ||||
| -rw-r--r-- | mm/page_alloc.c | 4 | ||||
| -rw-r--r-- | mm/rmap.c | 20 | ||||
| -rw-r--r-- | security/device_cgroup.c | 87 | ||||
| -rw-r--r-- | tools/testing/selftests/epoll/test_epoll.c | 4 | ||||
| -rw-r--r-- | tools/vm/page-types.c | 2 | ||||
| -rw-r--r-- | usr/gen_init_cpio.c | 43 |
15 files changed, 160 insertions, 77 deletions
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index 677cd6e4e1a1..d4c12180c654 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig | |||
| @@ -90,6 +90,17 @@ config DW_DMAC | |||
| 90 | Support the Synopsys DesignWare AHB DMA controller. This | 90 | Support the Synopsys DesignWare AHB DMA controller. This |
| 91 | can be integrated in chips such as the Atmel AT32ap7000. | 91 | can be integrated in chips such as the Atmel AT32ap7000. |
| 92 | 92 | ||
| 93 | config DW_DMAC_BIG_ENDIAN_IO | ||
| 94 | bool "Use big endian I/O register access" | ||
| 95 | default y if AVR32 | ||
| 96 | depends on DW_DMAC | ||
| 97 | help | ||
| 98 | Say yes here to use big endian I/O access when reading and writing | ||
| 99 | to the DMA controller registers. This is needed on some platforms, | ||
| 100 | like the Atmel AVR32 architecture. | ||
| 101 | |||
| 102 | If unsure, use the default setting. | ||
| 103 | |||
| 93 | config AT_HDMAC | 104 | config AT_HDMAC |
| 94 | tristate "Atmel AHB DMA support" | 105 | tristate "Atmel AHB DMA support" |
| 95 | depends on ARCH_AT91 | 106 | depends on ARCH_AT91 |
diff --git a/drivers/dma/dw_dmac_regs.h b/drivers/dma/dw_dmac_regs.h index ff39fa6cd2bc..88965597b7d0 100644 --- a/drivers/dma/dw_dmac_regs.h +++ b/drivers/dma/dw_dmac_regs.h | |||
| @@ -98,9 +98,17 @@ struct dw_dma_regs { | |||
| 98 | u32 DW_PARAMS; | 98 | u32 DW_PARAMS; |
| 99 | }; | 99 | }; |
| 100 | 100 | ||
| 101 | #ifdef CONFIG_DW_DMAC_BIG_ENDIAN_IO | ||
| 102 | #define dma_readl_native ioread32be | ||
| 103 | #define dma_writel_native iowrite32be | ||
| 104 | #else | ||
| 105 | #define dma_readl_native readl | ||
| 106 | #define dma_writel_native writel | ||
| 107 | #endif | ||
| 108 | |||
| 101 | /* To access the registers in early stage of probe */ | 109 | /* To access the registers in early stage of probe */ |
| 102 | #define dma_read_byaddr(addr, name) \ | 110 | #define dma_read_byaddr(addr, name) \ |
| 103 | readl((addr) + offsetof(struct dw_dma_regs, name)) | 111 | dma_readl_native((addr) + offsetof(struct dw_dma_regs, name)) |
| 104 | 112 | ||
| 105 | /* Bitfields in DW_PARAMS */ | 113 | /* Bitfields in DW_PARAMS */ |
| 106 | #define DW_PARAMS_NR_CHAN 8 /* number of channels */ | 114 | #define DW_PARAMS_NR_CHAN 8 /* number of channels */ |
| @@ -216,9 +224,9 @@ __dwc_regs(struct dw_dma_chan *dwc) | |||
| 216 | } | 224 | } |
| 217 | 225 | ||
| 218 | #define channel_readl(dwc, name) \ | 226 | #define channel_readl(dwc, name) \ |
| 219 | readl(&(__dwc_regs(dwc)->name)) | 227 | dma_readl_native(&(__dwc_regs(dwc)->name)) |
| 220 | #define channel_writel(dwc, name, val) \ | 228 | #define channel_writel(dwc, name, val) \ |
| 221 | writel((val), &(__dwc_regs(dwc)->name)) | 229 | dma_writel_native((val), &(__dwc_regs(dwc)->name)) |
| 222 | 230 | ||
| 223 | static inline struct dw_dma_chan *to_dw_dma_chan(struct dma_chan *chan) | 231 | static inline struct dw_dma_chan *to_dw_dma_chan(struct dma_chan *chan) |
| 224 | { | 232 | { |
| @@ -246,9 +254,9 @@ static inline struct dw_dma_regs __iomem *__dw_regs(struct dw_dma *dw) | |||
| 246 | } | 254 | } |
| 247 | 255 | ||
| 248 | #define dma_readl(dw, name) \ | 256 | #define dma_readl(dw, name) \ |
| 249 | readl(&(__dw_regs(dw)->name)) | 257 | dma_readl_native(&(__dw_regs(dw)->name)) |
| 250 | #define dma_writel(dw, name, val) \ | 258 | #define dma_writel(dw, name, val) \ |
| 251 | writel((val), &(__dw_regs(dw)->name)) | 259 | dma_writel_native((val), &(__dw_regs(dw)->name)) |
| 252 | 260 | ||
| 253 | #define channel_set_bit(dw, reg, mask) \ | 261 | #define channel_set_bit(dw, reg, mask) \ |
| 254 | dma_writel(dw, reg, ((mask) << 8) | (mask)) | 262 | dma_writel(dw, reg, ((mask) << 8) | (mask)) |
diff --git a/drivers/rtc/rtc-imxdi.c b/drivers/rtc/rtc-imxdi.c index 891cd6c61d0a..4eed51044c5d 100644 --- a/drivers/rtc/rtc-imxdi.c +++ b/drivers/rtc/rtc-imxdi.c | |||
| @@ -392,6 +392,8 @@ static int dryice_rtc_probe(struct platform_device *pdev) | |||
| 392 | if (imxdi->ioaddr == NULL) | 392 | if (imxdi->ioaddr == NULL) |
| 393 | return -ENOMEM; | 393 | return -ENOMEM; |
| 394 | 394 | ||
| 395 | spin_lock_init(&imxdi->irq_lock); | ||
| 396 | |||
| 395 | imxdi->irq = platform_get_irq(pdev, 0); | 397 | imxdi->irq = platform_get_irq(pdev, 0); |
| 396 | if (imxdi->irq < 0) | 398 | if (imxdi->irq < 0) |
| 397 | return imxdi->irq; | 399 | return imxdi->irq; |
diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig index c101697a4ba7..765a945f8ea1 100644 --- a/drivers/video/backlight/Kconfig +++ b/drivers/video/backlight/Kconfig | |||
| @@ -60,7 +60,8 @@ config LCD_LTV350QV | |||
| 60 | The LTV350QV panel is present on all ATSTK1000 boards. | 60 | The LTV350QV panel is present on all ATSTK1000 boards. |
| 61 | 61 | ||
| 62 | config LCD_ILI9320 | 62 | config LCD_ILI9320 |
| 63 | tristate | 63 | tristate "ILI Technology ILI9320 controller support" |
| 64 | depends on SPI | ||
| 64 | help | 65 | help |
| 65 | If you have a panel based on the ILI9320 controller chip | 66 | If you have a panel based on the ILI9320 controller chip |
| 66 | then say y to include a power driver for it. | 67 | then say y to include a power driver for it. |
diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c index f5054025f9da..4c6285fff598 100644 --- a/fs/compat_ioctl.c +++ b/fs/compat_ioctl.c | |||
| @@ -210,6 +210,8 @@ static int do_video_set_spu_palette(unsigned int fd, unsigned int cmd, | |||
| 210 | 210 | ||
| 211 | err = get_user(palp, &up->palette); | 211 | err = get_user(palp, &up->palette); |
| 212 | err |= get_user(length, &up->length); | 212 | err |= get_user(length, &up->length); |
| 213 | if (err) | ||
| 214 | return -EFAULT; | ||
| 213 | 215 | ||
| 214 | up_native = compat_alloc_user_space(sizeof(struct video_spu_palette)); | 216 | up_native = compat_alloc_user_space(sizeof(struct video_spu_palette)); |
| 215 | err = put_user(compat_ptr(palp), &up_native->palette); | 217 | err = put_user(compat_ptr(palp), &up_native->palette); |
diff --git a/include/linux/rbtree_augmented.h b/include/linux/rbtree_augmented.h index 214caa33433b..2ac60c9cf644 100644 --- a/include/linux/rbtree_augmented.h +++ b/include/linux/rbtree_augmented.h | |||
| @@ -24,6 +24,7 @@ | |||
| 24 | #ifndef _LINUX_RBTREE_AUGMENTED_H | 24 | #ifndef _LINUX_RBTREE_AUGMENTED_H |
| 25 | #define _LINUX_RBTREE_AUGMENTED_H | 25 | #define _LINUX_RBTREE_AUGMENTED_H |
| 26 | 26 | ||
| 27 | #include <linux/compiler.h> | ||
| 27 | #include <linux/rbtree.h> | 28 | #include <linux/rbtree.h> |
| 28 | 29 | ||
| 29 | /* | 30 | /* |
diff --git a/kernel/pid_namespace.c b/kernel/pid_namespace.c index eb00be205811..7b07cc0dfb75 100644 --- a/kernel/pid_namespace.c +++ b/kernel/pid_namespace.c | |||
| @@ -71,12 +71,22 @@ err_alloc: | |||
| 71 | return NULL; | 71 | return NULL; |
| 72 | } | 72 | } |
| 73 | 73 | ||
| 74 | /* MAX_PID_NS_LEVEL is needed for limiting size of 'struct pid' */ | ||
| 75 | #define MAX_PID_NS_LEVEL 32 | ||
| 76 | |||
| 74 | static struct pid_namespace *create_pid_namespace(struct pid_namespace *parent_pid_ns) | 77 | static struct pid_namespace *create_pid_namespace(struct pid_namespace *parent_pid_ns) |
| 75 | { | 78 | { |
| 76 | struct pid_namespace *ns; | 79 | struct pid_namespace *ns; |
| 77 | unsigned int level = parent_pid_ns->level + 1; | 80 | unsigned int level = parent_pid_ns->level + 1; |
| 78 | int i, err = -ENOMEM; | 81 | int i; |
| 82 | int err; | ||
| 83 | |||
| 84 | if (level > MAX_PID_NS_LEVEL) { | ||
| 85 | err = -EINVAL; | ||
| 86 | goto out; | ||
| 87 | } | ||
| 79 | 88 | ||
| 89 | err = -ENOMEM; | ||
| 80 | ns = kmem_cache_zalloc(pid_ns_cachep, GFP_KERNEL); | 90 | ns = kmem_cache_zalloc(pid_ns_cachep, GFP_KERNEL); |
| 81 | if (ns == NULL) | 91 | if (ns == NULL) |
| 82 | goto out; | 92 | goto out; |
diff --git a/lib/genalloc.c b/lib/genalloc.c index ca208a92628c..54920433705a 100644 --- a/lib/genalloc.c +++ b/lib/genalloc.c | |||
| @@ -178,7 +178,7 @@ int gen_pool_add_virt(struct gen_pool *pool, unsigned long virt, phys_addr_t phy | |||
| 178 | struct gen_pool_chunk *chunk; | 178 | struct gen_pool_chunk *chunk; |
| 179 | int nbits = size >> pool->min_alloc_order; | 179 | int nbits = size >> pool->min_alloc_order; |
| 180 | int nbytes = sizeof(struct gen_pool_chunk) + | 180 | int nbytes = sizeof(struct gen_pool_chunk) + |
| 181 | (nbits + BITS_PER_BYTE - 1) / BITS_PER_BYTE; | 181 | BITS_TO_LONGS(nbits) * sizeof(long); |
| 182 | 182 | ||
| 183 | chunk = kmalloc_node(nbytes, GFP_KERNEL | __GFP_ZERO, nid); | 183 | chunk = kmalloc_node(nbytes, GFP_KERNEL | __GFP_ZERO, nid); |
| 184 | if (unlikely(chunk == NULL)) | 184 | if (unlikely(chunk == NULL)) |
diff --git a/mm/mmu_notifier.c b/mm/mmu_notifier.c index 479a1e751a73..8a5ac8c686b0 100644 --- a/mm/mmu_notifier.c +++ b/mm/mmu_notifier.c | |||
| @@ -196,28 +196,28 @@ static int do_mmu_notifier_register(struct mmu_notifier *mn, | |||
| 196 | BUG_ON(atomic_read(&mm->mm_users) <= 0); | 196 | BUG_ON(atomic_read(&mm->mm_users) <= 0); |
| 197 | 197 | ||
| 198 | /* | 198 | /* |
| 199 | * Verify that mmu_notifier_init() already run and the global srcu is | 199 | * Verify that mmu_notifier_init() already run and the global srcu is |
| 200 | * initialized. | 200 | * initialized. |
| 201 | */ | 201 | */ |
| 202 | BUG_ON(!srcu.per_cpu_ref); | 202 | BUG_ON(!srcu.per_cpu_ref); |
| 203 | 203 | ||
| 204 | ret = -ENOMEM; | ||
| 205 | mmu_notifier_mm = kmalloc(sizeof(struct mmu_notifier_mm), GFP_KERNEL); | ||
| 206 | if (unlikely(!mmu_notifier_mm)) | ||
| 207 | goto out; | ||
| 208 | |||
| 204 | if (take_mmap_sem) | 209 | if (take_mmap_sem) |
| 205 | down_write(&mm->mmap_sem); | 210 | down_write(&mm->mmap_sem); |
| 206 | ret = mm_take_all_locks(mm); | 211 | ret = mm_take_all_locks(mm); |
| 207 | if (unlikely(ret)) | 212 | if (unlikely(ret)) |
| 208 | goto out; | 213 | goto out_clean; |
| 209 | 214 | ||
| 210 | if (!mm_has_notifiers(mm)) { | 215 | if (!mm_has_notifiers(mm)) { |
| 211 | mmu_notifier_mm = kmalloc(sizeof(struct mmu_notifier_mm), | ||
| 212 | GFP_KERNEL); | ||
| 213 | if (unlikely(!mmu_notifier_mm)) { | ||
| 214 | ret = -ENOMEM; | ||
| 215 | goto out_of_mem; | ||
| 216 | } | ||
| 217 | INIT_HLIST_HEAD(&mmu_notifier_mm->list); | 216 | INIT_HLIST_HEAD(&mmu_notifier_mm->list); |
| 218 | spin_lock_init(&mmu_notifier_mm->lock); | 217 | spin_lock_init(&mmu_notifier_mm->lock); |
| 219 | 218 | ||
| 220 | mm->mmu_notifier_mm = mmu_notifier_mm; | 219 | mm->mmu_notifier_mm = mmu_notifier_mm; |
| 220 | mmu_notifier_mm = NULL; | ||
| 221 | } | 221 | } |
| 222 | atomic_inc(&mm->mm_count); | 222 | atomic_inc(&mm->mm_count); |
| 223 | 223 | ||
| @@ -233,12 +233,12 @@ static int do_mmu_notifier_register(struct mmu_notifier *mn, | |||
| 233 | hlist_add_head(&mn->hlist, &mm->mmu_notifier_mm->list); | 233 | hlist_add_head(&mn->hlist, &mm->mmu_notifier_mm->list); |
| 234 | spin_unlock(&mm->mmu_notifier_mm->lock); | 234 | spin_unlock(&mm->mmu_notifier_mm->lock); |
| 235 | 235 | ||
| 236 | out_of_mem: | ||
| 237 | mm_drop_all_locks(mm); | 236 | mm_drop_all_locks(mm); |
| 238 | out: | 237 | out_clean: |
| 239 | if (take_mmap_sem) | 238 | if (take_mmap_sem) |
| 240 | up_write(&mm->mmap_sem); | 239 | up_write(&mm->mmap_sem); |
| 241 | 240 | kfree(mmu_notifier_mm); | |
| 241 | out: | ||
| 242 | BUG_ON(atomic_read(&mm->mm_users) <= 0); | 242 | BUG_ON(atomic_read(&mm->mm_users) <= 0); |
| 243 | return ret; | 243 | return ret; |
| 244 | } | 244 | } |
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index b0012ab372a4..5b74de6702e0 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c | |||
| @@ -1809,10 +1809,10 @@ static void __paginginit init_zone_allows_reclaim(int nid) | |||
| 1809 | int i; | 1809 | int i; |
| 1810 | 1810 | ||
| 1811 | for_each_online_node(i) | 1811 | for_each_online_node(i) |
| 1812 | if (node_distance(nid, i) <= RECLAIM_DISTANCE) { | 1812 | if (node_distance(nid, i) <= RECLAIM_DISTANCE) |
| 1813 | node_set(i, NODE_DATA(nid)->reclaim_nodes); | 1813 | node_set(i, NODE_DATA(nid)->reclaim_nodes); |
| 1814 | else | ||
| 1814 | zone_reclaim_mode = 1; | 1815 | zone_reclaim_mode = 1; |
| 1815 | } | ||
| 1816 | } | 1816 | } |
| 1817 | 1817 | ||
| 1818 | #else /* CONFIG_NUMA */ | 1818 | #else /* CONFIG_NUMA */ |
| @@ -56,6 +56,7 @@ | |||
| 56 | #include <linux/mmu_notifier.h> | 56 | #include <linux/mmu_notifier.h> |
| 57 | #include <linux/migrate.h> | 57 | #include <linux/migrate.h> |
| 58 | #include <linux/hugetlb.h> | 58 | #include <linux/hugetlb.h> |
| 59 | #include <linux/backing-dev.h> | ||
| 59 | 60 | ||
| 60 | #include <asm/tlbflush.h> | 61 | #include <asm/tlbflush.h> |
| 61 | 62 | ||
| @@ -926,11 +927,8 @@ int page_mkclean(struct page *page) | |||
| 926 | 927 | ||
| 927 | if (page_mapped(page)) { | 928 | if (page_mapped(page)) { |
| 928 | struct address_space *mapping = page_mapping(page); | 929 | struct address_space *mapping = page_mapping(page); |
| 929 | if (mapping) { | 930 | if (mapping) |
| 930 | ret = page_mkclean_file(mapping, page); | 931 | ret = page_mkclean_file(mapping, page); |
| 931 | if (page_test_and_clear_dirty(page_to_pfn(page), 1)) | ||
| 932 | ret = 1; | ||
| 933 | } | ||
| 934 | } | 932 | } |
| 935 | 933 | ||
| 936 | return ret; | 934 | return ret; |
| @@ -1116,6 +1114,7 @@ void page_add_file_rmap(struct page *page) | |||
| 1116 | */ | 1114 | */ |
| 1117 | void page_remove_rmap(struct page *page) | 1115 | void page_remove_rmap(struct page *page) |
| 1118 | { | 1116 | { |
| 1117 | struct address_space *mapping = page_mapping(page); | ||
| 1119 | bool anon = PageAnon(page); | 1118 | bool anon = PageAnon(page); |
| 1120 | bool locked; | 1119 | bool locked; |
| 1121 | unsigned long flags; | 1120 | unsigned long flags; |
| @@ -1138,8 +1137,19 @@ void page_remove_rmap(struct page *page) | |||
| 1138 | * this if the page is anon, so about to be freed; but perhaps | 1137 | * this if the page is anon, so about to be freed; but perhaps |
| 1139 | * not if it's in swapcache - there might be another pte slot | 1138 | * not if it's in swapcache - there might be another pte slot |
| 1140 | * containing the swap entry, but page not yet written to swap. | 1139 | * containing the swap entry, but page not yet written to swap. |
| 1140 | * | ||
| 1141 | * And we can skip it on file pages, so long as the filesystem | ||
| 1142 | * participates in dirty tracking; but need to catch shm and tmpfs | ||
| 1143 | * and ramfs pages which have been modified since creation by read | ||
| 1144 | * fault. | ||
| 1145 | * | ||
| 1146 | * Note that mapping must be decided above, before decrementing | ||
| 1147 | * mapcount (which luckily provides a barrier): once page is unmapped, | ||
| 1148 | * it could be truncated and page->mapping reset to NULL at any moment. | ||
| 1149 | * Note also that we are relying on page_mapping(page) to set mapping | ||
| 1150 | * to &swapper_space when PageSwapCache(page). | ||
| 1141 | */ | 1151 | */ |
| 1142 | if ((!anon || PageSwapCache(page)) && | 1152 | if (mapping && !mapping_cap_account_dirty(mapping) && |
| 1143 | page_test_and_clear_dirty(page_to_pfn(page), 1)) | 1153 | page_test_and_clear_dirty(page_to_pfn(page), 1)) |
| 1144 | set_page_dirty(page); | 1154 | set_page_dirty(page); |
| 1145 | /* | 1155 | /* |
diff --git a/security/device_cgroup.c b/security/device_cgroup.c index 44dfc415a379..842c254396db 100644 --- a/security/device_cgroup.c +++ b/security/device_cgroup.c | |||
| @@ -42,7 +42,10 @@ struct dev_exception_item { | |||
| 42 | struct dev_cgroup { | 42 | struct dev_cgroup { |
| 43 | struct cgroup_subsys_state css; | 43 | struct cgroup_subsys_state css; |
| 44 | struct list_head exceptions; | 44 | struct list_head exceptions; |
| 45 | bool deny_all; | 45 | enum { |
| 46 | DEVCG_DEFAULT_ALLOW, | ||
| 47 | DEVCG_DEFAULT_DENY, | ||
| 48 | } behavior; | ||
| 46 | }; | 49 | }; |
| 47 | 50 | ||
| 48 | static inline struct dev_cgroup *css_to_devcgroup(struct cgroup_subsys_state *s) | 51 | static inline struct dev_cgroup *css_to_devcgroup(struct cgroup_subsys_state *s) |
| @@ -182,13 +185,13 @@ static struct cgroup_subsys_state *devcgroup_create(struct cgroup *cgroup) | |||
| 182 | parent_cgroup = cgroup->parent; | 185 | parent_cgroup = cgroup->parent; |
| 183 | 186 | ||
| 184 | if (parent_cgroup == NULL) | 187 | if (parent_cgroup == NULL) |
| 185 | dev_cgroup->deny_all = false; | 188 | dev_cgroup->behavior = DEVCG_DEFAULT_ALLOW; |
| 186 | else { | 189 | else { |
| 187 | parent_dev_cgroup = cgroup_to_devcgroup(parent_cgroup); | 190 | parent_dev_cgroup = cgroup_to_devcgroup(parent_cgroup); |
| 188 | mutex_lock(&devcgroup_mutex); | 191 | mutex_lock(&devcgroup_mutex); |
| 189 | ret = dev_exceptions_copy(&dev_cgroup->exceptions, | 192 | ret = dev_exceptions_copy(&dev_cgroup->exceptions, |
| 190 | &parent_dev_cgroup->exceptions); | 193 | &parent_dev_cgroup->exceptions); |
| 191 | dev_cgroup->deny_all = parent_dev_cgroup->deny_all; | 194 | dev_cgroup->behavior = parent_dev_cgroup->behavior; |
| 192 | mutex_unlock(&devcgroup_mutex); | 195 | mutex_unlock(&devcgroup_mutex); |
| 193 | if (ret) { | 196 | if (ret) { |
| 194 | kfree(dev_cgroup); | 197 | kfree(dev_cgroup); |
| @@ -260,7 +263,7 @@ static int devcgroup_seq_read(struct cgroup *cgroup, struct cftype *cft, | |||
| 260 | * - List the exceptions in case the default policy is to deny | 263 | * - List the exceptions in case the default policy is to deny |
| 261 | * This way, the file remains as a "whitelist of devices" | 264 | * This way, the file remains as a "whitelist of devices" |
| 262 | */ | 265 | */ |
| 263 | if (devcgroup->deny_all == false) { | 266 | if (devcgroup->behavior == DEVCG_DEFAULT_ALLOW) { |
| 264 | set_access(acc, ACC_MASK); | 267 | set_access(acc, ACC_MASK); |
| 265 | set_majmin(maj, ~0); | 268 | set_majmin(maj, ~0); |
| 266 | set_majmin(min, ~0); | 269 | set_majmin(min, ~0); |
| @@ -314,12 +317,12 @@ static int may_access(struct dev_cgroup *dev_cgroup, | |||
| 314 | * In two cases we'll consider this new exception valid: | 317 | * In two cases we'll consider this new exception valid: |
| 315 | * - the dev cgroup has its default policy to allow + exception list: | 318 | * - the dev cgroup has its default policy to allow + exception list: |
| 316 | * the new exception should *not* match any of the exceptions | 319 | * the new exception should *not* match any of the exceptions |
| 317 | * (!deny_all, !match) | 320 | * (behavior == DEVCG_DEFAULT_ALLOW, !match) |
| 318 | * - the dev cgroup has its default policy to deny + exception list: | 321 | * - the dev cgroup has its default policy to deny + exception list: |
| 319 | * the new exception *should* match the exceptions | 322 | * the new exception *should* match the exceptions |
| 320 | * (deny_all, match) | 323 | * (behavior == DEVCG_DEFAULT_DENY, match) |
| 321 | */ | 324 | */ |
| 322 | if (dev_cgroup->deny_all == match) | 325 | if ((dev_cgroup->behavior == DEVCG_DEFAULT_DENY) == match) |
| 323 | return 1; | 326 | return 1; |
| 324 | return 0; | 327 | return 0; |
| 325 | } | 328 | } |
| @@ -341,6 +344,17 @@ static int parent_has_perm(struct dev_cgroup *childcg, | |||
| 341 | return may_access(parent, ex); | 344 | return may_access(parent, ex); |
| 342 | } | 345 | } |
| 343 | 346 | ||
| 347 | /** | ||
| 348 | * may_allow_all - checks if it's possible to change the behavior to | ||
| 349 | * allow based on parent's rules. | ||
| 350 | * @parent: device cgroup's parent | ||
| 351 | * returns: != 0 in case it's allowed, 0 otherwise | ||
| 352 | */ | ||
| 353 | static inline int may_allow_all(struct dev_cgroup *parent) | ||
| 354 | { | ||
| 355 | return parent->behavior == DEVCG_DEFAULT_ALLOW; | ||
| 356 | } | ||
| 357 | |||
| 344 | /* | 358 | /* |
| 345 | * Modify the exception list using allow/deny rules. | 359 | * Modify the exception list using allow/deny rules. |
| 346 | * CAP_SYS_ADMIN is needed for this. It's at least separate from CAP_MKNOD | 360 | * CAP_SYS_ADMIN is needed for this. It's at least separate from CAP_MKNOD |
| @@ -358,9 +372,11 @@ static int devcgroup_update_access(struct dev_cgroup *devcgroup, | |||
| 358 | int filetype, const char *buffer) | 372 | int filetype, const char *buffer) |
| 359 | { | 373 | { |
| 360 | const char *b; | 374 | const char *b; |
| 361 | char *endp; | 375 | char temp[12]; /* 11 + 1 characters needed for a u32 */ |
| 362 | int count; | 376 | int count, rc; |
| 363 | struct dev_exception_item ex; | 377 | struct dev_exception_item ex; |
| 378 | struct cgroup *p = devcgroup->css.cgroup; | ||
| 379 | struct dev_cgroup *parent = cgroup_to_devcgroup(p->parent); | ||
| 364 | 380 | ||
| 365 | if (!capable(CAP_SYS_ADMIN)) | 381 | if (!capable(CAP_SYS_ADMIN)) |
| 366 | return -EPERM; | 382 | return -EPERM; |
| @@ -372,14 +388,18 @@ static int devcgroup_update_access(struct dev_cgroup *devcgroup, | |||
| 372 | case 'a': | 388 | case 'a': |
| 373 | switch (filetype) { | 389 | switch (filetype) { |
| 374 | case DEVCG_ALLOW: | 390 | case DEVCG_ALLOW: |
| 375 | if (!parent_has_perm(devcgroup, &ex)) | 391 | if (!may_allow_all(parent)) |
| 376 | return -EPERM; | 392 | return -EPERM; |
| 377 | dev_exception_clean(devcgroup); | 393 | dev_exception_clean(devcgroup); |
| 378 | devcgroup->deny_all = false; | 394 | rc = dev_exceptions_copy(&devcgroup->exceptions, |
| 395 | &parent->exceptions); | ||
| 396 | if (rc) | ||
| 397 | return rc; | ||
| 398 | devcgroup->behavior = DEVCG_DEFAULT_ALLOW; | ||
| 379 | break; | 399 | break; |
| 380 | case DEVCG_DENY: | 400 | case DEVCG_DENY: |
| 381 | dev_exception_clean(devcgroup); | 401 | dev_exception_clean(devcgroup); |
| 382 | devcgroup->deny_all = true; | 402 | devcgroup->behavior = DEVCG_DEFAULT_DENY; |
| 383 | break; | 403 | break; |
| 384 | default: | 404 | default: |
| 385 | return -EINVAL; | 405 | return -EINVAL; |
| @@ -402,8 +422,16 @@ static int devcgroup_update_access(struct dev_cgroup *devcgroup, | |||
| 402 | ex.major = ~0; | 422 | ex.major = ~0; |
| 403 | b++; | 423 | b++; |
| 404 | } else if (isdigit(*b)) { | 424 | } else if (isdigit(*b)) { |
| 405 | ex.major = simple_strtoul(b, &endp, 10); | 425 | memset(temp, 0, sizeof(temp)); |
| 406 | b = endp; | 426 | for (count = 0; count < sizeof(temp) - 1; count++) { |
| 427 | temp[count] = *b; | ||
| 428 | b++; | ||
| 429 | if (!isdigit(*b)) | ||
| 430 | break; | ||
| 431 | } | ||
| 432 | rc = kstrtou32(temp, 10, &ex.major); | ||
| 433 | if (rc) | ||
| 434 | return -EINVAL; | ||
| 407 | } else { | 435 | } else { |
| 408 | return -EINVAL; | 436 | return -EINVAL; |
| 409 | } | 437 | } |
| @@ -416,8 +444,16 @@ static int devcgroup_update_access(struct dev_cgroup *devcgroup, | |||
| 416 | ex.minor = ~0; | 444 | ex.minor = ~0; |
| 417 | b++; | 445 | b++; |
| 418 | } else if (isdigit(*b)) { | 446 | } else if (isdigit(*b)) { |
| 419 | ex.minor = simple_strtoul(b, &endp, 10); | 447 | memset(temp, 0, sizeof(temp)); |
| 420 | b = endp; | 448 | for (count = 0; count < sizeof(temp) - 1; count++) { |
| 449 | temp[count] = *b; | ||
| 450 | b++; | ||
| 451 | if (!isdigit(*b)) | ||
| 452 | break; | ||
| 453 | } | ||
| 454 | rc = kstrtou32(temp, 10, &ex.minor); | ||
| 455 | if (rc) | ||
| 456 | return -EINVAL; | ||
| 421 | } else { | 457 | } else { |
| 422 | return -EINVAL; | 458 | return -EINVAL; |
| 423 | } | 459 | } |
| @@ -452,7 +488,7 @@ static int devcgroup_update_access(struct dev_cgroup *devcgroup, | |||
| 452 | * an matching exception instead. And be silent about it: we | 488 | * an matching exception instead. And be silent about it: we |
| 453 | * don't want to break compatibility | 489 | * don't want to break compatibility |
| 454 | */ | 490 | */ |
| 455 | if (devcgroup->deny_all == false) { | 491 | if (devcgroup->behavior == DEVCG_DEFAULT_ALLOW) { |
| 456 | dev_exception_rm(devcgroup, &ex); | 492 | dev_exception_rm(devcgroup, &ex); |
| 457 | return 0; | 493 | return 0; |
| 458 | } | 494 | } |
| @@ -463,7 +499,7 @@ static int devcgroup_update_access(struct dev_cgroup *devcgroup, | |||
| 463 | * an matching exception instead. And be silent about it: we | 499 | * an matching exception instead. And be silent about it: we |
| 464 | * don't want to break compatibility | 500 | * don't want to break compatibility |
| 465 | */ | 501 | */ |
| 466 | if (devcgroup->deny_all == true) { | 502 | if (devcgroup->behavior == DEVCG_DEFAULT_DENY) { |
| 467 | dev_exception_rm(devcgroup, &ex); | 503 | dev_exception_rm(devcgroup, &ex); |
| 468 | return 0; | 504 | return 0; |
| 469 | } | 505 | } |
| @@ -533,10 +569,10 @@ struct cgroup_subsys devices_subsys = { | |||
| 533 | * | 569 | * |
| 534 | * returns 0 on success, -EPERM case the operation is not permitted | 570 | * returns 0 on success, -EPERM case the operation is not permitted |
| 535 | */ | 571 | */ |
| 536 | static int __devcgroup_check_permission(struct dev_cgroup *dev_cgroup, | 572 | static int __devcgroup_check_permission(short type, u32 major, u32 minor, |
| 537 | short type, u32 major, u32 minor, | ||
| 538 | short access) | 573 | short access) |
| 539 | { | 574 | { |
| 575 | struct dev_cgroup *dev_cgroup; | ||
| 540 | struct dev_exception_item ex; | 576 | struct dev_exception_item ex; |
| 541 | int rc; | 577 | int rc; |
| 542 | 578 | ||
| @@ -547,6 +583,7 @@ static int __devcgroup_check_permission(struct dev_cgroup *dev_cgroup, | |||
| 547 | ex.access = access; | 583 | ex.access = access; |
| 548 | 584 | ||
| 549 | rcu_read_lock(); | 585 | rcu_read_lock(); |
| 586 | dev_cgroup = task_devcgroup(current); | ||
| 550 | rc = may_access(dev_cgroup, &ex); | 587 | rc = may_access(dev_cgroup, &ex); |
| 551 | rcu_read_unlock(); | 588 | rcu_read_unlock(); |
| 552 | 589 | ||
| @@ -558,7 +595,6 @@ static int __devcgroup_check_permission(struct dev_cgroup *dev_cgroup, | |||
| 558 | 595 | ||
| 559 | int __devcgroup_inode_permission(struct inode *inode, int mask) | 596 | int __devcgroup_inode_permission(struct inode *inode, int mask) |
| 560 | { | 597 | { |
| 561 | struct dev_cgroup *dev_cgroup = task_devcgroup(current); | ||
| 562 | short type, access = 0; | 598 | short type, access = 0; |
| 563 | 599 | ||
| 564 | if (S_ISBLK(inode->i_mode)) | 600 | if (S_ISBLK(inode->i_mode)) |
| @@ -570,13 +606,12 @@ int __devcgroup_inode_permission(struct inode *inode, int mask) | |||
| 570 | if (mask & MAY_READ) | 606 | if (mask & MAY_READ) |
| 571 | access |= ACC_READ; | 607 | access |= ACC_READ; |
| 572 | 608 | ||
| 573 | return __devcgroup_check_permission(dev_cgroup, type, imajor(inode), | 609 | return __devcgroup_check_permission(type, imajor(inode), iminor(inode), |
| 574 | iminor(inode), access); | 610 | access); |
| 575 | } | 611 | } |
| 576 | 612 | ||
| 577 | int devcgroup_inode_mknod(int mode, dev_t dev) | 613 | int devcgroup_inode_mknod(int mode, dev_t dev) |
| 578 | { | 614 | { |
| 579 | struct dev_cgroup *dev_cgroup = task_devcgroup(current); | ||
| 580 | short type; | 615 | short type; |
| 581 | 616 | ||
| 582 | if (!S_ISBLK(mode) && !S_ISCHR(mode)) | 617 | if (!S_ISBLK(mode) && !S_ISCHR(mode)) |
| @@ -587,7 +622,7 @@ int devcgroup_inode_mknod(int mode, dev_t dev) | |||
| 587 | else | 622 | else |
| 588 | type = DEV_CHAR; | 623 | type = DEV_CHAR; |
| 589 | 624 | ||
| 590 | return __devcgroup_check_permission(dev_cgroup, type, MAJOR(dev), | 625 | return __devcgroup_check_permission(type, MAJOR(dev), MINOR(dev), |
| 591 | MINOR(dev), ACC_MKNOD); | 626 | ACC_MKNOD); |
| 592 | 627 | ||
| 593 | } | 628 | } |
diff --git a/tools/testing/selftests/epoll/test_epoll.c b/tools/testing/selftests/epoll/test_epoll.c index e0fcff1e8331..f7525392ce84 100644 --- a/tools/testing/selftests/epoll/test_epoll.c +++ b/tools/testing/selftests/epoll/test_epoll.c | |||
| @@ -162,14 +162,14 @@ void *write_thread_function(void *function_data) | |||
| 162 | int index; | 162 | int index; |
| 163 | struct write_thread_data *thread_data = | 163 | struct write_thread_data *thread_data = |
| 164 | (struct write_thread_data *)function_data; | 164 | (struct write_thread_data *)function_data; |
| 165 | while (!write_thread_data->stop) | 165 | while (!thread_data->stop) |
| 166 | for (index = 0; | 166 | for (index = 0; |
| 167 | !thread_data->stop && (index < thread_data->n_fds); | 167 | !thread_data->stop && (index < thread_data->n_fds); |
| 168 | ++index) | 168 | ++index) |
| 169 | if ((write(thread_data->fds[index], &data, 1) < 1) && | 169 | if ((write(thread_data->fds[index], &data, 1) < 1) && |
| 170 | (errno != EAGAIN) && | 170 | (errno != EAGAIN) && |
| 171 | (errno != EWOULDBLOCK)) { | 171 | (errno != EWOULDBLOCK)) { |
| 172 | write_thread_data->status = errno; | 172 | thread_data->status = errno; |
| 173 | return; | 173 | return; |
| 174 | } | 174 | } |
| 175 | } | 175 | } |
diff --git a/tools/vm/page-types.c b/tools/vm/page-types.c index cd1b03e80899..b76edf2f8333 100644 --- a/tools/vm/page-types.c +++ b/tools/vm/page-types.c | |||
| @@ -35,7 +35,7 @@ | |||
| 35 | #include <sys/mount.h> | 35 | #include <sys/mount.h> |
| 36 | #include <sys/statfs.h> | 36 | #include <sys/statfs.h> |
| 37 | #include "../../include/uapi/linux/magic.h" | 37 | #include "../../include/uapi/linux/magic.h" |
| 38 | #include "../../include/linux/kernel-page-flags.h" | 38 | #include "../../include/uapi/linux/kernel-page-flags.h" |
| 39 | 39 | ||
| 40 | 40 | ||
| 41 | #ifndef MAX_PATH | 41 | #ifndef MAX_PATH |
diff --git a/usr/gen_init_cpio.c b/usr/gen_init_cpio.c index af0f22fb1ef7..aca6edcbbc6f 100644 --- a/usr/gen_init_cpio.c +++ b/usr/gen_init_cpio.c | |||
| @@ -303,7 +303,7 @@ static int cpio_mkfile(const char *name, const char *location, | |||
| 303 | int retval; | 303 | int retval; |
| 304 | int rc = -1; | 304 | int rc = -1; |
| 305 | int namesize; | 305 | int namesize; |
| 306 | int i; | 306 | unsigned int i; |
| 307 | 307 | ||
| 308 | mode |= S_IFREG; | 308 | mode |= S_IFREG; |
| 309 | 309 | ||
| @@ -381,25 +381,28 @@ error: | |||
| 381 | 381 | ||
| 382 | static char *cpio_replace_env(char *new_location) | 382 | static char *cpio_replace_env(char *new_location) |
| 383 | { | 383 | { |
| 384 | char expanded[PATH_MAX + 1]; | 384 | char expanded[PATH_MAX + 1]; |
| 385 | char env_var[PATH_MAX + 1]; | 385 | char env_var[PATH_MAX + 1]; |
| 386 | char *start; | 386 | char *start; |
| 387 | char *end; | 387 | char *end; |
| 388 | 388 | ||
| 389 | for (start = NULL; (start = strstr(new_location, "${")); ) { | 389 | for (start = NULL; (start = strstr(new_location, "${")); ) { |
| 390 | end = strchr(start, '}'); | 390 | end = strchr(start, '}'); |
| 391 | if (start < end) { | 391 | if (start < end) { |
| 392 | *env_var = *expanded = '\0'; | 392 | *env_var = *expanded = '\0'; |
| 393 | strncat(env_var, start + 2, end - start - 2); | 393 | strncat(env_var, start + 2, end - start - 2); |
| 394 | strncat(expanded, new_location, start - new_location); | 394 | strncat(expanded, new_location, start - new_location); |
| 395 | strncat(expanded, getenv(env_var), PATH_MAX); | 395 | strncat(expanded, getenv(env_var), |
| 396 | strncat(expanded, end + 1, PATH_MAX); | 396 | PATH_MAX - strlen(expanded)); |
| 397 | strncpy(new_location, expanded, PATH_MAX); | 397 | strncat(expanded, end + 1, |
| 398 | } else | 398 | PATH_MAX - strlen(expanded)); |
| 399 | break; | 399 | strncpy(new_location, expanded, PATH_MAX); |
| 400 | } | 400 | new_location[PATH_MAX] = 0; |
| 401 | 401 | } else | |
| 402 | return new_location; | 402 | break; |
| 403 | } | ||
| 404 | |||
| 405 | return new_location; | ||
| 403 | } | 406 | } |
| 404 | 407 | ||
| 405 | 408 | ||
