x86/umip: Fix insn_get_code_seg_params()'s return value

In order to save on redundant structs definitions
insn_get_code_seg_params() was made to return two 4-bit values in a char
but clang complains:

arch/x86/lib/insn-eval.c:780:10: warning: implicit conversion from 'int' to 'char'
changes value from 132 to -124 [-Wconstant-conversion]
return INSN_CODE_SEG_PARAMS(4, 8);
~~~~~~ ^~~~~~~~~~~~~~~~~~~~~~~~~~
./arch/x86/include/asm/insn-eval.h:16:57: note: expanded from macro 'INSN_CODE_SEG_PARAMS'
#define INSN_CODE_SEG_PARAMS(oper_sz, addr_sz) (oper_sz | (addr_sz << 4))

Those two values do get picked apart afterwards the opposite way of how
they were ORed so wrt to the LSByte, the return value is the same.

But this function returns -EINVAL in the error case, which is an int. So
make it return an int which is the native word size anyway and thus fix
the clang warning.

Reported-by: Kees Cook <keescook@google.com>
Reported-by: Nick Desaulniers <nick.desaulniers@gmail.com>
Signed-off-by: Borislav Petkov <bp@suse.de>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: ricardo.neri-calderon@linux.intel.com
Link: https://lkml.kernel.org/r/20171123091951.1462-1-bp@alien8.de

authored by Borislav Petkov and committed by Thomas Gleixner e2a5dca7 69550d41

+4 -4
+1 -1
arch/x86/include/asm/insn-eval.h
··· 18 void __user *insn_get_addr_ref(struct insn *insn, struct pt_regs *regs); 19 int insn_get_modrm_rm_off(struct insn *insn, struct pt_regs *regs); 20 unsigned long insn_get_seg_base(struct pt_regs *regs, int seg_reg_idx); 21 - char insn_get_code_seg_params(struct pt_regs *regs); 22 23 #endif /* _ASM_X86_INSN_EVAL_H */
··· 18 void __user *insn_get_addr_ref(struct insn *insn, struct pt_regs *regs); 19 int insn_get_modrm_rm_off(struct insn *insn, struct pt_regs *regs); 20 unsigned long insn_get_seg_base(struct pt_regs *regs, int seg_reg_idx); 21 + int insn_get_code_seg_params(struct pt_regs *regs); 22 23 #endif /* _ASM_X86_INSN_EVAL_H */
+1 -1
arch/x86/kernel/umip.c
··· 319 unsigned char buf[MAX_INSN_SIZE]; 320 void __user *uaddr; 321 struct insn insn; 322 - char seg_defs; 323 324 if (!regs) 325 return false;
··· 319 unsigned char buf[MAX_INSN_SIZE]; 320 void __user *uaddr; 321 struct insn insn; 322 + int seg_defs; 323 324 if (!regs) 325 return false;
+2 -2
arch/x86/lib/insn-eval.c
··· 733 * 734 * Returns: 735 * 736 - * A signed 8-bit value containing the default parameters on success. 737 * 738 * -EINVAL on error. 739 */ 740 - char insn_get_code_seg_params(struct pt_regs *regs) 741 { 742 struct desc_struct *desc; 743 short sel;
··· 733 * 734 * Returns: 735 * 736 + * An int containing ORed-in default parameters on success. 737 * 738 * -EINVAL on error. 739 */ 740 + int insn_get_code_seg_params(struct pt_regs *regs) 741 { 742 struct desc_struct *desc; 743 short sel;