aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2018-09-25 05:27:20 -0400
committerEric W. Biederman <ebiederm@xmission.com>2018-10-03 10:47:43 -0400
commitae7795bc6187a15ec51cf258abae656a625f9980 (patch)
tree2456aa85c6b4be1ac58e272393056c0edbee038a /include/linux
parent4cd2e0e70af6897ca2247fa1ffb1553ca16b4903 (diff)
signal: Distinguish between kernel_siginfo and siginfo
Linus recently observed that if we did not worry about the padding member in struct siginfo it is only about 48 bytes, and 48 bytes is much nicer than 128 bytes for allocating on the stack and copying around in the kernel. The obvious thing of only adding the padding when userspace is including siginfo.h won't work as there are sigframe definitions in the kernel that embed struct siginfo. So split siginfo in two; kernel_siginfo and siginfo. Keeping the traditional name for the userspace definition. While the version that is used internally to the kernel and ultimately will not be padded to 128 bytes is called kernel_siginfo. The definition of struct kernel_siginfo I have put in include/signal_types.h A set of buildtime checks has been added to verify the two structures have the same field offsets. To make it easy to verify the change kernel_siginfo retains the same size as siginfo. The reduction in size comes in a following change. Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/binfmts.h2
-rw-r--r--include/linux/compat.h4
-rw-r--r--include/linux/coredump.h4
-rw-r--r--include/linux/lsm_hooks.h4
-rw-r--r--include/linux/posix-timers.h2
-rw-r--r--include/linux/ptrace.h2
-rw-r--r--include/linux/sched.h2
-rw-r--r--include/linux/sched/signal.h18
-rw-r--r--include/linux/security.h6
-rw-r--r--include/linux/signal.h15
-rw-r--r--include/linux/signal_types.h11
11 files changed, 39 insertions, 31 deletions
diff --git a/include/linux/binfmts.h b/include/linux/binfmts.h
index c05f24fac4f6..e9f5fe69df31 100644
--- a/include/linux/binfmts.h
+++ b/include/linux/binfmts.h
@@ -78,7 +78,7 @@ struct linux_binprm {
78 78
79/* Function parameter for binfmt->coredump */ 79/* Function parameter for binfmt->coredump */
80struct coredump_params { 80struct coredump_params {
81 const siginfo_t *siginfo; 81 const kernel_siginfo_t *siginfo;
82 struct pt_regs *regs; 82 struct pt_regs *regs;
83 struct file *file; 83 struct file *file;
84 unsigned long limit; 84 unsigned long limit;
diff --git a/include/linux/compat.h b/include/linux/compat.h
index 1a3c4f37e908..4565d65b1776 100644
--- a/include/linux/compat.h
+++ b/include/linux/compat.h
@@ -452,8 +452,8 @@ long compat_get_bitmap(unsigned long *mask, const compat_ulong_t __user *umask,
452 unsigned long bitmap_size); 452 unsigned long bitmap_size);
453long compat_put_bitmap(compat_ulong_t __user *umask, unsigned long *mask, 453long compat_put_bitmap(compat_ulong_t __user *umask, unsigned long *mask,
454 unsigned long bitmap_size); 454 unsigned long bitmap_size);
455int copy_siginfo_from_user32(siginfo_t *to, const struct compat_siginfo __user *from); 455int copy_siginfo_from_user32(kernel_siginfo_t *to, const struct compat_siginfo __user *from);
456int copy_siginfo_to_user32(struct compat_siginfo __user *to, const siginfo_t *from); 456int copy_siginfo_to_user32(struct compat_siginfo __user *to, const kernel_siginfo_t *from);
457int get_compat_sigevent(struct sigevent *event, 457int get_compat_sigevent(struct sigevent *event,
458 const struct compat_sigevent __user *u_event); 458 const struct compat_sigevent __user *u_event);
459 459
diff --git a/include/linux/coredump.h b/include/linux/coredump.h
index 207aed96a5b7..abf4b4e65dbb 100644
--- a/include/linux/coredump.h
+++ b/include/linux/coredump.h
@@ -17,9 +17,9 @@ extern int dump_emit(struct coredump_params *cprm, const void *addr, int nr);
17extern int dump_align(struct coredump_params *cprm, int align); 17extern int dump_align(struct coredump_params *cprm, int align);
18extern void dump_truncate(struct coredump_params *cprm); 18extern void dump_truncate(struct coredump_params *cprm);
19#ifdef CONFIG_COREDUMP 19#ifdef CONFIG_COREDUMP
20extern void do_coredump(const siginfo_t *siginfo); 20extern void do_coredump(const kernel_siginfo_t *siginfo);
21#else 21#else
22static inline void do_coredump(const siginfo_t *siginfo) {} 22static inline void do_coredump(const kernel_siginfo_t *siginfo) {}
23#endif 23#endif
24 24
25#endif /* _LINUX_COREDUMP_H */ 25#endif /* _LINUX_COREDUMP_H */
diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index 97a020c616ad..bb40f6d34163 100644
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -672,7 +672,7 @@
672 * Return 0 if permission is granted. 672 * Return 0 if permission is granted.
673 * @task_kill: 673 * @task_kill:
674 * Check permission before sending signal @sig to @p. @info can be NULL, 674 * Check permission before sending signal @sig to @p. @info can be NULL,
675 * the constant 1, or a pointer to a siginfo structure. If @info is 1 or 675 * the constant 1, or a pointer to a kernel_siginfo structure. If @info is 1 or
676 * SI_FROMKERNEL(info) is true, then the signal should be viewed as coming 676 * SI_FROMKERNEL(info) is true, then the signal should be viewed as coming
677 * from the kernel and should typically be permitted. 677 * from the kernel and should typically be permitted.
678 * SIGIO signals are handled separately by the send_sigiotask hook in 678 * SIGIO signals are handled separately by the send_sigiotask hook in
@@ -1606,7 +1606,7 @@ union security_list_options {
1606 int (*task_setscheduler)(struct task_struct *p); 1606 int (*task_setscheduler)(struct task_struct *p);
1607 int (*task_getscheduler)(struct task_struct *p); 1607 int (*task_getscheduler)(struct task_struct *p);
1608 int (*task_movememory)(struct task_struct *p); 1608 int (*task_movememory)(struct task_struct *p);
1609 int (*task_kill)(struct task_struct *p, struct siginfo *info, 1609 int (*task_kill)(struct task_struct *p, struct kernel_siginfo *info,
1610 int sig, const struct cred *cred); 1610 int sig, const struct cred *cred);
1611 int (*task_prctl)(int option, unsigned long arg2, unsigned long arg3, 1611 int (*task_prctl)(int option, unsigned long arg2, unsigned long arg3,
1612 unsigned long arg4, unsigned long arg5); 1612 unsigned long arg4, unsigned long arg5);
diff --git a/include/linux/posix-timers.h b/include/linux/posix-timers.h
index ee7e987ea1b4..e96581ca7c9d 100644
--- a/include/linux/posix-timers.h
+++ b/include/linux/posix-timers.h
@@ -126,5 +126,5 @@ void set_process_cpu_timer(struct task_struct *task, unsigned int clock_idx,
126 126
127void update_rlimit_cpu(struct task_struct *task, unsigned long rlim_new); 127void update_rlimit_cpu(struct task_struct *task, unsigned long rlim_new);
128 128
129void posixtimer_rearm(struct siginfo *info); 129void posixtimer_rearm(struct kernel_siginfo *info);
130#endif 130#endif
diff --git a/include/linux/ptrace.h b/include/linux/ptrace.h
index 1de2235511c8..d19a795100da 100644
--- a/include/linux/ptrace.h
+++ b/include/linux/ptrace.h
@@ -341,7 +341,7 @@ extern void user_single_step_report(struct pt_regs *regs);
341#else 341#else
342static inline void user_single_step_report(struct pt_regs *regs) 342static inline void user_single_step_report(struct pt_regs *regs)
343{ 343{
344 siginfo_t info; 344 kernel_siginfo_t info;
345 clear_siginfo(&info); 345 clear_siginfo(&info);
346 info.si_signo = SIGTRAP; 346 info.si_signo = SIGTRAP;
347 info.si_errno = 0; 347 info.si_errno = 0;
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 977cb57d7bc9..2ba88082e1ef 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -960,7 +960,7 @@ struct task_struct {
960 960
961 /* Ptrace state: */ 961 /* Ptrace state: */
962 unsigned long ptrace_message; 962 unsigned long ptrace_message;
963 siginfo_t *last_siginfo; 963 kernel_siginfo_t *last_siginfo;
964 964
965 struct task_io_accounting ioac; 965 struct task_io_accounting ioac;
966#ifdef CONFIG_TASK_XACCT 966#ifdef CONFIG_TASK_XACCT
diff --git a/include/linux/sched/signal.h b/include/linux/sched/signal.h
index 9e07f3521549..13789d10a50e 100644
--- a/include/linux/sched/signal.h
+++ b/include/linux/sched/signal.h
@@ -270,12 +270,12 @@ static inline int signal_group_exit(const struct signal_struct *sig)
270extern void flush_signals(struct task_struct *); 270extern void flush_signals(struct task_struct *);
271extern void ignore_signals(struct task_struct *); 271extern void ignore_signals(struct task_struct *);
272extern void flush_signal_handlers(struct task_struct *, int force_default); 272extern void flush_signal_handlers(struct task_struct *, int force_default);
273extern int dequeue_signal(struct task_struct *tsk, sigset_t *mask, siginfo_t *info); 273extern int dequeue_signal(struct task_struct *tsk, sigset_t *mask, kernel_siginfo_t *info);
274 274
275static inline int kernel_dequeue_signal(void) 275static inline int kernel_dequeue_signal(void)
276{ 276{
277 struct task_struct *tsk = current; 277 struct task_struct *tsk = current;
278 siginfo_t __info; 278 kernel_siginfo_t __info;
279 int ret; 279 int ret;
280 280
281 spin_lock_irq(&tsk->sighand->siglock); 281 spin_lock_irq(&tsk->sighand->siglock);
@@ -322,12 +322,12 @@ int force_sig_pkuerr(void __user *addr, u32 pkey);
322 322
323int force_sig_ptrace_errno_trap(int errno, void __user *addr); 323int force_sig_ptrace_errno_trap(int errno, void __user *addr);
324 324
325extern int send_sig_info(int, struct siginfo *, struct task_struct *); 325extern int send_sig_info(int, struct kernel_siginfo *, struct task_struct *);
326extern void force_sigsegv(int sig, struct task_struct *p); 326extern void force_sigsegv(int sig, struct task_struct *p);
327extern int force_sig_info(int, struct siginfo *, struct task_struct *); 327extern int force_sig_info(int, struct kernel_siginfo *, struct task_struct *);
328extern int __kill_pgrp_info(int sig, struct siginfo *info, struct pid *pgrp); 328extern int __kill_pgrp_info(int sig, struct kernel_siginfo *info, struct pid *pgrp);
329extern int kill_pid_info(int sig, struct siginfo *info, struct pid *pid); 329extern int kill_pid_info(int sig, struct kernel_siginfo *info, struct pid *pid);
330extern int kill_pid_info_as_cred(int, struct siginfo *, struct pid *, 330extern int kill_pid_info_as_cred(int, struct kernel_siginfo *, struct pid *,
331 const struct cred *); 331 const struct cred *);
332extern int kill_pgrp(struct pid *pid, int sig, int priv); 332extern int kill_pgrp(struct pid *pid, int sig, int priv);
333extern int kill_pid(struct pid *pid, int sig, int priv); 333extern int kill_pid(struct pid *pid, int sig, int priv);
@@ -475,8 +475,8 @@ static inline int kill_cad_pid(int sig, int priv)
475} 475}
476 476
477/* These can be the second arg to send_sig_info/send_group_sig_info. */ 477/* These can be the second arg to send_sig_info/send_group_sig_info. */
478#define SEND_SIG_NOINFO ((struct siginfo *) 0) 478#define SEND_SIG_NOINFO ((struct kernel_siginfo *) 0)
479#define SEND_SIG_PRIV ((struct siginfo *) 1) 479#define SEND_SIG_PRIV ((struct kernel_siginfo *) 1)
480 480
481/* 481/*
482 * True if we are on the alternate signal stack. 482 * True if we are on the alternate signal stack.
diff --git a/include/linux/security.h b/include/linux/security.h
index 75f4156c84d7..d170a5b031f3 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -35,7 +35,7 @@
35struct linux_binprm; 35struct linux_binprm;
36struct cred; 36struct cred;
37struct rlimit; 37struct rlimit;
38struct siginfo; 38struct kernel_siginfo;
39struct sembuf; 39struct sembuf;
40struct kern_ipc_perm; 40struct kern_ipc_perm;
41struct audit_context; 41struct audit_context;
@@ -361,7 +361,7 @@ int security_task_setrlimit(struct task_struct *p, unsigned int resource,
361int security_task_setscheduler(struct task_struct *p); 361int security_task_setscheduler(struct task_struct *p);
362int security_task_getscheduler(struct task_struct *p); 362int security_task_getscheduler(struct task_struct *p);
363int security_task_movememory(struct task_struct *p); 363int security_task_movememory(struct task_struct *p);
364int security_task_kill(struct task_struct *p, struct siginfo *info, 364int security_task_kill(struct task_struct *p, struct kernel_siginfo *info,
365 int sig, const struct cred *cred); 365 int sig, const struct cred *cred);
366int security_task_prctl(int option, unsigned long arg2, unsigned long arg3, 366int security_task_prctl(int option, unsigned long arg2, unsigned long arg3,
367 unsigned long arg4, unsigned long arg5); 367 unsigned long arg4, unsigned long arg5);
@@ -1020,7 +1020,7 @@ static inline int security_task_movememory(struct task_struct *p)
1020} 1020}
1021 1021
1022static inline int security_task_kill(struct task_struct *p, 1022static inline int security_task_kill(struct task_struct *p,
1023 struct siginfo *info, int sig, 1023 struct kernel_siginfo *info, int sig,
1024 const struct cred *cred) 1024 const struct cred *cred)
1025{ 1025{
1026 return 0; 1026 return 0;
diff --git a/include/linux/signal.h b/include/linux/signal.h
index de94c159bfb0..70031b10b918 100644
--- a/include/linux/signal.h
+++ b/include/linux/signal.h
@@ -11,18 +11,19 @@ struct task_struct;
11/* for sysctl */ 11/* for sysctl */
12extern int print_fatal_signals; 12extern int print_fatal_signals;
13 13
14static inline void copy_siginfo(struct siginfo *to, const struct siginfo *from) 14static inline void copy_siginfo(kernel_siginfo_t *to,
15 const kernel_siginfo_t *from)
15{ 16{
16 memcpy(to, from, sizeof(*to)); 17 memcpy(to, from, sizeof(*to));
17} 18}
18 19
19static inline void clear_siginfo(struct siginfo *info) 20static inline void clear_siginfo(kernel_siginfo_t *info)
20{ 21{
21 memset(info, 0, sizeof(*info)); 22 memset(info, 0, sizeof(*info));
22} 23}
23 24
24int copy_siginfo_to_user(struct siginfo __user *to, const struct siginfo *from); 25int copy_siginfo_to_user(siginfo_t __user *to, const kernel_siginfo_t *from);
25int copy_siginfo_from_user(struct siginfo *to, const struct siginfo __user *from); 26int copy_siginfo_from_user(kernel_siginfo_t *to, const siginfo_t __user *from);
26 27
27enum siginfo_layout { 28enum siginfo_layout {
28 SIL_KILL, 29 SIL_KILL,
@@ -258,11 +259,11 @@ struct pt_regs;
258enum pid_type; 259enum pid_type;
259 260
260extern int next_signal(struct sigpending *pending, sigset_t *mask); 261extern int next_signal(struct sigpending *pending, sigset_t *mask);
261extern int do_send_sig_info(int sig, struct siginfo *info, 262extern int do_send_sig_info(int sig, struct kernel_siginfo *info,
262 struct task_struct *p, enum pid_type type); 263 struct task_struct *p, enum pid_type type);
263extern int group_send_sig_info(int sig, struct siginfo *info, 264extern int group_send_sig_info(int sig, struct kernel_siginfo *info,
264 struct task_struct *p, enum pid_type type); 265 struct task_struct *p, enum pid_type type);
265extern int __group_send_sig_info(int, struct siginfo *, struct task_struct *); 266extern int __group_send_sig_info(int, struct kernel_siginfo *, struct task_struct *);
266extern int sigprocmask(int, sigset_t *, sigset_t *); 267extern int sigprocmask(int, sigset_t *, sigset_t *);
267extern void set_current_blocked(sigset_t *); 268extern void set_current_blocked(sigset_t *);
268extern void __set_current_blocked(const sigset_t *); 269extern void __set_current_blocked(const sigset_t *);
diff --git a/include/linux/signal_types.h b/include/linux/signal_types.h
index 222ae696000b..2a40a9c5e4ad 100644
--- a/include/linux/signal_types.h
+++ b/include/linux/signal_types.h
@@ -9,6 +9,13 @@
9#include <linux/list.h> 9#include <linux/list.h>
10#include <uapi/linux/signal.h> 10#include <uapi/linux/signal.h>
11 11
12typedef struct kernel_siginfo {
13 union {
14 __SIGINFO;
15 int _si_pad[SI_MAX_SIZE/sizeof(int)];
16 };
17} kernel_siginfo_t;
18
12/* 19/*
13 * Real Time signals may be queued. 20 * Real Time signals may be queued.
14 */ 21 */
@@ -16,7 +23,7 @@
16struct sigqueue { 23struct sigqueue {
17 struct list_head list; 24 struct list_head list;
18 int flags; 25 int flags;
19 siginfo_t info; 26 kernel_siginfo_t info;
20 struct user_struct *user; 27 struct user_struct *user;
21}; 28};
22 29
@@ -60,7 +67,7 @@ struct old_sigaction {
60 67
61struct ksignal { 68struct ksignal {
62 struct k_sigaction ka; 69 struct k_sigaction ka;
63 siginfo_t info; 70 kernel_siginfo_t info;
64 int sig; 71 int sig;
65}; 72};
66 73