- /* Only valid if client is remote */
- rc = mdt_init_ucred(info, (struct mdt_body *)info->mti_body);
- if (rc)
- GOTO(out_obj, rc = err_serious(rc));
+ /* Detect out-of range masks */
+ if ((hss->hss_setmask | hss->hss_clearmask) & ~HSM_FLAGS_MASK) {
+ CDEBUG(D_HSM, "Incompatible masks provided (set %#llx"
+ ", clear %#llx) vs supported set (%#x).\n",
+ hss->hss_setmask, hss->hss_clearmask, HSM_FLAGS_MASK);
+ GOTO(out_unlock, rc = -EINVAL);
+ }
+
+ /* Non-root users are forbidden to set or clear flags which are
+ * NOT defined in HSM_USER_MASK. */
+ if (((hss->hss_setmask | hss->hss_clearmask) & ~HSM_USER_MASK) &&
+ !md_capable(mdt_ucred(info), CFS_CAP_SYS_ADMIN)) {
+ CDEBUG(D_HSM, "Incompatible masks provided (set %#llx"
+ ", clear %#llx) vs unprivileged set (%#x).\n",
+ hss->hss_setmask, hss->hss_clearmask, HSM_USER_MASK);
+ GOTO(out_unlock, rc = -EPERM);
+ }