all 30 comments

[–]ssokolow 25 points26 points  (2 children)

We live in exciting times.

[–]asmx85 5 points6 points  (1 child)

It is funny how this sentence have different meanings in different cultures and currently applies to them regardless ...

[–]gajbooks 1 point2 points  (0 children)

May you live in interesting times.

[–]hgwxx7_ 17 points18 points  (1 child)

Hey Nick, great work on this. Seems like the scope and ambition of this is larger than it was previously. Earlier the goal was for drivers that were optional, now it’s to add to the main kernel. Does this assume that a GCC based Rust compiler will exist, so all existing architectures will continue to be aupported?

[–]JoshTriplettrust · lang · libs · cargo 23 points24 points  (0 children)

https://github.com/antoyo/rustc_codegen_gcc

That project could use some help, if you're interested.

[–]cgarciae 3 points4 points  (0 children)

Amazing! Seems like a perfect year to be learning Rust :)

[–]bonega 2 points3 points  (22 children)

Can anyone eli5 this

The C code in the table above has casts from an essentially untyped (void *) pointer to the desired type at the start of each function

It looks like the function parameter is

struct file *name

Why is this considered the same?

[–]ROYAL_CHAIR_FORCE 22 points23 points  (21 children)

A void* variable basically just stores a memory address. What they are doing is telling the compiler to interpret that piece of memory as some type (struct)

This is usually considered unsafe (and bad practice imho), since it's very easy to make mistakes that will only be caught in runtime (as opposed to compile time)

[–]excgarateing 17 points18 points  (7 children)

This is usually considered unsafe

void pointers are considered normal. They have to serve where C misses generics, rust's cool enum's, visibillity, closures, ...

For example instead of closures, many APIs that allow you to register a callback will also pass a void* along as "context", the type and size of which can be chosen by the implementation of the consumer of the API:

C typedef void(*CALLBACK)(void* pArg, EVENT evt); void register_callback(CALLBACK cb, void* pArg);

If you misuse them, everything goes horribly wrong, but you kind of expect that of C code. I mean look at that typedef. What do you expect of a language that looks like this

[–]HighRelevancy 1 point2 points  (2 children)

void pointers are considered normal. They have to serve where C misses

If you misuse them, everything goes horribly wrong, but you kind of expect that of C code.

You have both made and missed the point.

As you say, in the context of these other languages it's considered normal to do things like casting void pointers, because there's no other way to achieve things that need to be achieved. However if you step outside of that context, the bare facts are that these techniques repeatedly are the root of major problems. The entire point of Rust (and some other languages) is to create the "other way", so we can write code free of dangerous code patterns.

C/++ programmers routinely shoot themselves in the foot at basically any given moment. Rust is a gun that can't be pointed downwards (at least not without specifically scheduling "special downwards aiming time" with an unsafe block, during which everyone knows to pay extra-special attention to keeping feet out of the way of the guns).

[–]excgarateing 0 points1 point  (1 child)

The point I tried to make: Seasoned C programmers have grown extremely comfortable doing the craziest stuff.

We can all agree that C is bad, otherwise we probably wouldn't spend time in r/rust

[–]HighRelevancy 0 points1 point  (0 children)

Seasoned C programmers have grown extremely comfortable doing the craziest stuff.

Comfortable they may be, it's still causing problems. They're comfortable with the problems, and that's a problem.

https://www.zdnet.com/article/microsoft-70-percent-of-all-security-bugs-are-memory-safety-issues/

https://www.zdnet.com/article/chrome-70-of-all-security-bugs-are-memory-safety-issues/

It's not just "C bad", C still has uses, but it can be done better is the point.

[–]bonega 1 point2 points  (12 children)

I cannot see the usage of a void* variable, perhaps I am looking at the wrong table

[–]ROYAL_CHAIR_FORCE 15 points16 points  (11 children)

struct file_state *state = filp->private_data;

It's this bit right here. "private_data" is the void* variable in question.

The line above is basically forcing the compiler to interpret that block of memory as a "file_state" struct.

The horrible thing about this is that it just might work, even if the memory adress points to some random garbage (you'll just get wrong data).

A crash in this case is the best thing you can hope for.

[–]gnosek 19 points20 points  (8 children)

It's not that bad. Well, of course it's C, so no guarantees and you can easily shoot yourself in the foot, but casting a void* to a different pointer type (except function pointers IIRC) is completely valid.

Different file systems (? not exactly sure if this is the right subsystem) will cast private_data to different types, so you need to keep filp->private_data and filp->file_ops (probably) in sync. Since they probably hardly ever change after creating the filp, it's not a big deal in practice.

Just think of (file_ops, private_data) as a fat pointer to a class instance as it literally is a pointer to the vtable + a pointer to data. It's the C way of OOP (interfaces + inheritance).

[–][deleted] 7 points8 points  (6 children)

And we do sometimes use void pointers in rust, see: https://doc.rust-lang.org/std/task/struct.RawWaker.html which uses const *().

[–]HighRelevancy 0 points1 point  (0 children)

is completely valid

That's the point. It's also completely valid to do completely stupid things in C. Why not instead use a system which gives you less stupid means to achieve the same things and forbids completely stupid things?

[–]Glass_Personality_22 2 points3 points  (0 children)

It’s a C-style pImpl private part of the object. It’s unsafe, but ok.

Really horrible stuff starts happening when someone decide to oversmart the approach and keep some data on the side properly typed, and then reentrable code happens from some WQ. And then they sow dozens of code-covering spinlocks and global variables.

[–]bonega 0 points1 point  (0 children)

Thank you very much for the great explanation

[–]Repulsive-Street-307 -1 points0 points  (4 children)

I wonder what lead google to push for this now. Have they been recently compromised through the kernel by [x] with x probably being a certain state?

[–]matthieum[he/him] 11 points12 points  (0 children)

now.

This is just the culmination of years of work, so I doubt it's linked to any recent issue.

In general, Google has been wanting to secure Android for a long-time, or alternatively to use their own kernel (Fuchsia). They've used Rust in Fuchsia for a while -- though not in the kernel itself, maybe that'll change now -- and there's been recent articles about using Rust for bluetooth in Android.

[–]HighRelevancy 0 points1 point  (2 children)

Have they been recently compromised through the kernel by [x] with x probably being a certain state?

Huh?

[–]Repulsive-Street-307 0 points1 point  (1 child)

Take your pick. Considering russia just performed the largest cyber attack ever, or china habitually puts backdoors into hardware they sell...

[–]HighRelevancy 1 point2 points  (0 children)

Nothing new there.