Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

error.rs: check range and add type invariant to Error #295

Closed
ojeda opened this issue May 26, 2021 · 6 comments
Closed

error.rs: check range and add type invariant to Error #295

ojeda opened this issue May 26, 2021 · 6 comments
Labels
good first issue Good for newcomers • lib Related to the `rust/` library.

Comments

@ojeda
Copy link
Member

ojeda commented May 26, 2021

From @nbdd0121 #287 (comment):

We will need to make sure that no Error with out of range error code can be constructed (e.g. 0, > MAX_ERROR), as otherwise it might be a soundness hole (with the use of from_kernel_result for example).

@ojeda ojeda added • lib Related to the `rust/` library. prio: normal good first issue Good for newcomers labels May 26, 2021
@ojeda ojeda changed the title rust/kernel/error.rs: check range and add type invariant to Error error.rs: check range and add type invariant to Error May 26, 2021
@foxhlchen
Copy link

Sorry, I didn't quite get it.

Rust doesn't have the "constructor" concept, so we can't check that on
Error(error_val)
One way to solve this is to add a "new" method to Error and force people to use
Error::new(error_val)
But I don't think this is what you're asking.

Do you mean to add checks on from_kernel_errno and to_kernel_errno, and panics if it failed the check??

@ojeda
Copy link
Member Author

ojeda commented May 29, 2021

But I don't think this is what you're asking.

It is! The idea of type invariants is that we check something once at construction time and then we know it holds for the lifetime of the object (as long as other methods do not break it, of course). Search for INVARIANT inside rust/ for other examples.

@nbdd0121
Copy link
Member

Rust doesn't have the "constructor" concept, so we can't check that on
Error(error_val)

The field is private, so it wouldn't be seen outside the module.

Do you mean to add checks on from_kernel_errno and to_kernel_errno, and panics if it failed the check??

from_kernel_errno would require some check (and we might want a from_kernel_errno_unchecked to bypass the check, e.g. when converting from err ptr), but probably panicking is not the best option here. We can maybe warn and convert it to a sensible error like EINVAL.

to_kernel_errno does not need checks.

@foxhlchen
Copy link

Thank you both.

Combining what you are suggesting, I will do:

  1. Add a "new()" method to Error providing checks in creation.
  2. Add check to from_kernel_errno()
  3. Provide a non-checked version from_kernel_errno_unchecked()

During checking when an invalid err_no is found, they will 1) log a warning 2) convert it to EINVAL.

ojeda added a commit that referenced this issue Jun 3, 2021
rust: check range and add type invariant to Error (issue #295)
@TheSven73
Copy link
Collaborator

Does merging #324 close this Issue?

@ojeda
Copy link
Member Author

ojeda commented Jun 5, 2021

Yeah, even if we are still discussing how to approach errors, this one can go out.

@ojeda ojeda closed this as completed Jun 5, 2021
fbq pushed a commit that referenced this issue Sep 30, 2024
Inject fault while probing of-fpga-region, if kasprintf() fails in
module_add_driver(), the second sysfs_remove_link() in exit path will cause
null-ptr-deref as below because kernfs_name_hash() will call strlen() with
NULL driver_name.

Fix it by releasing resources based on the exit path sequence.

	 KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007]
	 Mem abort info:
	   ESR = 0x0000000096000005
	   EC = 0x25: DABT (current EL), IL = 32 bits
	   SET = 0, FnV = 0
	   EA = 0, S1PTW = 0
	   FSC = 0x05: level 1 translation fault
	 Data abort info:
	   ISV = 0, ISS = 0x00000005, ISS2 = 0x00000000
	   CM = 0, WnR = 0, TnD = 0, TagAccess = 0
	   GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
	 [dfffffc000000000] address between user and kernel address ranges
	 Internal error: Oops: 0000000096000005 [#1] PREEMPT SMP
	 Dumping ftrace buffer:
	    (ftrace buffer empty)
	 Modules linked in: of_fpga_region(+) fpga_region fpga_bridge cfg80211 rfkill 8021q garp mrp stp llc ipv6 [last unloaded: of_fpga_region]
	 CPU: 2 UID: 0 PID: 2036 Comm: modprobe Not tainted 6.11.0-rc2-g6a0e38264012 #295
	 Hardware name: linux,dummy-virt (DT)
	 pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
	 pc : strlen+0x24/0xb0
	 lr : kernfs_name_hash+0x1c/0xc4
	 sp : ffffffc081f97380
	 x29: ffffffc081f97380 x28: ffffffc081f97b90 x27: ffffff80c821c2a0
	 x26: ffffffedac0be418 x25: 0000000000000000 x24: ffffff80c09d2000
	 x23: 0000000000000000 x22: 0000000000000000 x21: 0000000000000000
	 x20: 0000000000000000 x19: 0000000000000000 x18: 0000000000001840
	 x17: 0000000000000000 x16: 0000000000000000 x15: 1ffffff8103f2e42
	 x14: 00000000f1f1f1f1 x13: 0000000000000004 x12: ffffffb01812d61d
	 x11: 1ffffff01812d61c x10: ffffffb01812d61c x9 : dfffffc000000000
	 x8 : 0000004fe7ed29e4 x7 : ffffff80c096b0e7 x6 : 0000000000000001
	 x5 : ffffff80c096b0e0 x4 : 1ffffffdb990efa2 x3 : 0000000000000000
	 x2 : 0000000000000000 x1 : dfffffc000000000 x0 : 0000000000000000
	 Call trace:
	  strlen+0x24/0xb0
	  kernfs_name_hash+0x1c/0xc4
	  kernfs_find_ns+0x118/0x2e8
	  kernfs_remove_by_name_ns+0x80/0x100
	  sysfs_remove_link+0x74/0xa8
	  module_add_driver+0x278/0x394
	  bus_add_driver+0x1f0/0x43c
	  driver_register+0xf4/0x3c0
	  __platform_driver_register+0x60/0x88
	  of_fpga_region_init+0x20/0x1000 [of_fpga_region]
	  do_one_initcall+0x110/0x788
	  do_init_module+0x1dc/0x5c8
	  load_module+0x3c38/0x4cac
	  init_module_from_file+0xd4/0x128
	  idempotent_init_module+0x2cc/0x528
	  __arm64_sys_finit_module+0xac/0x100
	  invoke_syscall+0x6c/0x258
	  el0_svc_common.constprop.0+0x160/0x22c
	  do_el0_svc+0x44/0x5c
	  el0_svc+0x48/0xb8
	  el0t_64_sync_handler+0x13c/0x158
	  el0t_64_sync+0x190/0x194
	 Code: f2fbffe1 a90157f4 12000802 aa0003f5 (38e16861)
	 ---[ end trace 0000000000000000 ]---
	 Kernel panic - not syncing: Oops: Fatal exception

Fixes: 85d2b0a ("module: don't ignore sysfs_create_link() failures")
Signed-off-by: Jinjie Ruan <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Greg Kroah-Hartman <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
good first issue Good for newcomers • lib Related to the `rust/` library.
Development

No branches or pull requests

4 participants