[systemd-devel] [PATCH 2/4] Allow systemd-tmpfiles to set the file/directory attributes
Lennart Poettering
lennart at poettering.net
Wed Apr 8 11:36:12 PDT 2015
On Mon, 16.03.15 20:33, Goffredo Baroncelli (kreijack at libero.it) wrote:
Sorry for warming up this old thread, but a few issues I see with this?
> RECURSIVE_RELABEL_PATH = 'Z',
> + SET_ATTRIB = 'h',
> + RECURSIVE_SET_ATTRIB = 'H',
> } ItemType;
>
> typedef struct Item {
> @@ -108,12 +111,15 @@ typedef struct Item {
> usec_t age;
>
> dev_t major_minor;
> + int attrib_value;
> + int attrib_mask;
I thought this was unsigned now?
>
> +static int get_attrib_from_arg(Item *item) {
> + static const unsigned attributes[] = {
> + [(uint8_t)'A'] = FS_NOATIME_FL, /* do not update atime */
> + [(uint8_t)'S'] = FS_SYNC_FL, /* Synchronous updates */
> + [(uint8_t)'D'] = FS_DIRSYNC_FL, /* dirsync behaviour (directories only) */
> + [(uint8_t)'a'] = FS_APPEND_FL, /* writes to file may only append */
> + [(uint8_t)'c'] = FS_COMPR_FL, /* Compress file */
> + [(uint8_t)'d'] = FS_NODUMP_FL, /* do not dump file */
> + [(uint8_t)'e'] = FS_EXTENT_FL, /* Top of directory hierarchies*/
> + [(uint8_t)'i'] = FS_IMMUTABLE_FL, /* Immutable file */
> + [(uint8_t)'j'] = FS_JOURNAL_DATA_FL, /* Reserved for ext3 */
> + [(uint8_t)'s'] = FS_SECRM_FL, /* Secure deletion */
> + [(uint8_t)'u'] = FS_UNRM_FL, /* Undelete */
> + [(uint8_t)'t'] = FS_NOTAIL_FL, /* file tail should not be merged */
> + [(uint8_t)'T'] = FS_TOPDIR_FL, /* Top of directory hierarchies*/
> + [(uint8_t)'C'] = FS_NOCOW_FL, /* Do not cow file */
> + };
Hmm, that's quite a sparse array! It wastes 116 entries, just to
store 13 entries... I think this should really be an array fo structs
with the chars and their flag, which we iterate through...
> + const unsigned all_flags = FS_NOATIME_FL|FS_SYNC_FL|FS_DIRSYNC_FL|
> + FS_APPEND_FL|FS_COMPR_FL|FS_NODUMP_FL|FS_EXTENT_FL|
> + FS_IMMUTABLE_FL|FS_JOURNAL_DATA_FL|FS_SECRM_FL|FS_UNRM_FL|
> + FS_NOTAIL_FL|FS_TOPDIR_FL|FS_NOCOW_FL;
> + char *p = item->argument;
> + enum {
> + MODE_ADD,
> + MODE_DEL,
> + MODE_SET
> + } mode = MODE_ADD;
> + unsigned long value = 0, mask = 0;
And now it is "unsigned long", not just "unsigned anymore?
> +
> +static int path_set_attrib(Item *item, const char *path) {
> + _cleanup_close_ int fd = -1;
> + int r;
> + unsigned f;
> + struct stat st;
> +
> + /* do nothing */
> + if (item->attrib_mask == 0 || !item->attrib_set)
> + return 0;
> + /*
> + * It is OK to ignore an lstat() error, because the error
> + * will be catch by the open() below anyway
> + */
> + if (lstat(path, &st) == 0 &&
> + !S_ISREG(st.st_mode) && !S_ISDIR(st.st_mode)) {
> + return 0;
> + }
Why do we need this check? What happens if we apply this onto
a device node, or socket, or whatever?
I really don#t like this seperate lstat() + open(). If it all it
should be open() + fstat(), to avoid TTOCTOU issues...
> + fd = open(path, O_RDONLY|O_NONBLOCK|O_CLOEXEC);
> +
> + if (fd < 0)
> + return log_error_errno(errno, "Cannot open \"%s\": %m", path);
>
> + case SET_ATTRIB:
> + case RECURSIVE_SET_ATTRIB:
> + if (!i.argument) {
> + log_error("[%s:%u] Set attrib requires
> argument.", fname, line);
Please don't abbreviate words like "attrib" in human language...
Lennart
--
Lennart Poettering, Red Hat
More information about the systemd-devel
mailing list