brintos

brintos / linux-shallow public Read only

0
0
Text · 3.1 KiB · 2ccd3ee Raw
134 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * 32bit compatibility wrappers for the input subsystem.4 *5 * Very heavily based on evdev.c - Copyright (c) 1999-2002 Vojtech Pavlik6 */7 8#include <linux/export.h>9#include <linux/uaccess.h>10#include "input-compat.h"11 12#ifdef CONFIG_COMPAT13 14int input_event_from_user(const char __user *buffer,15			  struct input_event *event)16{17	if (in_compat_syscall() && !COMPAT_USE_64BIT_TIME) {18		struct input_event_compat compat_event;19 20		if (copy_from_user(&compat_event, buffer,21				   sizeof(struct input_event_compat)))22			return -EFAULT;23 24		event->input_event_sec = compat_event.sec;25		event->input_event_usec = compat_event.usec;26		event->type = compat_event.type;27		event->code = compat_event.code;28		event->value = compat_event.value;29 30	} else {31		if (copy_from_user(event, buffer, sizeof(struct input_event)))32			return -EFAULT;33	}34 35	return 0;36}37 38int input_event_to_user(char __user *buffer,39			const struct input_event *event)40{41	if (in_compat_syscall() && !COMPAT_USE_64BIT_TIME) {42		struct input_event_compat compat_event;43 44		compat_event.sec = event->input_event_sec;45		compat_event.usec = event->input_event_usec;46		compat_event.type = event->type;47		compat_event.code = event->code;48		compat_event.value = event->value;49 50		if (copy_to_user(buffer, &compat_event,51				 sizeof(struct input_event_compat)))52			return -EFAULT;53 54	} else {55		if (copy_to_user(buffer, event, sizeof(struct input_event)))56			return -EFAULT;57	}58 59	return 0;60}61 62int input_ff_effect_from_user(const char __user *buffer, size_t size,63			      struct ff_effect *effect)64{65	if (in_compat_syscall()) {66		struct ff_effect_compat *compat_effect;67 68		if (size != sizeof(struct ff_effect_compat))69			return -EINVAL;70 71		/*72		 * It so happens that the pointer which needs to be changed73		 * is the last field in the structure, so we can retrieve the74		 * whole thing and replace just the pointer.75		 */76		compat_effect = (struct ff_effect_compat *)effect;77 78		if (copy_from_user(compat_effect, buffer,79				   sizeof(struct ff_effect_compat)))80			return -EFAULT;81 82		if (compat_effect->type == FF_PERIODIC &&83		    compat_effect->u.periodic.waveform == FF_CUSTOM)84			effect->u.periodic.custom_data =85				compat_ptr(compat_effect->u.periodic.custom_data);86	} else {87		if (size != sizeof(struct ff_effect))88			return -EINVAL;89 90		if (copy_from_user(effect, buffer, sizeof(struct ff_effect)))91			return -EFAULT;92	}93 94	return 0;95}96 97#else98 99int input_event_from_user(const char __user *buffer,100			 struct input_event *event)101{102	if (copy_from_user(event, buffer, sizeof(struct input_event)))103		return -EFAULT;104 105	return 0;106}107 108int input_event_to_user(char __user *buffer,109			const struct input_event *event)110{111	if (copy_to_user(buffer, event, sizeof(struct input_event)))112		return -EFAULT;113 114	return 0;115}116 117int input_ff_effect_from_user(const char __user *buffer, size_t size,118			      struct ff_effect *effect)119{120	if (size != sizeof(struct ff_effect))121		return -EINVAL;122 123	if (copy_from_user(effect, buffer, sizeof(struct ff_effect)))124		return -EFAULT;125 126	return 0;127}128 129#endif /* CONFIG_COMPAT */130 131EXPORT_SYMBOL_GPL(input_event_from_user);132EXPORT_SYMBOL_GPL(input_event_to_user);133EXPORT_SYMBOL_GPL(input_ff_effect_from_user);134