Bug#986332: lsattr on certiain files in /dev results in "stack smashing detected"

2021-07-21 Thread Theodore Ts'o
tags 986332 +pending
thanks

The following commit should fix things; it will be in the next release
of e2fsprogs.

- Ted

commit a3f844da91f0c01209a5d778a5af57fabe245332
Author: Theodore Ts'o 
Date:   Fri Jul 16 22:31:26 2021 -0400

libe2p: use stat to prevent calling EXT2_IOC_[GS]ETFLAGS on devices

Some devices can react badly to the EXT2_IOC_[GS]ETFLAGS ioctls, since
ioctl codes are not guaranteed to be unique across different device
drivers and file systems.

Addresses-Debian-Bug: #986332
Signed-off-by: Theodore Ts'o 

diff --git a/lib/e2p/fgetflags.c b/lib/e2p/fgetflags.c
index 93e130c6..24a7166b 100644
--- a/lib/e2p/fgetflags.c
+++ b/lib/e2p/fgetflags.c
@@ -79,14 +79,26 @@ int fgetflags (const char * name, unsigned long * flags)
*flags = f;
return (save_errno);
 #elif HAVE_EXT2_IOCTLS
+   struct stat buf;
int fd, r, f, save_errno = 0;
 
+   if (!stat(name, &buf) &&
+   !S_ISREG(buf.st_mode) && !S_ISDIR(buf.st_mode)) {
+   errno = EOPNOTSUPP;
+   return -1;
+   }
fd = open(name, OPEN_FLAGS);
if (fd == -1) {
if (errno == ELOOP || errno == ENXIO)
errno = EOPNOTSUPP;
return -1;
}
+   if (!fstat(fd, &buf) &&
+   !S_ISREG(buf.st_mode) && !S_ISDIR(buf.st_mode)) {
+   close(fd);
+   errno = EOPNOTSUPP;
+   return -1;
+   }
r = ioctl(fd, EXT2_IOC_GETFLAGS, &f);
if (r == -1) {
if (errno == ENOTTY)
diff --git a/lib/e2p/fsetflags.c b/lib/e2p/fsetflags.c
index 6455e386..d865d243 100644
--- a/lib/e2p/fsetflags.c
+++ b/lib/e2p/fsetflags.c
@@ -80,14 +80,26 @@ int fsetflags (const char * name, unsigned long flags)
int f = (int) flags;
return syscall(SYS_fsctl, name, EXT2_IOC_SETFLAGS, &f, 0);
 #elif HAVE_EXT2_IOCTLS
+   struct stat buf;
int fd, r, f, save_errno = 0;
 
+   if (!stat(name, &buf) &&
+   !S_ISREG(buf.st_mode) && !S_ISDIR(buf.st_mode)) {
+   errno = EOPNOTSUPP;
+   return -1;
+   }
fd = open(name, OPEN_FLAGS);
if (fd == -1) {
if (errno == ELOOP || errno == ENXIO)
errno = EOPNOTSUPP;
return -1;
}
+   if (!fstat(fd, &buf) &&
+   !S_ISREG(buf.st_mode) && !S_ISDIR(buf.st_mode)) {
+   close(fd);
+   errno = EOPNOTSUPP;
+   return -1;
+   }
f = (int) flags;
r = ioctl(fd, EXT2_IOC_SETFLAGS, &f);
if (r == -1) {



Bug#986332: lsattr on certiain files in /dev results in "stack smashing detected"

2021-04-24 Thread Chris Hofstaedtler
* Guillem Jover  [210424 16:53]:
> So, while I was trying to debug this in aide on my server, after
> having added few aide ignore entries for specific devices, at some
> point while within gdb, I suddenly lost the ssh connection as the
> server suddenly rebooted, for which I was very puzzled, and paranoid!

I tried to reproduce this, and stumbled upon the watchdog and
watchdog0 files. If they are the problem, well...

  echo > /dev/watchdog
  sleep 30
  # notice your machine is rebooting

That would probably by design. I guess its well understood that
writing to random "files" in /dev is a bad plan; it appears
-opening- then is, too.

Chris



Bug#986332: lsattr on certiain files in /dev results in "stack smashing detected"

2021-04-24 Thread Guillem Jover
[ Just upgraded my server to bullseye, and aide started to fail, now
  noticed this report, after also hitting the error via lsattr.  ]

On Mon, 2021-04-05 at 17:35:54 -0400, Theodore Ts'o wrote:
> On Mon, Apr 05, 2021 at 12:46:48AM +0200, Chris Hofstaedtler wrote:
> > AFAICT, for /dev/dri/card0 the ioctl ends up in the kernel's
> > drm_ioctl [2], which will blindly call copy_to_user assuming the
> > output size is the same as the input size (8 bytes). This is wrong
> > for FS_IOC_GETFLAGS, at least for normal files.
> > 
> > Maybe the best thing is to put the lstat check back in?
> > Or maybe lsattr should expect that the kernel might actually use the
> > 8 bytes? I have checked various fs ioctl functions, and they all
> > seem to return 4 bytes, except for orangefs [3] ...
> 
> What's going on is that apparently there is an overlap between the
> ioctl code FS_IOC_GETFLAGS (aka EXT2_IOC_GETFLAGS) and some ioctl code
> used by device driver responding to /dev/dri/card0, in drm_ioctl.  I
> had the vague thought that at some point, we might be able to set and
> get file system flags on device files, which is why I removed the
> lstat check.  I wasn't counting on the fact that there would be ioctl
> code collisions --- which in retrospect, was hopelessly optimistic on
> my part.

So, while I was trying to debug this in aide on my server, after
having added few aide ignore entries for specific devices, at some
point while within gdb, I suddenly lost the ssh connection as the
server suddenly rebooted, for which I was very puzzled, and paranoid!

What you mention above, of colliding IOCTL codes would actually
explain the cause of the reboot, if it ends up hitting an IOCTL
setting some wrong state somewhere.

I also noticed this being an issue with at least /dev/kfd, but I'm not
very eager to try this again there to determine what other devices
this might affect, if this can result in sending random commands to
random devices on the live server. :/

> So yeah, we need to put the lstat check back in.

> Fortunately, the fortify compile option detectsd the stack smash, so
> it's not critical that we get this fixed ASAP, but we ultimately do
> need to put the lstat check back in.

I'd appreciate if this could be done sooner rather than later, and it
seems to me it probably deserves a higher severity.

(I've for now disabled aide to avoid any crashes or strange behavior.)

Thanks,
Guillem



Bug#986332: lsattr on certiain files in /dev results in "stack smashing detected"

2021-04-05 Thread Theodore Ts'o
On Mon, Apr 05, 2021 at 12:46:48AM +0200, Chris Hofstaedtler wrote:
> 
> AFAICT, for /dev/dri/card0 the ioctl ends up in the kernel's
> drm_ioctl [2], which will blindly call copy_to_user assuming the
> output size is the same as the input size (8 bytes). This is wrong
> for FS_IOC_GETFLAGS, at least for normal files.
> 
> Maybe the best thing is to put the lstat check back in?
> Or maybe lsattr should expect that the kernel might actually use the
> 8 bytes? I have checked various fs ioctl functions, and they all
> seem to return 4 bytes, except for orangefs [3] ...

What's going on is that apparently there is an overlap between the
ioctl code FS_IOC_GETFLAGS (aka EXT2_IOC_GETFLAGS) and some ioctl code
used by device driver responding to /dev/dri/card0, in drm_ioctl.  I
had the vague thought that at some point, we might be able to set and
get file system flags on device files, which is why I removed the
lstat check.  I wasn't counting on the fact that there would be ioctl
code collisions --- which in retrospect, was hopelessly optimistic on
my part.

So yeah, we need to put the lstat check back in.

I checked fs/orange/file.c and it is also using 4 bytes (int is always
32 bits even on 64-bit platforms):

if (cmd == FS_IOC_GETFLAGS) {
ret = orangefs_getflags(inode, &uval);
if (ret)
return ret;
gossip_debug(GOSSIP_FILE_DEBUG,
 "orangefs_ioctl: FS_IOC_GETFLAGS: %llu\n",
 (unsigned long long)uval);
return put_user(uval, (int __user *)arg);
  ^

% cat /tmp/foo.c
#include 
#include 

int main(int argc, char **argv)
{
printf("size of int: %d\n", sizeof(int));
return 0;
}
% cc -o /tmp/foo /tmp/foo.c
% /tmp/foo
size of int: 4

Fortunately, the fortify compile option detectsd the stack smash, so
it's not critical that we get this fixed ASAP, but we ultimately do
need to put the lstat check back in.

- Ted



Bug#986332: lsattr on certiain files in /dev results in "stack smashing detected"

2021-04-04 Thread Bernhard Übelacker

Hello Chris,


Am 04.04.21 um 22:33 schrieb Chris Hofstaedtler:

Hello Bernhard, Marc,



Some more questions:
1) which kernel version is this?


My test was just inside a temporary VM with current testing.
But I can still reproduce this with current testing kernel at the host too:
Linux rechner 5.10.0-5-amd64 #1 SMP Debian 5.10.24-1 (2021-03-19) x86_64 
GNU/Linux



2) /dev/dri is on tmpfs?


bernhard@rechner:~$ mount
udev on /dev type devtmpfs 
(rw,nosuid,noexec,relatime,size=8075552k,nr_inodes=201,mode=755)
...


Kind regards,
Bernhard



Bug#986332: lsattr on certiain files in /dev results in "stack smashing detected"

2021-04-04 Thread Chris Hofstaedtler
Hi Marc,

thanks for the followup.

* Marc Haber  [210404 22:03]:
> On Sun, Apr 04, 2021 at 10:33:46PM +0200, Chris Hofstaedtler wrote:
> > * Bernhard Übelacker  [210404 20:32]:
> > > Dear Maintainer,
> > > tried to locate the exact smashing.
> > > It looks like the ioctl(EXT2_IOC_GETFLAGS) takes an int* parameter,
> > > but writes 8 bytes instead of just sizeof(int) to the given address.
> > 
> > Some more questions:
> > 1) which kernel version is this?
> > 2) /dev/dri is on tmpfs?
> 
> 1 [2/4021]mh@testsid85:~ $ sudo lsattr /dev/dri/card0 
> [sudo] password for mh: 
> *** stack smashing detected ***: terminated
> Aborted
> 134 [3/4022]mh@testsid85:~ $ uname -a
> Linux testsid85 5.10.0-5-amd64 #1 SMP Debian 5.10.26-1 (2021-03-27) x86_64 
> GNU/Linux
> [4/4023]mh@testsid85:~ $ stat -f /dev/dri
>   File: "/dev/dri"
> ID: 0Namelen: 255 Type: tmpfs
> Block size: 4096   Fundamental block size: 4096
> Blocks: Total: 40336  Free: 40336  Available: 40336
> Inodes: Total: 40336  Free: 39600
> [5/4024]mh@testsid85:~ $ 
> 
> Other /dev device nods can be lsattr'd without error.

I was wondering about changes since buster, and indeed:

Upstream commit 40ea4628 [1] removes the lstat call which shielded
the ioctl call later on. On buster, lsattr /dev/dri/card0 just
gives:
  lsattr: Operation not supported While reading flags on /dev/dri/card0

(Even with Linux 5.10.0-0.bpo.3-amd64.)


Now, for the actual issue:

AFAICT, for /dev/dri/card0 the ioctl ends up in the kernel's
drm_ioctl [2], which will blindly call copy_to_user assuming the
output size is the same as the input size (8 bytes). This is wrong
for FS_IOC_GETFLAGS, at least for normal files.

Maybe the best thing is to put the lstat check back in?
Or maybe lsattr should expect that the kernel might actually use the
8 bytes? I have checked various fs ioctl functions, and they all
seem to return 4 bytes, except for orangefs [3] ... 

Chris

[1] 
https://git.kernel.org/pub/scm/fs/ext2/e2fsprogs.git/commit/lib/e2p/fgetflags.c?id=40ea4628ba1b55f8eba311f12399d039698dbeeb
[2] 
https://elixir.bootlin.com/linux/v5.10.27/source/drivers/gpu/drm/drm_ioctl.c#L888
[3] https://elixir.bootlin.com/linux/v5.10.27/source/fs/orangefs/file.c#L378



Bug#986332: lsattr on certiain files in /dev results in "stack smashing detected"

2021-04-04 Thread Marc Haber
Hi Chris,

On Sun, Apr 04, 2021 at 10:33:46PM +0200, Chris Hofstaedtler wrote:
> * Bernhard Übelacker  [210404 20:32]:
> > Dear Maintainer,
> > tried to locate the exact smashing.
> > It looks like the ioctl(EXT2_IOC_GETFLAGS) takes an int* parameter,
> > but writes 8 bytes instead of just sizeof(int) to the given address.
> 
> Some more questions:
> 1) which kernel version is this?
> 2) /dev/dri is on tmpfs?

1 [2/4021]mh@testsid85:~ $ sudo lsattr /dev/dri/card0 
[sudo] password for mh: 
*** stack smashing detected ***: terminated
Aborted
134 [3/4022]mh@testsid85:~ $ uname -a
Linux testsid85 5.10.0-5-amd64 #1 SMP Debian 5.10.26-1 (2021-03-27) x86_64 
GNU/Linux
[4/4023]mh@testsid85:~ $ stat -f /dev/dri
  File: "/dev/dri"
ID: 0Namelen: 255 Type: tmpfs
Block size: 4096   Fundamental block size: 4096
Blocks: Total: 40336  Free: 40336  Available: 40336
Inodes: Total: 40336  Free: 39600
[5/4024]mh@testsid85:~ $ 

Other /dev device nods can be lsattr'd without error.

Greetings
Marc

-- 
-
Marc Haber | "I don't trust Computers. They | Mailadresse im Header
Leimen, Germany|  lose things."Winona Ryder | Fon: *49 6224 1600402
Nordisch by Nature |  How to make an American Quilt | Fax: *49 6224 1600421



Bug#986332: lsattr on certiain files in /dev results in "stack smashing detected"

2021-04-04 Thread Chris Hofstaedtler
Hello Bernhard, Marc,

* Bernhard Übelacker  [210404 20:32]:
> Dear Maintainer,
> tried to locate the exact smashing.
> It looks like the ioctl(EXT2_IOC_GETFLAGS) takes an int* parameter,
> but writes 8 bytes instead of just sizeof(int) to the given address.

Some more questions:
1) which kernel version is this?
2) /dev/dri is on tmpfs?

Chris



Bug#986332: lsattr on certiain files in /dev results in "stack smashing detected"

2021-04-04 Thread Bernhard Übelacker

Dear Maintainer,
tried to locate the exact smashing.
It looks like the ioctl(EXT2_IOC_GETFLAGS) takes an int* parameter,
but writes 8 bytes instead of just sizeof(int) to the given address.

Kind regards,
Bernhard


Old value = (void *) 0xf759b62c03711000
New value = (void *) 0xf759b62c
0x77ec0cc7 in ioctl () at ../sysdeps/unix/syscall-template.S:120
120 ../sysdeps/unix/syscall-template.S: Datei oder Verzeichnis nicht 
gefunden.
1: x/i $pc
=> 0x77ec0cc7 :cmp$0xf001,%rax
(gdb) bt
#0  0x77ec0cc7 in ioctl () at ../sysdeps/unix/syscall-template.S:120
#1  0x77fbcb17 in fgetflags (name=name@entry=0x7fffe83f 
"/dev/dri/card0", flags=flags@entry=0x7fffe3e0) at 
../../../../lib/e2p/fgetflags.c:90
#2  0x54d5 in list_attributes (name=name@entry=0x7fffe83f 
"/dev/dri/card0") at ../../../misc/lsattr.c:85
#3  0x56c9 in lsattr_args (name=0x7fffe83f 
"/dev/dri/card0") at ../../../misc/lsattr.c:134
#4  0x5369 in main (argc=, argv=) 
at ../../../misc/lsattr.c:221

https://sources.debian.org/src/e2fsprogs/1.46.2-1/lib/e2p/fgetflags.c/#L90
https://git.kernel.org/pub/scm/fs/ext2/e2fsprogs.git/tree/lib/e2p/fgetflags.c#n90

# single-use Bullseye/testing amd64 qemu VM 2021-04-04

echo "set enable-bracketed-paste off" >> /etc/inputrc; bash

apt update

# to speedup testing
mv /etc/manpath.config /etc/manpath.config.renamed
apt install libeatmydata1
export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libeatmydata.so

apt dist-upgrade
apt install systemd-coredump gdb valgrind \
e2fsprogs-dbgsym libext2fs2-dbgsym
.










benutzer@debian:~$ lsattr /dev/dri/card0
*** stack smashing detected ***: terminated
Abgebrochen (Speicherabzug geschrieben)

root@debian:~# coredumpctl list
TIMEPID   UID   GID SIG COREFILE  EXE
Sun 2021-04-04 14:22:59 CEST   1921  1000  1000   6 present   /usr/bin/lsattr

root@debian:~# coredumpctl gdb 1921
   PID: 1921 (lsattr)
   UID: 1000 (benutzer)
   GID: 1000 (benutzer)
Signal: 6 (ABRT)
 Timestamp: Sun 2021-04-04 14:22:59 CEST (50s ago)
  Command Line: lsattr /dev/dri/card0
Executable: /usr/bin/lsattr
 Control Group: /user.slice/user-1000.slice/session-3.scope
  Unit: session-3.scope
 Slice: user-1000.slice
   Session: 3
 Owner UID: 1000 (benutzer)
   Boot ID: de580d9e15564f17b195ec068c7129dc
Machine ID: 33f18f39d2a9438eb75b0ed52848afcd
  Hostname: debian
   Storage: 
/var/lib/systemd/coredump/core.lsattr.1000.de580d9e15564f17b195ec068c7129dc.1921.161753897900.zst
   Message: Process 1921 (lsattr) of user 1000 dumped core.

Stack trace of thread 1921:
#0  0x7f7ea4286ce1 __GI_raise (libc.so.6 + 0x3bce1)
#1  0x7f7ea4270537 __GI_abort (libc.so.6 + 0x25537)
#2  0x7f7ea42c9768 __libc_message (libc.so.6 + 0x7e768)
#3  0x7f7ea4358652 __GI___fortify_fail (libc.so.6 + 
0x10d652)
#4  0x7f7ea4358630 __stack_chk_fail (libc.so.6 + 0x10d630)
#5  0x7f7ea443bbd6 fgetflags (libe2p.so.2 + 0x3bd6)
#6  0x557d54ea24d5 n/a (lsattr + 0x14d5)
#7  0x557d54ea26c9 n/a (lsattr + 0x16c9)
#8  0x557d54ea2369 n/a (lsattr + 0x1369)
#9  0x7f7ea4271d0a __libc_start_main (libc.so.6 + 0x26d0a)
#10 0x557d54ea23ea n/a (lsattr + 0x13ea)


...
Core was generated by `lsattr /dev/dri/card0'.
Program terminated with signal SIGABRT, Aborted.
#0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
50  ../sysdeps/unix/sysv/linux/raise.c: Datei oder Verzeichnis nicht 
gefunden.
(gdb) bt
#0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
#1  0x7f7ea4270537 in __GI_abort () at abort.c:79
#2  0x7f7ea42c9768 in __libc_message (action=action@entry=do_abort, 
fmt=fmt@entry=0x7f7ea43d7c24 "*** %s ***: terminated\n") at 
../sysdeps/posix/libc_fatal.c:155
#3  0x7f7ea4358652 in __GI___fortify_fail (msg=msg@entry=0x7f7ea43d7c0c 
"stack smashing detected") at fortify_fail.c:26
#4  0x7f7ea4358630 in __stack_chk_fail () at stack_chk_fail.c:24
#5  0x7f7ea443bbd6 in fgetflags () from /lib/x86_64-linux-gnu/libe2p.so.2
#6  0x557d54ea24d5 in ?? ()
#7  0x557d54ea26c9 in ?? ()
#8  0x557d54ea2369 in ?? ()
#9  0x7f7ea4271d0a in __libc_start_main (main=0x557d54ea21d0, argc=2, 
argv=0x7ffda1e5c978, init=, fini=, 
rtld_fini=, stack_end=0x7ffda1e5c968) at ../csu/libc-start.c:308
#10 0x557d54ea23ea in ?? ()

(gdb) bt
#0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
#1  0x7f7ea4270537 in __GI_abort () at abort.c:79
#2  0x7f7ea42c9768 in __libc_message (action=action@entry=do_abort, 
fmt=fmt@entry=0x7f7ea43d7c24 "*** %s ***: terminated\n") at 
../

Bug#986332: lsattr on certiain files in /dev results in "stack smashing detected"

2021-04-03 Thread Marc Haber
Package: e2fsprogs
Version: 1.46.2-1
Severity: normal
File: /usr/bin/lsattr

Hi,

while debugging aide, I have stumbled upon a possible bug in lsattr or
one of the underlying libraries. Doing lsattr on /dev/dri/card0 results
in an abort with "stack smashing detected":

| root@testsid85:~# sudo lsattr /dev/dri/card0
| *** stack smashing detected ***: terminated
| Aborted

Similiar behavior is observed when aide is trying to read the ext2 attrs
of this file, so this is most probably a library issue.

I can provide a backtrace if it helps.

Greetings
Marc


-- System Information:
Debian Release: bullseye/sid
  APT prefers unstable
  APT policy: (500, 'unstable'), (500, 'testing'), (500, 'stable')
Architecture: amd64 (x86_64)

Kernel: Linux 5.10.0-5-amd64 (SMP w/2 CPU threads)
Locale: LANG=de_DE.utf8, LC_CTYPE=de_DE.utf8 (charmap=UTF-8), LANGUAGE=en
Shell: /bin/sh linked to /usr/bin/dash
Init: systemd (via /run/systemd/system)
LSM: AppArmor: enabled

Versions of packages e2fsprogs depends on:
ii  libblkid12.36.1-7
ii  libc62.31-11
ii  libcom-err2  1.46.2-1
ii  libext2fs2   1.46.2-1
ii  libss2   1.46.2-1
ii  libuuid1 2.36.1-7
ii  logsave  1.46.2-1

Versions of packages e2fsprogs recommends:
pn  e2fsprogs-l10n  

Versions of packages e2fsprogs suggests:
pn  e2fsck-static  
pn  fuse2fs
pn  gpart  
ii  parted 3.4-1

-- no debconf information