On a system that restricts access to dmesg, don't let people
side-step that by reading copies that pstore saved. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJUheJgAAoJEKurIx+X31iB5F0P/jdpAw6cI26icGiOcRvRYvce jLq/WbGggxZlx3rtgGpekJmcJ1NBBTLdyx4b86q4q/zstQkoJ9lqGCn63YcIMJNB pdctmbkGyoQQXBTAzSCFs6pybMUmtYKMDiT3OJddcCm4fUjd4RQHvNP+5ESsf0lQ 9YpIS+rZOtB2/5N6/i4+Lnaffc3s5gXw/dJMxOm/laWtRFRyhf22YP18cRp5LmuV NHqu1NoeLnar/qL6plPl73lEyZVOPRC01T7OWmmCkcLieYPGkqQlkoXp95VBKf5u CvD167oM71OccMa0gOTlCS8a6y5KO6y8I+YAR60iANTLDh+rHZiwNj1gY4v/Z29m 2ba1xAulQrpCxqml6eVxAKaF+4HXaXVXKqjQIivJcGyfYf6BXLMvC0M3Lsv7XQdz HKl++o0JELDEJjVW0i9Wa5CjgcqXdvuRXOoKDaKTZWff2yfUxqIN5Xl7zIV2kgVy ZqPDBHJSmHjuzmJ6inhPkmdS2uz94PVSE7ykeaa8iCBbpdsS+FchtF2sRMvUhU23 ekHsxk0Mk/pS5EBNc6rrrM9NtKrUQMa1e/oT5G7QowksDeNpsPjx92OeUImxgh3x +hmObN9vx6SepwVSfjI1rwrMsAknphJfPmyi/XJgkVbfRMCv2we1npvYd6hqFUMV daekMzGOi5eqoaWB8hje =Ezg0 -----END PGP SIGNATURE----- Merge tag 'please-pull-pstore' of git://git.kernel.org/pub/scm/linux/kernel/git/aegl/linux Pull pstore fixes from Tony Luck: "On a system that restricts access to dmesg, don't let people side-step that by reading copies that pstore saved" * tag 'please-pull-pstore' of git://git.kernel.org/pub/scm/linux/kernel/git/aegl/linux: syslog: Provide stub check_syslog_permissions pstore: Honor dmesg_restrict sysctl on dmesg dumps pstore/ram: Strip ramoops header for correct decompression
This commit is contained in:
Коммит
08e2fb6ce6
|
@ -36,6 +36,7 @@
|
|||
#include <linux/slab.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/syslog.h>
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
|
@ -120,6 +121,18 @@ static const struct seq_operations pstore_ftrace_seq_ops = {
|
|||
.show = pstore_ftrace_seq_show,
|
||||
};
|
||||
|
||||
static int pstore_check_syslog_permissions(struct pstore_private *ps)
|
||||
{
|
||||
switch (ps->type) {
|
||||
case PSTORE_TYPE_DMESG:
|
||||
case PSTORE_TYPE_CONSOLE:
|
||||
return check_syslog_permissions(SYSLOG_ACTION_READ_ALL,
|
||||
SYSLOG_FROM_READER);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static ssize_t pstore_file_read(struct file *file, char __user *userbuf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
|
@ -138,6 +151,10 @@ static int pstore_file_open(struct inode *inode, struct file *file)
|
|||
int err;
|
||||
const struct seq_operations *sops = NULL;
|
||||
|
||||
err = pstore_check_syslog_permissions(ps);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (ps->type == PSTORE_TYPE_FTRACE)
|
||||
sops = &pstore_ftrace_seq_ops;
|
||||
|
||||
|
@ -174,6 +191,11 @@ static const struct file_operations pstore_file_operations = {
|
|||
static int pstore_unlink(struct inode *dir, struct dentry *dentry)
|
||||
{
|
||||
struct pstore_private *p = dentry->d_inode->i_private;
|
||||
int err;
|
||||
|
||||
err = pstore_check_syslog_permissions(p);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (p->psi->erase)
|
||||
p->psi->erase(p->type, p->id, p->count,
|
||||
|
|
|
@ -135,25 +135,27 @@ ramoops_get_next_prz(struct persistent_ram_zone *przs[], uint *c, uint max,
|
|||
return prz;
|
||||
}
|
||||
|
||||
static void ramoops_read_kmsg_hdr(char *buffer, struct timespec *time,
|
||||
static int ramoops_read_kmsg_hdr(char *buffer, struct timespec *time,
|
||||
bool *compressed)
|
||||
{
|
||||
char data_type;
|
||||
int header_length = 0;
|
||||
|
||||
if (sscanf(buffer, RAMOOPS_KERNMSG_HDR "%lu.%lu-%c\n",
|
||||
&time->tv_sec, &time->tv_nsec, &data_type) == 3) {
|
||||
if (sscanf(buffer, RAMOOPS_KERNMSG_HDR "%lu.%lu-%c\n%n", &time->tv_sec,
|
||||
&time->tv_nsec, &data_type, &header_length) == 3) {
|
||||
if (data_type == 'C')
|
||||
*compressed = true;
|
||||
else
|
||||
*compressed = false;
|
||||
} else if (sscanf(buffer, RAMOOPS_KERNMSG_HDR "%lu.%lu\n",
|
||||
&time->tv_sec, &time->tv_nsec) == 2) {
|
||||
} else if (sscanf(buffer, RAMOOPS_KERNMSG_HDR "%lu.%lu\n%n",
|
||||
&time->tv_sec, &time->tv_nsec, &header_length) == 2) {
|
||||
*compressed = false;
|
||||
} else {
|
||||
time->tv_sec = 0;
|
||||
time->tv_nsec = 0;
|
||||
*compressed = false;
|
||||
}
|
||||
return header_length;
|
||||
}
|
||||
|
||||
static ssize_t ramoops_pstore_read(u64 *id, enum pstore_type_id *type,
|
||||
|
@ -165,6 +167,7 @@ static ssize_t ramoops_pstore_read(u64 *id, enum pstore_type_id *type,
|
|||
ssize_t ecc_notice_size;
|
||||
struct ramoops_context *cxt = psi->data;
|
||||
struct persistent_ram_zone *prz;
|
||||
int header_length;
|
||||
|
||||
prz = ramoops_get_next_prz(cxt->przs, &cxt->dump_read_cnt,
|
||||
cxt->max_dump_cnt, id, type,
|
||||
|
@ -178,7 +181,13 @@ static ssize_t ramoops_pstore_read(u64 *id, enum pstore_type_id *type,
|
|||
if (!prz)
|
||||
return 0;
|
||||
|
||||
if (!persistent_ram_old(prz))
|
||||
return 0;
|
||||
|
||||
size = persistent_ram_old_size(prz);
|
||||
header_length = ramoops_read_kmsg_hdr(persistent_ram_old(prz), time,
|
||||
compressed);
|
||||
size -= header_length;
|
||||
|
||||
/* ECC correction notice */
|
||||
ecc_notice_size = persistent_ram_ecc_string(prz, NULL, 0);
|
||||
|
@ -187,8 +196,7 @@ static ssize_t ramoops_pstore_read(u64 *id, enum pstore_type_id *type,
|
|||
if (*buf == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
memcpy(*buf, persistent_ram_old(prz), size);
|
||||
ramoops_read_kmsg_hdr(*buf, time, compressed);
|
||||
memcpy(*buf, (char *)persistent_ram_old(prz) + header_length, size);
|
||||
persistent_ram_ecc_string(prz, *buf + size, ecc_notice_size + 1);
|
||||
|
||||
return size + ecc_notice_size;
|
||||
|
|
|
@ -49,4 +49,13 @@
|
|||
|
||||
int do_syslog(int type, char __user *buf, int count, bool from_file);
|
||||
|
||||
#ifdef CONFIG_PRINTK
|
||||
int check_syslog_permissions(int type, bool from_file);
|
||||
#else
|
||||
static inline int check_syslog_permissions(int type, bool from_file)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _LINUX_SYSLOG_H */
|
||||
|
|
|
@ -480,7 +480,7 @@ static int syslog_action_restricted(int type)
|
|||
type != SYSLOG_ACTION_SIZE_BUFFER;
|
||||
}
|
||||
|
||||
static int check_syslog_permissions(int type, bool from_file)
|
||||
int check_syslog_permissions(int type, bool from_file)
|
||||
{
|
||||
/*
|
||||
* If this is from /proc/kmsg and we've already opened it, then we've
|
||||
|
|
Загрузка…
Ссылка в новой задаче