Commit 0683b531 authored by Eric W. Biederman's avatar Eric W. Biederman
Browse files

signal: Deliver all of the siginfo perf data in _perf

Don't abuse si_errno and deliver all of the perf data in _perf member
of siginfo_t.

Note: The data field in the perf data structures in a u64 to allow a
pointer to be encoded without needed to implement a 32bit and 64bit
version of the same structure.  There already exists a 32bit and 64bit
versions siginfo_t, and the 32bit version can not include a 64bit
member as it only has 32bit alignment.  So unsigned long is used in
siginfo_t instead of a u64 as unsigned long can encode a pointer on
all architectures linux supports.

v1: https://lkml.kernel.org/r/m11rarqqx2.fsf_-_@fess.ebiederm.org
v2: https://lkml.kernel.org/r/20210503203814.25487-10-ebiederm@xmission.com
v3: https://lkml.kernel.org/r/20210505141101.11519-11-ebiederm@xmission.com
Link: https://lkml.kernel.org/r/20210517195748.8880-4-ebiederm@xmission.com


Reviewed-by: default avatarMarco Elver <elver@google.com>
Signed-off-by: default avatar"Eric W. Biederman" <ebiederm@xmission.com>
parent af5eeab7
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -623,7 +623,8 @@ static inline void siginfo_build_tests(void)
	BUILD_BUG_ON(offsetof(siginfo_t, si_pkey) != 0x12);

	/* _sigfault._perf */
	BUILD_BUG_ON(offsetof(siginfo_t, si_perf) != 0x10);
	BUILD_BUG_ON(offsetof(siginfo_t, si_perf_data) != 0x10);
	BUILD_BUG_ON(offsetof(siginfo_t, si_perf_type) != 0x14);

	/* _sigpoll */
	BUILD_BUG_ON(offsetof(siginfo_t, si_band)   != 0x0c);
+4 −2
Original line number Diff line number Diff line
@@ -141,8 +141,10 @@ static inline void signal_compat_build_tests(void)
	BUILD_BUG_ON(offsetof(siginfo_t, si_pkey) != 0x20);
	BUILD_BUG_ON(offsetof(compat_siginfo_t, si_pkey) != 0x14);

	BUILD_BUG_ON(offsetof(siginfo_t, si_perf) != 0x18);
	BUILD_BUG_ON(offsetof(compat_siginfo_t, si_perf) != 0x10);
	BUILD_BUG_ON(offsetof(siginfo_t, si_perf_data) != 0x18);
	BUILD_BUG_ON(offsetof(siginfo_t, si_perf_type) != 0x20);
	BUILD_BUG_ON(offsetof(compat_siginfo_t, si_perf_data) != 0x10);
	BUILD_BUG_ON(offsetof(compat_siginfo_t, si_perf_type) != 0x14);

	CHECK_CSI_OFFSET(_sigpoll);
	CHECK_CSI_SIZE  (_sigpoll, 2*sizeof(int));
+2 −1
Original line number Diff line number Diff line
@@ -134,7 +134,8 @@ static int signalfd_copyinfo(struct signalfd_siginfo __user *uinfo,
		break;
	case SIL_PERF_EVENT:
		new.ssi_addr = (long) kinfo->si_addr;
		new.ssi_perf = kinfo->si_perf;
		new.ssi_perf_type = kinfo->si_perf_type;
		new.ssi_perf_data = kinfo->si_perf_data;
		break;
	case SIL_CHLD:
		new.ssi_pid    = kinfo->si_pid;
+4 −1
Original line number Diff line number Diff line
@@ -236,7 +236,10 @@ typedef struct compat_siginfo {
					u32 _pkey;
				} _addr_pkey;
				/* used when si_code=TRAP_PERF */
				compat_ulong_t _perf;
				struct {
					compat_ulong_t _data;
					u32 _type;
				} _perf;
			};
		} _sigfault;

+6 −2
Original line number Diff line number Diff line
@@ -91,7 +91,10 @@ union __sifields {
				__u32 _pkey;
			} _addr_pkey;
			/* used when si_code=TRAP_PERF */
			unsigned long _perf;
			struct {
				unsigned long _data;
				__u32 _type;
			} _perf;
		};
	} _sigfault;

@@ -154,7 +157,8 @@ typedef struct siginfo {
#define si_lower	_sifields._sigfault._addr_bnd._lower
#define si_upper	_sifields._sigfault._addr_bnd._upper
#define si_pkey		_sifields._sigfault._addr_pkey._pkey
#define si_perf		_sifields._sigfault._perf
#define si_perf_data	_sifields._sigfault._perf._data
#define si_perf_type	_sifields._sigfault._perf._type
#define si_band		_sifields._sigpoll._band
#define si_fd		_sifields._sigpoll._fd
#define si_call_addr	_sifields._sigsys._call_addr
Loading