← Commit list

9468ea06d

Denys Vlasenko
Denys Vlasenko
2021-06-24
SUCCESS Duration: 154s

Subject

lsattr,chattr: do not open e.g. device files unless asked directly; do not follow links

Binary

No binary (build failed)

Architecture & Compiler Flags

Architecture: x86_64-linux-gnu Compiler: gcc (Ubuntu 11.4.0-1ubuntu1~22.04.3) 11.4.0

—

Build Log

(log yok)

Commit Diff GitHub →

e2fsprogs/chattr.c+6 -3
@@ -162,8 +162,6 @@ static void change_attributes(const char *name, struct globals *gp)
bb_perror_msg("can't stat '%s'", name);
return;
}
- if (S_ISLNK(st.st_mode) && gp->recursive)
- return;
/* Don't try to open device files, fifos etc. We probably
* ought to display an error if the file was explicitly given
@@ -172,7 +170,12 @@ 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;
- fd = open_or_warn(name, O_RDONLY | O_NONBLOCK); /* neither read nor write asked for */
+ /* There is no way to run needed ioctls on a symlink.
+ * open(O_PATH | O_NOFOLLOW) _can_ be used to get a fd referring to the symlink,
+ * but ioctls fail on such a fd (tried on 4.12.0 kernel).
+ * e2fsprogs-1.46.2 uses open(O_NOFOLLOW), it fails on symlinks.
+ */
+ fd = open_or_warn(name, O_RDONLY | O_NONBLOCK | O_NOCTTY | O_NOFOLLOW);
if (fd >= 0) {
int r;
e2fsprogs/lsattr.c+12 -3
@@ -49,8 +49,13 @@ static void list_attributes(const char *name)
unsigned fsflags;
int fd, r;
- fd = open_or_warn(name, O_RDONLY | O_NONBLOCK); /* neither read nor write asked for */
- if (fd < 0) /* for example, dangling links */
+ /* There is no way to run needed ioctls on a symlink.
+ * open(O_PATH | O_NOFOLLOW) _can_ be used to get a fd referring to the symlink,
+ * but ioctls fail on such a fd (tried on 4.12.0 kernel).
+ * e2fsprogs-1.46.2 uses open(O_NOFOLLOW), it fails on symlinks.
+ */
+ fd = open_or_warn(name, O_RDONLY | O_NONBLOCK | O_NOCTTY | O_NOFOLLOW);
+ if (fd < 0)
return;
if (option_mask32 & OPT_PROJID) {
@@ -102,8 +107,12 @@ static int FAST_FUNC lsattr_dir_proc(const char *dir_name,
if (lstat(path, &st) != 0)
bb_perror_msg("can't stat '%s'", path);
+
else if (de->d_name[0] != '.' || (option_mask32 & OPT_ALL)) {
- list_attributes(path);
+ /* Don't try to open device files, fifos etc */
+ if (S_ISREG(st.st_mode) || S_ISLNK(st.st_mode) || S_ISDIR(st.st_mode))
+ list_attributes(path);
+
if (S_ISDIR(st.st_mode) && (option_mask32 & OPT_RECUR)
&& !DOT_OR_DOTDOT(de->d_name)
) {