Closed Bug 1579549 Opened 5 years ago Closed 5 years ago

support building dynamic libraries from rust crates

Categories

(Firefox Build System :: General, enhancement)

enhancement
Not set
normal

Tracking

(Not tracked)

RESOLVED WORKSFORME

People

(Reporter: keeler, Unassigned)

Details

Our (the crypto engineering team's) approach to supporting client certificates that come from OS storage (e.g. MacOS keychain, Windows certificate store(s)) will be to implement a PKCS#11 module with the necessary functionality. We're writing it in Rust to make the development process easier and to hopefully avoid the usual classes of memory bugs. Since we want this to be part of the Firefox build, we'll need the build system to support building a dynamic library from a rust crate (i.e. crate-type = ["cdylib"]) (PKCS#11 modules are just dynamic libraries that expose a specific symbol).
I managed to hack something together that appears to work, but I'm sure someone who actually knows the build system would be able to do it more correctly, so let me know if that's of interest at all.

Why does this need to be a dynamic library specifically, rather than part of libxul? Does NSS need to load it in addition to its uses in Firefox?

It needs to be a separate library that NSS loads with dlopen (or the platform equivalent). That's the only way NSS knows how to handle PKCS#11 modules, and PKCS#11 modules are the only way we can make NSS aware of client certificates/keys.

(or rather, client certificates/keys that aren't stored in NSS)

libxul could be the PKCS#11 library NSS dlopens.

Please note that there are subtle issues with having rust create its own dynamic libraries:

  • all dynamic libraries used by Firefox should be linked against libmozglue on Mac, Windows, and Android. That requires some specific linker flags being used by the build. That also requires the build system knowing that it needs to build libmozglue before that rust crate.
  • all rust code part of Firefox should be using at least some parts of toolkit/library/rust/shared/lib.rs

For the first, it would actually be better for the rust code to be built as a static library, and have the build system define a shared library that uses that static library (but then there's the funny problem that the linker would create an empty shared library ; would need something like --whole-archive).

(In reply to Mike Hommey [:glandium] from comment #4)

libxul could be the PKCS#11 library NSS dlopens.

I suppose so, although that would require exposing a function (C_GetFunctionList) on the library - is that an acceptable consequence?

Please note that there are subtle issues with having rust create its own dynamic libraries:

  • all dynamic libraries used by Firefox should be linked against libmozglue on Mac, Windows, and Android. That requires some specific linker flags being used by the build. That also requires the build system knowing that it needs to build libmozglue before that rust crate.
  • all rust code part of Firefox should be using at least some parts of toolkit/library/rust/shared/lib.rs

Can you elaborate more on these points? Why would this library need to link against libmozglue? It's not using anything in xpcom/gecko. Similarly, it isn't using anything in the shared rust gecko library, so why do we need to use it?

For the first, it would actually be better for the rust code to be built as a static library, and have the build system define a shared library that uses that static library (but then there's the funny problem that the linker would create an empty shared library ; would need something like --whole-archive).

That sounds like a reasonable solution - is that doable?

Flags: needinfo?(mh+mozilla)

(In reply to Dana Keeler (she/her) (use needinfo) (:keeler for reviews) from comment #5)

(In reply to Mike Hommey [:glandium] from comment #4)

libxul could be the PKCS#11 library NSS dlopens.

I suppose so, although that would require exposing a function (C_GetFunctionList) on the library - is that an acceptable consequence?

I wouldn't object to it, even though it's gross.

Please note that there are subtle issues with having rust create its own dynamic libraries:

  • all dynamic libraries used by Firefox should be linked against libmozglue on Mac, Windows, and Android. That requires some specific linker flags being used by the build. That also requires the build system knowing that it needs to build libmozglue before that rust crate.
  • all rust code part of Firefox should be using at least some parts of toolkit/library/rust/shared/lib.rs

Can you elaborate more on these points? Why would this library need to link against libmozglue? It's not using anything in xpcom/gecko. Similarly, it isn't using anything in the shared rust gecko library, so why do we need to use it?

For things like memory allocation and dynamic library loading (Mac, Windows, Android for the former, Android-only for the latter)

For the first, it would actually be better for the rust code to be built as a static library, and have the build system define a shared library that uses that static library (but then there's the funny problem that the linker would create an empty shared library ; would need something like --whole-archive).

That sounds like a reasonable solution - is that doable?

It should be.

Flags: needinfo?(mh+mozilla)

(In reply to Mike Hommey [:glandium] from comment #6)

For the first, it would actually be better for the rust code to be built as a static library, and have the build system define a shared library that uses that static library (but then there's the funny problem that the linker would create an empty shared library ; would need something like --whole-archive).

That sounds like a reasonable solution - is that doable?

It should be.

This seems to "just work" (I did have to add an empty file to UNIFIED_SOURCES to get it to create the necessary symbols on Windows), so we probably don't need to do anything here. Thanks for your help!

Status: NEW → RESOLVED
Closed: 5 years ago
Resolution: --- → WORKSFORME
You need to log in before you can comment on or make changes to this bug.