aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2021-06-23 12:45:51 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2021-06-23 12:56:40 +0200
commit96436fb36a5fa0ac8e993fb093b4788fb5448afe (patch)
tree6804eb71f9dd765b193be9875ad4974d702f3d59
parente7ff017a1a8a429aabb02e80fbede1ce1126d8ea (diff)
downloadbusybox-w32-96436fb36a5fa0ac8e993fb093b4788fb5448afe.tar.gz
busybox-w32-96436fb36a5fa0ac8e993fb093b4788fb5448afe.tar.bz2
busybox-w32-96436fb36a5fa0ac8e993fb093b4788fb5448afe.zip
e2fsprogs/*: remove ioctl calling obfuscation
function old new delta change_attributes 326 416 +90 list_attributes 222 248 +26 close_silently 22 - -22 .rodata 103722 103692 -30 fgetsetversion 74 - -74 fgetsetprojid 107 - -107 fgetsetflags 148 - -148 ------------------------------------------------------------------------------ (add/remove: 0/4 grow/shrink: 2/1 up/down: 116/-381) Total: -265 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--e2fsprogs/chattr.c70
-rw-r--r--e2fsprogs/e2fs_lib.c119
-rw-r--r--e2fsprogs/e2fs_lib.h17
-rw-r--r--e2fsprogs/lsattr.c29
-rw-r--r--shell/ash.c9
5 files changed, 69 insertions, 175 deletions
diff --git a/e2fsprogs/chattr.c b/e2fsprogs/chattr.c
index 4dfe803d2..f6a9fcf30 100644
--- a/e2fsprogs/chattr.c
+++ b/e2fsprogs/chattr.c
@@ -61,9 +61,9 @@
61#define OPT_SET_PROJ (1 << 4) 61#define OPT_SET_PROJ (1 << 4)
62 62
63struct globals { 63struct globals {
64 unsigned long version; 64 unsigned version;
65 unsigned long af; 65 unsigned af;
66 unsigned long rf; 66 unsigned rf;
67 int flags; 67 int flags;
68 uint32_t projid; 68 uint32_t projid;
69 smallint recursive; 69 smallint recursive;
@@ -79,7 +79,7 @@ static unsigned long get_flag(char c)
79 79
80static char** decode_arg(char **argv, struct globals *gp) 80static char** decode_arg(char **argv, struct globals *gp)
81{ 81{
82 unsigned long *fl; 82 unsigned *fl;
83 const char *arg = *argv; 83 const char *arg = *argv;
84 char opt = *arg; 84 char opt = *arg;
85 85
@@ -149,7 +149,8 @@ static int FAST_FUNC chattr_dir_proc(const char *dir_name, struct dirent *de, vo
149 149
150static void change_attributes(const char *name, struct globals *gp) 150static void change_attributes(const char *name, struct globals *gp)
151{ 151{
152 unsigned long fsflags; 152 unsigned fsflags;
153 int fd;
153 struct stat st; 154 struct stat st;
154 155
155 if (lstat(name, &st) != 0) { 156 if (lstat(name, &st) != 0) {
@@ -166,33 +167,50 @@ static void change_attributes(const char *name, struct globals *gp)
166 if (!S_ISREG(st.st_mode) && !S_ISLNK(st.st_mode) && !S_ISDIR(st.st_mode)) 167 if (!S_ISREG(st.st_mode) && !S_ISLNK(st.st_mode) && !S_ISDIR(st.st_mode))
167 return; 168 return;
168 169
169 if (gp->flags & OPT_SET_VER) 170 fd = open_or_warn(name, O_RDONLY | O_NONBLOCK); /* neither read nor write asked for */
170 if (fsetversion(name, gp->version) != 0) 171 if (fd >= 0) {
171 bb_perror_msg("setting %s on %s", "version", name); 172 int r;
172 173
173 if (gp->flags & OPT_SET_PROJ) 174 if (gp->flags & OPT_SET_VER) {
174 if (fsetprojid(name, gp->projid) != 0) 175 r = ioctl(fd, EXT2_IOC_SETVERSION, &gp->version);
175 bb_perror_msg("setting %s on %s", "project ID", name); 176 if (r != 0)
177 bb_perror_msg("setting %s on %s", "version", name);
178 }
176 179
177 if (gp->flags & OPT_SET) { 180 if (gp->flags & OPT_SET_PROJ) {
178 fsflags = gp->af; 181 struct ext2_fsxattr fsxattr;
179 } else { 182 r = ioctl(fd, EXT2_IOC_FSGETXATTR, &fsxattr);
180 if (fgetflags(name, &fsflags) != 0) { 183 if (r != 0)
181 bb_perror_msg("reading flags on %s", name); 184 bb_perror_msg("getting %s on %s", "project ID", name);
182 goto skip_setflags; 185 fsxattr.fsx_projid = gp->projid;
186 r = ioctl(fd, EXT2_IOC_FSSETXATTR, &fsxattr);
187 if (r != 0)
188 bb_perror_msg("setting %s on %s", "project ID", name);
183 } 189 }
184 /*if (gp->flags & OPT_REM) - not needed, rf is zero otherwise */ 190
185 fsflags &= ~gp->rf; 191 if (gp->flags & OPT_SET) {
186 /*if (gp->flags & OPT_ADD) - not needed, af is zero otherwise */ 192 fsflags = gp->af;
187 fsflags |= gp->af; 193 } else {
194 r = ioctl(fd, EXT2_IOC_GETFLAGS, &fsflags);
195 if (r != 0) {
196 bb_perror_msg("getting %s on %s", "flags", name);
197 goto skip_setflags;
198 }
199 /*if (gp->flags & OPT_REM) - not needed, rf is zero otherwise */
200 fsflags &= ~gp->rf;
201 /*if (gp->flags & OPT_ADD) - not needed, af is zero otherwise */
202 fsflags |= gp->af;
188// What is this? And why it's not done for SET case? 203// What is this? And why it's not done for SET case?
189 if (!S_ISDIR(st.st_mode)) 204 if (!S_ISDIR(st.st_mode))
190 fsflags &= ~EXT2_DIRSYNC_FL; 205 fsflags &= ~EXT2_DIRSYNC_FL;
206 }
207 r = ioctl(fd, EXT2_IOC_SETFLAGS, &fsflags);
208 if (r != 0)
209 bb_perror_msg("setting %s on %s", "flags", name);
210 skip_setflags:
211 close(fd);
191 } 212 }
192 if (fsetflags(name, fsflags) != 0)
193 bb_perror_msg("setting flags on %s", name);
194 213
195 skip_setflags:
196 if (gp->recursive && S_ISDIR(st.st_mode)) 214 if (gp->recursive && S_ISDIR(st.st_mode))
197 iterate_on_dir(name, chattr_dir_proc, gp); 215 iterate_on_dir(name, chattr_dir_proc, gp);
198} 216}
diff --git a/e2fsprogs/e2fs_lib.c b/e2fsprogs/e2fs_lib.c
index 8d56add2d..0ec4eb2f2 100644
--- a/e2fsprogs/e2fs_lib.c
+++ b/e2fsprogs/e2fs_lib.c
@@ -8,8 +8,6 @@
8#include "libbb.h" 8#include "libbb.h"
9#include "e2fs_lib.h" 9#include "e2fs_lib.h"
10 10
11#define HAVE_EXT2_IOCTLS 1
12
13#if INT_MAX == LONG_MAX 11#if INT_MAX == LONG_MAX
14#define IF_LONG_IS_SAME(...) __VA_ARGS__ 12#define IF_LONG_IS_SAME(...) __VA_ARGS__
15#define IF_LONG_IS_WIDER(...) 13#define IF_LONG_IS_WIDER(...)
@@ -18,14 +16,6 @@
18#define IF_LONG_IS_WIDER(...) __VA_ARGS__ 16#define IF_LONG_IS_WIDER(...) __VA_ARGS__
19#endif 17#endif
20 18
21static void close_silently(int fd)
22{
23 int e = errno;
24 close(fd);
25 errno = e;
26}
27
28
29/* Iterate a function on each entry of a directory */ 19/* Iterate a function on each entry of a directory */
30int iterate_on_dir(const char *dir_name, 20int iterate_on_dir(const char *dir_name,
31 int FAST_FUNC (*func)(const char *, struct dirent *, void *), 21 int FAST_FUNC (*func)(const char *, struct dirent *, void *),
@@ -45,113 +35,6 @@ int iterate_on_dir(const char *dir_name,
45 return 0; 35 return 0;
46} 36}
47 37
48
49/* Get/set a file version on an ext2 file system */
50int fgetsetversion(const char *name, unsigned long *get_version, unsigned long set_version)
51{
52#if HAVE_EXT2_IOCTLS
53 int fd, r;
54 IF_LONG_IS_WIDER(unsigned ver;)
55
56 fd = open(name, O_RDONLY | O_NONBLOCK);
57 if (fd == -1)
58 return -1;
59 if (!get_version) {
60 IF_LONG_IS_WIDER(
61 ver = (unsigned) set_version;
62 r = ioctl(fd, EXT2_IOC_SETVERSION, &ver);
63 )
64 IF_LONG_IS_SAME(
65 r = ioctl(fd, EXT2_IOC_SETVERSION, (void*)&set_version);
66 )
67 } else {
68 IF_LONG_IS_WIDER(
69 r = ioctl(fd, EXT2_IOC_GETVERSION, &ver);
70 *get_version = ver;
71 )
72 IF_LONG_IS_SAME(
73 r = ioctl(fd, EXT2_IOC_GETVERSION, (void*)get_version);
74 )
75 }
76 close_silently(fd);
77 return r;
78#else /* ! HAVE_EXT2_IOCTLS */
79 errno = EOPNOTSUPP;
80 return -1;
81#endif /* ! HAVE_EXT2_IOCTLS */
82}
83
84int fgetsetprojid(const char *name, uint32_t *get, uint32_t set)
85{
86#if HAVE_EXT2_IOCTLS
87 struct ext2_fsxattr fsxattr;
88 int fd, r;
89
90 fd = open(name, O_RDONLY | O_NONBLOCK);
91 if (fd == -1)
92 return -1;
93 r = ioctl(fd, EXT2_IOC_FSGETXATTR, &fsxattr);
94 /* note: ^^^ may fail in 32-bit userspace on 64-bit kernel (seen on 4.12.0) */
95 if (r == 0) {
96 if (get) {
97 *get = fsxattr.fsx_projid;
98 } else {
99 fsxattr.fsx_projid = set;
100 r = ioctl(fd, EXT2_IOC_FSSETXATTR, &fsxattr);
101 }
102 }
103 close_silently(fd);
104 return r;
105#else /* ! HAVE_EXT2_IOCTLS */
106 errno = EOPNOTSUPP;
107 return -1;
108#endif /* ! HAVE_EXT2_IOCTLS */
109}
110
111/* Get/set a file flags on an ext2 file system */
112int fgetsetflags(const char *name, unsigned long *get_flags, unsigned long set_flags)
113{
114#if HAVE_EXT2_IOCTLS
115 struct stat buf;
116 int fd, r;
117 IF_LONG_IS_WIDER(unsigned f;)
118
119 if (stat(name, &buf) == 0 /* stat is ok */
120 && !S_ISREG(buf.st_mode) && !S_ISDIR(buf.st_mode)
121 ) {
122 goto notsupp;
123 }
124 fd = open(name, O_RDONLY | O_NONBLOCK); /* neither read nor write asked for */
125 if (fd == -1)
126 return -1;
127
128 if (!get_flags) {
129 IF_LONG_IS_WIDER(
130 f = (unsigned) set_flags;
131 r = ioctl(fd, EXT2_IOC_SETFLAGS, &f);
132 )
133 IF_LONG_IS_SAME(
134 r = ioctl(fd, EXT2_IOC_SETFLAGS, (void*)&set_flags);
135 )
136 } else {
137 IF_LONG_IS_WIDER(
138 r = ioctl(fd, EXT2_IOC_GETFLAGS, &f);
139 *get_flags = f;
140 )
141 IF_LONG_IS_SAME(
142 r = ioctl(fd, EXT2_IOC_GETFLAGS, (void*)get_flags);
143 )
144 }
145
146 close_silently(fd);
147 return r;
148 notsupp:
149#endif /* HAVE_EXT2_IOCTLS */
150 errno = EOPNOTSUPP;
151 return -1;
152}
153
154
155/* Print file attributes on an ext2 file system */ 38/* Print file attributes on an ext2 file system */
156const uint32_t e2attr_flags_value[] ALIGN4 = { 39const uint32_t e2attr_flags_value[] ALIGN4 = {
157#ifdef ENABLE_COMPRESSION 40#ifdef ENABLE_COMPRESSION
@@ -215,7 +98,7 @@ static const char e2attr_flags_lname[] ALIGN1 =
215 "Verity" "\0" 98 "Verity" "\0"
216 /* Another trailing NUL is added by compiler */; 99 /* Another trailing NUL is added by compiler */;
217 100
218void print_e2flags(FILE *f, unsigned long flags, unsigned options) 101void print_e2flags(FILE *f, unsigned flags, unsigned options)
219{ 102{
220 const uint32_t *fv; 103 const uint32_t *fv;
221 const char *fn; 104 const char *fn;
diff --git a/e2fsprogs/e2fs_lib.h b/e2fsprogs/e2fs_lib.h
index 82a1581cb..1a5d092c0 100644
--- a/e2fsprogs/e2fs_lib.h
+++ b/e2fsprogs/e2fs_lib.h
@@ -16,25 +16,10 @@ int iterate_on_dir(const char *dir_name,
16 int FAST_FUNC (*func)(const char *, struct dirent *, void *), 16 int FAST_FUNC (*func)(const char *, struct dirent *, void *),
17 void *private); 17 void *private);
18 18
19/* Get/set a file version on an ext2 file system */
20int fgetsetversion(const char *name, unsigned long *get_version, unsigned long set_version);
21#define fgetversion(name, version) fgetsetversion(name, version, 0)
22#define fsetversion(name, version) fgetsetversion(name, NULL, version)
23
24/* Get/set a file project ID on an ext2 file system */
25int fgetsetprojid(const char *name, uint32_t *get, uint32_t set);
26#define fgetprojid(name, projid) fgetsetprojid(name, projid, 0)
27#define fsetprojid(name, projid) fgetsetprojid(name, NULL, projid)
28
29/* Get/set a file flags on an ext2 file system */
30int fgetsetflags(const char *name, unsigned long *get_flags, unsigned long set_flags);
31#define fgetflags(name, flags) fgetsetflags(name, flags, 0)
32#define fsetflags(name, flags) fgetsetflags(name, NULL, flags)
33
34/* Must be 1 for compatibility with 'int long_format'. */ 19/* Must be 1 for compatibility with 'int long_format'. */
35#define PFOPT_LONG 1 20#define PFOPT_LONG 1
36/* Print file attributes on an ext2 file system */ 21/* Print file attributes on an ext2 file system */
37void print_e2flags(FILE *f, unsigned long flags, unsigned options); 22void print_e2flags(FILE *f, unsigned flags, unsigned options);
38 23
39extern const uint32_t e2attr_flags_value[]; 24extern const uint32_t e2attr_flags_value[];
40extern const char e2attr_flags_sname[]; 25extern const char e2attr_flags_sname[];
diff --git a/e2fsprogs/lsattr.c b/e2fsprogs/lsattr.c
index 9b035f584..3972ce8a7 100644
--- a/e2fsprogs/lsattr.c
+++ b/e2fsprogs/lsattr.c
@@ -46,25 +46,35 @@ enum {
46 46
47static void list_attributes(const char *name) 47static void list_attributes(const char *name)
48{ 48{
49 unsigned long fsflags; 49 unsigned fsflags;
50 int fd, r;
50 51
51 if (fgetflags(name, &fsflags) != 0) 52 fd = open_or_warn(name, O_RDONLY | O_NONBLOCK); /* neither read nor write asked for */
52 goto read_err; 53 if (fd < 0) /* for example, dangling links */
54 return;
53 55
54 if (option_mask32 & OPT_PROJID) { 56 if (option_mask32 & OPT_PROJID) {
55 uint32_t p; 57 struct ext2_fsxattr fsxattr;
56 if (fgetprojid(name, &p) != 0) 58 r = ioctl(fd, EXT2_IOC_FSGETXATTR, &fsxattr);
59 if (r != 0)
57 goto read_err; 60 goto read_err;
58 printf("%5lu ", (unsigned long)p); 61 printf("%5u ", (unsigned)fsxattr.fsx_projid);
59 } 62 }
60 63
61 if (option_mask32 & OPT_GENERATION) { 64 if (option_mask32 & OPT_GENERATION) {
62 unsigned long generation; 65 unsigned generation;
63 if (fgetversion(name, &generation) != 0) 66 r = ioctl(fd, EXT2_IOC_GETVERSION, &generation);
67 if (r != 0)
64 goto read_err; 68 goto read_err;
65 printf("%-10lu ", generation); 69 printf("%-10u ", generation);
66 } 70 }
67 71
72 r = ioctl(fd, EXT2_IOC_GETFLAGS, &fsflags);
73 if (r != 0)
74 goto read_err;
75
76 close(fd);
77
68 if (option_mask32 & OPT_PF_LONG) { 78 if (option_mask32 & OPT_PF_LONG) {
69 printf("%-28s ", name); 79 printf("%-28s ", name);
70 print_e2flags(stdout, fsflags, PFOPT_LONG); 80 print_e2flags(stdout, fsflags, PFOPT_LONG);
@@ -77,6 +87,7 @@ static void list_attributes(const char *name)
77 return; 87 return;
78 read_err: 88 read_err:
79 bb_perror_msg("reading %s", name); 89 bb_perror_msg("reading %s", name);
90 close(fd);
80} 91}
81 92
82static int FAST_FUNC lsattr_dir_proc(const char *dir_name, 93static int FAST_FUNC lsattr_dir_proc(const char *dir_name,
diff --git a/shell/ash.c b/shell/ash.c
index bee81920a..2eac6e113 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -12751,7 +12751,7 @@ parsesub: {
12751 do { 12751 do {
12752 STPUTC(c, out); 12752 STPUTC(c, out);
12753 c = pgetc_eatbnl(); 12753 c = pgetc_eatbnl();
12754 } while (!subtype && isdigit(c)); 12754 } while ((subtype == 0 || subtype == VSLENGTH) && isdigit(c));
12755 } else if (c != '}') { 12755 } else if (c != '}') {
12756 /* $[{[#]]<specialchar>[}] */ 12756 /* $[{[#]]<specialchar>[}] */
12757 int cc = c; 12757 int cc = c;
@@ -12781,11 +12781,6 @@ parsesub: {
12781 } else 12781 } else
12782 goto badsub; 12782 goto badsub;
12783 12783
12784 if (c != '}' && subtype == VSLENGTH) {
12785 /* ${#VAR didn't end with } */
12786 goto badsub;
12787 }
12788
12789 if (subtype == 0) { 12784 if (subtype == 0) {
12790 static const char types[] ALIGN1 = "}-+?="; 12785 static const char types[] ALIGN1 = "}-+?=";
12791 /* ${VAR...} but not $VAR or ${#VAR} */ 12786 /* ${VAR...} but not $VAR or ${#VAR} */
@@ -12842,6 +12837,8 @@ parsesub: {
12842#endif 12837#endif
12843 } 12838 }
12844 } else { 12839 } else {
12840 if (subtype == VSLENGTH && c != '}')
12841 subtype = 0;
12845 badsub: 12842 badsub:
12846 pungetc(); 12843 pungetc();
12847 } 12844 }