lkml.org 
[lkml]   [1999]   [Apr]   [26]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
SubjectRE: Latest capabilities patch(getting close)

On 26-Apr-99 Y2K wrote:
> Supports "soiled" and "pure draft".
> Preliminary support for required caps in elf header.
> per task or global securebits settings.
> Elf note fixups.
> ld scripts that might useful, might not.
> I hope that this is close enough that some real testing might begin soon.
> Once elf cap adder is finished then you can play with caps RSN.

Here's my patch to binfmt_elf for finding the caps data. It's a little cleaner
with respect to parsing the notes segment, but it contains no active
ingredients.

J

==== //depot/linux/local/fs/binfmt_elf.c#2 - /home/jeremy/perforce/work/linux/lo
cal/fs/binfmt_elf.c ====
@@ -396,12 +396,42 @@
#define INTERPRETER_AOUT 1
#define INTERPRETER_ELF 2

+#define roundup(x, y) ((((x)+((y)-1))/(y))*(y))
+
+/* Given a pointer to a set of notes, find the first with the given
+ name and type */
+static void *find_note(char *buf, int bufsz, const char *notename, int type)
+{
+ while(bufsz > sizeof(Elf32_Nhdr)) {
+ Elf32_Nhdr *nhdr = (Elf32_Nhdr *)buf;
+ char *name;
+ void *desc;
+ int sz;
+
+ sz = sizeof(Elf32_Nhdr) +
+ roundup(nhdr->n_namesz, 4) +
+ roundup(nhdr->n_descsz, 4);
+ if (bufsz < sz)
+ break;
+ name = buf + sizeof(Elf32_Nhdr);
+ desc = name + roundup(nhdr->n_namesz, 4);

+ if (strncmp(name, notename, nhdr->n_namesz) == 0 &&
+ type == nhdr->n_type)
+ return desc;
+
+ buf += sz;
+ bufsz -= sz;
+ }
+
+ return NULL;
+}
+
static inline int
do_load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
{
struct file * file;
- struct dentry *interpreter_dentry = NULL; /* to shut gcc up */
+ struct dentry *interpreter_dentry = NULL;
unsigned long load_addr = 0, load_bias;
int load_addr_set = 0;
char * elf_interpreter = NULL;
@@ -473,7 +503,42 @@
end_data = 0;

for (i = 0; i < elf_ex.e_phnum; i++) {
- if (elf_ppnt->p_type == PT_INTERP) {
+ switch(elf_ppnt->p_type) {
+ case PT_NOTE: {
+ struct elf_capabilities_note *caps;
+ char *buf;
+
+ retval = -ENOMEM;
+ buf = kmalloc(elf_ppnt->p_filesz, GFP_KERNEL);
+
+ if (buf == NULL)
+ goto out_free_dentry;
+
+ retval = read_exec(bprm->dentry, elf_ppnt->p_offset, buf,
+ elf_ppnt->p_filesz, 1);
+
+ if (retval < 0) {
+ kfree(buf);
+ goto out_free_dentry;
+ }
+
+ caps = (struct elf_capabilities_note *)find_note(buf, elf_ppnt->p_filesz,
+ "CAPS", 1);
+
+ if (caps != NULL) {
+ /* what to do with multiple CAPS notes?
+ Find the most restrictive union? */
+
+ /* process caps here */
+
+ printk("found CAPS note!\n");
+ }
+
+ kfree(buf);
+ }
+ break;
+
+ case PT_INTERP: {
retval = -EINVAL;
if (elf_interpreter)
goto out_free_interp;
@@ -533,6 +598,8 @@
interp_ex = *((struct exec *) bprm->buf);
interp_elf_ex = *((struct elfhdr *) bprm->buf);
}
+ break;
+ }
elf_ppnt++;
}

@@ -777,7 +844,8 @@

/* error cleanup */
out_free_dentry:
- dput(interpreter_dentry);
+ if (interpreter_dentry)
+ dput(interpreter_dentry);
out_free_interp:
if (elf_interpreter)
kfree(elf_interpreter);
\
 
 \ /
  Last update: 2005-03-22 13:51    [from the cache]
©2003-2014 Jasper Spaans. Advertise on this site