Просмотр исходного кода

Merge tag 'upstream-3.15-rc5' of git://git.infradead.org/linux-ubifs

Pull ubifs fixes from Artem Bityutskiy:
 "This includes the following fixes:

   - two real bug-fixes from Tanya for the still "experimental" UBI
     fastmap feature
   - a one-liner from Kees which hardens kernel security
   - a small error-path fix, where we forget to free various resources
     in case of failure - spotted by the 'smatch' tool"

* tag 'upstream-3.15-rc5' of git://git.infradead.org/linux-ubifs:
  UBI: avoid workqueue format string leak
  UBI: fix ubi free PEBs count calculation
  UBI: fix error path in __wl_get_peb
  UBIFS: fix remount error path
Linus Torvalds 11 лет назад
Родитель
Сommit
cae1d2cab4
3 измененных файлов с 8 добавлено и 2 удалено
  1. 1 1
      drivers/mtd/ubi/block.c
  2. 6 0
      drivers/mtd/ubi/wl.c
  3. 1 1
      fs/ubifs/super.c

+ 1 - 1
drivers/mtd/ubi/block.c

@@ -431,7 +431,7 @@ int ubiblock_create(struct ubi_volume_info *vi)
 	 * Create one workqueue per volume (per registered block device).
 	 * Create one workqueue per volume (per registered block device).
 	 * Rembember workqueues are cheap, they're not threads.
 	 * Rembember workqueues are cheap, they're not threads.
 	 */
 	 */
-	dev->wq = alloc_workqueue(gd->disk_name, 0, 0);
+	dev->wq = alloc_workqueue("%s", 0, 0, gd->disk_name);
 	if (!dev->wq)
 	if (!dev->wq)
 		goto out_free_queue;
 		goto out_free_queue;
 	INIT_WORK(&dev->work, ubiblock_do_work);
 	INIT_WORK(&dev->work, ubiblock_do_work);

+ 6 - 0
drivers/mtd/ubi/wl.c

@@ -671,6 +671,8 @@ static struct ubi_wl_entry *get_peb_for_wl(struct ubi_device *ubi)
 
 
 	e = find_wl_entry(ubi, &ubi->free, WL_FREE_MAX_DIFF);
 	e = find_wl_entry(ubi, &ubi->free, WL_FREE_MAX_DIFF);
 	self_check_in_wl_tree(ubi, e, &ubi->free);
 	self_check_in_wl_tree(ubi, e, &ubi->free);
+	ubi->free_count--;
+	ubi_assert(ubi->free_count >= 0);
 	rb_erase(&e->u.rb, &ubi->free);
 	rb_erase(&e->u.rb, &ubi->free);
 
 
 	return e;
 	return e;
@@ -684,6 +686,9 @@ int ubi_wl_get_peb(struct ubi_device *ubi)
 	peb = __wl_get_peb(ubi);
 	peb = __wl_get_peb(ubi);
 	spin_unlock(&ubi->wl_lock);
 	spin_unlock(&ubi->wl_lock);
 
 
+	if (peb < 0)
+		return peb;
+
 	err = ubi_self_check_all_ff(ubi, peb, ubi->vid_hdr_aloffset,
 	err = ubi_self_check_all_ff(ubi, peb, ubi->vid_hdr_aloffset,
 				    ubi->peb_size - ubi->vid_hdr_aloffset);
 				    ubi->peb_size - ubi->vid_hdr_aloffset);
 	if (err) {
 	if (err) {
@@ -1068,6 +1073,7 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk,
 
 
 			/* Give the unused PEB back */
 			/* Give the unused PEB back */
 			wl_tree_add(e2, &ubi->free);
 			wl_tree_add(e2, &ubi->free);
+			ubi->free_count++;
 			goto out_cancel;
 			goto out_cancel;
 		}
 		}
 		self_check_in_wl_tree(ubi, e1, &ubi->used);
 		self_check_in_wl_tree(ubi, e1, &ubi->used);

+ 1 - 1
fs/ubifs/super.c

@@ -1556,7 +1556,7 @@ static int ubifs_remount_rw(struct ubifs_info *c)
 	if (c->space_fixup) {
 	if (c->space_fixup) {
 		err = ubifs_fixup_free_space(c);
 		err = ubifs_fixup_free_space(c);
 		if (err)
 		if (err)
-			return err;
+			goto out;
 	}
 	}
 
 
 	err = check_free_space(c);
 	err = check_free_space(c);