diff options
author | Philippe Reynes <philippe.reynes@sagemcom.com> | 2016-06-29 17:19:44 +0200 |
---|---|---|
committer | Peter Korsgaard <peter@korsgaard.com> | 2016-06-30 12:13:38 +0200 |
commit | 688059ebb23227fb13aad319df6e78686ea6e14a (patch) | |
tree | 5a848ce8eaa5b54bdfb89aeb6fc6ab53f0f5ae53 /package/makedevs | |
parent | 4520524ba055706236db9f00dd79f1b2e2e87fde (diff) |
makedevs: add capability support
Add the support of capability to makedevs as extended attribute.
Now, it's possible to add a line "|xattr <capability>" after a
file description to also add a capability to this file. It's
possible to add severals capabilities with severals lines.
[Peter: extend doc, reword Config.in, extend error message,
use HOST_MAKEDEVS_CFLAGS/LDFLAGS for all flags]
Signed-off-by: Philippe Reynes <philippe.reynes@sagemcom.com>
Signed-off-by: Peter Korsgaard <peter@korsgaard.com>
Diffstat (limited to 'package/makedevs')
-rw-r--r-- | package/makedevs/makedevs.c | 72 | ||||
-rw-r--r-- | package/makedevs/makedevs.mk | 13 |
2 files changed, 81 insertions, 4 deletions
diff --git a/package/makedevs/makedevs.c b/package/makedevs/makedevs.c index e5ef16413..cacb144e2 100644 --- a/package/makedevs/makedevs.c +++ b/package/makedevs/makedevs.c @@ -35,6 +35,9 @@ #include <sys/sysmacros.h> /* major() and minor() */ #endif #include <ftw.h> +#ifdef EXTENDED_ATTRIBUTES +#include <sys/capability.h> +#endif /* EXTENDED_ATTRIBUTES */ const char *bb_applet_name; uid_t recursive_uid; @@ -349,6 +352,49 @@ char *concat_path_file(const char *path, const char *filename) return outbuf; } +#ifdef EXTENDED_ATTRIBUTES +int bb_set_xattr(const char *fpath, const char *xattr) +{ + cap_t cap, cap_file, cap_new; + char *cap_file_text, *cap_new_text; + ssize_t length; + + cap = cap_from_text(xattr); + if (cap == NULL) + bb_perror_msg_and_die("cap_from_text failed for %s", xattr); + + cap_file = cap_get_file(fpath); + if (cap_file == NULL) { + /* if no capability was set before, we initialize cap_file */ + if (errno != ENODATA) + bb_perror_msg_and_die("cap_get_file failed on %s", fpath); + + cap_file = cap_init(); + if (!cap_file) + bb_perror_msg_and_die("cap_init failed"); + } + + if ((cap_file_text = cap_to_text(cap_file, &length)) == NULL) + bb_perror_msg_and_die("cap_to_name failed on %s", fpath); + + bb_xasprintf(&cap_new_text, "%s %s", cap_file_text, xattr); + + if ((cap_new = cap_from_text(cap_new_text)) == NULL) + bb_perror_msg_and_die("cap_from_text failed on %s", cap_new_text); + + if (cap_set_file(fpath, cap_new) == -1) + bb_perror_msg_and_die("cap_set_file failed for %s (xattr = %s)", fpath, xattr); + + cap_free(cap); + cap_free(cap_file); + cap_free(cap_file_text); + cap_free(cap_new); + cap_free(cap_new_text); + + return 0; +} +#endif /* EXTENDED_ATTRIBUTES */ + void bb_show_usage(void) { fprintf(stderr, "%s: [-d device_table] rootdir\n\n", bb_applet_name); @@ -413,6 +459,7 @@ int main(int argc, char **argv) int opt; FILE *table = stdin; char *rootdir = NULL; + char *full_name = NULL; char *line = NULL; int linenum = 0; int ret = EXIT_SUCCESS; @@ -454,15 +501,30 @@ int main(int argc, char **argv) unsigned int count = 0; unsigned int increment = 0; unsigned int start = 0; + char xattr[255]; char name[4096]; char user[41]; char group[41]; - char *full_name; uid_t uid; gid_t gid; linenum++; + if (1 == sscanf(line, "|xattr %254s", xattr)) { +#ifdef EXTENDED_ATTRIBUTES + if (!full_name) + bb_error_msg_and_die("line %d should be after a file\n", linenum); + + if (bb_set_xattr(full_name, xattr) < 0) + bb_error_msg_and_die("can't set cap %s on file %s\n", xattr, full_name); +#else + bb_error_msg_and_die("line %d not supported: '%s'\nDid you forget to enable " + "BR2_ROOTFS_DEVICE_TABLE_SUPPORTS_EXTENDED_ATTRIBUTES?\n", + linenum, line); +#endif /* EXTENDED_ATTRIBUTES */ + continue; + } + if ((2 > sscanf(line, "%4095s %c %o %40s %40s %u %u %u %u %u", name, &type, &mode, user, group, &major, &minor, &start, &increment, &count)) || @@ -487,6 +549,13 @@ int main(int argc, char **argv) } else { uid = getuid(); } + + /* + * free previous full name + * we don't de-allocate full_name at the end of the parsing, + * because we may need it if the next line is an xattr. + */ + free(full_name); full_name = concat_path_file(rootdir, name); if (type == 'd') { @@ -585,7 +654,6 @@ int main(int argc, char **argv) } loop: free(line); - free(full_name); } fclose(table); diff --git a/package/makedevs/makedevs.mk b/package/makedevs/makedevs.mk index fa8e753cb..130f5bc9c 100644 --- a/package/makedevs/makedevs.mk +++ b/package/makedevs/makedevs.mk @@ -11,6 +11,15 @@ HOST_MAKEDEVS_SOURCE = MAKEDEVS_VERSION = buildroot-$(BR2_VERSION) MAKEDEVS_LICENSE = GPLv2 +HOST_MAKEDEVS_CFLAGS = $(HOST_CFLAGS) +HOST_MAKEDEVS_LDFLAGS = $(HOST_LDFLAGS) + +ifeq ($(BR2_ROOTFS_DEVICE_TABLE_SUPPORTS_EXTENDED_ATTRIBUTES),y) +HOST_MAKEDEVS_DEPENDENCIES += host-libcap +HOST_MAKEDEVS_CFLAGS += -DEXTENDED_ATTRIBUTES +HOST_MAKEDEVS_LDFLAGS += -lcap +endif + define MAKEDEVS_BUILD_CMDS $(TARGET_CC) $(TARGET_CFLAGS) $(TARGET_LDFLAGS) \ package/makedevs/makedevs.c -o $(@D)/makedevs @@ -21,8 +30,8 @@ define MAKEDEVS_INSTALL_TARGET_CMDS endef define HOST_MAKEDEVS_BUILD_CMDS - $(HOSTCC) $(HOST_CFLAGS) $(HOST_LDFLAGS) \ - package/makedevs/makedevs.c -o $(@D)/makedevs + $(HOSTCC) $(HOST_MAKEDEVS_CFLAGS) package/makedevs/makedevs.c \ + -o $(@D)/makedevs $(HOST_MAKEDEVS_LDFLAGS) endef define HOST_MAKEDEVS_INSTALL_CMDS |