Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tarea 4 #300

Open
wants to merge 6 commits into
base: riscv
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 92 additions & 0 deletions Informe.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
# Informe Oscar Lobo

## Funcionamiento del Sistema de Permisos
El sistema de permisos básicos implementado en xv6 utiliza una nueva función de sistema chmod para gestionar permisos de archivos. Este sistema permite definir restricciones de acceso para los archivos en los siguientes modos:

### Lectura/Escriptura: Permite operaciones tanto de lectura como escritura.
Solo Lectura: Restringe las operaciones de escritura en el archivo.
Inmutable: Marca el archivo como no modificable, tanto en contenido como en permisos.
Estas funcionalidades mejoran el control de acceso, garantizando la seguridad y consistencia de los archivos almacenados.

### chmod
La función chmod permite cambiar los permisos asociados a un archivo. Sus características principales incluyen:

Actualizar los permisos de un archivo especificado a los valores definidos por el usuario.
Proteger archivos inmutables (perm = 5) contra cualquier tipo de modificación, tanto en contenido como en permisos.

## Modificaciones Realizadas

### Archivo sysfile.c
Se realizaron las siguientes modificaciones para respetar los permisos:

Función sys_open
Verifica los permisos del archivo antes de abrirlo:
Archivos de solo lectura (perm = 1) no pueden ser abiertos en modo escritura.
Archivos inmutables (perm = 5) solo pueden ser abiertos en modo lectura.
Función writei
Restringe las operaciones de escritura en archivos:
Si perm = 1 (solo lectura), la operación es denegada.
Si perm = 5 (inmutable), la operación también es denegada.
Archivo sysproc.c
Se implementó la función sys_chmod, que realiza las siguientes operaciones:

Cambia los permisos del archivo especificado a los valores definidos por el usuario.
Devuelve un error si el archivo es inmutable (perm = 5).

### Archivo syscall.h
Se añadió la definición de la nueva llamada al sistema


### Archivo usys.pl
Se agregó la entrada para la nueva función de sistema

### Archivo chmodtest.c
Se creó un programa de prueba para validar las funcionalidades implementadas. Este programa realiza las siguientes operaciones:

Creación del archivo:

Crea un archivo con permisos iniciales de lectura/escritura (O_CREATE | O_RDWR).
Escribe datos en el archivo y lo cierra.
Cambio a solo lectura:

Cambia los permisos del archivo a solo lectura (chmod(filename, 1)).
Intenta abrir el archivo en modo escritura, lo que debe fallar.
Restauración de permisos:

Cambia los permisos a lectura/escritura (chmod(filename, 3)).
Escribe nuevamente en el archivo para confirmar los permisos.
Prueba de inmutabilidad:

Cambia los permisos del archivo a inmutable (chmod(filename, 5)).
Intenta escribir en el archivo y modificar sus permisos, ambas operaciones deben fallar.
Manejo de Excepciones

### Cambios en sysfile.c:
Se añadieron validaciones para los permisos definidos en inode al manejar operaciones de apertura, lectura y escritura.
Manejo en chmod:
Si un archivo es inmutable, la función devuelve un error, bloqueando cambios en sus permisos.
Pruebas

## Descripción del Programa de Prueba
El programa chmodtest.c simula el uso de las nuevas funcionalidades de permisos en xv6. Sus pasos son:

Crear un archivo con permisos de lectura/escritura.
Cambiar los permisos a solo lectura y verificar que la escritura sea denegada.
Restaurar los permisos y confirmar que la escritura sea posible.
Cambiar los permisos a inmutable y verificar que no se pueda ni escribir ni modificar sus permisos.
Resultados de las Pruebas
Archivos con permisos de solo lectura restringen correctamente la escritura.
Archivos inmutables bloquean modificaciones tanto en contenido como en permisos.
El sistema genera mensajes de error apropiados cuando se violan las restricciones.
Dificultades Encontradas y Soluciones
Desalineación de la estructura inode
La inclusión del campo perm en el inode aumentó su tamaño, rompiendo la alineación requerida con BSIZE. Esto generó errores durante la inicialización del sistema de archivos. La solución fue añadir un campo de relleno para garantizar que la estructura sea múltiplo de BSIZE.

## Dificultades Encontradas y Soluciones

### Manejo de errores
surgieron muchos errores al intentar hacer la tarea, los cuales tuve que apoyarme de otros compañeros para soluconarlos, ya que no encontraba solución en internet.

### Validación de permisos
Inicialmente, las operaciones de escritura y apertura no verificaban correctamente los permisos. Este problema se resolvió añadiendo validaciones explícitas en las funciones sys_open y writei.

1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ UPROGS=\
$U/_grind\
$U/_wc\
$U/_zombie\
$U/_chmodtest\

fs.img: mkfs/mkfs README $(UPROGS)
mkfs/mkfs fs.img README $(UPROGS)
Expand Down
3 changes: 1 addition & 2 deletions kernel/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -178,5 +178,4 @@ filewrite(struct file *f, uint64 addr, int n)
}

return ret;
}

}
4 changes: 3 additions & 1 deletion kernel/file.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ struct inode {
short nlink;
uint size;
uint addrs[NDIRECT+1];

int perm; // Nuevo campo para permisos o uso en memoria.
};

// map major device number to device functions.
Expand All @@ -37,4 +39,4 @@ struct devsw {

extern struct devsw devsw[];

#define CONSOLE 1
#define CONSOLE 1
123 changes: 68 additions & 55 deletions kernel/fs.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,14 @@
struct superblock sb;

// Read the super block.
static void
void
readsb(int dev, struct superblock *sb)
{
struct buf *bp;
struct buf *bp;

bp = bread(dev, 1);
memmove(sb, bp->data, sizeof(*sb));
brelse(bp);
bp = bread(dev, 1);
memmove(sb, bp->data, sizeof(*sb));
brelse(bp);
}

// Init fs
Expand Down Expand Up @@ -198,48 +198,56 @@ static struct inode* iget(uint dev, uint inum);
struct inode*
ialloc(uint dev, short type)
{
int inum;
struct buf *bp;
struct dinode *dip;

for(inum = 1; inum < sb.ninodes; inum++){
bp = bread(dev, IBLOCK(inum, sb));
dip = (struct dinode*)bp->data + inum%IPB;
if(dip->type == 0){ // a free inode
memset(dip, 0, sizeof(*dip));
dip->type = type;
log_write(bp); // mark it allocated on the disk
brelse(bp);
return iget(dev, inum);
int inum;
struct buf *bp;
struct dinode *dip;

for (inum = 1; inum < sb.ninodes; inum++) {
bp = bread(dev, IBLOCK(inum, sb));
dip = (struct dinode*)bp->data + inum % IPB;
if (dip->type == 0) { // Un inodo libre
memset(dip, 0, sizeof(*dip));
dip->type = type;
dip->perm = 0; // Inicializar permisos a 0
log_write(bp); // Marcar como asignado en el disco
brelse(bp);
return iget(dev, inum);
}
brelse(bp);
}
brelse(bp);
}
printf("ialloc: no inodes\n");
return 0;
printf("ialloc: no inodes\n");
return 0;
}


// Copy a modified in-memory inode to disk.
// Must be called after every change to an ip->xxx field
// that lives on disk.
// Caller must hold ip->lock.
void
iupdate(struct inode *ip)
{
struct buf *bp;
struct dinode *dip;

bp = bread(ip->dev, IBLOCK(ip->inum, sb));
dip = (struct dinode*)bp->data + ip->inum%IPB;
dip->type = ip->type;
dip->major = ip->major;
dip->minor = ip->minor;
dip->nlink = ip->nlink;
dip->size = ip->size;
memmove(dip->addrs, ip->addrs, sizeof(ip->addrs));
log_write(bp);
brelse(bp);
struct buf *bp;
struct dinode *dip;

bp = bread(ip->dev, IBLOCK(ip->inum, sb));
dip = (struct dinode *)bp->data + ip->inum % IPB;

dip->type = ip->type;
dip->major = ip->major;
dip->minor = ip->minor;
dip->nlink = ip->nlink;
dip->size = ip->size;

// Eliminar referencias a ip->perm porque ip es de tipo inode
// Si ip->perm no es relevante aquí, basta con sincronizar con dip->perm
memmove(dip->addrs, ip->addrs, sizeof(ip->addrs));
log_write(bp);
brelse(bp);
}



// Find the inode with number inum on device dev
// and return the in-memory copy. Does not lock
// the inode and does not read it from disk.
Expand Down Expand Up @@ -292,30 +300,35 @@ idup(struct inode *ip)
void
ilock(struct inode *ip)
{
struct buf *bp;
struct dinode *dip;
struct buf *bp;
struct dinode *dip;

if(ip == 0 || ip->ref < 1)
panic("ilock");
if (ip == 0 || ip->ref < 1)
panic("ilock");

acquiresleep(&ip->lock);
acquiresleep(&ip->lock);

if(ip->valid == 0){
bp = bread(ip->dev, IBLOCK(ip->inum, sb));
dip = (struct dinode*)bp->data + ip->inum%IPB;
ip->type = dip->type;
ip->major = dip->major;
ip->minor = dip->minor;
ip->nlink = dip->nlink;
ip->size = dip->size;
memmove(ip->addrs, dip->addrs, sizeof(ip->addrs));
brelse(bp);
ip->valid = 1;
if(ip->type == 0)
panic("ilock: no type");
}
if (ip->valid == 0) {
bp = bread(ip->dev, IBLOCK(ip->inum, sb));
dip = (struct dinode *)bp->data + ip->inum % IPB;

ip->type = dip->type;
ip->major = dip->major;
ip->minor = dip->minor;
ip->nlink = dip->nlink;
ip->size = dip->size;

// Eliminar cualquier referencia a ip->perm
memmove(ip->addrs, dip->addrs, sizeof(ip->addrs));
brelse(bp);
ip->valid = 1;
if (ip->type == 0)
panic("ilock: no type");
}
}



// Unlock the given inode.
void
iunlock(struct inode *ip)
Expand Down Expand Up @@ -694,4 +707,4 @@ struct inode*
nameiparent(char *path, char *name)
{
return namex(path, 1, name);
}
}
21 changes: 13 additions & 8 deletions kernel/fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,16 @@ struct superblock {

// On-disk inode structure
struct dinode {
short type; // File type
short major; // Major device number (T_DEVICE only)
short minor; // Minor device number (T_DEVICE only)
short nlink; // Number of links to inode in file system
uint size; // Size of file (bytes)
uint addrs[NDIRECT+1]; // Data block addresses
short type; // Tipo de archivo
short major; // Número de dispositivo mayor
short minor; // Número de dispositivo menor
short nlink; // Número de enlaces
uint size; // Tamaño del archivo en bytes
uint addrs[NDIRECT+1]; // Direcciones de bloques de datos
int perm; // Permisos del archivo
char padding[57]; // Ajusta el tamaño del padding según sea necesario

//char padding[BSIZE - ((sizeof(short) * 3 + sizeof(uint) * (NDIRECT + 2) + sizeof(int)) % BSIZE)];
};

// Inodes per block.
Expand All @@ -44,6 +48,8 @@ struct dinode {
// Block containing inode i
#define IBLOCK(i, sb) ((i) / IPB + sb.inodestart)

void readsb(int dev, struct superblock *sb);

// Bitmap bits per block
#define BPB (BSIZE*8)

Expand All @@ -56,5 +62,4 @@ struct dinode {
struct dirent {
ushort inum;
char name[DIRSIZ];
};

};
Loading