e2fsprogs/*: remove ioctl calling obfuscation
No binary (build failed)
—
(log yok)
| @@ -61,9 +61,9 @@ | |
| #define OPT_SET_PROJ (1 << 4) | |
| struct globals { | |
| - | unsigned long version; |
| - | unsigned long af; |
| - | unsigned long rf; |
| + | unsigned version; |
| + | unsigned af; |
| + | unsigned rf; |
| int flags; | |
| uint32_t projid; | |
| smallint recursive; | |
| @@ -79,7 +79,7 @@ static unsigned long get_flag(char c) | |
| static char** decode_arg(char **argv, struct globals *gp) | |
| { | |
| - | unsigned long *fl; |
| + | unsigned *fl; |
| const char *arg = *argv; | |
| char opt = *arg; | |
| @@ -149,7 +149,8 @@ static int FAST_FUNC chattr_dir_proc(const char *dir_name, struct dirent *de, vo | |
| static void change_attributes(const char *name, struct globals *gp) | |
| { | |
| - | unsigned long fsflags; |
| + | unsigned fsflags; |
| + | int fd; |
| struct stat st; | |
| if (lstat(name, &st) != 0) { | |
| @@ -166,33 +167,50 @@ static void change_attributes(const char *name, struct globals *gp) | |
| if (!S_ISREG(st.st_mode) && !S_ISLNK(st.st_mode) && !S_ISDIR(st.st_mode)) | |
| return; | |
| - | if (gp->flags & OPT_SET_VER) |
| - | if (fsetversion(name, gp->version) != 0) |
| - | bb_perror_msg("setting %s on %s", "version", name); |
| + | fd = open_or_warn(name, O_RDONLY | O_NONBLOCK); /* neither read nor write asked for */ |
| + | if (fd >= 0) { |
| + | int r; |
| - | if (gp->flags & OPT_SET_PROJ) |
| - | if (fsetprojid(name, gp->projid) != 0) |
| - | bb_perror_msg("setting %s on %s", "project ID", name); |
| + | if (gp->flags & OPT_SET_VER) { |
| + | r = ioctl(fd, EXT2_IOC_SETVERSION, &gp->version); |
| + | if (r != 0) |
| + | bb_perror_msg("setting %s on %s", "version", name); |
| + | } |
| - | if (gp->flags & OPT_SET) { |
| - | fsflags = gp->af; |
| - | } else { |
| - | if (fgetflags(name, &fsflags) != 0) { |
| - | bb_perror_msg("reading flags on %s", name); |
| - | goto skip_setflags; |
| + | if (gp->flags & OPT_SET_PROJ) { |
| + | struct ext2_fsxattr fsxattr; |
| + | r = ioctl(fd, EXT2_IOC_FSGETXATTR, &fsxattr); |
| + | if (r != 0) |
| + | bb_perror_msg("getting %s on %s", "project ID", name); |
| + | fsxattr.fsx_projid = gp->projid; |
| + | r = ioctl(fd, EXT2_IOC_FSSETXATTR, &fsxattr); |
| + | if (r != 0) |
| + | bb_perror_msg("setting %s on %s", "project ID", name); |
| } | |
| - | /*if (gp->flags & OPT_REM) - not needed, rf is zero otherwise */ |
| - | fsflags &= ~gp->rf; |
| - | /*if (gp->flags & OPT_ADD) - not needed, af is zero otherwise */ |
| - | fsflags |= gp->af; |
| + | |
| + | if (gp->flags & OPT_SET) { |
| + | fsflags = gp->af; |
| + | } else { |
| + | r = ioctl(fd, EXT2_IOC_GETFLAGS, &fsflags); |
| + | if (r != 0) { |
| + | bb_perror_msg("getting %s on %s", "flags", name); |
| + | goto skip_setflags; |
| + | } |
| + | /*if (gp->flags & OPT_REM) - not needed, rf is zero otherwise */ |
| + | fsflags &= ~gp->rf; |
| + | /*if (gp->flags & OPT_ADD) - not needed, af is zero otherwise */ |
| + | fsflags |= gp->af; |
| // What is this? And why it's not done for SET case? | |
| - | if (!S_ISDIR(st.st_mode)) |
| - | fsflags &= ~EXT2_DIRSYNC_FL; |
| + | if (!S_ISDIR(st.st_mode)) |
| + | fsflags &= ~EXT2_DIRSYNC_FL; |
| + | } |
| + | r = ioctl(fd, EXT2_IOC_SETFLAGS, &fsflags); |
| + | if (r != 0) |
| + | bb_perror_msg("setting %s on %s", "flags", name); |
| + | skip_setflags: |
| + | close(fd); |
| } | |
| - | if (fsetflags(name, fsflags) != 0) |
| - | bb_perror_msg("setting flags on %s", name); |
| - | skip_setflags: |
| if (gp->recursive && S_ISDIR(st.st_mode)) | |
| iterate_on_dir(name, chattr_dir_proc, gp); | |
| } | |
| @@ -8,8 +8,6 @@ | |
| #include "libbb.h" | |
| #include "e2fs_lib.h" | |
| - | #define HAVE_EXT2_IOCTLS 1 |
| - | |
| #if INT_MAX == LONG_MAX | |
| #define IF_LONG_IS_SAME(...) __VA_ARGS__ | |
| #define IF_LONG_IS_WIDER(...) | |
| @@ -18,14 +16,6 @@ | |
| #define IF_LONG_IS_WIDER(...) __VA_ARGS__ | |
| #endif | |
| - | static void close_silently(int fd) |
| - | { |
| - | int e = errno; |
| - | close(fd); |
| - | errno = e; |
| - | } |
| - | |
| - | |
| /* Iterate a function on each entry of a directory */ | |
| int iterate_on_dir(const char *dir_name, | |
| int FAST_FUNC (*func)(const char *, struct dirent *, void *), | |
| @@ -45,113 +35,6 @@ int iterate_on_dir(const char *dir_name, | |
| return 0; | |
| } | |
| - | |
| - | /* Get/set a file version on an ext2 file system */ |
| - | int fgetsetversion(const char *name, unsigned long *get_version, unsigned long set_version) |
| - | { |
| - | #if HAVE_EXT2_IOCTLS |
| - | int fd, r; |
| - | IF_LONG_IS_WIDER(unsigned ver;) |
| - | |
| - | fd = open(name, O_RDONLY | O_NONBLOCK); |
| - | if (fd == -1) |
| - | return -1; |
| - | if (!get_version) { |
| - | IF_LONG_IS_WIDER( |
| - | ver = (unsigned) set_version; |
| - | r = ioctl(fd, EXT2_IOC_SETVERSION, &ver); |
| - | ) |
| - | IF_LONG_IS_SAME( |
| - | r = ioctl(fd, EXT2_IOC_SETVERSION, (void*)&set_version); |
| - | ) |
| - | } else { |
| - | IF_LONG_IS_WIDER( |
| - | r = ioctl(fd, EXT2_IOC_GETVERSION, &ver); |
| - | *get_version = ver; |
| - | ) |
| - | IF_LONG_IS_SAME( |
| - | r = ioctl(fd, EXT2_IOC_GETVERSION, (void*)get_version); |
| - | ) |
| - | } |
| - | close_silently(fd); |
| - | return r; |
| - | #else /* ! HAVE_EXT2_IOCTLS */ |
| - | errno = EOPNOTSUPP; |
| - | return -1; |
| - | #endif /* ! HAVE_EXT2_IOCTLS */ |
| - | } |
| - | |
| - | int fgetsetprojid(const char *name, uint32_t *get, uint32_t set) |
| - | { |
| - | #if HAVE_EXT2_IOCTLS |
| - | struct ext2_fsxattr fsxattr; |
| - | int fd, r; |
| - | |
| - | fd = open(name, O_RDONLY | O_NONBLOCK); |
| - | if (fd == -1) |
| - | return -1; |
| - | r = ioctl(fd, EXT2_IOC_FSGETXATTR, &fsxattr); |
| - | /* note: ^^^ may fail in 32-bit userspace on 64-bit kernel (seen on 4.12.0) */ |
| - | if (r == 0) { |
| - | if (get) { |
| - | *get = fsxattr.fsx_projid; |
| - | } else { |
| - | fsxattr.fsx_projid = set; |
| - | r = ioctl(fd, EXT2_IOC_FSSETXATTR, &fsxattr); |
| - | } |
| - | } |
| - | close_silently(fd); |
| - | return r; |
| - | #else /* ! HAVE_EXT2_IOCTLS */ |
| - | errno = EOPNOTSUPP; |
| - | return -1; |
| - | #endif /* ! HAVE_EXT2_IOCTLS */ |
| - | } |
| - | |
| - | /* Get/set a file flags on an ext2 file system */ |
| - | int fgetsetflags(const char *name, unsigned long *get_flags, unsigned long set_flags) |
| - | { |
| - | #if HAVE_EXT2_IOCTLS |
| - | struct stat buf; |
| - | int fd, r; |
| - | IF_LONG_IS_WIDER(unsigned f;) |
| - | |
| - | if (stat(name, &buf) == 0 /* stat is ok */ |
| - | && !S_ISREG(buf.st_mode) && !S_ISDIR(buf.st_mode) |
| - | ) { |
| - | goto notsupp; |
| - | } |
| - | fd = open(name, O_RDONLY | O_NONBLOCK); /* neither read nor write asked for */ |
| - | if (fd == -1) |
| - | return -1; |
| - | |
| - | if (!get_flags) { |
| - | IF_LONG_IS_WIDER( |
| - | f = (unsigned) set_flags; |
| - | r = ioctl(fd, EXT2_IOC_SETFLAGS, &f); |
| - | ) |
| - | IF_LONG_IS_SAME( |
| - | r = ioctl(fd, EXT2_IOC_SETFLAGS, (void*)&set_flags); |
| - | ) |
| - | } else { |
| - | IF_LONG_IS_WIDER( |
| - | r = ioctl(fd, EXT2_IOC_GETFLAGS, &f); |
| - | *get_flags = f; |
| - | ) |
| - | IF_LONG_IS_SAME( |
| - | r = ioctl(fd, EXT2_IOC_GETFLAGS, (void*)get_flags); |
| - | ) |
| - | } |
| - | |
| - | close_silently(fd); |
| - | return r; |
| - | notsupp: |
| - | #endif /* HAVE_EXT2_IOCTLS */ |
| - | errno = EOPNOTSUPP; |
| - | return -1; |
| - | } |
| - | |
| - | |
| /* Print file attributes on an ext2 file system */ | |
| const uint32_t e2attr_flags_value[] ALIGN4 = { | |
| #ifdef ENABLE_COMPRESSION | |
| @@ -215,7 +98,7 @@ static const char e2attr_flags_lname[] ALIGN1 = | |
| "Verity" "\0" | |
| /* Another trailing NUL is added by compiler */; | |
| - | void print_e2flags(FILE *f, unsigned long flags, unsigned options) |
| + | void print_e2flags(FILE *f, unsigned flags, unsigned options) |
| { | |
| const uint32_t *fv; | |
| const char *fn; | |
| @@ -16,25 +16,10 @@ int iterate_on_dir(const char *dir_name, | |
| int FAST_FUNC (*func)(const char *, struct dirent *, void *), | |
| void *private); | |
| - | /* Get/set a file version on an ext2 file system */ |
| - | int fgetsetversion(const char *name, unsigned long *get_version, unsigned long set_version); |
| - | #define fgetversion(name, version) fgetsetversion(name, version, 0) |
| - | #define fsetversion(name, version) fgetsetversion(name, NULL, version) |
| - | |
| - | /* Get/set a file project ID on an ext2 file system */ |
| - | int fgetsetprojid(const char *name, uint32_t *get, uint32_t set); |
| - | #define fgetprojid(name, projid) fgetsetprojid(name, projid, 0) |
| - | #define fsetprojid(name, projid) fgetsetprojid(name, NULL, projid) |
| - | |
| - | /* Get/set a file flags on an ext2 file system */ |
| - | int fgetsetflags(const char *name, unsigned long *get_flags, unsigned long set_flags); |
| - | #define fgetflags(name, flags) fgetsetflags(name, flags, 0) |
| - | #define fsetflags(name, flags) fgetsetflags(name, NULL, flags) |
| - | |
| /* Must be 1 for compatibility with 'int long_format'. */ | |
| #define PFOPT_LONG 1 | |
| /* Print file attributes on an ext2 file system */ | |
| - | void print_e2flags(FILE *f, unsigned long flags, unsigned options); |
| + | void print_e2flags(FILE *f, unsigned flags, unsigned options); |
| extern const uint32_t e2attr_flags_value[]; | |
| extern const char e2attr_flags_sname[]; | |
| @@ -46,25 +46,35 @@ enum { | |
| static void list_attributes(const char *name) | |
| { | |
| - | unsigned long fsflags; |
| + | unsigned fsflags; |
| + | int fd, r; |
| - | if (fgetflags(name, &fsflags) != 0) |
| - | goto read_err; |
| + | fd = open_or_warn(name, O_RDONLY | O_NONBLOCK); /* neither read nor write asked for */ |
| + | if (fd < 0) /* for example, dangling links */ |
| + | return; |
| if (option_mask32 & OPT_PROJID) { | |
| - | uint32_t p; |
| - | if (fgetprojid(name, &p) != 0) |
| + | struct ext2_fsxattr fsxattr; |
| + | r = ioctl(fd, EXT2_IOC_FSGETXATTR, &fsxattr); |
| + | if (r != 0) |
| goto read_err; | |
| - | printf("%5lu ", (unsigned long)p); |
| + | printf("%5u ", (unsigned)fsxattr.fsx_projid); |
| } | |
| if (option_mask32 & OPT_GENERATION) { | |
| - | unsigned long generation; |
| - | if (fgetversion(name, &generation) != 0) |
| + | unsigned generation; |
| + | r = ioctl(fd, EXT2_IOC_GETVERSION, &generation); |
| + | if (r != 0) |
| goto read_err; | |
| - | printf("%-10lu ", generation); |
| + | printf("%-10u ", generation); |
| } | |
| + | r = ioctl(fd, EXT2_IOC_GETFLAGS, &fsflags); |
| + | if (r != 0) |
| + | goto read_err; |
| + | |
| + | close(fd); |
| + | |
| if (option_mask32 & OPT_PF_LONG) { | |
| printf("%-28s ", name); | |
| print_e2flags(stdout, fsflags, PFOPT_LONG); | |
| @@ -77,6 +87,7 @@ static void list_attributes(const char *name) | |
| return; | |
| read_err: | |
| bb_perror_msg("reading %s", name); | |
| + | close(fd); |
| } | |
| static int FAST_FUNC lsattr_dir_proc(const char *dir_name, | |
| @@ -12751,7 +12751,7 @@ parsesub: { | |
| do { | |
| STPUTC(c, out); | |
| c = pgetc_eatbnl(); | |
| - | } while (!subtype && isdigit(c)); |
| + | } while ((subtype == 0 || subtype == VSLENGTH) && isdigit(c)); |
| } else if (c != '}') { | |
| /* $[{[#]]<specialchar>[}] */ | |
| int cc = c; | |
| @@ -12781,11 +12781,6 @@ parsesub: { | |
| } else | |
| goto badsub; | |
| - | if (c != '}' && subtype == VSLENGTH) { |
| - | /* ${#VAR didn't end with } */ |
| - | goto badsub; |
| - | } |
| - | |
| if (subtype == 0) { | |
| static const char types[] ALIGN1 = "}-+?="; | |
| /* ${VAR...} but not $VAR or ${#VAR} */ | |
| @@ -12842,6 +12837,8 @@ parsesub: { | |
| #endif | |
| } | |
| } else { | |
| + | if (subtype == VSLENGTH && c != '}') |
| + | subtype = 0; |
| badsub: | |
| pungetc(); | |
| } | |