diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-10-25 19:05:57 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-10-25 19:05:57 -0400 |
commit | 2ab3f29dddfb444c9fcc0a2f3a56ed4bdba41969 (patch) | |
tree | b1999129c781fbd524c921c4ebfde029a48cca17 | |
parent | b1e4279e4ef5549bf6ebf8f6f17dd26f0af8e8a2 (diff) | |
parent | 12176503366885edd542389eed3aaf94be163fdb (diff) |
Merge branch 'akpm' (Andrew's fixes)
Merge misc fixes from Andrew Morton:
"18 total. 15 fixes and some updates to a device_cgroup patchset which
bring it up to date with the version which I should have merged in the
first place."
* emailed patches from Andrew Morton <akpm@linux-foundation.org>: (18 patches)
fs/compat_ioctl.c: VIDEO_SET_SPU_PALETTE missing error check
gen_init_cpio: avoid stack overflow when expanding
drivers/rtc/rtc-imxdi.c: add missing spin lock initialization
mm, numa: avoid setting zone_reclaim_mode unless a node is sufficiently distant
pidns: limit the nesting depth of pid namespaces
drivers/dma/dw_dmac: make driver's endianness configurable
mm/mmu_notifier: allocate mmu_notifier in advance
tools/testing/selftests/epoll/test_epoll.c: fix build
UAPI: fix tools/vm/page-types.c
mm/page_alloc.c:alloc_contig_range(): return early for err path
rbtree: include linux/compiler.h for definition of __always_inline
genalloc: stop crashing the system when destroying a pool
backlight: ili9320: add missing SPI dependency
device_cgroup: add proper checking when changing default behavior
device_cgroup: stop using simple_strtoul()
device_cgroup: rename deny_all to behavior
cgroup: fix invalid rcu dereference
mm: fix XFS oops due to dirty pages without buffers on s390
-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 | ||