From: Alan Cox Date: Sun, 24 Jul 2016 11:11:36 +0000 (+0100) Subject: ioctl: do the job right this time I hope X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=7c5ac8b92a2671f6cd8454558284e62f054428eb;p=FUZIX.git ioctl: do the job right this time I hope We now have four ioctl classes but don't yet use the write only class --- diff --git a/Kernel/include/kernel.h b/Kernel/include/kernel.h index 88173c2d..ef0f878a 100644 --- a/Kernel/include/kernel.h +++ b/Kernel/include/kernel.h @@ -588,7 +588,14 @@ struct s_argblk { #define SELECT_BEGIN 0x8000 #define SELECT_END 0x8001 -#define IOCTL_SUPER 0x4000 /* superuser needed */ +#define IOCTL_NORMAL 0x0000 /* No special rules */ +#define IOCTL_SUPER 0x4000 /* Superuser needed */ +#define IOCTL_KERNEL 0x8000 /* Kernel side only */ +#define IOCTL_WRONLY 0xC000 /* Write handle needed */ + +#define IOCTL_CLASS_SUPER 0x40 +#define IOCTL_CLASS_KERNEL 0x80 +#define IOCTL_CLASS_WRONLY 0xC0 /* * Ioctl ranges diff --git a/Kernel/syscall_fs.c b/Kernel/syscall_fs.c index 43d13348..10d7c550 100644 --- a/Kernel/syscall_fs.c +++ b/Kernel/syscall_fs.c @@ -251,27 +251,29 @@ arg_t _ioctl(void) { inoptr ino; uint16_t dev; + uint8_t rclass = ((uint8_t)(request >> 8)) & 0xC0; + struct oft *oftp; if ((ino = getinode(fd)) == NULLINODE) return -1; - if (!(isdevice(ino))) { + oftp = of_tab + udata.u_files[fd]; + + if (!(isdevice(ino)) || rclass == IOCTL_CLASS_KERNEL) { udata.u_error = ENOTTY; return -1; } - if ((request & IOCTL_SUPER) && esuper()) + if (rclass == IOCTL_CLASS_SUPER && esuper()) return -1; - - if (!(getperm(ino) & OTH_WR)) { + if (rclass == IOCTL_CLASS_WRONLY && O_ACCMODE(oftp->o_access) == O_RDONLY) { udata.u_error = EPERM; return -1; } dev = ino->c_node.i_addr[0]; - /* top bit of request is reserved for kernel originated magic */ - return d_ioctl(dev, request & 0x7FFF, data); + return d_ioctl(dev, request, data); } #undef fd