Example #1
0
static inline void __user *get_sigframe(struct k_sigaction *ka,
					struct pt_regs *regs, size_t frame_size)
{
	unsigned long sp = regs->sp;
	int onsigstack = on_sig_stack(sp);

	/*         */
	sp -= STACK_FRAME_OVERHEAD;

	/*                                                        */
	if ((ka->sa.sa_flags & SA_ONSTACK) && !onsigstack) {
		if (current->sas_ss_size)
			sp = current->sas_ss_sp + current->sas_ss_size;
	}

	sp = align_sigframe(sp - frame_size);

	/*
                                                                         
                                                                       
  */
	if (onsigstack && !likely(on_sig_stack(sp)))
		return (void __user *)-1L;

	return (void __user *)sp;
}
Example #2
0
static inline void __user *get_sigframe(struct ksignal *ksig,
					struct pt_regs *regs, size_t frame_size)
{
	unsigned long sp = regs->sp;

	/* redzone */
	sp -= STACK_FRAME_OVERHEAD;
	sp = sigsp(sp, ksig);
	sp = align_sigframe(sp - frame_size);

	return (void __user *)sp;
}
Example #3
0
static inline void __user *
get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size,
	     void __user **fpstate)
{
	/* Default to using normal stack */
	unsigned long math_size = 0;
	unsigned long sp = regs->sp;
	unsigned long buf_fx = 0;
	int onsigstack = on_sig_stack(sp);

	/* redzone */
	if (config_enabled(CONFIG_X86_64))
		sp -= 128;

	if (!onsigstack) {
		/* This is the X/Open sanctioned signal stack switching.  */
		if (ka->sa.sa_flags & SA_ONSTACK) {
			if (current->sas_ss_size)
				sp = current->sas_ss_sp + current->sas_ss_size;
		} else if (config_enabled(CONFIG_X86_32) &&
			   (regs->ss & 0xffff) != __USER_DS &&
#ifdef CONFIG_KERNEL_MODE_LINUX
			   (regs->sp > TASK_SIZE) &&
#endif
			   !(ka->sa.sa_flags & SA_RESTORER) &&
			   ka->sa.sa_restorer) {
				/* This is the legacy signal stack switching. */
				sp = (unsigned long) ka->sa.sa_restorer;
		}
	}

	if (used_math()) {
		sp = alloc_mathframe(sp, config_enabled(CONFIG_X86_32),
				     &buf_fx, &math_size);
		*fpstate = (void __user *)sp;
	}

	sp = align_sigframe(sp - frame_size);

	/*
	 * If we are on the alternate signal stack and would overflow it, don't.
	 * Return an always-bogus address instead so we will die with SIGSEGV.
	 */
	if (onsigstack && !likely(on_sig_stack(sp)))
		return (void __user *)-1L;

	/* save i387 and extended state */
	if (used_math() &&
	    save_xstate_sig(*fpstate, (void __user *)buf_fx, math_size) < 0)
		return (void __user *)-1L;

	return (void __user *)sp;
}
Example #4
0
static inline void __user *
get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size,
	     void __user **fpstate)
{
	/* Default to using normal stack */
	unsigned long sp = regs->sp;
	int onsigstack = on_sig_stack(sp);

#ifdef CONFIG_X86_64
	/* redzone */
	sp -= 128;
#endif /* CONFIG_X86_64 */

	if (!onsigstack) {
		/* This is the X/Open sanctioned signal stack switching.  */
		if (ka->sa.sa_flags & SA_ONSTACK) {
			if (current->sas_ss_size)
				sp = current->sas_ss_sp + current->sas_ss_size;
		} else {
#ifdef CONFIG_X86_32
			/* This is the legacy signal stack switching. */
			if ((regs->ss & 0xffff) != __USER_DS &&
				!(ka->sa.sa_flags & SA_RESTORER) &&
					ka->sa.sa_restorer)
				sp = (unsigned long) ka->sa.sa_restorer;
#endif /* CONFIG_X86_32 */
		}
	}

	if (used_math()) {
		sp -= sig_xstate_size;
#ifdef CONFIG_X86_64
		sp = round_down(sp, 64);
#endif /* CONFIG_X86_64 */
		*fpstate = (void __user *)sp;
	}

	sp = align_sigframe(sp - frame_size);

	/*
	 * If we are on the alternate signal stack and would overflow it, don't.
	 * Return an always-bogus address instead so we will die with SIGSEGV.
	 */
	if (onsigstack && !likely(on_sig_stack(sp)))
		return (void __user *)-1L;

	/* save i387 state */
	if (used_math() && save_i387_xstate(*fpstate) < 0)
		return (void __user *)-1L;

	return (void __user *)sp;
}
Example #5
0
static inline void __user *
get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size,
	     void __user **fpstate)
{
	/*                               */
	unsigned long sp = regs->sp;
	int onsigstack = on_sig_stack(sp);

#ifdef CONFIG_X86_64
	/*         */
	sp -= 128;
#endif /*               */

	if (!onsigstack) {
		/*                                                        */
		if (ka->sa.sa_flags & SA_ONSTACK) {
			if (current->sas_ss_size)
				sp = current->sas_ss_sp + current->sas_ss_size;
		} else {
#ifdef CONFIG_X86_32
			/*                                            */
			if ((regs->ss & 0xffff) != __USER_DS &&
				!(ka->sa.sa_flags & SA_RESTORER) &&
					ka->sa.sa_restorer)
				sp = (unsigned long) ka->sa.sa_restorer;
#endif /*               */
		}
	}

	if (used_math()) {
		sp -= sig_xstate_size;
#ifdef CONFIG_X86_64
		sp = round_down(sp, 64);
#endif /*               */
		*fpstate = (void __user *)sp;
	}

	sp = align_sigframe(sp - frame_size);

	/*
                                                                         
                                                                       
  */
	if (onsigstack && !likely(on_sig_stack(sp)))
		return (void __user *)-1L;

	/*                 */
	if (used_math() && save_i387_xstate(*fpstate) < 0)
		return (void __user *)-1L;

	return (void __user *)sp;
}