.. | .. |
---|
20 | 20 | |
---|
21 | 21 | enum reg_type { |
---|
22 | 22 | REG_TYPE_RM = 0, |
---|
| 23 | + REG_TYPE_REG, |
---|
23 | 24 | REG_TYPE_INDEX, |
---|
24 | 25 | REG_TYPE_BASE, |
---|
25 | 26 | }; |
---|
.. | .. |
---|
50 | 51 | default: |
---|
51 | 52 | return false; |
---|
52 | 53 | } |
---|
| 54 | +} |
---|
| 55 | + |
---|
| 56 | +/** |
---|
| 57 | + * insn_has_rep_prefix() - Determine if instruction has a REP prefix |
---|
| 58 | + * @insn: Instruction containing the prefix to inspect |
---|
| 59 | + * |
---|
| 60 | + * Returns: |
---|
| 61 | + * |
---|
| 62 | + * true if the instruction has a REP prefix, false if not. |
---|
| 63 | + */ |
---|
| 64 | +bool insn_has_rep_prefix(struct insn *insn) |
---|
| 65 | +{ |
---|
| 66 | + insn_byte_t p; |
---|
| 67 | + int i; |
---|
| 68 | + |
---|
| 69 | + insn_get_prefixes(insn); |
---|
| 70 | + |
---|
| 71 | + for_each_insn_prefix(insn, i, p) { |
---|
| 72 | + if (p == 0xf2 || p == 0xf3) |
---|
| 73 | + return true; |
---|
| 74 | + } |
---|
| 75 | + |
---|
| 76 | + return false; |
---|
53 | 77 | } |
---|
54 | 78 | |
---|
55 | 79 | /** |
---|
.. | .. |
---|
156 | 180 | */ |
---|
157 | 181 | static int resolve_default_seg(struct insn *insn, struct pt_regs *regs, int off) |
---|
158 | 182 | { |
---|
159 | | - if (user_64bit_mode(regs)) |
---|
| 183 | + if (any_64bit_mode(regs)) |
---|
160 | 184 | return INAT_SEG_REG_IGNORE; |
---|
161 | 185 | /* |
---|
162 | 186 | * Resolve the default segment register as described in Section 3.7.4 |
---|
.. | .. |
---|
179 | 203 | /* Need insn to verify address size. */ |
---|
180 | 204 | if (insn->addr_bytes == 2) |
---|
181 | 205 | return -EINVAL; |
---|
| 206 | + |
---|
| 207 | + fallthrough; |
---|
182 | 208 | |
---|
183 | 209 | case -EDOM: |
---|
184 | 210 | case offsetof(struct pt_regs, bx): |
---|
.. | .. |
---|
265 | 291 | * which may be invalid at this point. |
---|
266 | 292 | */ |
---|
267 | 293 | if (regoff == offsetof(struct pt_regs, ip)) { |
---|
268 | | - if (user_64bit_mode(regs)) |
---|
| 294 | + if (any_64bit_mode(regs)) |
---|
269 | 295 | return INAT_SEG_REG_IGNORE; |
---|
270 | 296 | else |
---|
271 | 297 | return INAT_SEG_REG_CS; |
---|
.. | .. |
---|
288 | 314 | * In long mode, segment override prefixes are ignored, except for |
---|
289 | 315 | * overrides for FS and GS. |
---|
290 | 316 | */ |
---|
291 | | - if (user_64bit_mode(regs)) { |
---|
| 317 | + if (any_64bit_mode(regs)) { |
---|
292 | 318 | if (idx != INAT_SEG_REG_FS && |
---|
293 | 319 | idx != INAT_SEG_REG_GS) |
---|
294 | 320 | idx = INAT_SEG_REG_IGNORE; |
---|
.. | .. |
---|
361 | 387 | case INAT_SEG_REG_GS: |
---|
362 | 388 | return vm86regs->gs; |
---|
363 | 389 | case INAT_SEG_REG_IGNORE: |
---|
364 | | - /* fall through */ |
---|
365 | 390 | default: |
---|
366 | 391 | return -EINVAL; |
---|
367 | 392 | } |
---|
.. | .. |
---|
385 | 410 | */ |
---|
386 | 411 | return get_user_gs(regs); |
---|
387 | 412 | case INAT_SEG_REG_IGNORE: |
---|
388 | | - /* fall through */ |
---|
389 | 413 | default: |
---|
390 | 414 | return -EINVAL; |
---|
391 | 415 | } |
---|
.. | .. |
---|
437 | 461 | return -EDOM; |
---|
438 | 462 | |
---|
439 | 463 | if (X86_REX_B(insn->rex_prefix.value)) |
---|
| 464 | + regno += 8; |
---|
| 465 | + break; |
---|
| 466 | + |
---|
| 467 | + case REG_TYPE_REG: |
---|
| 468 | + regno = X86_MODRM_REG(insn->modrm.value); |
---|
| 469 | + |
---|
| 470 | + if (X86_REX_R(insn->rex_prefix.value)) |
---|
440 | 471 | regno += 8; |
---|
441 | 472 | break; |
---|
442 | 473 | |
---|
.. | .. |
---|
645 | 676 | */ |
---|
646 | 677 | return (unsigned long)(sel << 4); |
---|
647 | 678 | |
---|
648 | | - if (user_64bit_mode(regs)) { |
---|
| 679 | + if (any_64bit_mode(regs)) { |
---|
649 | 680 | /* |
---|
650 | 681 | * Only FS or GS will have a base address, the rest of |
---|
651 | 682 | * the segments' bases are forced to 0. |
---|
652 | 683 | */ |
---|
653 | 684 | unsigned long base; |
---|
654 | 685 | |
---|
655 | | - if (seg_reg_idx == INAT_SEG_REG_FS) |
---|
| 686 | + if (seg_reg_idx == INAT_SEG_REG_FS) { |
---|
656 | 687 | rdmsrl(MSR_FS_BASE, base); |
---|
657 | | - else if (seg_reg_idx == INAT_SEG_REG_GS) |
---|
| 688 | + } else if (seg_reg_idx == INAT_SEG_REG_GS) { |
---|
658 | 689 | /* |
---|
659 | 690 | * swapgs was called at the kernel entry point. Thus, |
---|
660 | 691 | * MSR_KERNEL_GS_BASE will have the user-space GS base. |
---|
661 | 692 | */ |
---|
662 | | - rdmsrl(MSR_KERNEL_GS_BASE, base); |
---|
663 | | - else |
---|
| 693 | + if (user_mode(regs)) |
---|
| 694 | + rdmsrl(MSR_KERNEL_GS_BASE, base); |
---|
| 695 | + else |
---|
| 696 | + rdmsrl(MSR_GS_BASE, base); |
---|
| 697 | + } else { |
---|
664 | 698 | base = 0; |
---|
| 699 | + } |
---|
665 | 700 | return base; |
---|
666 | 701 | } |
---|
667 | 702 | |
---|
.. | .. |
---|
702 | 737 | if (sel < 0) |
---|
703 | 738 | return 0; |
---|
704 | 739 | |
---|
705 | | - if (user_64bit_mode(regs) || v8086_mode(regs)) |
---|
| 740 | + if (any_64bit_mode(regs) || v8086_mode(regs)) |
---|
706 | 741 | return -1L; |
---|
707 | 742 | |
---|
708 | 743 | if (!sel) |
---|
.. | .. |
---|
781 | 816 | */ |
---|
782 | 817 | return INSN_CODE_SEG_PARAMS(4, 8); |
---|
783 | 818 | case 3: /* Invalid setting. CS.L=1, CS.D=1 */ |
---|
784 | | - /* fall through */ |
---|
| 819 | + fallthrough; |
---|
785 | 820 | default: |
---|
786 | 821 | return -EINVAL; |
---|
787 | 822 | } |
---|
.. | .. |
---|
802 | 837 | int insn_get_modrm_rm_off(struct insn *insn, struct pt_regs *regs) |
---|
803 | 838 | { |
---|
804 | 839 | return get_reg_offset(insn, regs, REG_TYPE_RM); |
---|
| 840 | +} |
---|
| 841 | + |
---|
| 842 | +/** |
---|
| 843 | + * insn_get_modrm_reg_off() - Obtain register in reg part of the ModRM byte |
---|
| 844 | + * @insn: Instruction containing the ModRM byte |
---|
| 845 | + * @regs: Register values as seen when entering kernel mode |
---|
| 846 | + * |
---|
| 847 | + * Returns: |
---|
| 848 | + * |
---|
| 849 | + * The register indicated by the reg part of the ModRM byte. The |
---|
| 850 | + * register is obtained as an offset from the base of pt_regs. |
---|
| 851 | + */ |
---|
| 852 | +int insn_get_modrm_reg_off(struct insn *insn, struct pt_regs *regs) |
---|
| 853 | +{ |
---|
| 854 | + return get_reg_offset(insn, regs, REG_TYPE_REG); |
---|
805 | 855 | } |
---|
806 | 856 | |
---|
807 | 857 | /** |
---|
.. | .. |
---|
878 | 928 | static int get_eff_addr_reg(struct insn *insn, struct pt_regs *regs, |
---|
879 | 929 | int *regoff, long *eff_addr) |
---|
880 | 930 | { |
---|
881 | | - insn_get_modrm(insn); |
---|
| 931 | + int ret; |
---|
882 | 932 | |
---|
883 | | - if (!insn->modrm.nbytes) |
---|
884 | | - return -EINVAL; |
---|
| 933 | + ret = insn_get_modrm(insn); |
---|
| 934 | + if (ret) |
---|
| 935 | + return ret; |
---|
885 | 936 | |
---|
886 | 937 | if (X86_MODRM_MOD(insn->modrm.value) != 3) |
---|
887 | 938 | return -EINVAL; |
---|
.. | .. |
---|
927 | 978 | int *regoff, long *eff_addr) |
---|
928 | 979 | { |
---|
929 | 980 | long tmp; |
---|
| 981 | + int ret; |
---|
930 | 982 | |
---|
931 | 983 | if (insn->addr_bytes != 8 && insn->addr_bytes != 4) |
---|
932 | 984 | return -EINVAL; |
---|
933 | 985 | |
---|
934 | | - insn_get_modrm(insn); |
---|
935 | | - |
---|
936 | | - if (!insn->modrm.nbytes) |
---|
937 | | - return -EINVAL; |
---|
| 986 | + ret = insn_get_modrm(insn); |
---|
| 987 | + if (ret) |
---|
| 988 | + return ret; |
---|
938 | 989 | |
---|
939 | 990 | if (X86_MODRM_MOD(insn->modrm.value) > 2) |
---|
940 | 991 | return -EINVAL; |
---|
.. | .. |
---|
947 | 998 | * following instruction. |
---|
948 | 999 | */ |
---|
949 | 1000 | if (*regoff == -EDOM) { |
---|
950 | | - if (user_64bit_mode(regs)) |
---|
| 1001 | + if (any_64bit_mode(regs)) |
---|
951 | 1002 | tmp = regs->ip + insn->length; |
---|
952 | 1003 | else |
---|
953 | 1004 | tmp = 0; |
---|
.. | .. |
---|
1056 | 1107 | * @base_offset will have a register, as an offset from the base of pt_regs, |
---|
1057 | 1108 | * that can be used to resolve the associated segment. |
---|
1058 | 1109 | * |
---|
1059 | | - * -EINVAL on error. |
---|
| 1110 | + * Negative value on error. |
---|
1060 | 1111 | */ |
---|
1061 | 1112 | static int get_eff_addr_sib(struct insn *insn, struct pt_regs *regs, |
---|
1062 | 1113 | int *base_offset, long *eff_addr) |
---|
1063 | 1114 | { |
---|
1064 | 1115 | long base, indx; |
---|
1065 | 1116 | int indx_offset; |
---|
| 1117 | + int ret; |
---|
1066 | 1118 | |
---|
1067 | 1119 | if (insn->addr_bytes != 8 && insn->addr_bytes != 4) |
---|
1068 | 1120 | return -EINVAL; |
---|
1069 | 1121 | |
---|
1070 | | - insn_get_modrm(insn); |
---|
| 1122 | + ret = insn_get_modrm(insn); |
---|
| 1123 | + if (ret) |
---|
| 1124 | + return ret; |
---|
1071 | 1125 | |
---|
1072 | 1126 | if (!insn->modrm.nbytes) |
---|
1073 | 1127 | return -EINVAL; |
---|
.. | .. |
---|
1075 | 1129 | if (X86_MODRM_MOD(insn->modrm.value) > 2) |
---|
1076 | 1130 | return -EINVAL; |
---|
1077 | 1131 | |
---|
1078 | | - insn_get_sib(insn); |
---|
| 1132 | + ret = insn_get_sib(insn); |
---|
| 1133 | + if (ret) |
---|
| 1134 | + return ret; |
---|
1079 | 1135 | |
---|
1080 | 1136 | if (!insn->sib.nbytes) |
---|
1081 | 1137 | return -EINVAL; |
---|
.. | .. |
---|
1144 | 1200 | short eff_addr; |
---|
1145 | 1201 | long tmp; |
---|
1146 | 1202 | |
---|
1147 | | - insn_get_modrm(insn); |
---|
1148 | | - insn_get_displacement(insn); |
---|
| 1203 | + if (insn_get_displacement(insn)) |
---|
| 1204 | + goto out; |
---|
1149 | 1205 | |
---|
1150 | 1206 | if (insn->addr_bytes != 2) |
---|
1151 | 1207 | goto out; |
---|
.. | .. |
---|
1249 | 1305 | * After computed, the effective address is treated as an unsigned |
---|
1250 | 1306 | * quantity. |
---|
1251 | 1307 | */ |
---|
1252 | | - if (!user_64bit_mode(regs) && ((unsigned int)eff_addr > seg_limit)) |
---|
| 1308 | + if (!any_64bit_mode(regs) && ((unsigned int)eff_addr > seg_limit)) |
---|
1253 | 1309 | goto out; |
---|
1254 | 1310 | |
---|
1255 | 1311 | /* |
---|
.. | .. |
---|
1364 | 1420 | return (void __user *)-1L; |
---|
1365 | 1421 | } |
---|
1366 | 1422 | } |
---|
| 1423 | + |
---|
| 1424 | +unsigned long insn_get_effective_ip(struct pt_regs *regs) |
---|
| 1425 | +{ |
---|
| 1426 | + unsigned long seg_base = 0; |
---|
| 1427 | + |
---|
| 1428 | + /* |
---|
| 1429 | + * If not in user-space long mode, a custom code segment could be in |
---|
| 1430 | + * use. This is true in protected mode (if the process defined a local |
---|
| 1431 | + * descriptor table), or virtual-8086 mode. In most of the cases |
---|
| 1432 | + * seg_base will be zero as in USER_CS. |
---|
| 1433 | + */ |
---|
| 1434 | + if (!user_64bit_mode(regs)) { |
---|
| 1435 | + seg_base = insn_get_seg_base(regs, INAT_SEG_REG_CS); |
---|
| 1436 | + if (seg_base == -1L) |
---|
| 1437 | + return 0; |
---|
| 1438 | + } |
---|
| 1439 | + |
---|
| 1440 | + return seg_base + regs->ip; |
---|
| 1441 | +} |
---|
| 1442 | + |
---|
| 1443 | +/** |
---|
| 1444 | + * insn_fetch_from_user() - Copy instruction bytes from user-space memory |
---|
| 1445 | + * @regs: Structure with register values as seen when entering kernel mode |
---|
| 1446 | + * @buf: Array to store the fetched instruction |
---|
| 1447 | + * |
---|
| 1448 | + * Gets the linear address of the instruction and copies the instruction bytes |
---|
| 1449 | + * to the buf. |
---|
| 1450 | + * |
---|
| 1451 | + * Returns: |
---|
| 1452 | + * |
---|
| 1453 | + * Number of instruction bytes copied. |
---|
| 1454 | + * |
---|
| 1455 | + * 0 if nothing was copied. |
---|
| 1456 | + */ |
---|
| 1457 | +int insn_fetch_from_user(struct pt_regs *regs, unsigned char buf[MAX_INSN_SIZE]) |
---|
| 1458 | +{ |
---|
| 1459 | + unsigned long ip; |
---|
| 1460 | + int not_copied; |
---|
| 1461 | + |
---|
| 1462 | + ip = insn_get_effective_ip(regs); |
---|
| 1463 | + if (!ip) |
---|
| 1464 | + return 0; |
---|
| 1465 | + |
---|
| 1466 | + not_copied = copy_from_user(buf, (void __user *)ip, MAX_INSN_SIZE); |
---|
| 1467 | + |
---|
| 1468 | + return MAX_INSN_SIZE - not_copied; |
---|
| 1469 | +} |
---|
| 1470 | + |
---|
| 1471 | +/** |
---|
| 1472 | + * insn_fetch_from_user_inatomic() - Copy instruction bytes from user-space memory |
---|
| 1473 | + * while in atomic code |
---|
| 1474 | + * @regs: Structure with register values as seen when entering kernel mode |
---|
| 1475 | + * @buf: Array to store the fetched instruction |
---|
| 1476 | + * |
---|
| 1477 | + * Gets the linear address of the instruction and copies the instruction bytes |
---|
| 1478 | + * to the buf. This function must be used in atomic context. |
---|
| 1479 | + * |
---|
| 1480 | + * Returns: |
---|
| 1481 | + * |
---|
| 1482 | + * Number of instruction bytes copied. |
---|
| 1483 | + * |
---|
| 1484 | + * 0 if nothing was copied. |
---|
| 1485 | + */ |
---|
| 1486 | +int insn_fetch_from_user_inatomic(struct pt_regs *regs, unsigned char buf[MAX_INSN_SIZE]) |
---|
| 1487 | +{ |
---|
| 1488 | + unsigned long ip; |
---|
| 1489 | + int not_copied; |
---|
| 1490 | + |
---|
| 1491 | + ip = insn_get_effective_ip(regs); |
---|
| 1492 | + if (!ip) |
---|
| 1493 | + return 0; |
---|
| 1494 | + |
---|
| 1495 | + not_copied = __copy_from_user_inatomic(buf, (void __user *)ip, MAX_INSN_SIZE); |
---|
| 1496 | + |
---|
| 1497 | + return MAX_INSN_SIZE - not_copied; |
---|
| 1498 | +} |
---|
| 1499 | + |
---|
| 1500 | +/** |
---|
| 1501 | + * insn_decode_from_regs() - Decode an instruction |
---|
| 1502 | + * @insn: Structure to store decoded instruction |
---|
| 1503 | + * @regs: Structure with register values as seen when entering kernel mode |
---|
| 1504 | + * @buf: Buffer containing the instruction bytes |
---|
| 1505 | + * @buf_size: Number of instruction bytes available in buf |
---|
| 1506 | + * |
---|
| 1507 | + * Decodes the instruction provided in buf and stores the decoding results in |
---|
| 1508 | + * insn. Also determines the correct address and operand sizes. |
---|
| 1509 | + * |
---|
| 1510 | + * Returns: |
---|
| 1511 | + * |
---|
| 1512 | + * True if instruction was decoded, False otherwise. |
---|
| 1513 | + */ |
---|
| 1514 | +bool insn_decode_from_regs(struct insn *insn, struct pt_regs *regs, |
---|
| 1515 | + unsigned char buf[MAX_INSN_SIZE], int buf_size) |
---|
| 1516 | +{ |
---|
| 1517 | + int seg_defs; |
---|
| 1518 | + |
---|
| 1519 | + insn_init(insn, buf, buf_size, user_64bit_mode(regs)); |
---|
| 1520 | + |
---|
| 1521 | + /* |
---|
| 1522 | + * Override the default operand and address sizes with what is specified |
---|
| 1523 | + * in the code segment descriptor. The instruction decoder only sets |
---|
| 1524 | + * the address size it to either 4 or 8 address bytes and does nothing |
---|
| 1525 | + * for the operand bytes. This OK for most of the cases, but we could |
---|
| 1526 | + * have special cases where, for instance, a 16-bit code segment |
---|
| 1527 | + * descriptor is used. |
---|
| 1528 | + * If there is an address override prefix, the instruction decoder |
---|
| 1529 | + * correctly updates these values, even for 16-bit defaults. |
---|
| 1530 | + */ |
---|
| 1531 | + seg_defs = insn_get_code_seg_params(regs); |
---|
| 1532 | + if (seg_defs == -EINVAL) |
---|
| 1533 | + return false; |
---|
| 1534 | + |
---|
| 1535 | + insn->addr_bytes = INSN_CODE_SEG_ADDR_SZ(seg_defs); |
---|
| 1536 | + insn->opnd_bytes = INSN_CODE_SEG_OPND_SZ(seg_defs); |
---|
| 1537 | + |
---|
| 1538 | + if (insn_get_length(insn)) |
---|
| 1539 | + return false; |
---|
| 1540 | + |
---|
| 1541 | + if (buf_size < insn->length) |
---|
| 1542 | + return false; |
---|
| 1543 | + |
---|
| 1544 | + return true; |
---|
| 1545 | +} |
---|