Context
I've done a java library that uses a C library with JNI.
The C library is compiled in linux into a .so file. This library needs cap_net_raw capabilities.
Goal
Execute a java process without additional privileges, that uses said java library. The actual processes that are going to use the library are existing processes already in prod and we don't want to give them more rights.
To test that, I've created a jar and run it both with and without sudo. As expected, it succeeds with but fail without it.
Steps to reproduce the test
- Create a java class with a native method, let's call it 
SocketTester.java 
static {
    System.loadLibrary("SocketTester");
}
private native int socketTest();
- Generate 
socketTester.hfile with the command 
javac -h . SocketTester.java
- Create 
socketTester.cfile that implementssocketTester.hand which needs thecap_net_rawcapabitily - Compile with
 
gcc -o libSocketTester.so socketTester.c -shared -I/usr/lib/jvm/java-14-openjdk-amd64/include -I/usr/lib/jvm/java-14-openjdk-amd64/include/linux
- Move 
libSocketTester.soto /usr/lib - Run
 
sudo ldconfig
- Set the cap
 
cd /usr/lib
sudo setcap cap_net_raw=epi libSocketTester.so
- Create a 
Test.javaclass 
public static void main(final String[] args) {
    SocketTester tester = new SocketTester();
    tester.socketTest();
}
- Create a jar with 
SocketTester.javaandTest.java - Run the test
 
java -cp socketTester.jar Test
What I've already tried
Adding cap to the .so lib
sudo setcap cap_net_raw=epi libSocketTester.so
Result: Failure
Adding cap to java
sudo setcap cap_net_raw=epi /usr/lib/jvm/java-14-openjdk-amd64/bin/java
Result: It works, but it's not what I want because now all java process have the capability (see bold in goal section).
The question
Why is adding the cap to the .so doesn't work? How else can I accomplish the goal?