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

Check fixed args number for variadic function #4122

Open
wants to merge 18 commits into
base: master
Choose a base branch
from

Conversation

tiif
Copy link
Contributor

@tiif tiif commented Jan 4, 2025

This PR added

  • check_shim_variadic to be used by variadic function shims
  • check_min_vararg_count to retrieve varargs array from slice
  • check_fixed_args_count to check if we got expected number of fixed args

cc #4013

@rustbot rustbot added the S-waiting-on-review Status: Waiting for a review to complete label Jan 4, 2025
Copy link
Contributor

@oli-obk oli-obk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please squash

src/helpers.rs Outdated Show resolved Hide resolved
@tiif
Copy link
Contributor Author

tiif commented Jan 7, 2025

@rustbot author

@rustbot rustbot added S-waiting-on-author Status: Waiting for the PR author to address review comments and removed S-waiting-on-review Status: Waiting for a review to complete labels Jan 7, 2025
@rustbot

This comment has been minimized.

@tiif
Copy link
Contributor Author

tiif commented Jan 14, 2025

So now there is this weird function definition in this PR

    fn open(
        &mut self,
        args: &[OpTy<'tcx>],
        fixed: &[OpTy<'tcx>; 2],
        _var: &[OpTy<'tcx>],
    ) -> InterpResult<'tcx, Scalar> {

where args is the full function argument, fixed is the fixed args, and _var is var args.

Since we already split fixed and var args through check_shim_variadic before we call this.open, I have tried to not pass args into open, but the problem is if I avoid using args and do this instead

            let [mode] = check_min_arg_count("open(pathname, O_CREAT, ...)", var)?

It will lead to diagnostic like this:

11 |     let _fd = unsafe { libc::open(name_ptr, libc::O_CREAT) }; 
   |                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ incorrect number of arguments for `open(pathname, O_CREAT, ...)`: got 0, expected at least 1

Or maybe we can just ignore the fixed args and var args returned by check_shim_variadic?

@RalfJung
Copy link
Member

It will lead to diagnostic like this:

I would suggest to rename check_min_arg_count to check_min_vararg_count and make the error say something like "not enough variadic arguments for ...".

@tiif
Copy link
Contributor Author

tiif commented Jan 17, 2025

I didn't manage completely replace check_min_arg_count with check_min_vararg_count. There is only left with one check_min_arg_count, which is

fn handle_miri_get_backtrace(
&mut self,
abi: &FnAbi<'tcx, Ty<'tcx>>,
link_name: Symbol,
args: &[OpTy<'tcx>],
dest: &MPlaceTy<'tcx>,
) -> InterpResult<'tcx> {
let this = self.eval_context_mut();
let tcx = this.tcx;
let [flags] = check_min_arg_count("miri_get_backtrace", args)?;

I think as a miri specific extern function, the argument here shouldn't be classified as a vararg?

@@ -207,8 +207,9 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
"fcntl" => {
// `fcntl` is variadic. The argument count is checked based on the first argument
Copy link
Contributor Author

@tiif tiif Jan 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment looks weird, the argument count should be checked based on the second argument cmd instead of the first? (source)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably a copy-paste mistake.

@tiif
Copy link
Contributor Author

tiif commented Jan 17, 2025

@rustbot ready

@rustbot rustbot added S-waiting-on-review Status: Waiting for a review to complete and removed S-waiting-on-author Status: Waiting for the PR author to address review comments labels Jan 17, 2025
@RalfJung
Copy link
Member

I think as a miri specific extern function, the argument here shouldn't be classified as a vararg?

Oh dang.

We have a comment in the docs for this function saying "The flags argument must be 1."
So could you try making a PR that forces the function to have 2 arguments and flags == 1? We recently did the same with miri_resolve_frame, removing support for the old "version 0 protocol"; if we do the same here then we can get rid of this use of check_min_arg_count hopefully. :)

Copy link
Member

@RalfJung RalfJung left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I left some comments on the first place where you used the new infra; they apply everywhere in the PR.

@@ -928,6 +928,30 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
interp_ok(())
}

/// Check the number of fixed args.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// Check the number of fixed args.
/// Check the number of fixed args of a vararg function.

This should probably error if the function is not a vararg fn?

Please also put "vararg" in the name then, e.g. check_vargarg_fixed_arg_count.

(We used arg_count before so please don't use args_count here now.)

&'a [OpTy<'tcx>; N]: TryFrom<&'a [OpTy<'tcx>]>,
{
self.check_abi_and_shim_symbol_clash(abi, exp_abi, link_name)?;
self.check_fixed_args_count(shim_name, abi, args)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does this need self when check_arg_count does not?

@@ -1183,7 +1224,7 @@ where
throw_ub_format!("incorrect number of arguments: got {}, expected {}", args.len(), N)
}

/// Check that the number of args is at least the minumim what we expect.
/// Check that the number of args is at least the minimum what we expect.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// Check that the number of args is at least the minimum what we expect.
/// Check that the number of args is at least the minimum what we expect.
/// FIXME: Remove this function, use varargs and `check_min_vararg_count` instead.

// We do not use `check_shim` here because `prctl` is variadic. The argument
// count is checked bellow.
ecx.check_abi_and_shim_symbol_clash(abi, Conv::C, link_name)?;
// `prctl` is variadic. The argument count is checked below.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// `prctl` is variadic. The argument count is checked below.

Not sure which value this comment still adds.


// FIXME: Use constants once https://github.com/rust-lang/libc/pull/3941 backported to the 0.2 branch.
let pr_set_name = 15;
let pr_get_name = 16;

let [op] = check_min_arg_count("prctl", args)?;
let [op] = fixed_args;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
let [op] = fixed_args;

Comment on lines +20 to +21
let (fixed_args, varargs) =
ecx.check_shim_variadic::<1>(abi, Conv::C, link_name, "prctl", args)?;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
let (fixed_args, varargs) =
ecx.check_shim_variadic::<1>(abi, Conv::C, link_name, "prctl", args)?;
let ([op], varargs) =
ecx.check_shim_variadic(abi, Conv::C, link_name, "prctl", args)?;

Same everywhere else -- you should never use turbofish here.

fn fcntl(&mut self, args: &[OpTy<'tcx>]) -> InterpResult<'tcx, Scalar> {
fn fcntl(
&mut self,
fixed_args: &[OpTy<'tcx>; 2],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of passing a 2-element array, just pass two arguments.

@RalfJung
Copy link
Member

@rustbot author

@rustbot rustbot added S-waiting-on-author Status: Waiting for the PR author to address review comments and removed S-waiting-on-review Status: Waiting for a review to complete labels Jan 19, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-author Status: Waiting for the PR author to address review comments
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants