From d1fb871d99db38c7704d8e583ff5e0a00e713837 Mon Sep 17 00:00:00 2001 From: "ananth@in.ibm.com" Date: Fri, 12 Mar 2004 00:57:30 -0800 Subject: [PATCH] Libsysfs updates Please find attached a _BIG_ patch to update udev's libsysfs. Patch applies on udev-021 and contains: 1. Updates to get udev's libsysfs to the latest (to be released) level. 2. Changes for C++ compatibility (use "char" and not "unsigned char" unless absolutely necessary). 3. More importantly, take care of buffer overflows. Libsysfs now uses a scaled down version of Kay's "safe" macros. Tested using a usb-storage device. I will send you a doc update shortly. --- libsysfs/sysfs/libsysfs.h | 205 +++++++++++++++++++++++++++------------------- 1 file changed, 121 insertions(+), 84 deletions(-) (limited to 'libsysfs/sysfs') diff --git a/libsysfs/sysfs/libsysfs.h b/libsysfs/sysfs/libsysfs.h index f3d2dd4d16..cbde2f5783 100644 --- a/libsysfs/sysfs/libsysfs.h +++ b/libsysfs/sysfs/libsysfs.h @@ -24,6 +24,25 @@ #define _LIBSYSFS_H_ #include +#include + +/* + * Defines to prevent buffer overruns + */ +#define safestrcpy(to, from) strncpy(to, from, sizeof(to)-1) +#define safestrcat(to, from) strncat(to, from, sizeof(to) - strlen(to)-1) + +#define safestrncpy(to, from, maxsize) \ +do { \ + to[maxsize-1] = '\0'; \ + strncpy(to, from, maxsize-1); \ +} while (0) + +#define safestrncat(to, from, maxsize) \ +do { \ + to[maxsize-1] = '\0'; \ + strncat(to, from, maxsize - strlen(to)-1); \ +} while (0) /* * Generic #defines go here.. @@ -46,25 +65,28 @@ #define SYSFS_METHOD_SHOW 0x01 /* attr can be read by user */ #define SYSFS_METHOD_STORE 0x02 /* attr can be changed by user */ -struct dlist; +/* + * NOTE: We have the statically allocated "name" as the first element of all + * the structures. This feature is used in the "sorter" function for dlists + */ struct sysfs_attribute { - unsigned char *value; + char name[SYSFS_NAME_LEN]; + char path[SYSFS_PATH_MAX]; + char *value; unsigned short len; /* value length */ unsigned short method; /* show and store */ - unsigned char name[SYSFS_NAME_LEN]; - unsigned char path[SYSFS_PATH_MAX]; }; struct sysfs_link { - unsigned char name[SYSFS_NAME_LEN]; - unsigned char path[SYSFS_PATH_MAX]; - unsigned char target[SYSFS_PATH_MAX]; + char name[SYSFS_NAME_LEN]; + char path[SYSFS_PATH_MAX]; + char target[SYSFS_PATH_MAX]; }; struct sysfs_directory { - unsigned char name[SYSFS_NAME_LEN]; - unsigned char path[SYSFS_PATH_MAX]; + char name[SYSFS_NAME_LEN]; + char path[SYSFS_PATH_MAX]; /* Private: for internal use only */ struct dlist *subdirs; @@ -73,8 +95,8 @@ struct sysfs_directory { }; struct sysfs_driver { - unsigned char name[SYSFS_NAME_LEN]; - unsigned char path[SYSFS_PATH_MAX]; + char name[SYSFS_NAME_LEN]; + char path[SYSFS_PATH_MAX]; /* Private: for internal use only */ struct dlist *devices; @@ -82,11 +104,11 @@ struct sysfs_driver { }; struct sysfs_device { - unsigned char name[SYSFS_NAME_LEN]; - unsigned char bus_id[SYSFS_NAME_LEN]; - unsigned char bus[SYSFS_NAME_LEN]; - unsigned char driver_name[SYSFS_NAME_LEN]; - unsigned char path[SYSFS_PATH_MAX]; + char name[SYSFS_NAME_LEN]; + char bus_id[SYSFS_NAME_LEN]; + char bus[SYSFS_NAME_LEN]; + char driver_name[SYSFS_NAME_LEN]; + char path[SYSFS_PATH_MAX]; /* Private: for internal use only */ struct sysfs_device *parent; @@ -95,8 +117,8 @@ struct sysfs_device { }; struct sysfs_root_device { - unsigned char name[SYSFS_NAME_LEN]; - unsigned char path[SYSFS_PATH_MAX]; + char name[SYSFS_NAME_LEN]; + char path[SYSFS_PATH_MAX]; /* Private: for internal use only */ struct dlist *devices; @@ -104,8 +126,8 @@ struct sysfs_root_device { }; struct sysfs_bus { - unsigned char name[SYSFS_NAME_LEN]; - unsigned char path[SYSFS_PATH_MAX]; + char name[SYSFS_NAME_LEN]; + char path[SYSFS_PATH_MAX]; /* Private: for internal use only */ struct dlist *drivers; @@ -114,9 +136,9 @@ struct sysfs_bus { }; struct sysfs_class_device { - unsigned char name[SYSFS_NAME_LEN]; - unsigned char classname[SYSFS_NAME_LEN]; - unsigned char path[SYSFS_PATH_MAX]; + char name[SYSFS_NAME_LEN]; + char classname[SYSFS_NAME_LEN]; + char path[SYSFS_PATH_MAX]; /* Private: for internal use only */ struct sysfs_class_device *parent; @@ -126,8 +148,8 @@ struct sysfs_class_device { }; struct sysfs_class { - unsigned char name[SYSFS_NAME_LEN]; - unsigned char path[SYSFS_PATH_MAX]; + char name[SYSFS_NAME_LEN]; + char path[SYSFS_PATH_MAX]; /* Private: for internal use only */ struct dlist *devices; @@ -141,49 +163,47 @@ extern "C" { /* * Function Prototypes */ -extern int sysfs_get_mnt_path(unsigned char *mnt_path, size_t len); -extern int sysfs_remove_trailing_slash(unsigned char *path); -extern int sysfs_get_name_from_path(const unsigned char *path, - unsigned char *name, size_t len); -extern int sysfs_path_is_dir(const unsigned char *path); -extern int sysfs_path_is_link(const unsigned char *path); -extern int sysfs_path_is_file(const unsigned char *path); -extern int sysfs_get_link(const unsigned char *path, unsigned char *target, - size_t len); -extern struct dlist *sysfs_open_subsystem_list(unsigned char *name); -extern struct dlist *sysfs_open_bus_devices_list(unsigned char *name); +extern int sysfs_get_mnt_path(char *mnt_path, size_t len); +extern int sysfs_remove_trailing_slash(char *path); +extern int sysfs_get_name_from_path(const char *path, char *name, size_t len); +extern int sysfs_path_is_dir(const char *path); +extern int sysfs_path_is_link(const char *path); +extern int sysfs_path_is_file(const char *path); +extern int sysfs_get_link(const char *path, char *target, size_t len); +extern struct dlist *sysfs_open_subsystem_list(char *name); +extern struct dlist *sysfs_open_bus_devices_list(char *name); extern void sysfs_close_list(struct dlist *list); /* sysfs directory and file access */ extern void sysfs_close_attribute(struct sysfs_attribute *sysattr); -extern struct sysfs_attribute *sysfs_open_attribute(const unsigned char *path); +extern struct sysfs_attribute *sysfs_open_attribute(const char *path); extern int sysfs_read_attribute(struct sysfs_attribute *sysattr); -extern int sysfs_read_attribute_value(const unsigned char *attrpath, - unsigned char *value, size_t vsize); +extern int sysfs_read_attribute_value(const char *attrpath, + char *value, size_t vsize); extern int sysfs_write_attribute(struct sysfs_attribute *sysattr, - const unsigned char *new_value, size_t len); -extern unsigned char *sysfs_get_value_from_attributes(struct dlist *attr, - const unsigned char * name); + const char *new_value, size_t len); +extern char *sysfs_get_value_from_attributes(struct dlist *attr, + const char *name); extern int sysfs_refresh_dir_attributes(struct sysfs_directory *sysdir); extern int sysfs_refresh_dir_links(struct sysfs_directory *sysdir); extern int sysfs_refresh_dir_subdirs(struct sysfs_directory *sysdir); extern void sysfs_close_directory(struct sysfs_directory *sysdir); -extern struct sysfs_directory *sysfs_open_directory(const unsigned char *path); +extern struct sysfs_directory *sysfs_open_directory(const char *path); extern int sysfs_read_dir_attributes(struct sysfs_directory *sysdir); extern int sysfs_read_dir_links(struct sysfs_directory *sysdir); extern int sysfs_read_dir_subdirs(struct sysfs_directory *sysdir); extern int sysfs_read_directory(struct sysfs_directory *sysdir); extern int sysfs_read_all_subdirs(struct sysfs_directory *sysdir); extern struct sysfs_directory *sysfs_get_subdirectory - (struct sysfs_directory *dir, unsigned char *subname); + (struct sysfs_directory *dir, char *subname); extern void sysfs_close_link(struct sysfs_link *ln); -extern struct sysfs_link *sysfs_open_link(const unsigned char *lnpath); -extern struct sysfs_link *sysfs_get_directory_link(struct sysfs_directory *dir, - unsigned char *linkname); +extern struct sysfs_link *sysfs_open_link(const char *lnpath); +extern struct sysfs_link *sysfs_get_directory_link + (struct sysfs_directory *dir, char *linkname); extern struct sysfs_link *sysfs_get_subdirectory_link - (struct sysfs_directory *dir, unsigned char *linkname); + (struct sysfs_directory *dir, char *linkname); extern struct sysfs_attribute *sysfs_get_directory_attribute - (struct sysfs_directory *dir, unsigned char *attrname); + (struct sysfs_directory *dir, char *attrname); extern struct dlist *sysfs_get_dir_attributes(struct sysfs_directory *dir); extern struct dlist *sysfs_get_dir_links(struct sysfs_directory *dir); extern struct dlist *sysfs_get_dir_subdirs(struct sysfs_directory *dir); @@ -191,84 +211,101 @@ extern struct dlist *sysfs_get_dir_subdirs(struct sysfs_directory *dir); /* sysfs driver access */ extern void sysfs_close_driver(struct sysfs_driver *driver); extern struct sysfs_driver *sysfs_open_driver - (const unsigned char *drv_name, const unsigned char *bus_name); -extern struct sysfs_driver *sysfs_open_driver_path(const unsigned char *path); + (const char *bus_name, const char *drv_name); +extern struct sysfs_driver *sysfs_open_driver_path(const char *path); extern struct sysfs_attribute *sysfs_get_driver_attr - (struct sysfs_driver *drv, const unsigned char *name); + (struct sysfs_driver *drv, const char *name); extern struct dlist *sysfs_get_driver_attributes(struct sysfs_driver *driver); extern struct dlist *sysfs_get_driver_devices(struct sysfs_driver *driver); extern struct dlist *sysfs_refresh_driver_devices(struct sysfs_driver *driver); extern struct dlist *sysfs_get_driver_links(struct sysfs_driver *driver); extern struct sysfs_device *sysfs_get_driver_device - (struct sysfs_driver *driver, const unsigned char *name); + (struct sysfs_driver *driver, const char *name); extern struct dlist *sysfs_refresh_driver_attributes - (struct sysfs_driver *driver); -extern struct sysfs_attribute *sysfs_open_driver_attr(const unsigned char *bus, - const unsigned char *drv, const unsigned char *attrib); + (struct sysfs_driver *driver); +extern struct sysfs_attribute *sysfs_open_driver_attr + (const char *bus, const char *drv, const char *attrib); /* generic sysfs device access */ extern void sysfs_close_root_device(struct sysfs_root_device *root); -extern struct sysfs_root_device *sysfs_open_root_device - (const unsigned char *name); +extern struct sysfs_root_device *sysfs_open_root_device(const char *name); extern struct dlist *sysfs_get_root_devices(struct sysfs_root_device *root); +extern void sysfs_close_device_tree(struct sysfs_device *device); +extern struct sysfs_device *sysfs_open_device_tree(const char *path); extern void sysfs_close_device(struct sysfs_device *dev); extern struct sysfs_device *sysfs_open_device - (const unsigned char *bus_id, const unsigned char *bus); + (const char *bus, const char *bus_id); extern struct sysfs_device *sysfs_get_device_parent(struct sysfs_device *dev); -extern struct sysfs_device *sysfs_open_device_path(const unsigned char *path); +extern struct sysfs_device *sysfs_open_device_path(const char *path); extern int sysfs_get_device_bus(struct sysfs_device *dev); extern struct sysfs_attribute *sysfs_get_device_attr - (struct sysfs_device *dev, const unsigned char *name); + (struct sysfs_device *dev, const char *name); extern struct dlist *sysfs_get_device_attributes(struct sysfs_device *device); extern struct dlist *sysfs_refresh_device_attributes - (struct sysfs_device *device); -extern struct sysfs_attribute *sysfs_open_device_attr(const unsigned char *bus, - const unsigned char *bus_id, const unsigned char *attrib); + (struct sysfs_device *device); +extern struct sysfs_attribute *sysfs_open_device_attr(const char *bus, + const char *bus_id, const char *attrib); /* generic sysfs bus access */ extern void sysfs_close_bus(struct sysfs_bus *bus); -extern struct sysfs_bus *sysfs_open_bus(const unsigned char *name); -extern struct sysfs_device *sysfs_get_bus_device(struct sysfs_bus *bus, - unsigned char *id); +extern struct sysfs_bus *sysfs_open_bus(const char *name); +extern struct sysfs_device *sysfs_get_bus_device(struct sysfs_bus *bus, + char *id); extern struct sysfs_driver *sysfs_get_bus_driver(struct sysfs_bus *bus, - unsigned char *drvname); + char *drvname); extern struct dlist *sysfs_get_bus_drivers(struct sysfs_bus *bus); extern struct dlist *sysfs_get_bus_devices(struct sysfs_bus *bus); extern struct dlist *sysfs_get_bus_attributes(struct sysfs_bus *bus); extern struct dlist *sysfs_refresh_bus_attributes(struct sysfs_bus *bus); -extern struct sysfs_attribute *sysfs_get_bus_attribute(struct sysfs_bus *bus, - unsigned char *attrname); -extern struct sysfs_device *sysfs_open_bus_device(unsigned char *busname, - unsigned char *dev_id); -extern int sysfs_find_driver_bus(const unsigned char *driver, - unsigned char *busname, size_t bsize); +extern struct sysfs_attribute *sysfs_get_bus_attribute + (struct sysfs_bus *bus, char *attrname); +extern int sysfs_find_driver_bus(const char *driver, char *busname, + size_t bsize); /* generic sysfs class access */ extern void sysfs_close_class_device(struct sysfs_class_device *dev); extern struct sysfs_class_device *sysfs_open_class_device_path - (const unsigned char *path); + (const char *path); extern struct sysfs_class_device *sysfs_open_class_device - (const unsigned char *class, const unsigned char *name); + (const char *classname, const char *name); extern struct sysfs_device *sysfs_get_classdev_device - (struct sysfs_class_device *clsdev); + (struct sysfs_class_device *clsdev); extern struct sysfs_driver *sysfs_get_classdev_driver - (struct sysfs_class_device *clsdev); + (struct sysfs_class_device *clsdev); extern struct sysfs_class_device *sysfs_get_classdev_parent - (struct sysfs_class_device *clsdev); + (struct sysfs_class_device *clsdev); extern void sysfs_close_class(struct sysfs_class *cls); -extern struct sysfs_class *sysfs_open_class(const unsigned char *name); +extern struct sysfs_class *sysfs_open_class(const char *name); extern struct dlist *sysfs_get_class_devices(struct sysfs_class *cls); extern struct sysfs_class_device *sysfs_get_class_device - (struct sysfs_class *class, unsigned char *name); + (struct sysfs_class *cls, char *name); extern struct dlist *sysfs_get_classdev_attributes (struct sysfs_class_device *cdev); extern struct dlist *sysfs_refresh_classdev_attributes (struct sysfs_class_device *cdev); extern struct sysfs_attribute *sysfs_get_classdev_attr - (struct sysfs_class_device *clsdev, const unsigned char *name); + (struct sysfs_class_device *clsdev, const char *name); extern struct sysfs_attribute *sysfs_open_classdev_attr - (const unsigned char *classname, const unsigned char *dev, - const unsigned char *attrib); + (const char *classname, const char *dev, + const char *attrib); + +/** + * sort_list: sorter function to keep list elements sorted in alphabetical + * order. Just does a strncmp as you can see :) + * + * Returns 1 if less than 0 otherwise + * + * NOTE: We take care to have a statically allocated "name" as the first + * lement of all libsysfs structures. Hence, this function will work + * AS IS for _ALL_ the lists that have to be sorted. + */ +static inline int sort_list(void *new_elem, void *old_elem) +{ + return ((strncmp(((struct sysfs_attribute *)new_elem)->name, + ((struct sysfs_attribute *)old_elem)->name, + strlen(((struct sysfs_attribute *)new_elem)->name))) < 0 ? 1 : 0); +} + #ifdef __cplusplus } -- cgit v1.2.3-54-g00ecf