AMDmi3 / kiconvtool

FreeBSD tool which preloads kernel iconv charset tables to allow unprivileged filesystem mount
http://wiki.freebsd.org/DmitryMarakasov/kiconvtool
2 stars 0 forks source link

Doesn't work with SMBFS #3

Open tuaris opened 3 years ago

tuaris commented 3 years ago

This doesn't seem to work for mounting smbfs as non-root. Tested only with FreeBSD 12.2 and installed sysutils/kiconvtool using pkg.

In /etc/rc.conf I have:

# Lets non-root mount SMBFS, MSDOSFS, etc...
kiconv_preload="YES"
kiconv_local_charsets="UTF-8"
kiconv_foreign_charsets="UTF-8"

In /boot/loader.conf I have:

smbfs_load="YES"
cd9660_iconv_load="YES"
msdosfs_iconv_load="YES"

I make sure the modules are loaded:

kldstat | grep  "iconv\|smb"
 2    1 0xffffffff8247b000     11a8 cd9660_iconv.ko
 3    5 0xffffffff8247d000     8a38 libiconv.ko
 4    1 0xffffffff82487000     11c0 msdosfs_iconv.ko
55    1 0xffffffff84f38000    17060 smbfs.ko

Then I start the kiconv service:

#service kiconv start
Loading kernel iconv modules.
Loading kernel iconv tables.

# kiconvtool -d
UTF-8 -> UTF-16BE
UTF-16BE -> UTF-8
ISO8859-1 -> tolower
ISO8859-1 -> toupper
UTF-8 -> _wctype
ISO8859-1 -> UTF-16BE
UTF-16BE -> ISO8859-1
ISO8859-1 -> _wctype

Mounting an smbfs share as non-root still fails:

mount_smbfs -I server.domain.tld -O user:user -W DOMAIN "//user@server/Share" /media/Share
Warning: no cfg file(s) found.
mount_smbfs: can not setup kernel iconv table (ISO8859-1:tolower): syserr = Operation not permitted
AMDmi3 commented 3 years ago

Hmm, smbfs seems to have its own machinery for handling kiconv, this needs some investigation I unfortunately don't have time for right now.

Could you please post the log of the following:

If the last command fails the problem is likely not related to kiconvtool. Here's the place where it fails:

https://github.com/freebsd/freebsd-src/blob/88024c4a520bf762cf4154d730ad9784ed2acd90/contrib/smbfs/lib/smb/kiconv.c#L72

and I suspect that trying to write this sysctl from a plain user would always return EPERM regardless of whether it tries to load something or not. In this case the right fix would be to add check for whether the needed tables are already loaded in kiconv_add_xlat_table in FreeBSD source.

tuaris commented 3 years ago

Leaving loader.conf and rc.conf as is and rebooting:

# kiconvtool -d
UTF-8 -> UTF-16BE
UTF-16BE -> UTF-8
UTF-8 -> _wctype

After mounting smbsf share as root....

# kiconvtool -d
UTF-8 -> UTF-16BE
UTF-16BE -> UTF-8
UTF-8 -> _wctype
ISO8859-1 -> tolower
ISO8859-1 -> toupper

Then try to mount as plain user

mount_smbfs: can not setup kernel iconv table (ISO8859-1:tolower): syserr = Operation not permitted

Your suspicion would make sense. It seems that the kernel isn't checking to see if it's already loaded or not.

AMDmi3 commented 3 years ago

You can try https://github.com/AMDmi3/freebsd-src/commit/be3a3995e8a0ad869c42081ee1f9cd39560f1177 (patch to FreeBSD source tree which makes mount_smbfs check whether tables were already added before trying to add them) and see if it helps to mount as user after mounting as root.

If it works and can be accepted upstream it would be worth adding support for these translation tables to kiconvtool, otherwise user smbfs mounts would have to be considered unsupported.

tuaris commented 3 years ago

Getting some encouraging results after using your patch, but still failing. Used the root user to mount the share so that it loads the

ISO8859-1 -> tolower
ISO8859-1 -> toupper

thing. I'm not sure how to do that with kiconvtool tool yet.

Unmounted the share. Then as non-root tried to mount the same one and got:

mount_smbfs: can't get handle to requester (no /dev/nsmb* device)

Worked past that by fixing the permissions on the device file (my non-root user is in the operator group):

# ls -plarths /dev/nsmb
0 crw-------  1 root  operator   0x2d Mar 31 12:11 /dev/nsmb
# chmod g+rw /dev/nsmb
# ls -plarths /dev/nsmb
0 crw-rw----  1 root  operator   0x2d Mar 31 12:11 /dev/nsmb

Tried once more and now it fails with:

mount_smbfs: unable to open connection: syserr = Operation not permitted

Here's the last few lines of a ktrace of the attempt. Let me know if you need more and I'll attach the full thing.

  1515 mount_smbfs RET   read 0
  1515 mount_smbfs CALL  close(0x3)
  1515 mount_smbfs RET   close 0
  1515 mount_smbfs CALL  mmap(0,0x11000,0x3<PROT_READ|PROT_WRITE>,0x1002<MAP_PRIVATE|MAP_ANON>,0xffffffff,0)
  1515 mount_smbfs RET   mmap 34366767104/0x8006b4000
  1515 mount_smbfs CALL  socket(PF_INET,0x10000002<SOCK_DGRAM|SOCK_CLOEXEC>,IPPROTO_IP)
  1515 mount_smbfs RET   socket 3
  1515 mount_smbfs CALL  connect(0x3,0x8006432fc,0x10)
  1515 mount_smbfs STRU  struct sockaddr { AF_INET, 192.168.0.10:53 }
  1515 mount_smbfs RET   connect 0
  1515 mount_smbfs CALL  sendto(0x3,0x7fffffffce80,0x24,0,0,0)
  1515 mount_smbfs GIO   fd 3 wrote 36 bytes
       0x0000 7c7f 0100 0001 0000 0000 0000 0673 6572 7665 7207 6d6f 7261 6e74 6503 636f 6d00 0001 0001  ||............server.morante.com.....|
  1515 mount_smbfs RET   sendto 36/0x24
  1515 mount_smbfs CALL  poll(0x7fffffffce10,0x1,0x1388)
  1515 mount_smbfs RET   poll 1
  1515 mount_smbfs CALL  recvfrom(0x3,0x8006b4280,0x10000,0,0x7fffffffcc10,0x7fffffffc7f8)
  1515 mount_smbfs GIO   fd 3 read 52 bytes
       0x0000 7c7f 8580 0001 0001 0000 0000 0673 6572 7665 7207 6d6f 7261 6e74 6503 636f 6d00 0001 0001  ||............server.morante.com.....|
       0x0024 c00c 0001 0001 0000 0e10 0004 c0a8 000a                                                    |................|

  1515 mount_smbfs STRU  struct sockaddr { AF_INET, 192.168.0.10:53 }
  1515 mount_smbfs RET   recvfrom 52/0x34
  1515 mount_smbfs CALL  close(0x3)
  1515 mount_smbfs RET   close 0
  1515 mount_smbfs CALL  __sysctl(0x7fffffffdfb0,0x2,0x7fffffffdfe0,0x7fffffffdfa8,0,0)
  1515 mount_smbfs SCTL  "kern.hostname"
  1515 mount_smbfs RET   __sysctl 0
  1515 mount_smbfs CALL  open(0x8002a615b,0x100002<O_RDWR|O_CLOEXEC>)
  1515 mount_smbfs NAMI  "/dev/tty"
  1515 mount_smbfs RET   open 3
  1515 mount_smbfs CALL  ioctl(0x3,TIOCGETA,0x7fffffffe360)
  1515 mount_smbfs RET   ioctl 0
  1515 mount_smbfs CALL  ioctl(0x3,TIOCSETAF,0x7fffffffe1a0)
  1515 mount_smbfs RET   ioctl 0
  1515 mount_smbfs CALL  sigaction(SIGALRM,0x7fffffffe340,0x7fffffffe320)
  1515 mount_smbfs RET   sigaction 0
  1515 mount_smbfs CALL  sigaction(SIGHUP,0x7fffffffe340,0x7fffffffe2e0)
  1515 mount_smbfs RET   sigaction 0
  1515 mount_smbfs CALL  sigaction(SIGINT,0x7fffffffe340,0x7fffffffe300)
  1515 mount_smbfs RET   sigaction 0
  1515 mount_smbfs CALL  sigaction(SIGPIPE,0x7fffffffe340,0x7fffffffe220)
  1515 mount_smbfs RET   sigaction 0
  1515 mount_smbfs CALL  sigaction(SIGQUIT,0x7fffffffe340,0x7fffffffe2c0)
  1515 mount_smbfs RET   sigaction 0
  1515 mount_smbfs CALL  sigaction(SIGTERM,0x7fffffffe340,0x7fffffffe2a0)
  1515 mount_smbfs RET   sigaction 0
  1515 mount_smbfs CALL  sigaction(SIGTSTP,0x7fffffffe340,0x7fffffffe280)
  1515 mount_smbfs RET   sigaction 0
  1515 mount_smbfs CALL  sigaction(SIGTTIN,0x7fffffffe340,0x7fffffffe260)
  1515 mount_smbfs RET   sigaction 0
  1515 mount_smbfs CALL  sigaction(SIGTTOU,0x7fffffffe340,0x7fffffffe240)
  1515 mount_smbfs RET   sigaction 0
...... REDACTED ....
  1515 mount_smbfs RET   read 1
  1515 mount_smbfs CALL  write(0x3,0x8002a4e9c,0x1)
  1515 mount_smbfs GIO   fd 3 wrote 1 byte
       "
       "
  1515 mount_smbfs RET   write 1
  1515 mount_smbfs CALL  ioctl(0x3,TIOCSETAF,0x7fffffffe1a0)
  1515 mount_smbfs RET   ioctl 0
  1515 mount_smbfs CALL  sigaction(SIGALRM,0x7fffffffe320,0)
  1515 mount_smbfs RET   sigaction 0
  1515 mount_smbfs CALL  sigaction(SIGHUP,0x7fffffffe2e0,0)
  1515 mount_smbfs RET   sigaction 0
  1515 mount_smbfs CALL  sigaction(SIGINT,0x7fffffffe300,0)
  1515 mount_smbfs RET   sigaction 0
  1515 mount_smbfs CALL  sigaction(SIGQUIT,0x7fffffffe2c0,0)
  1515 mount_smbfs RET   sigaction 0
  1515 mount_smbfs CALL  sigaction(SIGPIPE,0x7fffffffe220,0)
  1515 mount_smbfs RET   sigaction 0
  1515 mount_smbfs CALL  sigaction(SIGTERM,0x7fffffffe2a0,0)
  1515 mount_smbfs RET   sigaction 0
  1515 mount_smbfs CALL  sigaction(SIGTSTP,0x7fffffffe280,0)
  1515 mount_smbfs RET   sigaction 0
  1515 mount_smbfs CALL  sigaction(SIGTTIN,0x7fffffffe260,0)
  1515 mount_smbfs RET   sigaction 0
  1515 mount_smbfs CALL  sigaction(SIGTTOU,0x7fffffffe240,0)
  1515 mount_smbfs RET   sigaction 0
  1515 mount_smbfs CALL  close(0x3)
  1515 mount_smbfs RET   close 0
  1515 mount_smbfs CALL  openat(AT_FDCWD,0x80025223b,0x2<O_RDWR>)
  1515 mount_smbfs NAMI  "/dev/nsmb"
  1515 mount_smbfs RET   openat 3
  1515 mount_smbfs CALL  ioctl(0x3,SMBIOC_LOOKUP,0x7fffffffe148)
  1515 mount_smbfs RET   ioctl -1 errno 1 Operation not permitted
  1515 mount_smbfs CALL  write(0x2,0x7fffffffd940,0xd)
  1515 mount_smbfs GIO   fd 2 wrote 13 bytes
       "mount_smbfs: "
  1515 mount_smbfs RET   write 13/0xd
  1515 mount_smbfs CALL  write(0x2,0x7fffffffda40,0x19)
  1515 mount_smbfs GIO   fd 2 wrote 25 bytes
       "unable to open connection"
  1515 mount_smbfs RET   write 25/0x19
  1515 mount_smbfs CALL  fstatat(AT_FDCWD,0x7fffffffdaa0,0x7fffffffdea0,0)
  1515 mount_smbfs NAMI  "/usr/share/nls/C/libc.cat"
  1515 mount_smbfs RET   fstatat -1 errno 2 No such file or directory
  1515 mount_smbfs CALL  fstatat(AT_FDCWD,0x7fffffffdaa0,0x7fffffffdea0,0)
  1515 mount_smbfs NAMI  "/usr/share/nls/libc/C"
  1515 mount_smbfs RET   fstatat -1 errno 2 No such file or directory
  1515 mount_smbfs CALL  fstatat(AT_FDCWD,0x7fffffffdaa0,0x7fffffffdea0,0)
  1515 mount_smbfs NAMI  "/usr/local/share/nls/C/libc.cat"
  1515 mount_smbfs RET   fstatat -1 errno 2 No such file or directory
  1515 mount_smbfs CALL  fstatat(AT_FDCWD,0x7fffffffdaa0,0x7fffffffdea0,0)
  1515 mount_smbfs NAMI  "/usr/local/share/nls/libc/C"
  1515 mount_smbfs RET   fstatat -1 errno 2 No such file or directory
  1515 mount_smbfs CALL  write(0x2,0x7fffffffd940,0x23)
  1515 mount_smbfs GIO   fd 2 wrote 35 bytes
       ": syserr = Operation not permitted
       "
  1515 mount_smbfs RET   write 35/0x23
  1515 mount_smbfs CALL  sigprocmask(SIG_BLOCK,0x80022bfb0,0x7fffffffe2e0)
  1515 mount_smbfs RET   sigprocmask 0
  1515 mount_smbfs CALL  sigprocmask(SIG_SETMASK,0x80022bfc4,0)
  1515 mount_smbfs RET   sigprocmask 0
  1515 mount_smbfs CALL  sigprocmask(SIG_BLOCK,0x80022bfb0,0x7fffffffde50)
  1515 mount_smbfs RET   sigprocmask 0
  1515 mount_smbfs CALL  sigprocmask(SIG_SETMASK,0x80022bfc4,0)
  1515 mount_smbfs RET   sigprocmask 0
  1515 mount_smbfs CALL  sigprocmask(SIG_BLOCK,0x80022bfb0,0x7fffffffde50)
  1515 mount_smbfs RET   sigprocmask 0
  1515 mount_smbfs CALL  sigprocmask(SIG_SETMASK,0x80022bfc4,0)
  1515 mount_smbfs RET   sigprocmask 0
  1515 mount_smbfs CALL  sigprocmask(SIG_BLOCK,0x80022bfb0,0x7fffffffde50)
  1515 mount_smbfs RET   sigprocmask 0
  1515 mount_smbfs CALL  sigprocmask(SIG_SETMASK,0x80022bfc4,0)
  1515 mount_smbfs RET   sigprocmask 0
  1515 mount_smbfs CALL  sigprocmask(SIG_BLOCK,0x80022bfb0,0x7fffffffde50)
  1515 mount_smbfs RET   sigprocmask 0
  1515 mount_smbfs CALL  sigprocmask(SIG_SETMASK,0x80022bfc4,0)
  1515 mount_smbfs RET   sigprocmask 0
  1515 mount_smbfs CALL  exit(0x1)
AMDmi3 commented 3 years ago

Looks like EPERM in ioctl(SMBIOC_LOOKUP). That needs to be traced through kernel netsmb code, a quick glance shows only two relevant places marked with Only superuser can create VCs with different uid and gid and Only superuser can create shares with different uid and gid comments, so you may try playing with -O. Or maybe some generic code is called which requires superuser privs, which is not directly greppably by EPERM.

I'm not sure how to do that with kiconvtool tool yet.

There's currently no way to do that with kiconvtool.