ipc, msg: forbid negative values for "msg{max,mnb,mni}"

Negative message lengths make no sense -- so don't do negative queue
lenghts or identifier counts. Prevent them from getting negative.

Also change the underlying data types to be unsigned to avoid hairy
surprises with sign extensions in cases where those variables get
evaluated in unsigned expressions with bigger data types, e.g size_t.

In case a user still wants to have "unlimited" sizes she could just use
INT_MAX instead.

Signed-off-by: Mathias Krause <minipli@googlemail.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
Mathias Krause 2013-11-03 12:36:28 +01:00 committed by Linus Torvalds
parent 9dc8c89dfb
commit 9bf76ca325
2 changed files with 15 additions and 11 deletions

View File

@ -34,9 +34,9 @@ struct ipc_namespace {
int sem_ctls[4]; int sem_ctls[4];
int used_sems; int used_sems;
int msg_ctlmax; unsigned int msg_ctlmax;
int msg_ctlmnb; unsigned int msg_ctlmnb;
int msg_ctlmni; unsigned int msg_ctlmni;
atomic_t msg_bytes; atomic_t msg_bytes;
atomic_t msg_hdrs; atomic_t msg_hdrs;
int auto_msgmni; int auto_msgmni;

View File

@ -62,7 +62,7 @@ static int proc_ipc_dointvec_minmax_orphans(ctl_table *table, int write,
return err; return err;
} }
static int proc_ipc_callback_dointvec(ctl_table *table, int write, static int proc_ipc_callback_dointvec_minmax(ctl_table *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos) void __user *buffer, size_t *lenp, loff_t *ppos)
{ {
struct ctl_table ipc_table; struct ctl_table ipc_table;
@ -72,7 +72,7 @@ static int proc_ipc_callback_dointvec(ctl_table *table, int write,
memcpy(&ipc_table, table, sizeof(ipc_table)); memcpy(&ipc_table, table, sizeof(ipc_table));
ipc_table.data = get_ipc(table); ipc_table.data = get_ipc(table);
rc = proc_dointvec(&ipc_table, write, buffer, lenp, ppos); rc = proc_dointvec_minmax(&ipc_table, write, buffer, lenp, ppos);
if (write && !rc && lenp_bef == *lenp) if (write && !rc && lenp_bef == *lenp)
/* /*
@ -152,15 +152,13 @@ static int proc_ipcauto_dointvec_minmax(ctl_table *table, int write,
#define proc_ipc_dointvec NULL #define proc_ipc_dointvec NULL
#define proc_ipc_dointvec_minmax NULL #define proc_ipc_dointvec_minmax NULL
#define proc_ipc_dointvec_minmax_orphans NULL #define proc_ipc_dointvec_minmax_orphans NULL
#define proc_ipc_callback_dointvec NULL #define proc_ipc_callback_dointvec_minmax NULL
#define proc_ipcauto_dointvec_minmax NULL #define proc_ipcauto_dointvec_minmax NULL
#endif #endif
static int zero; static int zero;
static int one = 1; static int one = 1;
#ifdef CONFIG_CHECKPOINT_RESTORE
static int int_max = INT_MAX; static int int_max = INT_MAX;
#endif
static struct ctl_table ipc_kern_table[] = { static struct ctl_table ipc_kern_table[] = {
{ {
@ -198,21 +196,27 @@ static struct ctl_table ipc_kern_table[] = {
.data = &init_ipc_ns.msg_ctlmax, .data = &init_ipc_ns.msg_ctlmax,
.maxlen = sizeof (init_ipc_ns.msg_ctlmax), .maxlen = sizeof (init_ipc_ns.msg_ctlmax),
.mode = 0644, .mode = 0644,
.proc_handler = proc_ipc_dointvec, .proc_handler = proc_ipc_dointvec_minmax,
.extra1 = &zero,
.extra2 = &int_max,
}, },
{ {
.procname = "msgmni", .procname = "msgmni",
.data = &init_ipc_ns.msg_ctlmni, .data = &init_ipc_ns.msg_ctlmni,
.maxlen = sizeof (init_ipc_ns.msg_ctlmni), .maxlen = sizeof (init_ipc_ns.msg_ctlmni),
.mode = 0644, .mode = 0644,
.proc_handler = proc_ipc_callback_dointvec, .proc_handler = proc_ipc_callback_dointvec_minmax,
.extra1 = &zero,
.extra2 = &int_max,
}, },
{ {
.procname = "msgmnb", .procname = "msgmnb",
.data = &init_ipc_ns.msg_ctlmnb, .data = &init_ipc_ns.msg_ctlmnb,
.maxlen = sizeof (init_ipc_ns.msg_ctlmnb), .maxlen = sizeof (init_ipc_ns.msg_ctlmnb),
.mode = 0644, .mode = 0644,
.proc_handler = proc_ipc_dointvec, .proc_handler = proc_ipc_dointvec_minmax,
.extra1 = &zero,
.extra2 = &int_max,
}, },
{ {
.procname = "sem", .procname = "sem",