Bug #20240
closedlibradosstriper processes arbitrary printf placeholders in user input
0%
Description
I've discovered an issue with libradosstriper. It seems it's
processing the printf formatting placeholders in the objects name (soid),
which can lead to broken striped objects.
For example:
test ~# echo 123 > test # Capturing striper segment suffix prematurely: test ~# rados -p sata --striper put "testme%016llx_TEST" test # Now pool contains an object with a valid striped segment name, # and some garbage object test ~# rados -p sata ls testme%016llx_TEST.0000000000000000 testme0000000000000000_TEST.3030656d74736574 # All data is in the garbage object, but xattrs on valid one test ~# rados -p sata stat testme%016llx_TEST.0000000000000000 sata/testme%016llx_TEST.0000000000000000 mtime 2017-06-06 02:56:06.000000, size 0 test ~# rados -p sata stat testme0000000000000000_TEST.3030656d74736574 sata/testme0000000000000000_TEST.3030656d74736574 mtime 2017-06-06 02:56:06.000000, size 4 test ~# rados -p sata listxattr testme0000000000000000_TEST.3030656d74736574 (empty output) test ~# rados -p sata listxattr testme%016llx_TEST.0000000000000000 lock.striper.lock striper.layout.object_size striper.layout.stripe_count striper.layout.stripe_unit striper.size
Also it can crash the whole program which is linked to libradosstriper by using '%n' in the soid:
test ~# rados -p sata --striper put "testme%n" test *** %n in writable segment detected *** *** Caught signal (Aborted) ** in thread 7f8a59d40a40 thread_name:rados ceph version 10.2.5 (c461ee19ecbc0c5c330aca20f7392c9a00730367) 1: (()+0x47a72) [0x7f8a59b49a72] 2: (()+0x10330) [0x7f8a466bd330] 3: (gsignal()+0x37) [0x7f8a458fac37] 4: (abort()+0x148) [0x7f8a458fe028] 5: (()+0x732a4) [0x7f8a459372a4] 6: (__libc_fatal()+0x1e) [0x7f8a459372ce] 7: (_IO_vfprintf()+0x1e00) [0x7f8a4590fa40] 8: (__vsnprintf_chk()+0x95) [0x7f8a459cd165] 9: (__snprintf_chk()+0x78) [0x7f8a459cd0c8] 10: (Striper::file_to_extents(CephContext*, char const*, file_layout_t const*, unsigned long, unsigned long, unsigned long, std::map<object_t, std::vector<ObjectExtent, std::allocator<ObjectExtent> >, std::less<object_t>, std::allocator<std::pair<object_t const, std::vector<ObjectExtent, std::allocator<ObjectExtent> > > > >&, unsigned long)+0x341) [0x7f8a46b427d1] 11: (Striper::file_to_extents(CephContext*, char const*, file_layout_t const*, unsigned long, unsigned long, unsigned long, std::vector<ObjectExtent, std::allocator<ObjectExtent> >&, unsigned long)+0x46) [0x7f8a46b450d6] 12: (libradosstriper::RadosStriperImpl::internal_aio_write(std::string const&, libradosstriper::MultiAioCompletionImpl*, ceph::buffer::list const&, unsigned long, unsigned long, ceph_file_layout const&)+0x117) [0x7f8a46ab1687] 13: (libradosstriper::RadosStriperImpl::write_in_open_object(std::string const&, ceph_file_layout const&, std::string const&, ceph::buffer::list const&, unsigned long, unsigned long)+0xac) [0x7f8a46ab1a8c] 14: (libradosstriper::RadosStriperImpl::write(std::string const&, ceph::buffer::list const&, unsigned long, unsigned long)+0x6f) [0x7f8a46ab64af] 15: (main()+0x6911) [0x7f8a59b1adc1] 16: (__libc_start_main()+0xf5) [0x7f8a458e5f45] 17: (()+0x23597) [0x7f8a59b25597] 2017-06-06 03:10:36.766597 7f8a59d40a40 -1 *** Caught signal (Aborted) ** in thread 7f8a59d40a40 thread_name:rados ceph version 10.2.5 (c461ee19ecbc0c5c330aca20f7392c9a00730367) 1: (()+0x47a72) [0x7f8a59b49a72] 2: (()+0x10330) [0x7f8a466bd330] 3: (gsignal()+0x37) [0x7f8a458fac37] 4: (abort()+0x148) [0x7f8a458fe028] 5: (()+0x732a4) [0x7f8a459372a4] 6: (__libc_fatal()+0x1e) [0x7f8a459372ce] 7: (_IO_vfprintf()+0x1e00) [0x7f8a4590fa40] 8: (__vsnprintf_chk()+0x95) [0x7f8a459cd165] 9: (__snprintf_chk()+0x78) [0x7f8a459cd0c8] 10: (Striper::file_to_extents(CephContext*, char const*, file_layout_t const*, unsigned long, unsigned long, unsigned long, std::map<object_t, std::vector<ObjectExtent, std::allocator<ObjectExtent> >, std::less<object_t>, std::allocator<std::pair<object_t const, std::vector<ObjectExtent, std::allocator<ObjectExtent> > > > >&, unsigned long)+0x341) [0x7f8a46b427d1] 11: (Striper::file_to_extents(CephContext*, char const*, file_layout_t const*, unsigned long, unsigned long, unsigned long, std::vector<ObjectExtent, std::allocator<ObjectExtent> >&, unsigned long)+0x46) [0x7f8a46b450d6] 12: (libradosstriper::RadosStriperImpl::internal_aio_write(std::string const&, libradosstriper::MultiAioCompletionImpl*, ceph::buffer::list const&, unsigned long, unsigned long, ceph_file_layout const&)+0x117) [0x7f8a46ab1687] 13: (libradosstriper::RadosStriperImpl::write_in_open_object(std::string const&, ceph_file_layout const&, std::string const&, ceph::buffer::list const&, unsigned long, unsigned long)+0xac) [0x7f8a46ab1a8c] 14: (libradosstriper::RadosStriperImpl::write(std::string const&, ceph::buffer::list const&, unsigned long, unsigned long)+0x6f) [0x7f8a46ab64af] 15: (main()+0x6911) [0x7f8a59b1adc1] 16: (__libc_start_main()+0xf5) [0x7f8a458e5f45] 17: (()+0x23597) [0x7f8a59b25597] NOTE: a copy of the executable, or `objdump -rdS <executable>` is needed to interpret this. --- begin dump of recent events --- -14> 2017-06-06 03:10:36.707505 7f8a59d40a40 5 asok(0x7f8a59f16f90) register_command perfcounters_dump hook 0x7f8a59f1a2a0 -13> 2017-06-06 03:10:36.707542 7f8a59d40a40 5 asok(0x7f8a59f16f90) register_command 1 hook 0x7f8a59f1a2a0 -12> 2017-06-06 03:10:36.707554 7f8a59d40a40 5 asok(0x7f8a59f16f90) register_command perf dump hook 0x7f8a59f1a2a0 -11> 2017-06-06 03:10:36.707558 7f8a59d40a40 5 asok(0x7f8a59f16f90) register_command perfcounters_schema hook 0x7f8a59f1a2a0 -10> 2017-06-06 03:10:36.707563 7f8a59d40a40 5 asok(0x7f8a59f16f90) register_command 2 hook 0x7f8a59f1a2a0 -9> 2017-06-06 03:10:36.707566 7f8a59d40a40 5 asok(0x7f8a59f16f90) register_command perf schema hook 0x7f8a59f1a2a0 -8> 2017-06-06 03:10:36.707570 7f8a59d40a40 5 asok(0x7f8a59f16f90) register_command perf reset hook 0x7f8a59f1a2a0 -7> 2017-06-06 03:10:36.707592 7f8a59d40a40 5 asok(0x7f8a59f16f90) register_command config show hook 0x7f8a59f1a2a0 -6> 2017-06-06 03:10:36.707599 7f8a59d40a40 5 asok(0x7f8a59f16f90) register_command config set hook 0x7f8a59f1a2a0 -5> 2017-06-06 03:10:36.707610 7f8a59d40a40 5 asok(0x7f8a59f16f90) register_command config get hook 0x7f8a59f1a2a0 -4> 2017-06-06 03:10:36.707613 7f8a59d40a40 5 asok(0x7f8a59f16f90) register_command config diff hook 0x7f8a59f1a2a0 -3> 2017-06-06 03:10:36.707616 7f8a59d40a40 5 asok(0x7f8a59f16f90) register_command log flush hook 0x7f8a59f1a2a0 -2> 2017-06-06 03:10:36.707619 7f8a59d40a40 5 asok(0x7f8a59f16f90) register_command log dump hook 0x7f8a59f1a2a0 -1> 2017-06-06 03:10:36.707623 7f8a59d40a40 5 asok(0x7f8a59f16f90) register_command log reopen hook 0x7f8a59f1a2a0 0> 2017-06-06 03:10:36.766597 7f8a59d40a40 -1 *** Caught signal (Aborted) ** in thread 7f8a59d40a40 thread_name:rados ceph version 10.2.5 (c461ee19ecbc0c5c330aca20f7392c9a00730367) 1: (()+0x47a72) [0x7f8a59b49a72] 2: (()+0x10330) [0x7f8a466bd330] 3: (gsignal()+0x37) [0x7f8a458fac37] 4: (abort()+0x148) [0x7f8a458fe028] 5: (()+0x732a4) [0x7f8a459372a4] 6: (__libc_fatal()+0x1e) [0x7f8a459372ce] 7: (_IO_vfprintf()+0x1e00) [0x7f8a4590fa40] 8: (__vsnprintf_chk()+0x95) [0x7f8a459cd165] 9: (__snprintf_chk()+0x78) [0x7f8a459cd0c8] 10: (Striper::file_to_extents(CephContext*, char const*, file_layout_t const*, unsigned long, unsigned long, unsigned long, std::map<object_t, std::vector<ObjectExtent, std::allocator<ObjectExtent> >, std::less<object_t>, std::allocator<std::pair<object_t const, std::vector<ObjectExtent, std::allocator<ObjectExtent> > > > >&, unsigned long)+0x341) [0x7f8a46b427d1] 11: (Striper::file_to_extents(CephContext*, char const*, file_layout_t const*, unsigned long, unsigned long, unsigned long, std::vector<ObjectExtent, std::allocator<ObjectExtent> >&, unsigned long)+0x46) [0x7f8a46b450d6] 12: (libradosstriper::RadosStriperImpl::internal_aio_write(std::string const&, libradosstriper::MultiAioCompletionImpl*, ceph::buffer::list const&, unsigned long, unsigned long, ceph_file_layout const&)+0x117) [0x7f8a46ab1687] 13: (libradosstriper::RadosStriperImpl::write_in_open_object(std::string const&, ceph_file_layout const&, std::string const&, ceph::buffer::list const&, unsigned long, unsigned long)+0xac) [0x7f8a46ab1a8c] 14: (libradosstriper::RadosStriperImpl::write(std::string const&, ceph::buffer::list const&, unsigned long, unsigned long)+0x6f) [0x7f8a46ab64af] 15: (main()+0x6911) [0x7f8a59b1adc1] 16: (__libc_start_main()+0xf5) [0x7f8a458e5f45] 17: (()+0x23597) [0x7f8a59b25597] NOTE: a copy of the executable, or `objdump -rdS <executable>` is needed to interpret this. --- logging levels --- 0/ 0 none 0/ 0 lockdep 0/ 0 context 0/ 0 crush 0/ 0 mds 0/ 0 mds_balancer 0/ 0 mds_locker 0/ 0 mds_log 0/ 0 mds_log_expire 0/ 0 mds_migrator 0/ 0 buffer 0/ 0 timer 0/ 0 filer 0/ 0 striper 0/ 0 objecter 0/ 0 rados 0/ 0 rbd 0/ 5 rbd_mirror 0/ 0 rbd_replay 0/ 0 journaler 0/ 0 objectcacher 0/ 0 client 0/ 0 osd 0/ 0 optracker 0/ 0 objclass 0/ 0 filestore 0/ 0 journal 0/ 0 ms 0/ 0 mon 0/ 0 monc 0/ 0 paxos 0/ 0 tp 0/ 0 auth 0/ 0 crypto 0/ 0 finisher 0/ 0 heartbeatmap 0/ 0 perfcounter 0/ 0 rgw 1/10 civetweb 1/ 5 javaclient 0/ 0 asok 0/ 0 throttle 0/ 0 refs 1/ 5 xio 1/ 5 compressor 1/ 5 newstore 1/ 5 bluestore 1/ 5 bluefs 1/ 3 bdev 1/ 5 kstore 4/ 5 rocksdb 4/ 5 leveldb 1/ 5 kinetic 1/ 5 fuse -2/-2 (syslog threshold) 99/99 (stderr threshold) max_recent 500 max_new 1000 log_file --- end dump of recent events --- Aborted
As far as I discovered "rados_striper_write()" and "rados_striper_read()"
functions are affected, "rados_striper_trunc()" and "rados_striper_remove()"
are not.
It seems that format processing happens in snprintf() in the
"Striper::file_to_extents()", which creates a stripe name. This function
is used in client interfaces, including librbd and libradosstriper.
libradosstriper needs to escape formatable sequences in user input
before calling "file_to_extents()". This change has been introduced in the
attached patch.
Additional review of the the code which uses "Striper::file_to_extents()" would be appropriate.
Files
Updated by Stan K almost 7 years ago
Red Hat has assigned CVE ID CVE-2017-7519 to this issue.
Updated by Greg Farnum almost 7 years ago
- Category set to libradosstriper
- Status changed from New to Fix Under Review
Updated by Jesse Williamson almost 7 years ago
- Assignee set to Jesse Williamson
Stan, your patch is applied here:
https://github.com/ceph/ceph/pull/15674
...I'm looking for other places this might occur.
Thank you!
Updated by Jesse Williamson almost 7 years ago
@Stan K, I'll need to your email address to sign you off as the author of the patch, assuming that you've given me permission to use that code.
Updated by Stan K almost 7 years ago
@Jesse Williamson, yes, of course you have my permission to use this code.
My email is redrampage@selectel.ru.
Updated by Kefu Chai almost 7 years ago
- Status changed from Fix Under Review to Resolved
Updated by Nathan Cutler over 6 years ago
- Status changed from Resolved to 15
- Backport set to jewel
Updated by Nathan Cutler over 6 years ago
- Status changed from 15 to Pending Backport
Updated by Nathan Cutler over 6 years ago
- Copied to Backport #21297: jewel: libradosstriper processes arbitrary printf placeholders in user input added
Updated by Nathan Cutler over 6 years ago
- Status changed from Pending Backport to Resolved