lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [day] [month] [year] [list]
Date:   Fri, 24 Nov 2023 22:39:42 +0800
From:   kernel test robot <lkp@...el.com>
To:     Ard Biesheuvel <ardb@...nel.org>
Cc:     oe-kbuild-all@...ts.linux.dev, linux-kernel@...r.kernel.org,
        Will Deacon <will@...nel.org>,
        Sami Tolvanen <samitolvanen@...gle.com>
Subject: arch/arm64/kernel/patch-scs.c:67:29: sparse: sparse: incorrect type
 in assignment (different base types)

tree:   https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master
head:   f1a09972a45ae63efbd1587337c4be13b1893330
commit: 3b619e22c4601b444ed2d6a5458271f72625ac89 arm64: implement dynamic shadow call stack for Clang
date:   1 year ago
config: arm64-randconfig-r133-20231123 (https://download.01.org/0day-ci/archive/20231124/202311241547.VshdwLyK-lkp@intel.com/config)
compiler: clang version 15.0.7 (https://github.com/llvm/llvm-project.git 8dfdcc7b7bf66834a761bd8de445840ef68e4d1a)
reproduce: (https://download.01.org/0day-ci/archive/20231124/202311241547.VshdwLyK-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@...el.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202311241547.VshdwLyK-lkp@intel.com/

sparse warnings: (new ones prefixed by >>)
   arch/arm64/kernel/patch-scs.c:249:24: sparse: sparse: symbol 'scs_patch_vmlinux' was not declared. Should it be static?
>> arch/arm64/kernel/patch-scs.c:67:29: sparse: sparse: incorrect type in assignment (different base types) @@     expected unsigned int [usertype] @@     got restricted __le32 [usertype] @@
   arch/arm64/kernel/patch-scs.c:67:29: sparse:     expected unsigned int [usertype]
   arch/arm64/kernel/patch-scs.c:67:29: sparse:     got restricted __le32 [usertype]
   arch/arm64/kernel/patch-scs.c:70:29: sparse: sparse: incorrect type in assignment (different base types) @@     expected unsigned int [usertype] @@     got restricted __le32 [usertype] @@
   arch/arm64/kernel/patch-scs.c:70:29: sparse:     expected unsigned int [usertype]
   arch/arm64/kernel/patch-scs.c:70:29: sparse:     got restricted __le32 [usertype]

vim +67 arch/arm64/kernel/patch-scs.c

    60	
    61	static void __always_inline scs_patch_loc(u64 loc)
    62	{
    63		u32 insn = le32_to_cpup((void *)loc);
    64	
    65		switch (insn) {
    66		case PACIASP:
  > 67			*(u32 *)loc = cpu_to_le32(SCS_PUSH);
    68			break;
    69		case AUTIASP:
    70			*(u32 *)loc = cpu_to_le32(SCS_POP);
    71			break;
    72		default:
    73			/*
    74			 * While the DW_CFA_negate_ra_state directive is guaranteed to
    75			 * appear right after a PACIASP/AUTIASP instruction, it may
    76			 * also appear after a DW_CFA_restore_state directive that
    77			 * restores a state that is only partially accurate, and is
    78			 * followed by DW_CFA_negate_ra_state directive to toggle the
    79			 * PAC bit again. So we permit other instructions here, and ignore
    80			 * them.
    81			 */
    82			return;
    83		}
    84		dcache_clean_pou(loc, loc + sizeof(u32));
    85	}
    86	
    87	/*
    88	 * Skip one uleb128/sleb128 encoded quantity from the opcode stream. All bytes
    89	 * except the last one have bit #7 set.
    90	 */
    91	static int __always_inline skip_xleb128(const u8 **opcode, int size)
    92	{
    93		u8 c;
    94	
    95		do {
    96			c = *(*opcode)++;
    97			size--;
    98		} while (c & BIT(7));
    99	
   100		return size;
   101	}
   102	
   103	struct eh_frame {
   104		/*
   105		 * The size of this frame if 0 < size < U32_MAX, 0 terminates the list.
   106		 */
   107		u32	size;
   108	
   109		/*
   110		 * The first frame is a Common Information Entry (CIE) frame, followed
   111		 * by one or more Frame Description Entry (FDE) frames. In the former
   112		 * case, this field is 0, otherwise it is the negated offset relative
   113		 * to the associated CIE frame.
   114		 */
   115		u32	cie_id_or_pointer;
   116	
   117		union {
   118			struct { // CIE
   119				u8	version;
   120				u8	augmentation_string[];
   121			};
   122	
   123			struct { // FDE
   124				s32	initial_loc;
   125				s32	range;
   126				u8	opcodes[];
   127			};
   128		};
   129	};
   130	
   131	static int noinstr scs_handle_fde_frame(const struct eh_frame *frame,
   132						bool fde_has_augmentation_data,
   133						int code_alignment_factor)
   134	{
   135		int size = frame->size - offsetof(struct eh_frame, opcodes) + 4;
   136		u64 loc = (u64)offset_to_ptr(&frame->initial_loc);
   137		const u8 *opcode = frame->opcodes;
   138	
   139		if (fde_has_augmentation_data) {
   140			int l;
   141	
   142			// assume single byte uleb128_t
   143			if (WARN_ON(*opcode & BIT(7)))
   144				return -ENOEXEC;
   145	
   146			l = *opcode++;
   147			opcode += l;
   148			size -= l + 1;
   149		}
   150	
   151		/*
   152		 * Starting from 'loc', apply the CFA opcodes that advance the location
   153		 * pointer, and identify the locations of the PAC instructions.
   154		 */
   155		while (size-- > 0) {
   156			switch (*opcode++) {
   157			case DW_CFA_nop:
   158			case DW_CFA_remember_state:
   159			case DW_CFA_restore_state:
   160				break;
   161	
   162			case DW_CFA_advance_loc1:
   163				loc += *opcode++ * code_alignment_factor;
   164				size--;
   165				break;
   166	
   167			case DW_CFA_advance_loc2:
   168				loc += *opcode++ * code_alignment_factor;
   169				loc += (*opcode++ << 8) * code_alignment_factor;
   170				size -= 2;
   171				break;
   172	
   173			case DW_CFA_def_cfa:
   174			case DW_CFA_offset_extended:
   175				size = skip_xleb128(&opcode, size);
   176				fallthrough;
   177			case DW_CFA_def_cfa_offset:
   178			case DW_CFA_def_cfa_offset_sf:
   179			case DW_CFA_def_cfa_register:
   180			case DW_CFA_same_value:
   181			case DW_CFA_restore_extended:
   182			case 0x80 ... 0xbf:
   183				size = skip_xleb128(&opcode, size);
   184				break;
   185	
   186			case DW_CFA_negate_ra_state:
   187				scs_patch_loc(loc - 4);
   188				break;
   189	
   190			case 0x40 ... 0x7f:
   191				// advance loc
   192				loc += (opcode[-1] & 0x3f) * code_alignment_factor;
   193				break;
   194	
   195			case 0xc0 ... 0xff:
   196				break;
   197	
   198			default:
   199				pr_err("unhandled opcode: %02x in FDE frame %lx\n", opcode[-1], (uintptr_t)frame);
   200				return -ENOEXEC;
   201			}
   202		}
   203		return 0;
   204	}
   205	
   206	int noinstr scs_patch(const u8 eh_frame[], int size)
   207	{
   208		const u8 *p = eh_frame;
   209	
   210		while (size > 4) {
   211			const struct eh_frame *frame = (const void *)p;
   212			bool fde_has_augmentation_data = true;
   213			int code_alignment_factor = 1;
   214			int ret;
   215	
   216			if (frame->size == 0 ||
   217			    frame->size == U32_MAX ||
   218			    frame->size > size)
   219				break;
   220	
   221			if (frame->cie_id_or_pointer == 0) {
   222				const u8 *p = frame->augmentation_string;
   223	
   224				/* a 'z' in the augmentation string must come first */
   225				fde_has_augmentation_data = *p == 'z';
   226	
   227				/*
   228				 * The code alignment factor is a uleb128 encoded field
   229				 * but given that the only sensible values are 1 or 4,
   230				 * there is no point in decoding the whole thing.
   231				 */
   232				p += strlen(p) + 1;
   233				if (!WARN_ON(*p & BIT(7)))
   234					code_alignment_factor = *p;
   235			} else {
   236				ret = scs_handle_fde_frame(frame,
   237							   fde_has_augmentation_data,
   238							   code_alignment_factor);
   239				if (ret)
   240					return ret;
   241			}
   242	
   243			p += sizeof(frame->size) + frame->size;
   244			size -= sizeof(frame->size) + frame->size;
   245		}
   246		return 0;
   247	}
   248	
 > 249	asmlinkage void __init scs_patch_vmlinux(void)

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ