123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222 |
- diff -rcNP linux/Documentation/admin-guide/sysctl/kernel.rst ipc/Documentation/admin-guide/sysctl/kernel.rst
- *** linux/Documentation/admin-guide/sysctl/kernel.rst 2021-02-24 11:30:42.253000000 -0500
- --- ipc/Documentation/admin-guide/sysctl/kernel.rst 2021-02-24 15:56:41.302000000 -0500
- ***************
- *** 283,288 ****
- --- 283,311 ----
- default value of dmesg_restrict.
-
-
- + harden_ipc
- + ==========
- +
- + This toggle indicates whether access to overly-permissive IPC objects
- + is disallowed.
- +
- + If harden_ipc is set to (0), there are no restrictions. If harden_ipc
- + is set to (1), access to overly-permissive IPC objects (shared
- + memory, message queues, and semaphores) will be denied for processes
- + given the following criteria beyond normal permission checks:
- + 1) If the IPC object is world-accessible and the euid doesn't match
- + that of the creator or current uid for the IPC object
- + 2) If the IPC object is group-accessible and the egid doesn't
- + match that of the creator or current gid for the IPC object
- + It's a common error to grant too much permission to these objects,
- + with impact ranging from denial of service and information leaking to
- + privilege escalation. This feature was developed in response to
- + research by Tim Brown:
- + http://labs.portcullis.co.uk/whitepapers/memory-squatting-attacks-on-system-v-shared-memory/
- + who found hundreds of such insecure usages. Processes with
- + CAP_IPC_OWNER are still permitted to access these IPC objects.
- +
- +
- domainname & hostname:
- ======================
-
- diff -rcNP linux/include/linux/ipc.h ipc/include/linux/ipc.h
- *** linux/include/linux/ipc.h 2021-02-23 09:02:26.000000000 -0500
- --- ipc/include/linux/ipc.h 2021-02-24 15:57:28.815000000 -0500
- ***************
- *** 8,13 ****
- --- 8,15 ----
- #include <uapi/linux/ipc.h>
- #include <linux/refcount.h>
-
- + extern int harden_ipc;
- +
- /* used by in-kernel data structures */
- struct kern_ipc_perm {
- spinlock_t lock;
- diff -rcNP linux/ipc/harden_ipc.c ipc/ipc/harden_ipc.c
- *** linux/ipc/harden_ipc.c 1969-12-31 19:00:00.000000000 -0500
- --- ipc/ipc/harden_ipc.c 2021-02-24 15:59:45.029000000 -0500
- ***************
- *** 0 ****
- --- 1,46 ----
- + #include <linux/kernel.h>
- + #include <linux/mm.h>
- + #include <linux/sched.h>
- + #include <linux/file.h>
- + #include <linux/ipc.h>
- + #include <linux/ipc_namespace.h>
- + #include <linux/cred.h>
- +
- + int harden_ipc __read_mostly = IS_ENABLED(CONFIG_SECURITY_HARDEN_IPC);
- +
- + int
- + ipc_permitted(struct ipc_namespace *ns, struct kern_ipc_perm *ipcp, int requested_mode, int granted_mode)
- + {
- + int write;
- + int orig_granted_mode;
- + kuid_t euid;
- + kgid_t egid;
- +
- + if (!harden_ipc)
- + return 1;
- +
- + euid = current_euid();
- + egid = current_egid();
- +
- + write = requested_mode & 00002;
- + orig_granted_mode = ipcp->mode;
- +
- + if (uid_eq(euid, ipcp->cuid) || uid_eq(euid, ipcp->uid))
- + orig_granted_mode >>= 6;
- + else {
- + /* if likely wrong permissions, lock to user */
- + if (orig_granted_mode & 0007)
- + orig_granted_mode = 0;
- + /* otherwise do a egid-only check */
- + else if (gid_eq(egid, ipcp->cgid) || gid_eq(egid, ipcp->gid))
- + orig_granted_mode >>= 3;
- + /* otherwise, no access */
- + else
- + orig_granted_mode = 0;
- + }
- + if (!(requested_mode & ~granted_mode & 0007) && (requested_mode & ~orig_granted_mode & 0007) &&
- + !ns_capable_noaudit(ns->user_ns, CAP_IPC_OWNER)) {
- + return 0;
- + }
- + return 1;
- + }
- diff -rcNP linux/ipc/Makefile ipc/ipc/Makefile
- *** linux/ipc/Makefile 2021-02-23 09:02:26.000000000 -0500
- --- ipc/ipc/Makefile 2021-02-24 16:01:14.313000000 -0500
- ***************
- *** 4,12 ****
- #
-
- obj-$(CONFIG_SYSVIPC_COMPAT) += compat.o
- ! obj-$(CONFIG_SYSVIPC) += util.o msgutil.o msg.o sem.o shm.o syscall.o
- obj-$(CONFIG_SYSVIPC_SYSCTL) += ipc_sysctl.o
- obj-$(CONFIG_POSIX_MQUEUE) += mqueue.o msgutil.o
- obj-$(CONFIG_IPC_NS) += namespace.o
- obj-$(CONFIG_POSIX_MQUEUE_SYSCTL) += mq_sysctl.o
- -
- --- 4,11 ----
- #
-
- obj-$(CONFIG_SYSVIPC_COMPAT) += compat.o
- ! obj-$(CONFIG_SYSVIPC) += util.o msgutil.o msg.o sem.o shm.o syscall.o harden_ipc.o
- obj-$(CONFIG_SYSVIPC_SYSCTL) += ipc_sysctl.o
- obj-$(CONFIG_POSIX_MQUEUE) += mqueue.o msgutil.o
- obj-$(CONFIG_IPC_NS) += namespace.o
- obj-$(CONFIG_POSIX_MQUEUE_SYSCTL) += mq_sysctl.o
- diff -rcNP linux/ipc/util.c ipc/ipc/util.c
- *** linux/ipc/util.c 2021-02-23 09:02:26.000000000 -0500
- --- ipc/ipc/util.c 2021-02-24 16:02:24.916000000 -0500
- ***************
- *** 76,81 ****
- --- 76,83 ----
- int (*show)(struct seq_file *, void *);
- };
-
- + extern int ipc_permitted(struct ipc_namespace *ns, struct kern_ipc_perm *ipcp, int requested_mode, int granted_mode);
- +
- /**
- * ipc_init - initialise ipc subsystem
- *
- ***************
- *** 529,534 ****
- --- 531,540 ----
- granted_mode >>= 6;
- else if (in_group_p(ipcp->cgid) || in_group_p(ipcp->gid))
- granted_mode >>= 3;
- +
- + if (!ipc_permitted(ns, ipcp, requested_mode, granted_mode))
- + return -1;
- +
- /* is there some bit set in requested_mode but not in granted_mode? */
- if ((requested_mode & ~granted_mode & 0007) &&
- !ns_capable(ns->user_ns, CAP_IPC_OWNER))
- diff -rcNP linux/kernel/sysctl.c ipc/kernel/sysctl.c
- *** linux/kernel/sysctl.c 2021-02-24 11:30:42.279000000 -0500
- --- ipc/kernel/sysctl.c 2021-02-24 16:03:28.137000000 -0500
- ***************
- *** 68,73 ****
- --- 68,74 ----
- #include <linux/bpf.h>
- #include <linux/mount.h>
- #include <linux/userfaultfd_k.h>
- + #include <linux/ipc.h>
-
- #include "../lib/kstrtox.h"
-
- ***************
- *** 935,940 ****
- --- 936,952 ----
- .extra1 = SYSCTL_ZERO,
- .extra2 = SYSCTL_ONE,
- },
- + #ifdef CONFIG_SYSVIPC
- + {
- + .procname = "harden_ipc",
- + .data = &harden_ipc,
- + .maxlen = sizeof(int),
- + .mode = 0644,
- + .proc_handler = &proc_dointvec_minmax_sysadmin,
- + .extra1 = SYSCTL_ZERO,
- + .extra2 = SYSCTL_ONE,
- + },
- + #endif
- {
- .procname = "ngroups_max",
- .data = &ngroups_max,
- diff -rcNP linux/security/Kconfig ipc/security/Kconfig
- *** linux/security/Kconfig 2021-02-24 11:30:42.289000000 -0500
- --- ipc/security/Kconfig 2021-02-24 16:05:10.104000000 -0500
- ***************
- *** 61,66 ****
- --- 61,91 ----
- bool
- default n
-
- + config SECURITY_HARDEN_IPC
- + bool "Disallow access to overly-permissive IPC objects"
- + default y
- + depends on SYSVIPC
- + help
- + If you say Y here, access to overly-permissive IPC objects (shared
- + memory, message queues, and semaphores) will be denied for processes
- + given the following criteria beyond normal permission checks:
- + 1) If the IPC object is world-accessible and the euid doesn't match
- + that of the creator or current uid for the IPC object
- + 2) If the IPC object is group-accessible and the egid doesn't
- + match that of the creator or current gid for the IPC object
- + It's a common error to grant too much permission to these objects,
- + with impact ranging from denial of service and information leaking to
- + privilege escalation. This feature was developed in response to
- + research by Tim Brown:
- + http://labs.portcullis.co.uk/whitepapers/memory-squatting-attacks-on-system-v-shared-memory/
- + who found hundreds of such insecure usages. Processes with
- + CAP_IPC_OWNER are still permitted to access these IPC objects.
- +
- + This setting can be overridden at runtime via the kernel.harden_ipc
- + sysctl.
- +
- + If unsure, say Y.
- +
- config SECURITYFS
- bool "Enable the securityfs filesystem"
- help
|