Skip to content

Commit 72116ef

Browse files
committed
Merge tag 'pstore-v6.8-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux
Pull pstore updates from Kees Cook: - Do not allow misconfigured ECC sizes (Sergey Shtylyov) - Allow for odd number of CPUs (Weichen Chen) - Refactor error handling to use cleanup.h * tag 'pstore-v6.8-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux: pstore: inode: Use cleanup.h for struct pstore_private pstore: inode: Use __free(pstore_iput) for inode allocations pstore: inode: Convert mutex usage to guard(mutex) pstore: inode: Convert kfree() usage to __free(kfree) pstore: ram_core: fix possible overflow in persistent_ram_init_ecc() pstore/ram: Fix crash when setting number of cpus to an odd number
2 parents 4d925f6 + 24a0b5e commit 72116ef

File tree

3 files changed

+46
-66
lines changed

3 files changed

+46
-66
lines changed

fs/pstore/inode.c

Lines changed: 44 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include <linux/pstore.h>
2424
#include <linux/slab.h>
2525
#include <linux/uaccess.h>
26+
#include <linux/cleanup.h>
2627

2728
#include "internal.h"
2829

@@ -34,6 +35,8 @@ static LIST_HEAD(records_list);
3435
static DEFINE_MUTEX(pstore_sb_lock);
3536
static struct super_block *pstore_sb;
3637

38+
DEFINE_FREE(pstore_iput, struct inode *, if (_T) iput(_T))
39+
3740
struct pstore_private {
3841
struct list_head list;
3942
struct dentry *dentry;
@@ -60,25 +63,23 @@ static void free_pstore_private(struct pstore_private *private)
6063
}
6164
kfree(private);
6265
}
66+
DEFINE_FREE(pstore_private, struct pstore_private *, free_pstore_private(_T));
6367

6468
static void *pstore_ftrace_seq_start(struct seq_file *s, loff_t *pos)
6569
{
6670
struct pstore_private *ps = s->private;
67-
struct pstore_ftrace_seq_data *data;
71+
struct pstore_ftrace_seq_data *data __free(kfree) = NULL;
6872

6973
data = kzalloc(sizeof(*data), GFP_KERNEL);
7074
if (!data)
7175
return NULL;
7276

7377
data->off = ps->total_size % REC_SIZE;
7478
data->off += *pos * REC_SIZE;
75-
if (data->off + REC_SIZE > ps->total_size) {
76-
kfree(data);
79+
if (data->off + REC_SIZE > ps->total_size)
7780
return NULL;
78-
}
79-
80-
return data;
8181

82+
return_ptr(data);
8283
}
8384

8485
static void pstore_ftrace_seq_stop(struct seq_file *s, void *v)
@@ -182,25 +183,21 @@ static int pstore_unlink(struct inode *dir, struct dentry *dentry)
182183
{
183184
struct pstore_private *p = d_inode(dentry)->i_private;
184185
struct pstore_record *record = p->record;
185-
int rc = 0;
186186

187187
if (!record->psi->erase)
188188
return -EPERM;
189189

190190
/* Make sure we can't race while removing this file. */
191-
mutex_lock(&records_list_lock);
192-
if (!list_empty(&p->list))
193-
list_del_init(&p->list);
194-
else
195-
rc = -ENOENT;
196-
p->dentry = NULL;
197-
mutex_unlock(&records_list_lock);
198-
if (rc)
199-
return rc;
200-
201-
mutex_lock(&record->psi->read_mutex);
202-
record->psi->erase(record);
203-
mutex_unlock(&record->psi->read_mutex);
191+
scoped_guard(mutex, &records_list_lock) {
192+
if (!list_empty(&p->list))
193+
list_del_init(&p->list);
194+
else
195+
return -ENOENT;
196+
p->dentry = NULL;
197+
}
198+
199+
scoped_guard(mutex, &record->psi->read_mutex)
200+
record->psi->erase(record);
204201

205202
return simple_unlink(dir, dentry);
206203
}
@@ -292,19 +289,16 @@ static struct dentry *psinfo_lock_root(void)
292289
{
293290
struct dentry *root;
294291

295-
mutex_lock(&pstore_sb_lock);
292+
guard(mutex)(&pstore_sb_lock);
296293
/*
297294
* Having no backend is fine -- no records appear.
298295
* Not being mounted is fine -- nothing to do.
299296
*/
300-
if (!psinfo || !pstore_sb) {
301-
mutex_unlock(&pstore_sb_lock);
297+
if (!psinfo || !pstore_sb)
302298
return NULL;
303-
}
304299

305300
root = pstore_sb->s_root;
306301
inode_lock(d_inode(root));
307-
mutex_unlock(&pstore_sb_lock);
308302

309303
return root;
310304
}
@@ -319,19 +313,19 @@ int pstore_put_backend_records(struct pstore_info *psi)
319313
if (!root)
320314
return 0;
321315

322-
mutex_lock(&records_list_lock);
323-
list_for_each_entry_safe(pos, tmp, &records_list, list) {
324-
if (pos->record->psi == psi) {
325-
list_del_init(&pos->list);
326-
rc = simple_unlink(d_inode(root), pos->dentry);
327-
if (WARN_ON(rc))
328-
break;
329-
d_drop(pos->dentry);
330-
dput(pos->dentry);
331-
pos->dentry = NULL;
316+
scoped_guard(mutex, &records_list_lock) {
317+
list_for_each_entry_safe(pos, tmp, &records_list, list) {
318+
if (pos->record->psi == psi) {
319+
list_del_init(&pos->list);
320+
rc = simple_unlink(d_inode(root), pos->dentry);
321+
if (WARN_ON(rc))
322+
break;
323+
d_drop(pos->dentry);
324+
dput(pos->dentry);
325+
pos->dentry = NULL;
326+
}
332327
}
333328
}
334-
mutex_unlock(&records_list_lock);
335329

336330
inode_unlock(d_inode(root));
337331

@@ -346,29 +340,27 @@ int pstore_put_backend_records(struct pstore_info *psi)
346340
int pstore_mkfile(struct dentry *root, struct pstore_record *record)
347341
{
348342
struct dentry *dentry;
349-
struct inode *inode;
350-
int rc = 0;
343+
struct inode *inode __free(pstore_iput) = NULL;
351344
char name[PSTORE_NAMELEN];
352-
struct pstore_private *private, *pos;
345+
struct pstore_private *private __free(pstore_private) = NULL, *pos;
353346
size_t size = record->size + record->ecc_notice_size;
354347

355348
if (WARN_ON(!inode_is_locked(d_inode(root))))
356349
return -EINVAL;
357350

358-
rc = -EEXIST;
351+
guard(mutex)(&records_list_lock);
352+
359353
/* Skip records that are already present in the filesystem. */
360-
mutex_lock(&records_list_lock);
361354
list_for_each_entry(pos, &records_list, list) {
362355
if (pos->record->type == record->type &&
363356
pos->record->id == record->id &&
364357
pos->record->psi == record->psi)
365-
goto fail;
358+
return -EEXIST;
366359
}
367360

368-
rc = -ENOMEM;
369361
inode = pstore_get_inode(root->d_sb);
370362
if (!inode)
371-
goto fail;
363+
return -ENOMEM;
372364
inode->i_mode = S_IFREG | 0444;
373365
inode->i_fop = &pstore_file_operations;
374366
scnprintf(name, sizeof(name), "%s-%s-%llu%s",
@@ -378,11 +370,11 @@ int pstore_mkfile(struct dentry *root, struct pstore_record *record)
378370

379371
private = kzalloc(sizeof(*private), GFP_KERNEL);
380372
if (!private)
381-
goto fail_inode;
373+
return -ENOMEM;
382374

383375
dentry = d_alloc_name(root, name);
384376
if (!dentry)
385-
goto fail_private;
377+
return -ENOMEM;
386378

387379
private->dentry = dentry;
388380
private->record = record;
@@ -393,20 +385,11 @@ int pstore_mkfile(struct dentry *root, struct pstore_record *record)
393385
inode_set_mtime_to_ts(inode,
394386
inode_set_ctime_to_ts(inode, record->time));
395387

396-
d_add(dentry, inode);
388+
d_add(dentry, no_free_ptr(inode));
397389

398-
list_add(&private->list, &records_list);
399-
mutex_unlock(&records_list_lock);
390+
list_add(&(no_free_ptr(private))->list, &records_list);
400391

401392
return 0;
402-
403-
fail_private:
404-
free_pstore_private(private);
405-
fail_inode:
406-
iput(inode);
407-
fail:
408-
mutex_unlock(&records_list_lock);
409-
return rc;
410393
}
411394

412395
/*
@@ -451,9 +434,8 @@ static int pstore_fill_super(struct super_block *sb, void *data, int silent)
451434
if (!sb->s_root)
452435
return -ENOMEM;
453436

454-
mutex_lock(&pstore_sb_lock);
455-
pstore_sb = sb;
456-
mutex_unlock(&pstore_sb_lock);
437+
scoped_guard(mutex, &pstore_sb_lock)
438+
pstore_sb = sb;
457439

458440
pstore_get_records(0);
459441

@@ -468,17 +450,14 @@ static struct dentry *pstore_mount(struct file_system_type *fs_type,
468450

469451
static void pstore_kill_sb(struct super_block *sb)
470452
{
471-
mutex_lock(&pstore_sb_lock);
453+
guard(mutex)(&pstore_sb_lock);
472454
WARN_ON(pstore_sb && pstore_sb != sb);
473455

474456
kill_litter_super(sb);
475457
pstore_sb = NULL;
476458

477-
mutex_lock(&records_list_lock);
459+
guard(mutex)(&records_list_lock);
478460
INIT_LIST_HEAD(&records_list);
479-
mutex_unlock(&records_list_lock);
480-
481-
mutex_unlock(&pstore_sb_lock);
482461
}
483462

484463
static struct file_system_type pstore_fs_type = {

fs/pstore/ram.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -529,6 +529,7 @@ static int ramoops_init_przs(const char *name,
529529
}
530530

531531
zone_sz = mem_sz / *cnt;
532+
zone_sz = ALIGN_DOWN(zone_sz, 2);
532533
if (!zone_sz) {
533534
dev_err(dev, "%s zone size == 0\n", name);
534535
goto fail;

fs/pstore/ram_core.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ static int persistent_ram_init_ecc(struct persistent_ram_zone *prz,
190190
{
191191
int numerr;
192192
struct persistent_ram_buffer *buffer = prz->buffer;
193-
int ecc_blocks;
193+
size_t ecc_blocks;
194194
size_t ecc_total;
195195

196196
if (!ecc_info || !ecc_info->ecc_size)

0 commit comments

Comments
 (0)