From 18f81b3dfa0fb4430a0d9734c657387ed3caf843 Mon Sep 17 00:00:00 2001 From: Alexander Leidinger Date: Sat, 16 Sep 2006 14:12:04 +0000 Subject: [PATCH] - don't reboot() when feed with wrong parameters (and enough permissions) [1] - add support to power off the system [2] - check the linux magic values [3] Submitted by: Marcin Cieslak [1,2] Modelled after: linux man page of the reboot() syscall [3] Found by: LTP testcase "reboot02" [1] Tested with: LTP testcase "reboot02" [1,3] MFC after: 1 week --- sys/compat/linux/linux_misc.c | 42 +++++++++++++++++++++++++++++++---- 1 file changed, 38 insertions(+), 4 deletions(-) diff --git a/sys/compat/linux/linux_misc.c b/sys/compat/linux/linux_misc.c index d512994d551d..9631ac222e9d 100644 --- a/sys/compat/linux/linux_misc.c +++ b/sys/compat/linux/linux_misc.c @@ -1299,6 +1299,13 @@ linux_sched_get_priority_min(struct thread *td, #define REBOOT_CAD_ON 0x89abcdef #define REBOOT_CAD_OFF 0 #define REBOOT_HALT 0xcdef0123 +#define REBOOT_RESTART 0x01234567 +#define REBOOT_RESTART2 0xA1B2C3D4 +#define REBOOT_POWEROFF 0x4321FEDC +#define REBOOT_MAGIC1 0xfee1dead +#define REBOOT_MAGIC2 0x28121969 +#define REBOOT_MAGIC2A 0x05121996 +#define REBOOT_MAGIC2B 0x16041998 int linux_reboot(struct thread *td, struct linux_reboot_args *args) @@ -1309,10 +1316,37 @@ linux_reboot(struct thread *td, struct linux_reboot_args *args) if (ldebug(reboot)) printf(ARGS(reboot, "0x%x"), args->cmd); #endif - if (args->cmd == REBOOT_CAD_ON || args->cmd == REBOOT_CAD_OFF) - return (0); - bsd_args.opt = (args->cmd == REBOOT_HALT) ? RB_HALT : 0; - return (reboot(td, &bsd_args)); + + if (args->magic1 != REBOOT_MAGIC1) + return EINVAL; + + switch (args->magic2) { + case REBOOT_MAGIC2: + case REBOOT_MAGIC2A: + case REBOOT_MAGIC2B: + break; + default: + return EINVAL; + } + + switch (args->cmd) { + case REBOOT_CAD_ON: + case REBOOT_CAD_OFF: + return suser(td); + case REBOOT_HALT: + bsd_args.opt = RB_HALT; + break; + case REBOOT_RESTART: + case REBOOT_RESTART2: + bsd_args.opt = 0; + break; + case REBOOT_POWEROFF: + bsd_args.opt = RB_POWEROFF; + break; + default: + return EINVAL; + } + return reboot(td, &bsd_args); }