usermode: Rework Z_SYSCALL_SPECIFIC_DRIVER to fit with device refactoring

init_fn is not anymore part of struct device, so let's test instead the
driver's API structure pointer which is also unique per device driver.

Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
This commit is contained in:
Tomasz Bursztyka 2020-03-13 09:53:54 +01:00 committed by Carles Cufí
commit 48135cdd34
3 changed files with 10 additions and 11 deletions

View file

@ -295,10 +295,10 @@ Several macros exist to validate arguments:
* :c:macro:`Z_SYSCALL_SPECIFIC_DRIVER()` is a runtime check to verify that
a provided pointer is a valid instance of a specific device driver, that
the calling thread has permissions on it, and that the driver has been
initialized. It does this by checking the init function pointer that
initialized. It does this by checking the API structure pointer that
is stored within the driver instance and ensuring that it matches the
provided value, which should be the address of the specific driver's
init function.
API structure.
If any check fails, the macros will return a nonzero value. The macro
:c:macro:`Z_OOPS()` can be used to induce a kernel oops which will kill the

View file

@ -1339,7 +1339,7 @@ int z_vrfy_maxim_ds3231_get_syncpoint(struct device *dev,
struct maxim_ds3231_syncpoint value;
int rv;
Z_OOPS(Z_SYSCALL_SPECIFIC_DRIVER(dev, K_OBJ_DRIVER_COUNTER, ds3231_init));
Z_OOPS(Z_SYSCALL_SPECIFIC_DRIVER(dev, K_OBJ_DRIVER_COUNTER, &ds3231_api));
Z_OOPS(Z_SYSCALL_MEMORY_WRITE(syncpoint, sizeof(*syncpoint)));
rv = z_impl_maxim_ds3231_get_syncpoint(dev, &value);
@ -1356,7 +1356,7 @@ int z_vrfy_maxim_ds3231_get_syncpoint(struct device *dev,
int z_vrfy_maxim_ds3231_req_syncpoint(struct device *dev,
struct k_poll_signal *sig)
{
Z_OOPS(Z_SYSCALL_SPECIFIC_DRIVER(dev, K_OBJ_DRIVER_COUNTER, ds3231_init));
Z_OOPS(Z_SYSCALL_SPECIFIC_DRIVER(dev, K_OBJ_DRIVER_COUNTER, &ds3231_api));
if (sig != NULL) {
Z_OOPS(Z_SYSCALL_OBJ(sig, K_OBJ_POLL_SIGNAL));
}

View file

@ -442,9 +442,8 @@ static inline int z_obj_validation_check(struct z_object *ko,
*
* Checks that the driver object passed in is initialized, the caller has
* correct permissions, and that it belongs to the specified driver
* subsystems. Additionally, all devices store a function pointer to the
* driver's init function. If this doesn't match the value provided, the
* check will fail.
* subsystems. Additionally, all devices store a structure pointer of the
* driver's API. If this doesn't match the value provided, the check will fail.
*
* This provides an easy way to determine if a device object not only
* belongs to a particular subsystem, but is of a specific device driver
@ -453,15 +452,15 @@ static inline int z_obj_validation_check(struct z_object *ko,
*
* @param _device Untrusted device pointer
* @param _dtype Expected kernel object type for the provided device pointer
* @param _init_fn Expected init function memory address
* @param _api Expected driver API structure memory address
* @return 0 on success, nonzero on failure
*/
#define Z_SYSCALL_SPECIFIC_DRIVER(_device, _dtype, _init_fn) \
#define Z_SYSCALL_SPECIFIC_DRIVER(_device, _dtype, _api) \
({ \
struct device *_dev = (struct device *)_device; \
Z_SYSCALL_OBJ(_dev, _dtype) || \
Z_SYSCALL_VERIFY_MSG(_dev->init == _init_fn, \
"init function mismatch"); \
Z_SYSCALL_VERIFY_MSG(_dev->driver_api == _api, \
"API structure mismatch"); \
})
/**