Passing capabilities through exec
Solution 1
It turns out that setting +i on the wrapper does not add the capability to the CAP_INHERITABLE
set for the wrapper process, thus it is not passed through exec
. I therefore had to manually add CAP_DAC_OVERRIDE
to CAP_INHERITABLE
before calling execl
:
#include <sys/capability.h>
#include <stdio.h>
#include <unistd.h>
int main(int argc, char **argv[]) {
cap_t caps = cap_get_proc();
printf("Capabilities: %s\n", cap_to_text(caps, NULL));
cap_value_t newcaps[1] = { CAP_DAC_OVERRIDE, };
cap_set_flag(caps, CAP_INHERITABLE, 1, newcaps, CAP_SET);
cap_set_proc(caps);
printf("Capabilities: %s\n", cap_to_text(caps, NULL));
cap_free(caps);
return execl("/usr/bin/net", "net", "ads", "dns", "register", "-P", NULL);
}
In addition, I had to add cap_dac_override
to the permitted file capabilities set on /usr/bin/net
and set the effective bit:
~ $ sudo setcap cap_dac_override=p ./registerdns
~ $ sudo setcap cap_dac_override=ei /usr/bin/net
~ $ ./registerdns
Capabilities = cap_dac_override+p
Capabilities = cap_dac_override+ip
Successfully registered hostname with DNS
I think I now fully understand what's happening:
- The wrapper needs
CAP_DAC_OVERRIDE
in its permitted set so it can add it to its inheritable set. - The wrapper's process inheritable set is different than its file inheritable set, so setting +i on the file is useless; the wrapper must explicitly add
CAP_DAC_OVERRIDE
toCAP_INHERITABLE
usingcap_set_flag
/cap_set_proc
. - The
net
file needs to haveCAP_DAC_OVERRIDE
in its inheritable set so that it can in fact inherit the capability from the wrapper into itsCAP_PERMITTED
set. It also needs the effective bit to be set so that it will be automatically promoted toCAP_EFFECTIVE
.
Solution 2
I think you need both:
setcap cap_dac_override+pe ./registerdns
setcap cap_dac_override+i /usr/bin/net
The pe
flags on registerdns
say that running the program acquires the capability. The i
flag on net
says that it's allowed to inherit the capability from the calling program.
Related videos on Youtube
hhhh
Updated on September 18, 2022Comments
-
hhhh almost 2 years
Hi when i am trying this code to dipaly images from imageurl in gridview it is showing null pointer exception can any one help me: my code is
public class Gridview extends Activity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_gridview); GridView gridview = (GridView) findViewById(R.id.gridview); gridview.setAdapter(new ImageAdapter(this)); } public class ImageAdapter extends BaseAdapter{ private Context mContext; private Integer[] mThumbIds; public ImageAdapter(Context c) { mContext = c; } public int getCount() { return mThumbIds.length; } public Object getItem(int position) { return position; } public long getItemId(int position) { return position; } public View getView(int position, View convertView, ViewGroup parent) { ImageView imageView; if (convertView == null) { imageView = new ImageView(mContext); imageView.setLayoutParams(new GridView.LayoutParams(45, 45)); imageView.setAdjustViewBounds(false); imageView.setScaleType(ImageView.ScaleType.CENTER_CROP); imageView.setPadding(8, 8, 8, 8); } else { imageView = (ImageView) convertView; } imageView .setImageDrawable(LoadImageFromWebOperations("http://tmcrmappsqa.inservices.tatamotors.com/cordys/Images/mobile.png"+position)); return imageView; } protected Drawable LoadImageFromWebOperations(String url) { try { InputStream is = (InputStream) new URL(url).getContent(); Drawable d = Drawable.createFromStream(is, "src name"); return d; } catch (Exception e) { System.exit(0); return null; } } }
-
dennisdrew over 11 yearsYou should not be loading images individually from a URL on the UI thread in getView. You should fetch all the images through an AsyncTask and update the GridView in onPostExecute.
-
Bratchley about 10 yearsThe man page for capabilities is pretty invaluable when dealing with them. Look for the section called "Transformation of capabilities during execve" which explains the exact mechanics of how the new Permitted and Effective sets are populated from the Inheritable set.
-
Bratchley about 10 yearsThe UID of zero is special in capability calculation in that execve doesn't default to resetting the inheritable set. That's probably why the setuid is working. I would add the inheritable bit to the
net
binary and see if that fixes it. -
Josiah Yoder almost 6 years@Bratchley What is the inheritable set? The man page you link to mentions it several times, but I'm just looking for a quick summary of the important things in it -- like the PID, UID bit and other permissions, std in and out file descriptors, etc.
-
Bratchley almost 6 years@JosiahYoder They actually have an entry for it under "Thread capability sets" but basically it's the set of capabilities child processes can inherit from the parent process if the parent process has that capability. It's basically a way to prevent programs you kick off from having a capability without the parent process giving up the capability for itself.
-
Josiah Yoder almost 6 years@Bratchley Thank you, but that didn't fully answer my question. I've started a new question to ask it clearly. The section "Capabilities list" in the man page you linked to answers my question partly, but I'm also interested in properties of a process that are inherited which are not capabilities.
-
Josiah Yoder almost 6 yearsI'd like to echo @AdmiralNero's comments from below. After reading the man pages that Bratchley linked, I think the Ambient Set is a better choice than the Inherited Set for unprivileged processes.
-
-
AdmiralNemo about 10 yearsThis is exactly what I've tried. I've edited my question to better reflect that.
-
ctrl-alt-delor about 4 yearsYou are mixing inheritable and permitted way in a dangerous may: By giving the file permitted permission, you give everyone that calls it this permission. Consider also the newer ambient set.